From 0c92b18a1e174f84aaa9c37b821a4752d253c8fd Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 3 Sep 2016 11:19:19 -0400 Subject: [PATCH 01/42] Updating the mgxs library format manual as a starting point --- docs/source/io_formats/mgxs_library.rst | 385 +++++++----------------- 1 file changed, 109 insertions(+), 276 deletions(-) diff --git a/docs/source/io_formats/mgxs_library.rst b/docs/source/io_formats/mgxs_library.rst index b6708a88d..0313369d9 100644 --- a/docs/source/io_formats/mgxs_library.rst +++ b/docs/source/io_formats/mgxs_library.rst @@ -8,19 +8,17 @@ OpenMC can be run in continuous-energy mode or multi-group mode, provided the nuclear data is available. In continuous-energy mode, the ``cross_sections.xml`` file contains necessary meta-data for each data set, including the name and a file system location where the complete library -can be found. In multi-group mode, this ``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``. 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,112 @@ 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. + - **inverse velocities** (*double[]*) -- Average inverse velocitiy + for each of the groups in the library. This is an optional + attribute. -```` 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: - **awr** (*double*) -- The atomic weight ratio (optional, i.e. it + is not meaningful for material-wise data) + - **fissionable** (*int*) -- Whether the dataset is fissionable + (1) or not (0). + - **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-type** (*char[]*) -- The representation of the + scattering angular distribution. The options are either + "legendre", "histogram", or "tabular". + - **order** (*int*) -- Either the Legendre order, number of bins, + or number of points (depending on the value of `scatter-type`) + used to describe the angular distribution associated with each group-to-group transfer probability. -.. _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 - - 0.0 0.625E-6 20.0 - -*Default*: None, this must be provided. - -.. _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. +Temperature-dependent data, provided for temperature K. +: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]. + - **scatter matrix** (*double[][][]* or *double[][][][][]*) -- + Scattering moment matrices. This dataset 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 `scatter-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 matrix** (*double[][]* or *double[][][][]*) -- + Scattering multiplicity matrices. + This dataset 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 is not repeated for + every Legendre moment or histogram/tabular bin. This matrix + follows the same arrangement as described for the `scatter` + dataset, with the exception of the data needed to provide the + scattering type information. + This dataset is optional, if it is not provided no multiplication + (i.e., values of 1.0) will be assumed. + - **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 data set + 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 data set + 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 data set + 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`. \ No newline at end of file From 35c8caaae8dc9ce1ddd1a70b259c99b5f0cf2e85 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 3 Sep 2016 13:09:55 -0400 Subject: [PATCH 02/42] Updated python api to support new MGXS Library format --- openmc/mgxs/library.py | 105 ++---- openmc/mgxs_library.py | 791 +++++++++++++++++++++++------------------ 2 files changed, 471 insertions(+), 425 deletions(-) diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 4b68952a6..9f0e173f3 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -822,11 +822,12 @@ 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). + (i.e., the library). 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 ---------- @@ -845,18 +846,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 @@ -890,10 +879,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) @@ -922,11 +907,6 @@ 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} - if nuclide is not 'total': xsdata.zaid = self._nuclides[nuclide][0] xsdata.awr = self._nuclides[nuclide][1] @@ -979,48 +959,52 @@ 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)) + 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. + Multi-Group mode of OpenMC. Note that this library will not make use + of nested temperature tables. Every dataset in te library will be + treated as if it was at the same default temperature. Parameters ---------- @@ -1031,18 +1015,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 ------- @@ -1094,8 +1066,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 @@ -1117,16 +1087,13 @@ class Library(object): 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 @@ -1134,24 +1101,15 @@ class Library(object): 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 te 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 @@ -1198,8 +1156,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 37ad6c1be..68c0063f2 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1,82 +1,31 @@ from collections import Iterable from numbers import Real, Integral -from xml.etree import ElementTree as ET import sys 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 + check_less_than, check_iterable_type if sys.version_info[0] >= 3: basestring = str # Supported incoming particle MGXS angular treatment representations +_REPRESENTATION_ISOTROPIC = 1 +_REPRESENTATION_ANGLE = 2 +_SCATTER_TYPE_TABULAR = 3 +_SCATTER_TYPE_LEGENDRE = 4 +_SCATTER_TYPE_HISTOGRAM = 5 _REPRESENTATIONS = ['isotropic', 'angle'] - - -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 +_REPRESENTATIONS_TEXT = {'isotropic': _REPRESENTATION_ISOTROPIC, + 'angle': _REPRESENTATION_ANGLE} +_SCATTER_TYPES = ['tabular', 'legendre', 'histogram'] +_SCATTER_TYPES_TEXT = {'tabular': _SCATTER_TYPE_TABULAR, + 'legendre': _SCATTER_TYPE_LEGENDRE, + 'histogram': _SCATTER_TYPE_HISTOGRAM} class XSdata(object): @@ -85,40 +34,37 @@ class XSdata(object): Parameters ---------- - name : str, optional + name : str Name of the mgxs data set. energy_groups : openmc.mgxs.EnergyGroups Energygroup structure representation : {'isotropic', 'angle'}, optional Method used in generating the MGXS (isotropic or angle-dependent flux weighting). Defaults to 'isotropic' + temperatures : numpy.ndarray + Temperatures (in units of Kelvin) of the provided datasets. Defaults + to a single temperature at 300K. Attributes ---------- name : str Unique identifier for the xsdata object - alias : str - Separate unique identifier for the xsdata object awr : float Atomic weight ratio of an isotope. That is, the ratio of the mass of the isotope to the mass of a single neutron. - kT : float - Temperature (in units of MeV). + temperatures : numpy.ndarray + Temperatures (in units of Kelvin) of the provided datasets. Defaults + to a single temperature at 300K. 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_type : {'legendre', 'histogram', or 'tabular'} Angular distribution representation (legendre, histogram, or tabular) 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). @@ -160,16 +106,16 @@ class XSdata(object): 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 + scatter_matrix : 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 + orders) if ``scatter_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 + multiplicity_matrix : 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 @@ -218,29 +164,28 @@ class XSdata(object): """ - def __init__(self, name, energy_groups, representation='isotropic'): + def __init__(self, name, energy_groups, temperatures=[300.], + representation='isotropic'): # Initialize class attributes - self._name = name - self._energy_groups = energy_groups - self._representation = representation - self._alias = None + self.name = name + self.energy_groups = energy_groups + self.temperatures = temperatures + self.representation = representation self._awr = None - self._kT = None self._fissionable = False - self._scatt_type = 'legendre' + self._scatter_type = 'legendre' 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] @property def name(self): @@ -254,30 +199,26 @@ class XSdata(object): def representation(self): return self._representation - @property - def alias(self): - return self._alias - @property def awr(self): return self._awr @property - def kT(self): - return self._kT + def fissionable(self): + return self._fissionable @property - def scatt_type(self): - return self._scatt_type + def temperatures(self): + return self._temperatures + + @property + def scatter_type(self): + return self._scatter_type @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 @@ -299,12 +240,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): @@ -324,36 +265,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_type 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) @@ -380,13 +321,6 @@ 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, basestring) - self._alias = alias - else: - self._alias = self._name @awr.setter def awr(self, awr): @@ -395,19 +329,28 @@ class XSdata(object): check_greater_than('awr', awr, 0.0) self._awr = awr - @kT.setter - def kT(self, kT): - # Check validity of type and that the kT value is >= 0 - check_type('kT', kT, Real) - check_greater_than('kT', kT, 0.0, equality=True) - self._kT = kT + @fissionable.setter + def fissionable(self, fissionable): + check_type('fissionable', fissionable, bool) + self._fissionable = fissionable - @scatt_type.setter - def scatt_type(self, scatt_type): + @temperatures.setter + def temperatures(self, temperatures): + check_type('temperatures', temperatures, Iterable, + expected_iter_type=Real) + # Convert to a numpy array so we can easily get the shape for + # checking + nptemperatures = np.asarray(temperatures) + + check_value('temperatures dimensionality', nptemperatures.ndim, [1]) + + self._temperatures = nptemperatures + + @scatter_type.setter + def scatter_type(self, scatter_type): # 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_type', scatter_type, _SCATTER_TYPES) + self._scatter_type = scatter_type @order.setter def order(self, order): @@ -416,29 +359,6 @@ 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 @@ -457,42 +377,111 @@ class XSdata(object): check_type('use_chi', use_chi, bool) self._use_chi = use_chi - @total.setter - def total(self, total): + def set_total(self, total, temperature=300.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + total: nd.nparray + Total Cross Section + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 300K + + 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]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - self._total = nptotal + i = self.temperatures.tolist().index(temperature) + self._total[i] = nptotal - @absorption.setter - def absorption(self, absorption): + def set_absorption(self, absorption, temperature=300.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + absorption: nd.nparray + Absorption Cross Section + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 300K + + 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]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - self._absorption = npabsorption + i = self.temperatures.tolist().index(temperature) + self._absorption[i] = npabsorption - @fission.setter - def fission(self, fission): + def set_fission(self, fission, temperature=300.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + fission: nd.nparray + Fission Cross Section + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 300K + + 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]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - self._fission = npfission + i = self.temperatures.tolist().index(temperature) + self._fission[i] = npfission - if np.sum(self._fission) > 0.0: + if np.sum(npfission) > 0.0: self._fissionable = True - @kappa_fission.setter - def kappa_fission(self, kappa_fission): + def set_kappa_fission(self, kappa_fission, temperature=300.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + kappa_fission: nd.nparray + Kappa-Fission Cross Section + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 300K + + 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 @@ -500,18 +489,36 @@ class XSdata(object): npkappa_fission = np.asarray(kappa_fission) check_value('kappa fission shape', npkappa_fission.shape, [self.vector_shape]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - self._kappa_fission = npkappa_fission + i = self.temperatures.tolist().index(temperature) + self._kappa_fission[i] = npkappa_fission - if np.sum(self._kappa_fission) > 0.0: + if np.sum(npkappa_fission) > 0.0: self._fissionable = True - @chi.setter - def chi(self, chi): + def set_chi(self, chi, temperature=300.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + chi: nd.nparray + Fission Spectrum + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 300K + + 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) @@ -522,25 +529,61 @@ class XSdata(object): if npchi.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 = self.temperatures.tolist().index(temperature) + self._chi[i] = npchi if self.use_chi is not None: self.use_chi = True - @scatter.setter - def scatter(self, scatter): + def set_scatter_matrix(self, scatter, temperature=300.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + scatter: nd.nparray + Scattering Matrix Cross Section + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 300K + + See also + -------- + openmc.mgxs_library.set_scatter_matrix_mgxs() + + """ # 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]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - self._scatter = npscatter + i = self.temperatures.tolist().index(temperature) + self._scatter_matrix[i] = npscatter - @multiplicity.setter - def multiplicity(self, multiplicity): + def set_multiplicity_matrix(self, multiplicity, temperature=300.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + multiplicity: nd.nparray + Multiplicity Matrix Cross Section + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 300K + + See also + -------- + openmc.mgxs_library.set_multiplicity_matrix_mgxs() + + """ # Convert to a numpy array so we can easily get the shape for # checking npmultiplicity = np.asarray(multiplicity) @@ -548,11 +591,29 @@ class XSdata(object): max_depth=len(npmultiplicity.shape)) check_value('multiplicity shape', npmultiplicity.shape, [self.matrix_shape]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - self._multiplicity = npmultiplicity + i = self.temperatures.tolist().index(temperature) + self._multiplicity_matrix[i] = npmultiplicity - @nu_fission.setter - def nu_fission(self, nu_fission): + def set_nu_fission(self, nu_fission, temperature=300.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + nu_fission: nd.nparray + Nu-fission Cross Section + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 300K + + 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. @@ -569,6 +630,8 @@ class XSdata(object): check_iterable_type('nu_fission', npnu_fission, Real, max_depth=len(npnu_fission.shape)) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) if self.use_chi is not None: if self.use_chi: @@ -582,14 +645,18 @@ class XSdata(object): [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 npnu_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 = self.temperatures.tolist().index(temperature) + self._nu_fission[i] = npnu_fission + if np.sum(npnu_fission) > 0.0: self._fissionable = True - def set_total_mgxs(self, total, nuclide='total', xs_type='macro', - subdomain='all'): + def set_total_mgxs(self, total, temperature=300., 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. @@ -599,6 +666,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 units of Kelvin) of the provided dataset. Defaults + to 300K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -621,16 +691,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) + i = self.temperatures.tolist().index(temperature) if self.representation is 'isotropic': - self._total = total.get_xs(nuclides=nuclide, xs_type=xs_type, - subdomains=subdomain) + self._total[i] = total.get_xs(nuclides=nuclide, xs_type=xs_type, + subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_absorption_mgxs(self, absorption, nuclide='total', - xs_type='macro', subdomain=None): + def set_absorption_mgxs(self, absorption, temperature=300., + 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. @@ -639,6 +712,9 @@ class XSdata(object): absorption: openmc.mgxs.AbsorptionXS MGXS Object containing the absorption cross section for the domain of interest. + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 300K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -661,17 +737,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) + i = self.temperatures.tolist().index(temperature) if self.representation is 'isotropic': - self._absorption = absorption.get_xs(nuclides=nuclide, - xs_type=xs_type, - subdomains=subdomain) + self._absorption[i] = absorption.get_xs(nuclides=nuclide, + xs_type=xs_type, + subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_fission_mgxs(self, fission, nuclide='total', xs_type='macro', - subdomain=None): + def set_fission_mgxs(self, fission, temperature=300., 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. @@ -680,6 +759,9 @@ class XSdata(object): fission: openmc.mgxs.FissionXS MGXS Object containing the fission cross section for the domain of interest. + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 300K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -702,17 +784,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) + i = self.temperatures.tolist().index(temperature) if self.representation is 'isotropic': - self._fission = fission.get_xs(nuclides=nuclide, - xs_type=xs_type, - subdomains=subdomain) + self._fission[i] = fission.get_xs(nuclides=nuclide, + xs_type=xs_type, + subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_nu_fission_mgxs(self, nu_fission, nuclide='total', - xs_type='macro', subdomain=None): + def set_nu_fission_mgxs(self, nu_fission, temperature=300., + 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. @@ -721,6 +806,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 units of Kelvin) of the provided dataset. Defaults + to 300K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -744,11 +832,14 @@ 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) + i = self.temperatures.tolist().index(temperature) if self.representation is 'isotropic': - self._nu_fission = nu_fission.get_xs(nuclides=nuclide, - xs_type=xs_type, - subdomains=subdomain) + self._nu_fission[i] = nu_fission.get_xs(nuclides=nuclide, + xs_type=xs_type, + subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -761,8 +852,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=300., + 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. @@ -772,6 +864,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 units of Kelvin) of the provided dataset. Defaults + to 300K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -794,17 +889,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) + i = self.temperatures.tolist().index(temperature) if self.representation is 'isotropic': - self._kappa_fission = k_fission.get_xs(nuclides=nuclide, - xs_type=xs_type, - subdomains=subdomain) + self._kappa_fission[i] = k_fission.get_xs(nuclides=nuclide, + xs_type=xs_type, + subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_chi_mgxs(self, chi, nuclide='total', xs_type='macro', - subdomain=None): + def set_chi_mgxs(self, chi, temperature=300., 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. @@ -812,6 +910,9 @@ class XSdata(object): ---------- chi: openmc.mgxs.Chi MGXS Object containing chi for the domain of interest. + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 300K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -839,10 +940,13 @@ 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) + i = self.temperatures.tolist().index(temperature) if self.representation is 'isotropic': - self._chi = chi.get_xs(nuclides=nuclide, - xs_type=xs_type, subdomains=subdomain) + self._chi[i] = chi.get_xs(nuclides=nuclide, + xs_type=xs_type, subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -850,8 +954,9 @@ class XSdata(object): 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=300., + 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 @@ -862,6 +967,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 units of Kelvin) of the provided dataset. Defaults + to 300K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -884,8 +992,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_type != 'legendre'): msg = 'Anisotropic scattering representations other than ' \ 'Legendre expansions have not yet been implemented in ' \ 'openmc.mgxs.' @@ -901,13 +1011,14 @@ class XSdata(object): check_value('legendre_order', scatter.legendre_order, [self.order]) + i = self.temperatures.tolist().index(temperature) if self.representation is 'isotropic': # Get the scattering orders in the outermost dimension - self._scatter = np.zeros((self.num_orders, - self.energy_groups.num_groups, - self.energy_groups.num_groups)) + 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) @@ -915,10 +1026,12 @@ class XSdata(object): 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=300., 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 @@ -935,6 +1048,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 units of Kelvin) of the provided dataset. Defaults + to 300K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -958,6 +1074,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): @@ -970,102 +1089,81 @@ class XSdata(object): check_value('domain_type', scatter.domain_type, ['universe', 'cell', 'material', 'mesh']) + i = self.temperatures.tolist().index(temperature) if self.representation is '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) + self._multiplicity_matrix[i] = np.divide(nuscatt, scatt) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - self._multiplicity = np.nan_to_num(self._multiplicity) + 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 _get_xsdata_group(self, file, compression): + if compression is not None: + check_type("compression", compression, Integral) + check_greater_than("compression", compression, 0, equality=True) + check_less_than("compression", compression, 9, equality=True) - if self._alias is not None: - subelement = ET.SubElement(element, 'alias') - subelement.text = self.alias + grp = file.create_group(self.name) + if self.awr is not None: + grp.attrs['awr'] = self.awr + if self.fissionable is not None: + grp.attrs['fissionable'] = self.fissionable + if self.representation is not None: + grp.attrs['representation'] = \ + np.string_(_REPRESENTATIONS_TEXT[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_type is not None: + grp.attrs['scatter-type'] = \ + np.string_(_SCATTER_TYPES_TEXT[self.scatter_type]) + if self.order is not None: + grp.attrs['order'] = self.order - if self._kT is not None: - subelement = ET.SubElement(element, 'kT') - subelement.text = str(self._kT) - - if self._awr is not None: - subelement = ET.SubElement(element, 'awr') - subelement.text = str(self._awr) - - if self._fissionable is not None: - subelement = ET.SubElement(element, 'fissionable') - subelement.text = str(self._fissionable) - - if self._representation is not None: - subelement = ET.SubElement(element, 'representation') - subelement.text = self._representation - - 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) - - if self._scatt_type is not None: - subelement = ET.SubElement(element, 'scatt_type') - subelement.text = self._scatt_type - - if self._order is not None: - subelement = ET.SubElement(element, 'order') - subelement.text = str(self._order) - - 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'])) - - 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 + # Create the temperature datasets + for i, temperature in enumerate(self.temperatures): + xsgrp = grp.create_group(str(np.round(temperature)) + "K") + if self._total[i] is not None: + xsgrp.create_dataset("total", data=self._total[i], + compression=compression) + if self._absorption[i] is not None: + xsgrp.create_dataset("absorption", data=self._absorption[i], + compression=compression) + if self._scatter_matrix[i] is not None: + xsgrp.create_dataset("scatter matrix", + data=self._scatter_matrix[i], + compression=compression) + if self._multiplicity_matrix[i] is not None: + xsgrp.create_dataset("multiplicity matrix", + data=self._multiplicity_matrix[i], + compression=compression) + if self.fissionable: + if self._fission[i] is not None: + xsgrp.create_dataset("fission", data=self._fission[i], + compression=compression) + if self._kappa_fission[i] is not None: + xsgrp.create_dataset("kappa-fission", + data=self._kappa_fission[i], + compression=compression) + if self._chi[i] is not None: + xsgrp.create_dataset("chi", data=self._chi[i], + compression=compression) + if self._nu_fission[i] is not None: + xsgrp.create_dataset("nu-fission", + data=self._nu_fission[i], + compression=compression) class MGXSLibrary(object): @@ -1073,6 +1171,11 @@ class MGXSLibrary(object): Corresponds directly to the MG version of the cross_sections.xml input file. + Parameters + ---------- + energy_groups : openmc.mgxs.EnergyGroups + Energygroup structure + Attributes ---------- energy_groups : openmc.mgxs.EnergyGroups @@ -1084,10 +1187,9 @@ class MGXSLibrary(object): """ def __init__(self, energy_groups): - self._xsdatas = [] - self._energy_groups = energy_groups + self.energy_groups = energy_groups self._inverse_velocities = None - self._cross_sections_file = ET.Element('cross_sections') + self._xsdatas = [] @property def inverse_velocities(self): @@ -1097,6 +1199,10 @@ class MGXSLibrary(object): def energy_groups(self): return self._energy_groups + @property + def temperatures(self): + return self._temperatures + @property def xsdatas(self): return self._xsdatas @@ -1163,52 +1269,35 @@ 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', compression=None): + """Create an mgxs.h5 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.xml. + compression : None or int + The compression level to use in the datasets within the hdf5 file. + A value of None implies no compression, numbers between 0 and 9 + refer to the compression level using the gzip algorithm. + Defaults to None. """ - # Reset xml element tree - self._cross_sections_file.clear() + check_type('filename', filename, basestring) + if compression is not None: + check_type("compression", compression, Integral) + check_greater_than("compression", compression, 0, equality=True) + check_less_than("compression", compression, 9, equality=True) - 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 + if self.inverse_velocities is not None: + file.attrs['inverse velocities'] = self.inverse_velocities - # 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._get_xsdata_group(file, compression) - # 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() From ab05e1b71b41ad6da911f7d36e6627d84a496d79 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 4 Sep 2016 05:26:16 -0400 Subject: [PATCH 03/42] finished updating mgxs_header, now just need to update the code that uses it --- docs/source/io_formats/mgxs_library.rst | 3 +- src/hdf5_interface.F90 | 78 +- src/mgxs_data.F90 | 6 +- src/mgxs_header.F90 | 2659 +++++++++++------------ 4 files changed, 1400 insertions(+), 1346 deletions(-) diff --git a/docs/source/io_formats/mgxs_library.rst b/docs/source/io_formats/mgxs_library.rst index 0313369d9..ccd68c184 100644 --- a/docs/source/io_formats/mgxs_library.rst +++ b/docs/source/io_formats/mgxs_library.rst @@ -62,7 +62,8 @@ data for the nuclide or material that it represents. ignored otherwise. - **scatter-type** (*char[]*) -- The representation of the scattering angular distribution. The options are either - "legendre", "histogram", or "tabular". + "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-type`) used to describe the angular distribution associated with each group-to-group transfer probability. diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index 415ec55c9..13abd9754 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,14 +85,17 @@ module hdf5_interface public :: write_dataset public :: read_dataset + public :: check_attribute public :: write_attribute public :: read_attribute public :: file_create public :: file_open public :: file_close public :: create_group + public :: check_group public :: open_group public :: close_group + public :: check_dataset public :: open_dataset public :: close_dataset public :: get_shape @@ -245,6 +249,52 @@ contains end subroutine get_groups +!=============================================================================== +! CHECK_ATTRIBUTE Checks to see if an attribute exists in the object +!=============================================================================== + + function check_attribute(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 check_attribute + +!=============================================================================== +! CHECK_GROUP Checks to see if a group exists in the object +!=============================================================================== + + function check_group(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 check_group + +!=============================================================================== +! CHECK_DATASET Checks to see if a dataset exists in the object +!=============================================================================== + + function check_dataset(object_id, name) result(exists) + integer(HID_T), intent(in) :: object_id + character(*), intent(in) :: name ! name of group + logical :: exists + + ! Wrap check_group since the method used there will work here too + exists = check_group(object_id, name) + + end function check_dataset + !=============================================================================== ! GET_DATASETS Gets a list of all the datasets in a given location. !=============================================================================== @@ -296,7 +346,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 = check_group(group_id, name) ! open group if it exists if (exists) then @@ -319,7 +369,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 = check_group(group_id, name) ! create group if (exists) then @@ -357,7 +407,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 = check_group(group_id, name) ! open group if it exists if (exists) then @@ -2487,6 +2537,28 @@ 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/mgxs_data.F90 b/src/mgxs_data.F90 index 05d6eb5ec..aa96910f3 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -172,7 +172,6 @@ contains subroutine create_macro_xs() integer :: i_mat ! index in materials array type(Material), pointer :: mat ! current material - integer :: scatt_type allocate(macro_xs(n_materials)) @@ -182,9 +181,6 @@ contains ! 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) @@ -192,7 +188,7 @@ contains 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) + max_order) end do end subroutine create_macro_xs diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 9409398b3..2f569c6fe 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -1,35 +1,66 @@ module mgxs_header + use, intrinsic :: ISO_FORTRAN_ENV + use, intrinsic :: ISO_C_BINDING + + use hdf5, only: HID_T, HSIZE_T, SIZE_T, h5iget_name_f + use h5lt, only: h5ltpath_valid_f + use constants, only: MAX_FILE_LEN, ZERO, ONE, TWO, PI use error, only: fatal_error - use, intrinsic :: ISO_FORTRAN_ENV, only: OUTPUT_UNIT - use list_header, only: ListInt + use 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 + 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 + 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=104) :: name ! name of dataset, e.g. 92235.03c + 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_type ! either legendre, histogram, or tabular. 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 @@ -51,63 +82,56 @@ 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) + 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(in) :: 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 + 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) + 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 + end subroutine mgxs_combine_ + + pure function mgxs_get_xs_(this, t, xstype, gin, gout, uvw, mu) result(xs_val) import Mgxs class(Mgxs), intent(in) :: this + integer, intent(in) :: t ! Temperature index of data character(*), intent(in) :: xstype ! Cross Section Type integer, intent(in) :: gin ! Incoming Energy group integer, optional, intent(in) :: gout ! Outgoing Group real(8), optional, intent(in) :: uvw(3) ! Requested Angle real(8), optional, intent(in) :: mu ! Change in angle - real(8) :: xs ! Resultant xs + 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) + function mgxs_sample_fission_(this, t, gin, uvw) result(gout) 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) :: t ! Temperature index integer, intent(in) :: gin ! Incoming energy group real(8), intent(in) :: uvw(3) ! Particle Direction integer :: gout ! Sampled outgoing group end function mgxs_sample_fission_ - subroutine mgxs_sample_scatter_(this, uvw, gin, gout, mu, wgt) + subroutine mgxs_sample_scatter_(this, t, uvw, gin, gout, mu, wgt) import Mgxs - class(Mgxs), intent(in) :: this + class(Mgxs), intent(in) :: this + integer, intent(in) :: t ! Temperature index of data real(8), intent(in) :: uvw(3) ! Incoming neutron direction integer, intent(in) :: gin ! Incoming neutron group integer, intent(out) :: gout ! Sampled outgoin group @@ -115,9 +139,10 @@ module mgxs_header real(8), intent(inout) :: wgt ! Particle weight end subroutine mgxs_sample_scatter_ - subroutine mgxs_calculate_xs_(this, gin, uvw, xs) + subroutine mgxs_calculate_xs_(this, t, gin, uvw, xs) import Mgxs, MaterialMacroXS class(Mgxs), intent(in) :: this + integer, intent(in) :: t ! Temperature index integer, intent(in) :: gin ! Incoming neutron group real(8), intent(in) :: uvw(3) ! Incoming neutron direction type(MaterialMacroXS), intent(inout) :: xs ! Resultant Mgxs Data @@ -130,18 +155,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 +171,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 @@ -184,69 +191,185 @@ module mgxs_header !=============================================================================== ! 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. +! the xs_id object node itself. !=============================================================================== - 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(in) :: 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 :: hdf5_err + integer(SIZE_T) :: name_len, name_file_len + integer(HID_T) :: kT_group, kT_dset + character(MAX_FILE_LEN), allocatable :: dset_names(:) + real(8), allocatable :: temps_available(:) ! temperatures available + real(8) :: temp_desired + real(8) :: temp_actual + logical :: exists + 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) + call h5iget_name_f(xs_id, this % name, name_len, name_file_len, hdf5_err) + + ! Get rid of leading '/' + this % name = trim(this % name(2:)) + + if (check_attribute(xs_id, "awr")) then + call read_attribute(this % awr, xs_id, "awr") else this % awr = -ONE end if - if (check_for_node(node_xsdata, "scatt_type")) then - call get_node_value(node_xsdata, "scatt_type", temp_str) - temp_str = trim(to_lower(temp_str)) - if (temp_str == 'legendre') then - this % scatt_type = ANGLE_LEGENDRE - else if (temp_str == 'histogram') then - this % scatt_type = ANGLE_HISTOGRAM - else if (temp_str == 'tabular') then - this % scatt_type = ANGLE_TABULAR + + ! 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))) + temps_available(i) = temps_available(i) / K_BOLTZMANN + end do + + 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) + ! TODO: Get bounding temperatures + call fatal_error("Temperature interpolation not yet implemented") + 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 (check_attribute(xs_id, "scatter-type")) then + call read_attribute(temp_str, xs_id, "scatter-type") + temp_str = trim(temp_str) + if (to_lower(temp_str) == 'legendre') then + this % scatter_type = ANGLE_LEGENDRE + else if (to_lower(temp_str) == 'histogram') then + this % scatter_type = ANGLE_HISTOGRAM + else if (to_lower(temp_str) == 'tabular') then + this % scatter_type = ANGLE_TABULAR else - call fatal_error("Invalid scatt_type option!") + call fatal_error("Invalid scatter-type option!") end if else - this % scatt_type = ANGLE_LEGENDRE + this % scatter_type = ANGLE_LEGENDRE end if - - if (check_for_node(node_xsdata, "fissionable")) then - call get_node_value(node_xsdata, "fissionable", temp_str) - temp_str = to_lower(temp_str) - if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') then - this % fissionable = .true. - else - this % fissionable = .false. - end if + if (check_attribute(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 + ! Get the library's value for the order + if (check_attribute(xs_id, "order")) then + call read_attribute(order_dim, xs_id, "order") + else + call fatal_error("Order must be provided!") + end if - 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 + ! 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 % scatter_type == ANGLE_LEGENDRE) then + order_dim = order_dim + 1 + else + order_dim = order_dim + end if + + ! Get angular meta-data and allocate as needed based off of the + ! information therein + select type(this) + type is (MgxsAngle) + if (check_attribute(xs_id, "num-polar")) then + call read_attribute(this % n_pol, xs_id, "num-polar") + else + call fatal_error("num-polar must be provided!") + end if + + if (check_attribute(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 + + ! 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 + 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 select + + end subroutine mgxs_from_hdf5 + + subroutine mgxsiso_from_hdf5(this, xs_id, groups, temperature, method, & + tolerance, get_kfiss, get_fiss, max_order) + 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(in) :: 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 - type(Node), pointer :: node_legendre_mu character(MAX_LINE_LEN) :: temp_str + integer(HID_T) :: xsdata_grp logical :: enable_leg_mu real(8), allocatable :: temp_arr(:), temp_2d(:, :) real(8), allocatable :: temp_mult(:, :) @@ -256,596 +379,138 @@ module mgxs_header real(8) :: dmu, mu, norm integer :: order, order_dim, gin, gout, l, arr_len integer :: legendre_mu_points, imu + type(VectorInt) :: temps_to_read + integer :: t ! Call generic data gathering routine (will populate the metadata) - call mgxs_init_file(this, node_xsdata) + call mgxs_from_hdf5(this, xs_id, temperature, method, tolerance, & + temps_to_read, order_dim) + !!!TODO: Fix + enable_leg_mu = .True. ! 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) - else - call fatal_error("Order must be provided!") - end if - - ! Before retrieving the data, store the dimensionality of the data in - ! order_dim. For Legendre data, we usually refer to it as Pn where - ! n is the order. However Pn has n+1 sets of points (since you need to - ! the count the P0 moment). Adjust for that. Histogram and Tabular - ! formats dont need this adjustment. - if (this % scatt_type == ANGLE_LEGENDRE) then - order_dim = order + 1 - else - order_dim = order - end if - - ! The input is gathered in the more user-friendly facing format of - ! Gout x Gin x Order. We will get it in that format in input_scatt, - ! but then need to convert it to a more useful ordering for processing - ! (Order x Gout x Gin). - allocate(input_scatt(groups, groups, order_dim)) - if (check_for_node(node_xsdata, "scatter")) then - allocate(temp_arr(groups * groups * order_dim)) - call get_node_array(node_xsdata, "scatter", temp_arr) - input_scatt = reshape(temp_arr, (/groups, groups, order_dim/)) - deallocate(temp_arr) - - ! Compare the number of orders given with the maximum order of the - ! problem. Strip off the supefluous orders if needed. - if (this % scatt_type == ANGLE_LEGENDRE) then - order = min(order_dim - 1, max_order) - order_dim = order + 1 - end if - allocate(temp_scatt(groups, groups, order_dim)) - temp_scatt(:, :, :) = input_scatt(:, :, 1:order_dim) - - ! Take input format (groups, groups, order) and convert to - ! the more useful format needed for scattdata: (order, groups, groups) - ! However, if scatt_type was ANGLE_LEGENDRE (i.e., the data was - ! provided as Legendre coefficients), and the user requested that - ! these legendres be converted to tabular form (note this is also - ! the default behavior), convert that now. - if (this % scatt_type == ANGLE_LEGENDRE .and. enable_leg_mu) then - ! Convert input parameters to what we need for the rest. - this % scatt_type = ANGLE_TABULAR - order_dim = legendre_mu_points - order = order_dim - dmu = TWO / real(order - 1, 8) - - allocate(scatt_coeffs(order_dim, groups, groups)) - do gin = 1, groups - do gout = 1, groups - norm = ZERO - do imu = 1, order_dim - if (imu == 1) then - mu = -ONE - else if (imu == order_dim) then - mu = ONE - else - mu = -ONE + real(imu - 1, 8) * dmu - end if - scatt_coeffs(imu, gout, gin) = & - evaluate_legendre(temp_scatt(gout, gin, :),mu) - ! Ensure positivity of distribution - if (scatt_coeffs(imu, gout, gin) < ZERO) & - scatt_coeffs(imu, gout, gin) = ZERO - ! And accrue the integral - if (imu > 1) then - norm = norm + HALF * dmu * & - (scatt_coeffs(imu - 1, gout, gin) + & - scatt_coeffs(imu, gout, gin)) - end if + 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(i))) // "K" + xsdata_grp = open_group(xs_id, trim(temp_str)) + if (this % fissionable) then + allocate(xs % nu_fission(groups)) + allocate(xs % chi(groups,groups)) + if (check_dataset(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 - ! 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 + deallocate(temp_arr) + + ! Get nu_fission (as a vector) + if (check_dataset(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 - end do - end do - else - ! Sticking with current representation, carry forward but change - ! the array ordering - allocate(scatt_coeffs(order_dim, groups, groups)) - do gin = 1, groups - do gout = 1, groups - do l = 1, order_dim - scatt_coeffs(l, gout, gin) = temp_scatt(gout, gin, l) + + else + ! chi isnt provided but is within nu_fission, existing as a matrix + ! So, get nu_fission (as a matrix) + if (check_dataset(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 - end do - end do - end if - deallocate(temp_scatt) - else - call fatal_error("Must provide scatter!") - end if - ! Allocate and initialize our ScattData Object. - if (this % scatt_type == ANGLE_HISTOGRAM) then - allocate(ScattDataHistogram :: this % scatter) - else if (this % scatt_type == ANGLE_TABULAR) then - allocate(ScattDataTabular :: this % scatter) - else if (this % scatt_type == ANGLE_LEGENDRE) then - allocate(ScattDataLegendre :: this % scatter) - end if - - ! Initialize the ScattData Object - call this % scatter % init(temp_mult, scatt_coeffs) - - ! Check sigA to ensure it is not 0 since it is - ! often divided by in the tally routines - ! (This may happen with Helium data) - do gin = 1, groups - if (this % absorption(gin) == ZERO) this % absorption(gin) = 1E-10_8 - end do - - ! Get, or infer, total xs data. - allocate(this % total(groups)) - if (check_for_node(node_xsdata, "total")) then - call get_node_array(node_xsdata, "total", this % total) - else - this % total(:) = this % absorption(:) + this % scatter % scattxs(:) - end if - - ! Deallocate temporaries for the next material - deallocate(input_scatt, scatt_coeffs, temp_mult) - - ! Finally, check sigT to ensure it is not 0 since it is - ! often divided by in the tally routines - do gin = 1, groups - if (this % total(gin) == ZERO) this % total(gin) = 1E-10_8 - end do - - - end subroutine mgxsiso_init_file - - subroutine mgxsang_init_file(this, node_xsdata, groups, get_kfiss, get_fiss, & - max_order) - 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 - dangle = PI / real(this % n_pol, 8) - do ipol = 1, this % n_pol - this % polar(ipol) = (real(ipol, 8) - HALF) * dangle - end do - end if - if (check_for_node(node_xsdata, "azimuthal")) then - call fatal_error("User-Specified azimuthal angle bins not yet supported!") - ! When this feature is supported, this line will be activated - call get_node_array(node_xsdata, "azimuthal", this % azimuthal) - else - dangle = TWO * PI / real(this % n_azi, 8) - do iazi = 1, this % n_azi - this % azimuthal(iazi) = -PI + (real(iazi, 8) - HALF) * dangle - end do - end if - - ! Load the more specific data - allocate(this % nu_fission(groups, this % n_azi, this % n_pol)) - allocate(this % chi(groups, groups, this % n_azi, this % n_pol)) - if (this % fissionable) then - if (check_for_node(node_xsdata, "chi")) then - ! Chi was provided, that means they are giving chi and nu-fission - ! vectors - ! Get chi - allocate(temp_arr(1 * groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "chi", temp_arr) - ! Initialize counter for temp_arr - l = 0 - gin = 1 - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gout = 1, groups - l = l + 1 - this % chi(gout, gin, iazi, ipol) = temp_arr(l) - end do + ! Now pull out information needed for chi + xs % chi(:, :) = temp_2d ! 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)) + xs % chi(:, gin) = xs % chi(:, gin) / sum(xs % chi(:, gin)) end do - end do - end do + deallocate(temp_2d) + end if - ! 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!") + ! If we have a need* for the fission and kappa-fission x/s, get them + ! (*Need is defined as will be using it to tally) + if (get_fiss) then + allocate(xs % fission(groups)) + if (check_dataset(xsdata_grp, "fission")) then + 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 + if (get_kfiss) then + allocate(xs % k_fission(groups)) + if (check_dataset(xsdata_grp, "kappa-fission")) then + 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 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) + + allocate(xs % absorption(groups)) + if (check_dataset(xsdata_grp, "absorption")) then + call read_dataset(xs % absorption, xsdata_grp, "absorption") else - call fatal_error("kappa_fission data missing, required due to & - &kappa-fission tallies in tallies.xml file!") + call fatal_error("Must provide absorption!") 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. + ! Get multiplication data if present + allocate(temp_mult(groups, groups)) + if (check_dataset(xsdata_grp, "multiplicity matrix")) then + call read_dataset(temp_mult, xsdata_grp, "multiplicity matrix") else - call fatal_error("Unrecognized tabular_legendre/enable: " & - // temp_str) + temp_mult(:, :) = ONE 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 + ! Get scattering data + ! 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_dataset(xsdata_grp, "scatter matrix")) then + call read_dataset(input_scatt, xsdata_grp, "scatter matrix") - ! 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 + ! Compare the number of orders given with the maximum order of the + ! problem. Strip off the supefluous orders if needed. + if (this % scatter_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) - ! 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) + ! 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 xs is also + ! the default behavior), convert that now. + if (this % scatter_type == ANGLE_LEGENDRE .and. enable_leg_mu) then + ! Convert input parameters to what we need for the rest. + this % scatter_type = ANGLE_TABULAR + order_dim = legendre_mu_points + order = order_dim + dmu = TWO / real(order - 1, 8) - ! 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 + allocate(scatt_coeffs(order_dim, groups, groups)) do gin = 1, groups do gout = 1, groups norm = ZERO @@ -857,371 +522,476 @@ module mgxs_header 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) + scatt_coeffs(imu, gout, gin) = & + evaluate_legendre(temp_scatt(gout, gin, :),mu) ! Ensure positivity of distribution - if (scatt_coeffs(imu, gout, gin, iazi, ipol) < ZERO) & - scatt_coeffs(imu, gout, gin, iazi, ipol) = ZERO + 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, iazi, ipol) + & - scatt_coeffs(imu, gout, gin, iazi, ipol)) + (scatt_coeffs(imu - 1, gout, gin) + & + scatt_coeffs(imu, gout, gin)) end if - end do + 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(:, gout, gin, iazi, ipol) = & - scatt_coeffs(:, gout, gin, iazi, ipol) * & - temp_scatt(gout, gin, 1, iazi, ipol) / norm + scatt_coeffs(:, gout, gin) = scatt_coeffs(:, gout, gin) * & + temp_scatt(gout, gin, 1) / 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 + end do ! gout + end do ! gin + 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, iazi, ipol) = & - temp_scatt(gout, gin, l, iazi, ipol) + scatt_coeffs(l, gout, gin) = temp_scatt(gout, gin, l) end do end do end do - end do - end do - end if - deallocate(temp_scatt) - else - call fatal_error("Must provide scatter!") - end if + end if + deallocate(temp_scatt) + else + call fatal_error("Must provide scatter matrix!") + 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) + if (this % scatter_type == ANGLE_HISTOGRAM) then + allocate(ScattDataHistogram :: xs % scatter) + else if (this % scatter_type == ANGLE_TABULAR) then + allocate(ScattDataTabular :: xs % scatter) + else if (this % scatter_type == ANGLE_LEGENDRE) then + allocate(ScattDataLegendre :: xs % scatter) 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) + call xs % scatter % init(temp_mult, scatt_coeffs) - 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(:) + ! 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 - 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 + ! Get, or infer, total xs data. + allocate(xs % total(groups)) + if (check_dataset(xsdata_grp, "total")) then + call read_dataset(xs % total, xsdata_grp, "total") else - xs = this % scatter % scattxs(gin) * & - this % scatter % energy(gin) % data(gout) + xs % total(:) = xs % absorption(:) + xs % scatter % scattxs(:) 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 + ! Finally, 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 - 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 + ! Close the groups we have opened and deallocate + call close_group(xsdata_grp) + deallocate(input_scatt, scatt_coeffs, temp_mult) + end associate ! xs + end do ! Temperatures + end subroutine mgxsiso_from_hdf5 - integer :: iazi, ipol + subroutine mgxsang_from_hdf5(this, xs_id, groups, temperature, method, & + tolerance, get_kfiss, get_fiss, max_order) + 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(in) :: 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 + + character(MAX_LINE_LEN) :: temp_str + integer(HID_T) :: xsdata_grp + 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 + type(VectorInt) :: temps_to_read + integer :: t + + ! Call generic data gathering routine (will populate the metadata) + call mgxs_from_hdf5(this, xs_id, temperature, method, tolerance, & + temps_to_read, order_dim) + !!!TODO: Fix + enable_leg_mu = .True. + + ! 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(i))) // "K" + xsdata_grp = open_group(xs_id, trim(temp_str)) + if (this % fissionable) then + if (check_dataset(xsdata_grp, "chi")) then + ! Chi was provided, that means we need chi and nu-fission vectors + ! Get chi + allocate(temp_arr(1 * groups * this % n_azi * this % n_pol)) + 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 (check_dataset(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 (check_dataset(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 - 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 (check_dataset(xsdata_grp, "fission")) then + allocate(xs % fission(groups, this % n_azi, this % n_pol)) + 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 (check_dataset(xsdata_grp, "kappa-fission")) then + allocate(xs % k_fission(groups, this % n_azi, this % n_pol)) + 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 (check_dataset(xsdata_grp, "absorption")) then + allocate(xs % absorption(groups, this % n_azi, this % n_pol)) + call read_dataset(xs % absorption, xsdata_grp, "absorption") + 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_dataset(xsdata_grp, "multiplicity matrix")) then + call read_dataset(temp_mult, xsdata_grp, "multiplicity matrix") + else + temp_mult(:, :, :, :) = ONE + end if + + ! Get scattering data + ! 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_dataset(xsdata_grp, "scatter matrix")) then + allocate(temp_arr(groups * groups * order_dim * this % n_azi * & + this % n_pol)) + call read_dataset(temp_arr, xsdata_grp, "scatter matrix") + 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 % scatter_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 xs is also + ! the default behavior), convert that now. + if (this % scatter_type == ANGLE_LEGENDRE .and. enable_leg_mu) then + + ! Convert input parameters to what we need for the rest. + this % scatter_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 matrix!") + end if + + 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_type == ANGLE_HISTOGRAM) then + allocate(ScattDataHistogram :: xs % scatter(iazi, ipol) % obj) + else if (this % scatter_type == ANGLE_TABULAR) then + allocate(ScattDataTabular :: xs % scatter(iazi, ipol) % obj) + else if (this % scatter_type == ANGLE_LEGENDRE) then + allocate(ScattDataLegendre :: xs % scatter(iazi, ipol) % obj) + end if + + ! Initialize the ScattData Object + call xs % scatter(iazi, ipol) % obj % init(& + temp_mult(:, :, iazi, ipol), & + scatt_coeffs(:, :, :, iazi, ipol)) + end do + end do + + allocate(xs % total(groups, this % n_azi, this % n_pol)) + if (check_dataset(xsdata_grp, "total")) then + call read_dataset(xs % total, xsdata_grp, "total") + 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 + + ! Close the groups we have opened and deallocate + call close_group(xsdata_grp) + deallocate(input_scatt, 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, scatter_type, 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(out) :: scatter_type ! Type of scatter + integer, intent(out) :: order_dim ! Scattering data order size + + integer :: t, mat_max_order, max_order, order, n_pol, n_azi + real(8) :: dangle ! 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 = 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(i) + 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_type = nuclides(mat % nuclide(1)) % obj % scatter_type 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_type == ANGLE_HISTOGRAM) then ! Check all scattering data to ensure it is the same size do i = 2, mat % n_nuclides select type(nuc => nuclides(mat % nuclide(i)) % obj) type is (MgxsIso) - if (order /= size(nuc % scatter % dist(1) % data, dim=1)) & + 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_type == ANGLE_TABULAR) then ! Check all scattering data to ensure it is the same size do i = 2, mat % n_nuclides select type(nuc => nuclides(mat % nuclide(i)) % obj) type is (MgxsIso) - if (order /= size(nuc % scatter % dist(1) % data, dim=1)) & + 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_type == ANGLE_LEGENDRE) then ! Need to determine the maximum scattering order of all data in this material mat_max_order = 0 do i = 1, mat % n_nuclides select type(nuc => nuclides(mat % nuclide(i)) % obj) type is (MgxsIso) - if (size(nuc % scatter % dist(1) % data, dim=1) > mat_max_order) & - mat_max_order = size(nuc % scatter % dist(1) % data, dim=1) + 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 @@ -1230,135 +1000,190 @@ module mgxs_header order = min(mat_max_order, max_order) ! Ok, got our order, store the dimensionality order_dim = order + 1 - - ! Set our Scatter Object Type - allocate(ScattDataLegendre :: this % scatter) end if - ! Allocate and initialize data needed for macro_xs(i_mat) object - allocate(this % total(groups)) - this % total(:) = ZERO - allocate(this % absorption(groups)) - this % absorption(:) = ZERO - allocate(this % fission(groups)) - this % fission(:) = ZERO - allocate(this % k_fission(groups)) - this % k_fission(:) = ZERO - allocate(this % nu_fission(groups)) - this % nu_fission(:) = ZERO - allocate(this % chi(groups,groups)) - this % chi(:, :) = ZERO - allocate(temp_mult(groups,groups)) - temp_mult(:, :) = ZERO - allocate(mult_num(groups,groups)) - mult_num(:, :) = ZERO - allocate(mult_denom(groups,groups)) - mult_denom(:, :) = ZERO - allocate(scatt_coeffs(order_dim,groups,groups)) - scatt_coeffs(:, :, :) = ZERO + 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) + class(MgxsIso), 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 + + 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 :: mat_max_order, order, order_dim, nuc_order_dim + real(8), allocatable :: temp_mult(:, :), mult_num(:, :), mult_denom(:, :) + real(8), allocatable :: scatt_coeffs(:, :, :) + integer :: nuc_t + real(8) :: temp_actual, temp_desired + integer :: scatter_type + + ! Set the meta-data + call mgxs_combine(this, temps, mat, nuclides, scatter_type, 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(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 + + if (scatter_type == ANGLE_LEGENDRE) then + allocate(ScattDataLegendre :: this % xs(t) % scatter) + else if (scatter_type == ANGLE_TABULAR) then + allocate(ScattDataTabular :: this % xs(t) % scatter) + else if (scatter_type == 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) + select case (method) + case (TEMPERATURE_NEAREST) + ! Determine actual temperatures to read + temp_desired = temps % data(i) + nuc_t = minloc(abs(nuc % kTs - temp_desired), dim=1) + temp_actual = nuc % kTs(i_closest) + if (abs(temp_actual - temp_desired) >= 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.") + end if + + case (TEMPERATURE_INTERPOLATION) + ! TODO: Get bounding temperatures + call fatal_error("Temperature interpolation not yet implemented") + end select + + ! Copy atom density of nuclide in material + atom_density = mat % atom_density(i) + + select type(nuc) + type is (MgxsIso) + ! Perform our operations which depend upon the type + ! Add contributions to total, absorption, and fission data (if necessary) + this % xs(t) % total(:) = this % xs(t) % total(:) + & + atom_density * nuc % xs(nuc_t) % total(:) + this % xs(t) % absorption(:) = this % xs(t) % absorption(:) + & + atom_density * nuc % xs(nuc_t) % absorption(:) + if (nuc % fissionable) then + this % xs(t) % chi(:, :) = this % xs(t) % chi(:, :) + & + atom_density * nuc % xs(nuc_t) % chi(:, :) + this % xs(t) % nu_fission(:) = this % xs(t) % nu_fission(:) + & + atom_density * nuc % xs(nuc_t) % nu_fission(:) + if (allocated(nuc % xs(nuc_t) % fission)) then + this % xs(t) % fission(:) = this % xs(t) % fission(:) + & + atom_density * nuc % xs(nuc_t) % fission(:) + end if + if (allocated(nuc % xs(nuc_t) % k_fission)) then + this % xs(t) % k_fission(:) = this % xs(t) % k_fission(:) + & + atom_density * nuc % xs(nuc_t) % k_fission(:) + 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 % 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 + 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) + 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 % xs(nuc_t) % 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 % xs(nuc_t) % scatter % get_matrix(min(nuc_order_dim, order_dim)) + 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 + + ! Initialize the ScattData Object + call this % xs(t) % scatter % init(temp_mult, scatt_coeffs) + + ! 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(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) + 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 - integer, intent(in) :: scatt_type ! Legendre or Tabular Scatt? 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 @@ -1366,9 +1191,12 @@ module mgxs_header integer :: mat_max_order, order, order_dim, nuc_order_dim real(8), allocatable :: temp_mult(:, :, :, :), mult_num(:, :, :, :) real(8), allocatable :: mult_denom(:, :, :, :), scatt_coeffs(:, :, :, :, :) + integer :: nuc_t + real(8) :: temp_actual, temp_desired + integer :: scatter_type ! Set the meta-data - call mgxs_combine(this, mat, scatt_type) + call mgxs_combine(this, temps, mat, nuclides, scatter_type, 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 +1220,419 @@ 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(n_azi, n_pol, groups)) + this % xs(t) % total = ZERO + allocate(this % xs(t) % absorption(n_azi, n_pol, groups)) + this % xs(t) % absorption = ZERO + allocate(this % xs(t) % fission(n_azi, n_pol, groups)) + this % xs(t) % fission = ZERO + allocate(this % xs(t) % k_fission(n_azi, n_pol, groups)) + this % xs(t) % k_fission = ZERO + allocate(this % xs(t) % nu_fission(n_azi, n_pol, groups)) + this % xs(t) % nu_fission = ZERO + allocate(this % xs(t) % chi(n_azi, n_pol, groups, groups)) + this % xs(t) % chi = ZERO + allocate(temp_mult(n_azi, n_pol, groups, groups)) + temp_mult = ZERO + allocate(mult_num(n_azi, n_pol, groups, groups)) + mult_num = ZERO + allocate(mult_denom(n_azi, n_pol, groups, groups)) + mult_denom = ZERO + allocate(scatt_coeffs(n_azi, n_pol, order_dim, groups, groups)) + 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_type == ANGLE_LEGENDRE) then + allocate(ScattDataLegendre :: & + this % xs(t) % scatter(iazi, ipol) % obj) + else if (scatter_type == ANGLE_TABULAR) then + allocate(ScattDataTabular :: & + this % xs(t) % scatter(iazi, ipol) % obj) + else if (scatter_type == 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 - end if + ! 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) + nuc_t = minloc(abs(nuc % kTs - temp_desired), dim=1) + temp_actual = nuc % kTs(i_closest) + if (abs(temp_actual - temp_desired) >= 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.") + end if + + case (TEMPERATURE_INTERPOLATION) + ! TODO: Get bounding temperatures + call fatal_error("Temperature interpolation not yet implemented") + end select + + ! Copy atom density of nuclide in material + atom_density = mat % atom_density(i) + + select type(nuc) + type is (MgxsAngle) + ! Perform our operations which depend upon the type + ! Add contributions to total, absorption, and fission data (if necessary) + this % xs(t) % total = this % xs(t) % total + & + atom_density * nuc % xs(nuc_t) % total + this % xs(t) % absorption = this % xs(t) % absorption + & + atom_density * nuc % xs(nuc_t) % absorption + if (nuc % fissionable) then + this % xs(t) % chi = this % xs(t) % chi + & + atom_density * nuc % xs(nuc_t) % chi + this % xs(t) % nu_fission = this % xs(t) % nu_fission + & + atom_density * nuc % xs(nuc_t) % nu_fission + if (allocated(nuc % xs(nuc_t) % fission)) then + this % xs(t) % fission = this % xs(t) % fission + & + atom_density * nuc % xs(nuc_t) % fission + end if + if (allocated(nuc % xs(nuc_t) % k_fission)) then + this % xs(t) % k_fission = this % xs(t) % k_fission + & + atom_density * nuc % xs(nuc_t) % k_fission + end if + end if + + ! Get the multiplication matrix + ! To combine from nuclidic data we need to use the final relationship + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / + ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) + ! Developed as follows: + ! mult_{gg'} = nuScatt{g,g'} / Scatt{g,g'} + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / sum(N_i*scatt_{i,g,g'}) + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / + ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) + ! nuscatt_{i,g,g'} can be reconstructed from scatter % energy and + ! scatter % scattxs + do ipol = 1, n_pol + do iazi = 1, n_azi + do gin = 1, groups + do gout = nuc % 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(iazi, ipol, gout, gin) = & + mult_num(iazi, ipo, gout, gin) + atom_density * & + nuscatt + if (nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % mult(gin) % data(gout) > ZERO) then + mult_denom(iazi, ipol, gout, gin) = & + mult_denom(iazi, ipol, gout, gin) + atom_density * & + nuscatt / & + nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % mult(gin) % data(gout) + else + ! Avoid division by zero + mult_denom(iazi, ipol, gout, gin) = & + mult_denom(iazi, ipol, gout, gin) + atom_density + 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) + scatt_coeffs(iazi, ipol, 1:min(nuc_order_dim, order_dim), :, :) = & + scatt_coeffs(iazi, ipol, 1:min(nuc_order_dim, order_dim), :, :) + & + atom_density * & + nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % get_matrix(min(nuc_order_dim, order_dim)) + end do + end do + type is (MgxsIso) + call fatal_error("Invalid passing of MgxsIso to MgxsAngle object") + end select + + ! Obtain temp_mult + do ipol = 1, n_pol + do iazi = 1, n_azi + do gin = 1, groups + do gout = 1, groups + if (mult_denom(iazi, ipol, gout, gin) > ZERO) then + temp_mult(iazi, ipol, gout, gin) = & + mult_num(iazi, ipol, gout, gin) / & + mult_denom(iazi, ipol, gout, gin) + else + temp_mult(iazi, ipol, gout, gin) = ONE + end if + end do end do end do end do - end do - ! Get the complete scattering matrix - nuc_order_dim = size(nuc % scatter(1, 1) % obj % dist(1) % data, dim=1) - do ipol = 1, n_pol - do iazi = 1, n_azi - scatt_coeffs(1:min(nuc_order_dim, order_dim), :, :, iazi, ipol) = & - scatt_coeffs(1:min(nuc_order_dim, order_dim), :, :, iazi, ipol) + & - atom_density * nuc % scatter(iazi, ipol) % obj % get_matrix(& - min(nuc_order_dim, order_dim)) + ! Initialize the ScattData Object + do ipol = 1, n_pol + do iazi = 1, n_azi + call this % xs(t) % scatter(iazi, ipol) % obj % init(& + temp_mult(iazi, ipol, :, :), & + scatt_coeffs(iazi, ipol, :, :, :)) + end do end do - end do - end select - end do - ! Obtain temp_mult - do ipol = 1, n_pol - do iazi = 1, n_azi - do gin = 1, groups - do gout = 1, groups - if (mult_denom(gout, gin, iazi, ipol) > ZERO) then - temp_mult(gout, gin, iazi, ipol) = & - mult_num(gout, gin, iazi, ipol) / & - mult_denom(gout, gin, iazi, ipol) - else - temp_mult(gout, gin, iazi, ipol) = ONE - end if - end do - end do - end do - end do + ! 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(iazi, ipol, :, gin)) + if (norm > ZERO) then + this % xs(t) % chi(iazi, ipol, :, gin) = & + this % xs(t) % chi(iazi, ipol, :, gin) / norm + end if + end do + end do + end do + end if - ! 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, t, xstype, gin, gout, uvw, mu) result(xs) + class(MgxsIso), intent(in) :: this ! The Xs to get data from + integer, intent(in) :: t ! Temperature index of data + 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 % 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 default + xs = ZERO + end select + end function mgxsiso_get_xs + + pure function mgxsang_get_xs(this, t, xstype, gin, gout, uvw, mu) result(xs) + class(MgxsAngle), intent(in) :: this ! The Mgxs to initialize + integer, intent(in) :: t ! Temperature index of data + character(*) , intent(in) :: xstype ! Type of xs requested + integer, intent(in) :: gin ! Incoming Energy group + integer, optional, intent(in) :: gout ! Outgoing Energy group + real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8), optional, intent(in) :: mu ! Change in angle + real(8) :: xs ! Requested x/s + + integer :: iazi, ipol + + if (present(uvw)) then + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + select case(xstype) + case('total') + xs = this % 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 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) + function mgxsiso_sample_fission_energy(this, t, 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) :: t ! Temperature index of data + 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(t) % chi(gout,gin) do while (prob < xi) gout = gout + 1 - prob = prob + this % chi(gout,gin) + prob = prob + this % xs(t) % chi(gout,gin) end do end function mgxsiso_sample_fission_energy - function mgxsang_sample_fission_energy(this, gin, uvw) result(gout) + function mgxsang_sample_fission_energy(this, t, 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) :: t ! Temperature index of data + 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(t) % chi(gout, gin, iazi, ipol) do while (prob < xi) gout = gout + 1 - prob = prob + this % chi(gout, gin, iazi, ipol) + prob = prob + this % xs(t) % chi(gout, gin, iazi, ipol) end do end function mgxsang_sample_fission_energy @@ -1660,30 +1641,32 @@ module mgxs_header ! MGXS*_SAMPLE_SCATTER Selects outgoing energy and angle after a scatter event !=============================================================================== - subroutine mgxsiso_sample_scatter(this, uvw, gin, gout, mu, wgt) + subroutine mgxsiso_sample_scatter(this, t, 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 + integer, intent(in) :: t ! Temperature index + 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(t) % scatter % sample(gin, gout, mu, wgt) end subroutine mgxsiso_sample_scatter - subroutine mgxsang_sample_scatter(this, uvw, gin, gout, mu, wgt) + subroutine mgxsang_sample_scatter(this, t, uvw, gin, gout, mu, wgt) class(MgxsAngle), intent(in) :: this - real(8), intent(in) :: uvw(3) ! Incoming neutron direction - integer, intent(in) :: gin ! Incoming neutron group - integer, intent(out) :: gout ! Sampled outgoin group - real(8), intent(out) :: mu ! Sampled change in angle - real(8), intent(inout) :: wgt ! Particle weight + integer, intent(in) :: t ! Temperature index + 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(t) % scatter(iazi, ipol) % obj % sample(gin, gout, mu, wgt) end subroutine mgxsang_sample_scatter @@ -1692,22 +1675,24 @@ module mgxs_header ! for the material the particle is currently traveling through. !=============================================================================== - subroutine mgxsiso_calculate_xs(this, gin, uvw, xs) + subroutine mgxsiso_calculate_xs(this, t, gin, uvw, xs) class(MgxsIso), intent(in) :: this + integer, intent(in) :: t ! Temperature index integer, intent(in) :: gin ! Incoming neutron group real(8), intent(in) :: uvw(3) ! Incoming neutron direction type(MaterialMacroXS), intent(inout) :: xs ! Resultant Mgxs Data - xs % total = this % total(gin) - xs % elastic = this % scatter % scattxs(gin) - xs % absorption = this % absorption(gin) - xs % fission = this % fission(gin) - xs % nu_fission = this % nu_fission(gin) + xs % total = this % xs(t) % total(gin) + xs % elastic = this % xs(t) % scatter % scattxs(gin) + xs % absorption = this % xs(t) % absorption(gin) + xs % fission = this % xs(t) % fission(gin) + xs % nu_fission = this % xs(t) % nu_fission(gin) end subroutine mgxsiso_calculate_xs - subroutine mgxsang_calculate_xs(this, gin, uvw, xs) + subroutine mgxsang_calculate_xs(this, t, gin, uvw, xs) class(MgxsAngle), intent(in) :: this + integer, intent(in) :: t ! Temperature index integer, intent(in) :: gin ! Incoming neutron group real(8), intent(in) :: uvw(3) ! Incoming neutron direction type(MaterialMacroXS), intent(inout) :: xs ! Resultant Mgxs Data @@ -1715,11 +1700,11 @@ 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(t) % total(gin, iazi, ipol) + xs % elastic = this % xs(t) % scatter(iazi, ipol) % obj % scattxs(gin) + xs % absorption = this % xs(t) % absorption(gin, iazi, ipol) + xs % fission = this % xs(t) % fission(gin, iazi, ipol) + xs % nu_fission = this % xs(t) % nu_fission(gin, iazi, ipol) end subroutine mgxsang_calculate_xs From aeb7f0c787f9069ca8f5ab1928a1165ef5c21efa Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 4 Sep 2016 06:34:33 -0400 Subject: [PATCH 04/42] Got the temperature dependent MGXS data hooked in to the rest of the code. On to debugging! --- src/cross_section.F90 | 1 + src/initialize.F90 | 6 --- src/input_xml.F90 | 84 +++++++++++++++--------------- src/mgxs_data.F90 | 117 ++++++++++++++++++++++++++---------------- src/mgxs_header.F90 | 109 +++++++++++++++++++++++---------------- src/tracking.F90 | 4 ++ 6 files changed, 186 insertions(+), 135 deletions(-) diff --git a/src/cross_section.F90 b/src/cross_section.F90 index 800552f89..e2cc31d5e 100644 --- a/src/cross_section.F90 +++ b/src/cross_section.F90 @@ -161,6 +161,7 @@ contains ! If using multipole data but outside the RRR, pick the nearest ! temperature. Note that there is no tolerance here, so this ! temperature could be very far off! + kT = sqrtkT**2 i_temp = minloc(abs(nuclides(i_nuclide) % kTs - kT), dim=1) end if else diff --git a/src/initialize.F90 b/src/initialize.F90 index 2bcf2e01f..4fe6f8769 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 eeeae865b..eafbc717c 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -48,8 +48,8 @@ contains call read_settings_xml() call read_geometry_xml() - call read_materials() call read_tallies_xml() + call read_materials() if (cmfd_run) call configure_cmfd() end subroutine read_input_xml @@ -1356,11 +1356,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. @@ -2038,7 +2034,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 @@ -2069,10 +2065,16 @@ contains call get_temperatures(nuc_temps, sab_temps) ! Read continuous-energy cross sections - if (run_CE .and. run_mode /= MODE_PLOTTING) then - call time_read_xs%start() - call read_ce_cross_sections(libraries, library_dict, nuc_temps, sab_temps) - call time_read_xs%stop() + if (run_mode /= MODE_PLOTTING) then + call time_read_xs % start() + if (run_CE) then + call read_ce_cross_sections(libraries, library_dict, nuc_temps, sab_temps) + else + ! Create material macroscopic data for MGXS + call read_mgxs(nuc_temps) + call create_macro_xs() + end if + call time_read_xs % stop() end if ! Normalize atom/weight percents @@ -4601,44 +4603,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=255), allocatable :: names(:) - ! Check if mgxs.xml exists + ! Check if mgxs.h5 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.h5 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 (check_attribute(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 (check_attribute(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 @@ -4650,9 +4651,9 @@ contains end do allocate(inverse_velocities(energy_groups)) - if (check_for_node(doc, "inverse_velocities")) then + if (check_attribute(file_id, "inverse velocities")) then ! Get inverse velocities - call get_node_array(doc, "inverse_velocities", inverse_velocities) + call read_attribute(inverse_velocities, file_id, "inverse velocities") else ! If not given, estimate them by using average energy in group which is ! assumed to be the midpoint @@ -4663,31 +4664,28 @@ contains end do end if - ! Get node list of all - call get_node_list(doc, "xsdata", node_xsdata_list) - n_libraries = get_list_size(node_xsdata_list) + ! Get the datasets present in the library + call get_groups(file_id, names) + n_libraries = size(names) - ! 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 HDF 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 diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index aa96910f3..7cbb4864c 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -3,13 +3,13 @@ module mgxs_data use constants use error, only: fatal_error use global + use hdf5 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 @@ -19,21 +19,20 @@ contains ! nuclides and sab_tables arrays !=============================================================================== - subroutine read_mgxs() + subroutine read_mgxs(temps) + type(VectorReal), allocatable :: temps(:) 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_nuclide ! index in nuclides array + character(20) :: name ! name of library to load integer :: representation ! Data representation - type(Material), pointer :: mat + 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() + integer(HID_T) :: file_id + integer(HID_T) :: xsdata_group logical :: file_exists - character(MAX_LINE_LEN) :: temp_str logical :: get_kfiss, get_fiss integer :: l type(DictCharInt) :: xsdata_dict @@ -42,30 +41,16 @@ contains 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 '" & + 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) + ! Open file for reading + file_id = file_open(path_cross_sections, 'r', parallel=.true.) - ! Get node list of all - call get_node_list(doc, "xsdata", node_xsdata_list) - - ! 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,20 +87,21 @@ 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 (check_group(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 - representation = MGXS_ISOTROPIC - else if (temp_str == 'angle') then - representation = MGXS_ANGLE - else + if (check_attribute(xsdata_group, "representation")) then + call read_attribute(representation, xsdata_group, "representation") + if (representation /= MGXS_ISOTROPIC .and. & + representation /= MGXS_ANGLE) then call fatal_error("Invalid Data Representation!") end if else @@ -132,8 +118,9 @@ 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) ! Add name to dictionary call already_read % add(name) @@ -172,9 +159,13 @@ contains subroutine create_macro_xs() integer :: i_mat ! index in materials array type(Material), pointer :: mat ! current material + 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) @@ -187,9 +178,49 @@ contains 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) + call macro_xs(i_mat) % obj % combine(kTs(i_mat), mat, nuclides_MG, & + energy_groups, max_order) 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 2f569c6fe..c86685bc0 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -57,6 +57,9 @@ module mgxs_header logical :: fissionable ! mgxs object is fissionable? integer :: scatter_type ! either legendre, histogram, or tabular. + ! Caching information + integer :: index_temp ! temperature index for nuclide + contains procedure(mgxs_from_hdf5_), deferred :: from_hdf5 ! Load the data procedure(mgxs_combine_), deferred :: combine ! initializes object @@ -67,6 +70,7 @@ module mgxs_header 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 !=============================================================================== @@ -106,10 +110,9 @@ module mgxs_header integer, intent(in) :: max_order ! Maximum requested order end subroutine mgxs_combine_ - pure function mgxs_get_xs_(this, t, xstype, gin, gout, uvw, mu) result(xs_val) + pure function mgxs_get_xs_(this, xstype, gin, gout, uvw, mu) result(xs_val) import Mgxs class(Mgxs), intent(in) :: this - integer, intent(in) :: t ! Temperature index of data character(*), intent(in) :: xstype ! Cross Section Type integer, intent(in) :: gin ! Incoming Energy group integer, optional, intent(in) :: gout ! Outgoing Group @@ -118,20 +121,18 @@ module mgxs_header real(8) :: xs_val ! Resultant xs end function mgxs_get_xs_ - function mgxs_sample_fission_(this, t, gin, uvw) result(gout) + function mgxs_sample_fission_(this, gin, uvw) result(gout) import Mgxs class(Mgxs), intent(in) :: this - integer, intent(in) :: t ! Temperature index integer, intent(in) :: gin ! Incoming energy group real(8), intent(in) :: uvw(3) ! Particle Direction integer :: gout ! Sampled outgoing group end function mgxs_sample_fission_ - subroutine mgxs_sample_scatter_(this, t, uvw, gin, gout, mu, wgt) + subroutine mgxs_sample_scatter_(this, uvw, gin, gout, mu, wgt) import Mgxs class(Mgxs), intent(in) :: this - integer, intent(in) :: t ! Temperature index of data real(8), intent(in) :: uvw(3) ! Incoming neutron direction integer, intent(in) :: gin ! Incoming neutron group integer, intent(out) :: gout ! Sampled outgoin group @@ -139,10 +140,9 @@ module mgxs_header real(8), intent(inout) :: wgt ! Particle weight end subroutine mgxs_sample_scatter_ - subroutine mgxs_calculate_xs_(this, t, gin, uvw, xs) + subroutine mgxs_calculate_xs_(this, gin, uvw, xs) import Mgxs, MaterialMacroXS class(Mgxs), intent(in) :: this - integer, intent(in) :: t ! Temperature index integer, intent(in) :: gin ! Incoming neutron group real(8), intent(in) :: uvw(3) ! Incoming neutron direction type(MaterialMacroXS), intent(inout) :: xs ! Resultant Mgxs Data @@ -1006,7 +1006,7 @@ module mgxs_header subroutine mgxsiso_combine(this, temps, mat, nuclides, groups, max_order) class(MgxsIso), intent(inout) :: this ! The Mgxs to initialize - type(VectorReal), intent(in) :: temps ! Temperatures to obtain + 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 @@ -1406,15 +1406,17 @@ module mgxs_header ! MGXS*_GET_XS returns the requested data cross section data !=============================================================================== - pure function mgxsiso_get_xs(this, t, xstype, gin, gout, uvw, mu) result(xs) + pure function mgxsiso_get_xs(this, xstype, gin, gout, uvw, mu) result(xs) class(MgxsIso), intent(in) :: this ! The Xs to get data from - integer, intent(in) :: t ! Temperature index of data 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') @@ -1494,9 +1496,8 @@ module mgxs_header end select end function mgxsiso_get_xs - pure function mgxsang_get_xs(this, t, xstype, gin, gout, uvw, mu) result(xs) + pure function mgxsang_get_xs(this, xstype, gin, gout, uvw, mu) result(xs) class(MgxsAngle), intent(in) :: this ! The Mgxs to initialize - integer, intent(in) :: t ! Temperature index of data character(*) , intent(in) :: xstype ! Type of xs requested integer, intent(in) :: gin ! Incoming Energy group integer, optional, intent(in) :: gout ! Outgoing Energy group @@ -1504,7 +1505,9 @@ module mgxs_header real(8), optional, intent(in) :: mu ! Change in angle real(8) :: xs ! Requested x/s - integer :: iazi, ipol + integer :: iazi, ipol, t + + t = this % index_temp if (present(uvw)) then call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) @@ -1594,9 +1597,8 @@ module mgxs_header ! MGXS*_SAMPLE_FISSION_ENERGY samples the outgoing energy from a fission event !=============================================================================== - function mgxsiso_sample_fission_energy(this, t, gin, uvw) result(gout) + function mgxsiso_sample_fission_energy(this, gin, uvw) result(gout) class(MgxsIso), intent(in) :: this ! Data to work with - integer, intent(in) :: t ! Temperature index of data integer, intent(in) :: gin ! Incoming energy group real(8), intent(in) :: uvw(3) ! Particle Direction integer :: gout ! Sampled outgoing group @@ -1605,18 +1607,17 @@ module mgxs_header xi = prn() gout = 1 - prob = this % xs(t) % chi(gout,gin) + prob = this % xs(this % index_temp) % chi(gout,gin) do while (prob < xi) gout = gout + 1 - prob = prob + this % xs(t) % 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, t, gin, uvw) result(gout) + function mgxsang_sample_fission_energy(this, gin, uvw) result(gout) class(MgxsAngle), intent(in) :: this ! Data to work with - integer, intent(in) :: t ! Temperature index of data integer, intent(in) :: gin ! Incoming energy group real(8), intent(in) :: uvw(3) ! Particle Direction integer :: gout ! Sampled outgoing group @@ -1628,11 +1629,11 @@ module mgxs_header xi = prn() gout = 1 - prob = this % xs(t) % 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 % xs(t) % 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 @@ -1641,22 +1642,20 @@ module mgxs_header ! MGXS*_SAMPLE_SCATTER Selects outgoing energy and angle after a scatter event !=============================================================================== - subroutine mgxsiso_sample_scatter(this, t, uvw, gin, gout, mu, wgt) + subroutine mgxsiso_sample_scatter(this, uvw, gin, gout, mu, wgt) class(MgxsIso), intent(in) :: this - integer, intent(in) :: t ! Temperature index 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 % xs(t) % 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, t, uvw, gin, gout, mu, wgt) + subroutine mgxsang_sample_scatter(this, uvw, gin, gout, mu, wgt) class(MgxsAngle), intent(in) :: this - integer, intent(in) :: t ! Temperature index real(8), intent(in) :: uvw(3) ! Incoming neutron direction integer, intent(in) :: gin ! Incoming neutron group integer, intent(out) :: gout ! Sampled outgoin group @@ -1666,7 +1665,8 @@ module mgxs_header integer :: iazi, ipol ! Angular indices call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - call this % xs(t) % 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 @@ -1675,24 +1675,22 @@ module mgxs_header ! for the material the particle is currently traveling through. !=============================================================================== - subroutine mgxsiso_calculate_xs(this, t, gin, uvw, xs) + subroutine mgxsiso_calculate_xs(this, gin, uvw, xs) class(MgxsIso), intent(in) :: this - integer, intent(in) :: t ! Temperature index integer, intent(in) :: gin ! Incoming neutron group real(8), intent(in) :: uvw(3) ! Incoming neutron direction type(MaterialMacroXS), intent(inout) :: xs ! Resultant Mgxs Data - xs % total = this % xs(t) % total(gin) - xs % elastic = this % xs(t) % scatter % scattxs(gin) - xs % absorption = this % xs(t) % absorption(gin) - xs % fission = this % xs(t) % fission(gin) - xs % nu_fission = this % xs(t) % 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 - subroutine mgxsang_calculate_xs(this, t, gin, uvw, xs) + subroutine mgxsang_calculate_xs(this, gin, uvw, xs) class(MgxsAngle), intent(in) :: this - integer, intent(in) :: t ! Temperature index integer, intent(in) :: gin ! Incoming neutron group real(8), intent(in) :: uvw(3) ! Incoming neutron direction type(MaterialMacroXS), intent(inout) :: xs ! Resultant Mgxs Data @@ -1700,16 +1698,41 @@ module mgxs_header integer :: iazi, ipol call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - xs % total = this % xs(t) % total(gin, iazi, ipol) - xs % elastic = this % xs(t) % scatter(iazi, ipol) % obj % scattxs(gin) - xs % absorption = this % xs(t) % absorption(gin, iazi, ipol) - xs % fission = this % xs(t) % fission(gin, iazi, ipol) - xs % nu_fission = this % xs(t) % 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) +!=============================================================================== + + pure subroutine mgxs_find_temperature(this, sqrtkT, tolerance) + class(Mgxs), intent(in) :: this + real(8), intent(in) :: sqrtkT ! Temperature (in units of of MeV) + real(8), intent(in) :: tolerance ! Temperature tolerance + + real(8) :: kT + integer :: i_temp + + kT = sqrtkT**2 + do i_temp = 1, size(this % kTs) + if (abs(this % kTs(i_temp) - kT) < K_BOLTZMANN * tolerance) exit + end do + + 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/tracking.F90 b/src/tracking.F90 index f2613146e..a03cde98d 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -92,6 +92,10 @@ 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, & + temperature_tolerance) + ! Get the data call macro_xs(p % material) % obj % calculate_xs(p % g, & p % coord(p % n_coord) % uvw, material_xs) else From 7e5326d705b90f5081eca9206388cc91fa6bafb9 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 4 Sep 2016 15:40:02 -0400 Subject: [PATCH 05/42] Removed unused variables, cleaned up other code base, fixed all the bugs (seems to work now!), set default MGXS library temperature (via the API) to 294K to be consistent with the default w/in OpenMC. Looking good folks. Next up is re-implementing the user-facing option for converting Legendre to tabular (it shouldnt be in the library like it was before), implementing a script to convert from xml to h5, and switching the library format to use sparse scattering matrices instead of dense --- openmc/mesh.py | 7 +++- openmc/mgxs/library.py | 5 ++- openmc/mgxs_library.py | 90 +++++++++++++++++++++--------------------- src/input_xml.F90 | 1 + src/mgxs_data.F90 | 15 +++++-- src/mgxs_header.F90 | 76 +++++++++++++++++++---------------- src/tracking.F90 | 3 +- 7 files changed, 108 insertions(+), 89 deletions(-) diff --git a/openmc/mesh.py b/openmc/mesh.py index 7d7b483f7..43ac7aef0 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -288,9 +288,12 @@ class Mesh(object): openmc.YPlane(y0=self.upper_right[1], boundary_type=bc[3])] if twod: - zplanes = [openmc.ZPlane(z0=np.finfo(np.float).min, + # 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. + zplanes = [openmc.ZPlane(z0=-1000., boundary_type='reflective'), - openmc.ZPlane(z0=np.finfo(np.float).max, + openmc.ZPlane(z0=1000., boundary_type='reflective')] else: zplanes = [openmc.ZPlane(z0=self.lower_left[2], diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 9f0e173f3..a04ec8c55 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -907,8 +907,11 @@ class Library(object): # the provided order or the Library's order. xsdata.order = min(order, self.legendre_order) + # Right now only 'legendre' data and isotropic weighting is supported + self.scatter_type = 'legendre' + self.representation = 'isotropic' + if nuclide is not 'total': - xsdata.zaid = self._nuclides[nuclide][0] xsdata.awr = self._nuclides[nuclide][1] if subdomain is None: diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 68c0063f2..15d80dc91 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -20,13 +20,7 @@ _SCATTER_TYPE_TABULAR = 3 _SCATTER_TYPE_LEGENDRE = 4 _SCATTER_TYPE_HISTOGRAM = 5 _REPRESENTATIONS = ['isotropic', 'angle'] -_REPRESENTATIONS_TEXT = {'isotropic': _REPRESENTATION_ISOTROPIC, - 'angle': _REPRESENTATION_ANGLE} _SCATTER_TYPES = ['tabular', 'legendre', 'histogram'] -_SCATTER_TYPES_TEXT = {'tabular': _SCATTER_TYPE_TABULAR, - 'legendre': _SCATTER_TYPE_LEGENDRE, - 'histogram': _SCATTER_TYPE_HISTOGRAM} - class XSdata(object): """A multi-group cross section data set providing all the @@ -43,7 +37,7 @@ class XSdata(object): weighting). Defaults to 'isotropic' temperatures : numpy.ndarray Temperatures (in units of Kelvin) of the provided datasets. Defaults - to a single temperature at 300K. + to a single temperature at 294K. Attributes ---------- @@ -54,7 +48,7 @@ class XSdata(object): of the isotope to the mass of a single neutron. temperatures : numpy.ndarray Temperatures (in units of Kelvin) of the provided datasets. Defaults - to a single temperature at 300K. + to a single temperature at 294K. energy_groups : openmc.mgxs.EnergyGroups Energy group structure fissionable : bool @@ -164,7 +158,7 @@ class XSdata(object): """ - def __init__(self, name, energy_groups, temperatures=[300.], + def __init__(self, name, energy_groups, temperatures=[294.], representation='isotropic'): # Initialize class attributes self.name = name @@ -377,7 +371,7 @@ class XSdata(object): check_type('use_chi', use_chi, bool) self._use_chi = use_chi - def set_total(self, total, temperature=300.): + def set_total(self, total, temperature=294.): """This method sets the cross section for this XSdata object at the provided temperature. @@ -387,7 +381,7 @@ class XSdata(object): Total Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K See also -------- @@ -405,7 +399,7 @@ class XSdata(object): i = self.temperatures.tolist().index(temperature) self._total[i] = nptotal - def set_absorption(self, absorption, temperature=300.): + def set_absorption(self, absorption, temperature=294.): """This method sets the cross section for this XSdata object at the provided temperature. @@ -415,7 +409,7 @@ class XSdata(object): Absorption Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K See also -------- @@ -434,7 +428,7 @@ class XSdata(object): i = self.temperatures.tolist().index(temperature) self._absorption[i] = npabsorption - def set_fission(self, fission, temperature=300.): + def set_fission(self, fission, temperature=294.): """This method sets the cross section for this XSdata object at the provided temperature. @@ -444,7 +438,7 @@ class XSdata(object): Fission Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K See also -------- @@ -465,7 +459,7 @@ class XSdata(object): if np.sum(npfission) > 0.0: self._fissionable = True - def set_kappa_fission(self, kappa_fission, temperature=300.): + def set_kappa_fission(self, kappa_fission, temperature=294.): """This method sets the cross section for this XSdata object at the provided temperature. @@ -475,7 +469,7 @@ class XSdata(object): Kappa-Fission Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K See also -------- @@ -498,7 +492,7 @@ class XSdata(object): if np.sum(npkappa_fission) > 0.0: self._fissionable = True - def set_chi(self, chi, temperature=300.): + def set_chi(self, chi, temperature=294.): """This method sets the cross section for this XSdata object at the provided temperature. @@ -508,7 +502,7 @@ class XSdata(object): Fission Spectrum temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K See also -------- @@ -538,7 +532,7 @@ class XSdata(object): if self.use_chi is not None: self.use_chi = True - def set_scatter_matrix(self, scatter, temperature=300.): + def set_scatter_matrix(self, scatter, temperature=294.): """This method sets the cross section for this XSdata object at the provided temperature. @@ -548,7 +542,7 @@ class XSdata(object): Scattering Matrix Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K See also -------- @@ -567,7 +561,7 @@ class XSdata(object): i = self.temperatures.tolist().index(temperature) self._scatter_matrix[i] = npscatter - def set_multiplicity_matrix(self, multiplicity, temperature=300.): + def set_multiplicity_matrix(self, multiplicity, temperature=294.): """This method sets the cross section for this XSdata object at the provided temperature. @@ -577,7 +571,7 @@ class XSdata(object): Multiplicity Matrix Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K See also -------- @@ -597,7 +591,7 @@ class XSdata(object): i = self.temperatures.tolist().index(temperature) self._multiplicity_matrix[i] = npmultiplicity - def set_nu_fission(self, nu_fission, temperature=300.): + def set_nu_fission(self, nu_fission, temperature=294.): """This method sets the cross section for this XSdata object at the provided temperature. @@ -607,7 +601,7 @@ class XSdata(object): Nu-fission Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K See also -------- @@ -655,7 +649,7 @@ class XSdata(object): if np.sum(npnu_fission) > 0.0: self._fissionable = True - def set_total_mgxs(self, total, temperature=300., nuclide='total', + 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 @@ -668,7 +662,7 @@ class XSdata(object): for the domain of interest. temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -702,7 +696,7 @@ class XSdata(object): msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_absorption_mgxs(self, absorption, temperature=300., + 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. @@ -714,7 +708,7 @@ class XSdata(object): for the domain of interest. temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -749,7 +743,7 @@ class XSdata(object): msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_fission_mgxs(self, fission, temperature=300., nuclide='total', + 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. @@ -761,7 +755,7 @@ class XSdata(object): for the domain of interest. temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -796,7 +790,7 @@ class XSdata(object): msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_nu_fission_mgxs(self, nu_fission, temperature=300., + 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. @@ -808,7 +802,7 @@ class XSdata(object): for the domain of interest. temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -852,7 +846,7 @@ class XSdata(object): if np.sum(self._nu_fission) > 0.0: self._fissionable = True - def set_kappa_fission_mgxs(self, k_fission, temperature=300., + 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 @@ -866,7 +860,7 @@ class XSdata(object): for the domain of interest. temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -901,7 +895,7 @@ class XSdata(object): msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_chi_mgxs(self, chi, temperature=300., nuclide='total', + 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. @@ -912,7 +906,7 @@ class XSdata(object): MGXS Object containing chi for the domain of interest. temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -954,7 +948,7 @@ class XSdata(object): if self.use_chi is not None: self.use_chi = True - def set_scatter_matrix_mgxs(self, scatter, temperature=300., + def set_scatter_matrix_mgxs(self, scatter, temperature=294., nuclide='total', xs_type='macro', subdomain=None): """This method allows for an openmc.mgxs.ScatterMatrixXS @@ -969,7 +963,7 @@ class XSdata(object): for the domain of interest. temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -1027,7 +1021,7 @@ class XSdata(object): raise ValueError(msg) def set_multiplicity_matrix_mgxs(self, nuscatter, scatter=None, - temperature=300., nuclide='total', + temperature=294., nuclide='total', xs_type='macro', subdomain=None): """This method allows for either the direct use of only an openmc.mgxs.MultiplicityMatrixXS OR @@ -1050,7 +1044,7 @@ class XSdata(object): for the domain of interest. temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults - to 300K + to 294K nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -1119,22 +1113,26 @@ class XSdata(object): if self.fissionable is not None: grp.attrs['fissionable'] = self.fissionable if self.representation is not None: - grp.attrs['representation'] = \ - np.string_(_REPRESENTATIONS_TEXT[self.representation]) + 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_type is not None: - grp.attrs['scatter-type'] = \ - np.string_(_SCATTER_TYPES_TEXT[self.scatter_type]) + grp.attrs['scatter-type'] = np.string_(self.scatter_type) if self.order is not None: grp.attrs['order'] = self.order + 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) + # Create the temperature datasets for i, temperature in enumerate(self.temperatures): - xsgrp = grp.create_group(str(np.round(temperature)) + "K") + xsgrp = grp.create_group(str(int(np.round(temperature))) + "K") if self._total[i] is not None: xsgrp.create_dataset("total", data=self._total[i], compression=compression) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index eafbc717c..c44c6b7bd 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -16,6 +16,7 @@ module input_xml 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 diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 7cbb4864c..d4ad96da5 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -1,6 +1,7 @@ module mgxs_data use constants + use algorithm, only: find use error, only: fatal_error use global use hdf5 @@ -28,6 +29,7 @@ contains integer :: i_nuclide ! index in nuclides array character(20) :: name ! name of library to load integer :: representation ! Data representation + character(MAX_LINE_LEN) :: temp_str type(Material), pointer :: mat type(SetChar) :: already_read integer(HID_T) :: file_id @@ -99,9 +101,12 @@ contains ! First find out the data representation if (check_attribute(xsdata_group, "representation")) then - call read_attribute(representation, xsdata_group, "representation") - if (representation /= MGXS_ISOTROPIC .and. & - representation /= MGXS_ANGLE) then + call read_attribute(temp_str, xsdata_group, "representation") + if (trim(temp_str) == 'isotropic') then + representation = MGXS_ISOTROPIC + else if (trim(temp_str) == 'angle') then + representation = MGXS_ANGLE + else call fatal_error("Invalid Data Representation!") end if else @@ -179,7 +184,9 @@ contains allocate(MgxsAngle :: macro_xs(i_mat) % obj) end select call macro_xs(i_mat) % obj % combine(kTs(i_mat), mat, nuclides_MG, & - energy_groups, max_order) + energy_groups, max_order, & + temperature_tolerance, & + temperature_method) end do end subroutine create_macro_xs diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index c86685bc0..0c0bcc94f 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -6,6 +6,7 @@ module mgxs_header use hdf5, only: HID_T, HSIZE_T, SIZE_T, h5iget_name_f use h5lt, only: h5ltpath_valid_f + use algorithm, only: find, sort use constants, only: MAX_FILE_LEN, ZERO, ONE, TWO, PI use error, only: fatal_error use hdf5_interface @@ -100,7 +101,8 @@ module mgxs_header integer, intent(in) :: max_order ! Maximum requested order end subroutine mgxs_from_hdf5_ - subroutine mgxs_combine_(this, temps, mat, nuclides, groups, max_order) + 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 @@ -108,6 +110,8 @@ module mgxs_header 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) @@ -206,12 +210,11 @@ module mgxs_header integer :: hdf5_err integer(SIZE_T) :: name_len, name_file_len - integer(HID_T) :: kT_group, kT_dset + integer(HID_T) :: kT_group character(MAX_FILE_LEN), allocatable :: dset_names(:) real(8), allocatable :: temps_available(:) ! temperatures available real(8) :: temp_desired real(8) :: temp_actual - logical :: exists character(MAX_WORD_LEN) :: temp_str real(8) :: dangle integer :: ipol, iazi @@ -236,6 +239,7 @@ module mgxs_header 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 @@ -377,7 +381,7 @@ module mgxs_header 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 :: order, order_dim, gin, gout, l integer :: legendre_mu_points, imu type(VectorInt) :: temps_to_read integer :: t @@ -387,12 +391,13 @@ module mgxs_header temps_to_read, order_dim) !!!TODO: Fix enable_leg_mu = .True. + legendre_mu_points = 33 ! 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(i))) // "K" + temp_str = trim(to_str(temps_to_read % data(t))) // "K" xsdata_grp = open_group(xs_id, trim(temp_str)) if (this % fissionable) then allocate(xs % nu_fission(groups)) @@ -619,8 +624,8 @@ module mgxs_header 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 + real(8) :: dmu, mu, norm + integer :: order, order_dim, gin, gout, l integer :: legendre_mu_points, imu, ipol, iazi type(VectorInt) :: temps_to_read integer :: t @@ -630,12 +635,13 @@ module mgxs_header temps_to_read, order_dim) !!!TODO: Fix enable_leg_mu = .True. + legendre_mu_points = 33 ! 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(i))) // "K" + temp_str = trim(to_str(temps_to_read % data(t))) // "K" xsdata_grp = open_group(xs_id, trim(temp_str)) if (this % fissionable) then if (check_dataset(xsdata_grp, "chi")) then @@ -899,16 +905,17 @@ module mgxs_header ! MGXS*_COMBINE Builds a macroscopic Mgxs object from microscopic Mgxs objects !=============================================================================== - subroutine mgxs_combine(this, temps, mat, nuclides, scatter_type, order_dim) + subroutine mgxs_combine(this, temps, mat, nuclides, max_order, & + scatter_type, 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 type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from + integer, intent(in) :: max_order ! Maximum requested order integer, intent(out) :: scatter_type ! Type of scatter integer, intent(out) :: order_dim ! Scattering data order size - integer :: t, mat_max_order, max_order, order, n_pol, n_azi - real(8) :: dangle + integer :: t, mat_max_order, order ! Fill in meta-data from material information if (mat % name == "") then @@ -924,7 +931,7 @@ module mgxs_header allocate(this % kTs(temps % size())) do t = 1, temps % size() - this % kTs(t) = temps % data(i) + this % kTs(t) = temps % data(t) end do ! Allocate the XS object for the number of temperatures @@ -1004,20 +1011,23 @@ module mgxs_header end subroutine mgxs_combine - subroutine mgxsiso_combine(this, temps, mat, nuclides, groups, max_order) + 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 + 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 :: mat_max_order, order, order_dim, nuc_order_dim + integer :: order_dim, nuc_order_dim real(8), allocatable :: temp_mult(:, :), mult_num(:, :), mult_denom(:, :) real(8), allocatable :: scatt_coeffs(:, :, :) integer :: nuc_t @@ -1025,7 +1035,8 @@ module mgxs_header integer :: scatter_type ! Set the meta-data - call mgxs_combine(this, temps, mat, nuclides, scatter_type, order_dim) + call mgxs_combine(this, temps, mat, nuclides, max_order, scatter_type, & + order_dim) ! Create the Xs Data for each temperature TEMP_LOOP: do t = 1, temps % size() @@ -1067,11 +1078,11 @@ module mgxs_header ! Determine actual temperatures to read temp_desired = temps % data(i) nuc_t = minloc(abs(nuc % kTs - temp_desired), dim=1) - temp_actual = nuc % kTs(i_closest) + temp_actual = nuc % kTs(nuc_t) if (abs(temp_actual - temp_desired) >= 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.") + trim(to_str(nint(temp_desired / K_BOLTZMANN))) // " K.") end if case (TEMPERATURE_INTERPOLATION) @@ -1174,13 +1185,16 @@ module mgxs_header end subroutine mgxsiso_combine - subroutine mgxsang_combine(this, temps, mat, nuclides, groups, max_order) + 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 @@ -1188,7 +1202,7 @@ module mgxs_header 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 @@ -1196,7 +1210,8 @@ module mgxs_header integer :: scatter_type ! Set the meta-data - call mgxs_combine(this, temps, mat, nuclides, scatter_type, order_dim) + call mgxs_combine(this, temps, mat, nuclides, max_order, scatter_type, & + 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 @@ -1268,11 +1283,11 @@ module mgxs_header ! Determine actual temperatures to read temp_desired = temps % data(i) nuc_t = minloc(abs(nuc % kTs - temp_desired), dim=1) - temp_actual = nuc % kTs(i_closest) + temp_actual = nuc % kTs(nuc_t) if (abs(temp_actual - temp_desired) >= 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.") + trim(to_str(nint(temp_desired / K_BOLTZMANN))) // " K.") end if case (TEMPERATURE_INTERPOLATION) @@ -1325,7 +1340,7 @@ module mgxs_header 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(iazi, ipol, gout, gin) = & - mult_num(iazi, ipo, gout, gin) + atom_density * & + mult_num(iazi, ipol, gout, gin) + atom_density * & nuscatt if (nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % mult(gin) % data(gout) > ZERO) then mult_denom(iazi, ipol, gout, gin) = & @@ -1716,18 +1731,11 @@ module mgxs_header ! sqrt(temperature), (with temperature in units of MeV) !=============================================================================== - pure subroutine mgxs_find_temperature(this, sqrtkT, tolerance) - class(Mgxs), intent(in) :: this - real(8), intent(in) :: sqrtkT ! Temperature (in units of of MeV) - real(8), intent(in) :: tolerance ! Temperature tolerance + pure subroutine mgxs_find_temperature(this, sqrtkT) + class(Mgxs), intent(inout) :: this + real(8), intent(in) :: sqrtkT ! Temperature (in units of of MeV) - real(8) :: kT - integer :: i_temp - - kT = sqrtkT**2 - do i_temp = 1, size(this % kTs) - if (abs(this % kTs(i_temp) - kT) < K_BOLTZMANN * tolerance) exit - end do + this % index_temp = minloc(abs(this % kTs - (sqrtkT * sqrtkT)), dim=1) end subroutine mgxs_find_temperature diff --git a/src/tracking.F90 b/src/tracking.F90 index a03cde98d..b62cfc85a 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -93,8 +93,7 @@ contains ! 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, & - temperature_tolerance) + 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) From 252c9152e67c6c25fab80e15fce82db63711f977 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 5 Sep 2016 06:09:05 -0400 Subject: [PATCH 06/42] Re-enabled the option to convert Legendre scattering kernels to tabular, but this time in settings.xml instead of within the library --- docs/source/usersguide/input.rst | 30 ++++++++++++++++++++++++ openmc/settings.py | 35 ++++++++++++++++++++++++++++ src/global.F90 | 6 +++++ src/input_xml.F90 | 26 +++++++++++++++++++++ src/mgxs_data.F90 | 3 ++- src/mgxs_header.F90 | 40 +++++++++++++++++--------------- 6 files changed, 120 insertions(+), 20 deletions(-) diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index e9126f16b..70ba30171 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -709,6 +709,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 not used in the multi-group :ref:`energy_mode`. + .. _temperature_default: ```` Element diff --git a/openmc/settings.py b/openmc/settings.py index 86aac9471..ffd7a4223 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -101,6 +101,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 @@ -199,6 +206,8 @@ class Settings(object): self._trace = None self._track = None + self._tabular_legendre = {} + self._temperature = {} # Cutoff subelement @@ -362,6 +371,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 @@ -667,6 +680,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) @@ -1048,6 +1074,14 @@ 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() + 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 self.temperature.items(): @@ -1149,6 +1183,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() diff --git a/src/global.F90 b/src/global.F90 index bea5f61a8..6e804c90a 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -128,6 +128,12 @@ module global ! Maximum Data Order integer :: max_order + ! Whether or no 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 diff --git a/src/input_xml.F90 b/src/input_xml.F90 index c44c6b7bd..24875d1fe 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -92,6 +92,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() @@ -1093,6 +1094,31 @@ contains call get_node_value(doc, "temperature_tolerance", temperature_tolerance) 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) diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index d4ad96da5..f17f2781e 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -125,7 +125,8 @@ contains ! Now read in the data specific to the type we just declared 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) + temperature_tolerance, get_kfiss, get_fiss, max_order, & + legendre_to_tabular, legendre_to_tabular_points) ! Add name to dictionary call already_read % add(name) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 0c0bcc94f..cefd8725d 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -88,7 +88,8 @@ module mgxs_header abstract interface subroutine mgxs_from_hdf5_(this, xs_id, groups, temperature, method, & - tolerance, get_kfiss, get_fiss, max_order) + 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 @@ -99,6 +100,9 @@ module mgxs_header 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_ subroutine mgxs_combine_(this, temps, mat, nuclides, groups, max_order, & @@ -361,7 +365,8 @@ module mgxs_header end subroutine mgxs_from_hdf5 subroutine mgxsiso_from_hdf5(this, xs_id, groups, temperature, method, & - tolerance, get_kfiss, get_fiss, max_order) + 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 @@ -371,27 +376,25 @@ module mgxs_header 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 - 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 - integer :: legendre_mu_points, imu + integer :: order, order_dim, gin, gout, l, imu type(VectorInt) :: temps_to_read integer :: t ! Call generic data gathering routine (will populate the metadata) call mgxs_from_hdf5(this, xs_id, temperature, method, tolerance, & temps_to_read, order_dim) - !!!TODO: Fix - enable_leg_mu = .True. - legendre_mu_points = 33 ! Load the more specific data do t = 1, temps_to_read % size() @@ -508,10 +511,10 @@ module mgxs_header ! provided as Legendre coefficients), and the user requested that ! these legendres be converted to tabular form (note xs is also ! the default behavior), convert that now. - if (this % scatter_type == ANGLE_LEGENDRE .and. enable_leg_mu) then + if (this % scatter_type == ANGLE_LEGENDRE .and. legendre_to_tabular) then ! Convert input parameters to what we need for the rest. this % scatter_type = ANGLE_TABULAR - order_dim = legendre_mu_points + order_dim = legendre_to_tabular_points order = order_dim dmu = TWO / real(order - 1, 8) @@ -605,7 +608,8 @@ module mgxs_header end subroutine mgxsiso_from_hdf5 subroutine mgxsang_from_hdf5(this, xs_id, groups, temperature, method, & - tolerance, get_kfiss, get_fiss, max_order) + 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 @@ -615,27 +619,25 @@ module mgxs_header 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 - 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 - integer :: order, order_dim, gin, gout, l - integer :: legendre_mu_points, imu, ipol, iazi + integer :: order, order_dim, gin, gout, l, imu, ipol, iazi type(VectorInt) :: temps_to_read integer :: t ! Call generic data gathering routine (will populate the metadata) call mgxs_from_hdf5(this, xs_id, temperature, method, tolerance, & temps_to_read, order_dim) - !!!TODO: Fix - enable_leg_mu = .True. - legendre_mu_points = 33 ! Load the more specific data do t = 1, temps_to_read % size() @@ -794,11 +796,11 @@ module mgxs_header ! provided as Legendre coefficients), and the user requested that ! these legendres be converted to tabular form (note xs is also ! the default behavior), convert that now. - if (this % scatter_type == ANGLE_LEGENDRE .and. enable_leg_mu) then + if (this % scatter_type == ANGLE_LEGENDRE .and. legendre_to_tabular) then ! Convert input parameters to what we need for the rest. this % scatter_type = ANGLE_TABULAR - order_dim = legendre_mu_points + order_dim = legendre_to_tabular_points order = order_dim dmu = TWO / real(order - 1, 8) From 6e68b23d58de20bf51532fb1372434a2d5279db0 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 5 Sep 2016 19:42:12 -0400 Subject: [PATCH 07/42] Added script to convert old xml mgxs libraries to new hdf5 libraries --- .../python/pincell_multigroup/build-xml.py | 69 ++-- .../pincell_multigroup/mg_cross_sections.xml | 383 ------------------ examples/xml/pincell_multigroup/settings.xml | 3 +- openmc/mgxs_library.py | 26 +- scripts/openmc-update-mgxs.py | 229 +++++++++++ src/mgxs_data.F90 | 14 +- src/mgxs_header.F90 | 15 +- 7 files changed, 308 insertions(+), 431 deletions(-) delete mode 100644 examples/xml/pincell_multigroup/mg_cross_sections.xml create mode 100755 scripts/openmc-update-mgxs.py diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index 2b08e8274..70421281d 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 af1f0072b..000000000 --- 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/settings.xml b/examples/xml/pincell_multigroup/settings.xml index dfd2fac81..1030762fa 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 + ./mg_cross_sections.h5 diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 15d80dc91..3188631bc 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -315,7 +315,6 @@ class XSdata(object): check_value('representation', representation, _REPRESENTATIONS) self._representation = representation - @awr.setter def awr(self, awr): # Check validity of type and that the awr value is > 0 @@ -371,6 +370,31 @@ class XSdata(object): check_type('use_chi', use_chi, bool) self._use_chi = use_chi + 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) + def set_total(self, total, temperature=294.): """This method sets the cross section for this XSdata object at the provided temperature. diff --git a/scripts/openmc-update-mgxs.py b/scripts/openmc-update-mgxs.py new file mode 100755 index 000000000..a13004042 --- /dev/null +++ b/scripts/openmc-update-mgxs.py @@ -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 +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('-c', '--compression', type=int, + help='input XML file') + 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'] == '': + fname = args['input'].name.split('.') + fname[-1] = '.h5' + args['output'] = ''.join(fname) + + # Parse and return commandline arguments. + return args + + +if __name__ == '__main__': + args = parse_args() + + # Parse the XML data. + tree = ET.parse(args['input']) + root = tree.getroot() + + if root.tag != 'library': + raise ValueError("Invalid XML file type") + + # Get old metadata + temp = tree.find('group_structure').text + 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 + 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 = xsdata_elem.find('name').text + + temperature = xsdata_elem.find('kT') + if temperature is not None: + temperature = \ + float(temperature.text) / openmc.data.K_BOLTZMANN + else: + temperature = 294. + temperatures = [temperature] + + awr = xsdata_elem.find('awr') + if awr is not None: + awr = float(awr.text) + + representation = xsdata_elem.find('representation') + if representation is not None: + representation = representation.text + else: + representation = 'isotropic' + if representation == 'angle': + n_azi = int(xsdata_elem.find('num_azimuthal').text) + n_pol = int(xsdata_elem.find('num_polar').text) + + scatter_type = xsdata_elem.find('scatt_type') + if scatter_type is not None: + scatter_type = scatter_type.text + else: + scatter_type = 'legendre' + + order = int(xsdata_elem.find('order').text) + + tab_leg = xsdata_elem.find('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: + # 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].awr = awr + if representation == 'angle': + xsd[-1].num_azimuthal = n_azi + xsd[-1].num_polar = n_pol + xsd[-1].scatter_type = scatter_type + xsd[-1].order = order + names.append(name) + + if scatter_type == 'legendre': + order_dim = order + 1 + else: + order_dim = order + + if i != -1: + xsd[i].add_temperature(temperature) + + temp = xsdata_elem.find('total') + if temp is not None: + temp = temp.text + temp = np.array(temp.split()) + total = temp.astype(np.float) + total = np.reshape(total, xsd[i].vector_shape) + xsd[i].set_total(total, temperature) + + temp = xsdata_elem.find('absorption').text + temp = np.array(temp.split()) + absorption = temp.astype(np.float) + absorption = np.reshape(absorption, xsd[i].vector_shape) + xsd[i].set_absorption(absorption, temperature) + + temp = xsdata_elem.find('scatter').text + temp = np.array(temp.split()) + temp = temp.astype(np.float) + scatter = np.reshape(temp, xsd[i].pn_matrix_shape) + xsd[i].set_scatter_matrix(scatter, temperature) + + temp = xsdata_elem.find('multiplicity') + if temp is not None: + temp = temp.text + temp = np.array(temp.split()) + temp = temp.astype(np.float) + multiplicity = np.reshape(temp, xsd[i].matrix_shape) + xsd[i].set_multiplicity_matrix(multiplicity, temperature) + + temp = xsdata_elem.find('fission') + if temp is not None: + temp = temp.text + temp = np.array(temp.split()) + fission = temp.astype(np.float) + fission = np.reshape(fission, xsd[i].vector_shape) + xsd[i].set_fission(fission, temperature) + + temp = xsdata_elem.find('kappa_fission') + if temp is not None: + temp = temp.text + temp = np.array(temp.split()) + kappa_fission = temp.astype(np.float) + kappa_fission = np.reshape(kappa_fission, xsd[i].vector_shape) + xsd[i].set_kappa_fission(kappa_fission, temperature) + + temp = xsdata_elem.find('chi') + if temp is not None: + temp = temp.text + temp = np.array(temp.split()) + chi = temp.astype(np.float) + chi = np.reshape(chi, xsd[i].vector_shape) + xsd[i].set_chi(chi, temperature) + else: + chi = None + + temp = xsdata_elem.find('nu_fission') + if temp is not None: + temp = temp.text + temp = np.array(temp.split()) + temp = temp.astype(np.float) + if chi is not None: + nu_fission = np.reshape(temp, xsd[i].vector_shape) + else: + nu_fission = np.reshape(temp, 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) + if inverse_velocities is not None: + lib.inverse_velocities = inverse_velocities + + lib.add_xsdatas(xsd) + + print(args['output']) + lib.export_to_hdf5(args['output'], compression=args['compression']) diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index f17f2781e..d9039a3ad 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -1,6 +1,6 @@ module mgxs_data -use constants + use constants use algorithm, only: find use error, only: fatal_error use global @@ -184,10 +184,14 @@ contains type is (MgxsAngle) allocate(MgxsAngle :: macro_xs(i_mat) % obj) end select - call macro_xs(i_mat) % obj % combine(kTs(i_mat), mat, nuclides_MG, & - energy_groups, max_order, & - temperature_tolerance, & - temperature_method) + ! 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 diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index cefd8725d..cef468517 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -923,7 +923,7 @@ module mgxs_header if (mat % name == "") then this % name = trim(to_str(mat % id)) else - this % name = mat % name + this % name = trim(mat % name) end if this % fissionable = mat % fissionable @@ -992,15 +992,16 @@ module mgxs_header do i = 1, mat % n_nuclides select type(nuc => nuclides(mat % nuclide(i)) % obj) type is (MgxsIso) - if (size(nuc % xs(1) % scatter % dist(1) % data, dim=1) > & - mat_max_order) & + 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) + 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 From 1305e99ce39f49471e1c37e52242bd7a00c5dcc4 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 5 Sep 2016 19:48:30 -0400 Subject: [PATCH 08/42] Updated test MGXS library an fixed bug in setting num_azimuthal and num_polar in mgxs_library. --- openmc/mgxs_library.py | 4 +- scripts/openmc-update-mgxs.py | 37 +- tests/1d_mgxs.xml | 9859 --------------------------------- 3 files changed, 20 insertions(+), 9880 deletions(-) delete mode 100644 tests/1d_mgxs.xml diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 3188631bc..ad60a5779 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -355,13 +355,13 @@ class XSdata(object): @num_polar.setter def num_polar(self, num_polar): # Make sure we have positive ints - check_value('num_polar', num_polar, Integral) + check_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 diff --git a/scripts/openmc-update-mgxs.py b/scripts/openmc-update-mgxs.py index a13004042..bc0c201c3 100755 --- a/scripts/openmc-update-mgxs.py +++ b/scripts/openmc-update-mgxs.py @@ -70,13 +70,13 @@ if __name__ == '__main__': raise ValueError("Invalid XML file type") # Get old metadata - temp = tree.find('group_structure').text + 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 + temp = temp.text.strip() temp = np.array(temp.split()) inverse_velocities = temp.astype(np.float) else: @@ -87,36 +87,36 @@ if __name__ == '__main__': # Now move on to the cross section data itself for xsdata_elem in root.iter('xsdata'): - name = xsdata_elem.find('name').text + name = xsdata_elem.find('name').text.strip() temperature = xsdata_elem.find('kT') if temperature is not None: temperature = \ - float(temperature.text) / openmc.data.K_BOLTZMANN + float(temperature.text.strip()) / openmc.data.K_BOLTZMANN else: temperature = 294. temperatures = [temperature] awr = xsdata_elem.find('awr') if awr is not None: - awr = float(awr.text) + awr = float(awr.text.strip()) representation = xsdata_elem.find('representation') if representation is not None: - representation = representation.text + representation = representation.text.strip() else: representation = 'isotropic' if representation == 'angle': - n_azi = int(xsdata_elem.find('num_azimuthal').text) - n_pol = int(xsdata_elem.find('num_polar').text) + n_azi = int(xsdata_elem.find('num_azimuthal').text.strip()) + n_pol = int(xsdata_elem.find('num_polar').text.strip()) scatter_type = xsdata_elem.find('scatt_type') if scatter_type is not None: - scatter_type = scatter_type.text + scatter_type = scatter_type.text.strip() else: scatter_type = 'legendre' - order = int(xsdata_elem.find('order').text) + order = int(xsdata_elem.find('order').text.strip()) tab_leg = xsdata_elem.find('tabular_legendre') if tab_leg is not None: @@ -155,19 +155,19 @@ if __name__ == '__main__': temp = xsdata_elem.find('total') if temp is not None: - temp = temp.text + temp = temp.text.strip() temp = np.array(temp.split()) total = temp.astype(np.float) total = np.reshape(total, xsd[i].vector_shape) xsd[i].set_total(total, temperature) - temp = xsdata_elem.find('absorption').text + temp = xsdata_elem.find('absorption').text.strip() temp = np.array(temp.split()) absorption = temp.astype(np.float) absorption = np.reshape(absorption, xsd[i].vector_shape) xsd[i].set_absorption(absorption, temperature) - temp = xsdata_elem.find('scatter').text + temp = xsdata_elem.find('scatter').text.strip() temp = np.array(temp.split()) temp = temp.astype(np.float) scatter = np.reshape(temp, xsd[i].pn_matrix_shape) @@ -175,7 +175,7 @@ if __name__ == '__main__': temp = xsdata_elem.find('multiplicity') if temp is not None: - temp = temp.text + temp = temp.text.strip() temp = np.array(temp.split()) temp = temp.astype(np.float) multiplicity = np.reshape(temp, xsd[i].matrix_shape) @@ -183,7 +183,7 @@ if __name__ == '__main__': temp = xsdata_elem.find('fission') if temp is not None: - temp = temp.text + temp = temp.text.strip() temp = np.array(temp.split()) fission = temp.astype(np.float) fission = np.reshape(fission, xsd[i].vector_shape) @@ -191,7 +191,7 @@ if __name__ == '__main__': temp = xsdata_elem.find('kappa_fission') if temp is not None: - temp = temp.text + temp = temp.text.strip() temp = np.array(temp.split()) kappa_fission = temp.astype(np.float) kappa_fission = np.reshape(kappa_fission, xsd[i].vector_shape) @@ -199,7 +199,7 @@ if __name__ == '__main__': temp = xsdata_elem.find('chi') if temp is not None: - temp = temp.text + temp = temp.text.strip() temp = np.array(temp.split()) chi = temp.astype(np.float) chi = np.reshape(chi, xsd[i].vector_shape) @@ -209,7 +209,7 @@ if __name__ == '__main__': temp = xsdata_elem.find('nu_fission') if temp is not None: - temp = temp.text + temp = temp.text.strip() temp = np.array(temp.split()) temp = temp.astype(np.float) if chi is not None: @@ -225,5 +225,4 @@ if __name__ == '__main__': lib.add_xsdatas(xsd) - print(args['output']) lib.export_to_hdf5(args['output'], compression=args['compression']) diff --git a/tests/1d_mgxs.xml b/tests/1d_mgxs.xml deleted file mode 100644 index 8704b49ad..000000000 --- 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 From 1625927b4427e80c508e29d709403f907dea5cb2 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 5 Sep 2016 21:04:50 -0400 Subject: [PATCH 09/42] Slowly getting the tests to work --- scripts/openmc-update-mgxs.py | 12 ++-- src/input_xml.F90 | 20 ++++--- src/mgxs_data.F90 | 54 ++++++++++++++++- src/mgxs_header.F90 | 58 +++++++++---------- tests/input_set.py | 2 +- tests/test_mg_basic/inputs_true.dat | 2 +- tests/test_mg_max_order/inputs_true.dat | 2 +- tests/test_mg_nuclide/inputs_true.dat | 2 +- tests/test_mg_tallies/inputs_true.dat | 2 +- .../test_mgxs_library_ce_to_mg.py | 6 +- 10 files changed, 106 insertions(+), 54 deletions(-) diff --git a/scripts/openmc-update-mgxs.py b/scripts/openmc-update-mgxs.py index bc0c201c3..fc9bad30f 100755 --- a/scripts/openmc-update-mgxs.py +++ b/scripts/openmc-update-mgxs.py @@ -42,18 +42,20 @@ def parse_args(): # Create argument parser parser = argparse.ArgumentParser(description=description, formatter_class=argparse.RawTextHelpFormatter) - parser.add_argument('-c', '--compression', type=int, - help='input XML file') 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') + parser.add_argument('-c', '--compression', type=int, + help='HDF5 Compression Level') args = vars(parser.parse_args()) if args['output'] == '': - fname = args['input'].name.split('.') - fname[-1] = '.h5' - args['output'] = ''.join(fname) + filename = args['input'].name + extension = filename[filename.rfind('.'):] + if extension == '.xml': + filename = filename[:filename.rfind('.')] + '.h5' + args['output'] = filename # Parse and return commandline arguments. return args diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 24875d1fe..d755f2168 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -49,10 +49,18 @@ contains call read_settings_xml() call read_geometry_xml() - call read_tallies_xml() call read_materials() + 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 + end subroutine read_input_xml !=============================================================================== @@ -2092,15 +2100,9 @@ contains call get_temperatures(nuc_temps, sab_temps) ! Read continuous-energy cross sections - if (run_mode /= MODE_PLOTTING) then + if (run_CE .and. run_mode /= MODE_PLOTTING) then call time_read_xs % start() - if (run_CE) then - call read_ce_cross_sections(libraries, library_dict, nuc_temps, sab_temps) - else - ! Create material macroscopic data for MGXS - call read_mgxs(nuc_temps) - call create_macro_xs() - end if + call read_ce_cross_sections(libraries, library_dict, nuc_temps, sab_temps) call time_read_xs % stop() end if diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index d9039a3ad..45737ff1d 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -20,9 +20,7 @@ contains ! nuclides and sab_tables arrays !=============================================================================== - subroutine read_mgxs(temps) - type(VectorReal), allocatable :: temps(:) - + subroutine read_mgxs() integer :: i ! index in materials array integer :: j ! index over nuclides in material integer :: i_xsdata ! index in list @@ -38,6 +36,7 @@ contains logical :: get_kfiss, get_fiss integer :: l type(DictCharInt) :: xsdata_dict + type(VectorReal), allocatable :: temps(:) ! Check if cross_sections.xml exists inquire(FILE=path_cross_sections, EXIST=file_exists) @@ -49,6 +48,9 @@ contains call write_message("Loading Cross Section Data...", 5) + ! Get temperatures + call get_temperatures(temps) + ! Open file for reading file_id = file_open(path_cross_sections, 'r', parallel=.true.) @@ -234,5 +236,51 @@ contains end subroutine get_mat_kTs +!=============================================================================== +! GET_TEMPERATURES returns a list of temperatures that each MGXS 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(temps) + type(VectorReal), allocatable, intent(out) :: temps(:) + + integer :: i, j, k + integer :: i_nuclide ! index in nuclides array + integer :: i_material + real(8) :: temperature ! temperature in Kelvin + + allocate(temps(n_nuclides_total)) + + 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 temps array + i_nuclide = nuclide_dict % get_key(to_lower(mat % names(k))) + + ! Add temperature if it hasn't already been added + if (find(temps(i_nuclide), temperature) == -1) then + call temps(i_nuclide) % push_back(temperature) + end if + end do NUC_NAMES_LOOP + end associate + end do + end do + + end subroutine get_temperatures + end module mgxs_data diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index cef468517..73a11476c 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -691,7 +691,7 @@ module mgxs_header if (check_dataset(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)) + 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) @@ -1241,25 +1241,25 @@ module mgxs_header ! 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(n_azi, n_pol, groups)) + allocate(this % xs(t) % total(groups, n_azi, n_pol)) this % xs(t) % total = ZERO - allocate(this % xs(t) % absorption(n_azi, n_pol, groups)) + allocate(this % xs(t) % absorption(groups, n_azi, n_pol)) this % xs(t) % absorption = ZERO - allocate(this % xs(t) % fission(n_azi, n_pol, groups)) + allocate(this % xs(t) % fission(groups, n_azi, n_pol)) this % xs(t) % fission = ZERO - allocate(this % xs(t) % k_fission(n_azi, n_pol, groups)) + allocate(this % xs(t) % k_fission(groups, n_azi, n_pol)) this % xs(t) % k_fission = ZERO - allocate(this % xs(t) % nu_fission(n_azi, n_pol, groups)) + allocate(this % xs(t) % nu_fission(groups, n_azi, n_pol)) this % xs(t) % nu_fission = ZERO - allocate(this % xs(t) % chi(n_azi, n_pol, groups, groups)) + allocate(this % xs(t) % chi(groups, groups, n_azi, n_pol)) this % xs(t) % chi = ZERO - allocate(temp_mult(n_azi, n_pol, groups, groups)) + allocate(temp_mult(groups, groups, n_azi, n_pol)) temp_mult = ZERO - allocate(mult_num(n_azi, n_pol, groups, groups)) + allocate(mult_num(groups, groups, n_azi, n_pol)) mult_num = ZERO - allocate(mult_denom(n_azi, n_pol, groups, groups)) + allocate(mult_denom(groups, groups, n_azi, n_pol)) mult_denom = ZERO - allocate(scatt_coeffs(n_azi, n_pol, order_dim, groups, groups)) + allocate(scatt_coeffs(order_dim, groups, groups, n_azi, n_pol)) scatt_coeffs = ZERO allocate(this % xs(t) % scatter(n_azi, n_pol)) @@ -1342,18 +1342,18 @@ module mgxs_header 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(iazi, ipol, gout, gin) = & - mult_num(iazi, ipol, gout, gin) + atom_density * & + mult_num(gout, gin, iazi, ipol) = & + mult_num(gout, gin, iazi, ipol) + atom_density * & nuscatt if (nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % mult(gin) % data(gout) > ZERO) then - mult_denom(iazi, ipol, gout, gin) = & - mult_denom(iazi, ipol, gout, gin) + atom_density * & + mult_denom(gout, gin, iazi, ipol) = & + mult_denom(gout, gin, iazi, ipol) + atom_density * & nuscatt / & nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % mult(gin) % data(gout) else ! Avoid division by zero - mult_denom(iazi, ipol, gout, gin) = & - mult_denom(iazi, ipol, gout, gin) + atom_density + mult_denom(gout, gin, iazi, ipol) = & + mult_denom(gout, gin, iazi, ipol) + atom_density end if end do end do @@ -1361,8 +1361,8 @@ module mgxs_header ! Get the complete scattering matrix nuc_order_dim = & size(nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % dist(1) % data, dim=1) - scatt_coeffs(iazi, ipol, 1:min(nuc_order_dim, order_dim), :, :) = & - scatt_coeffs(iazi, ipol, 1:min(nuc_order_dim, order_dim), :, :) + & + 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 % xs(nuc_t) % scatter(iazi, ipol) % obj % get_matrix(min(nuc_order_dim, order_dim)) end do @@ -1376,12 +1376,12 @@ module mgxs_header do iazi = 1, n_azi do gin = 1, groups do gout = 1, groups - if (mult_denom(iazi, ipol, gout, gin) > ZERO) then - temp_mult(iazi, ipol, gout, gin) = & - mult_num(iazi, ipol, gout, gin) / & - mult_denom(iazi, ipol, gout, gin) + 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(iazi, ipol, gout, gin) = ONE + temp_mult(gout, gin, iazi, ipol) = ONE end if end do end do @@ -1392,8 +1392,8 @@ module mgxs_header do ipol = 1, n_pol do iazi = 1, n_azi call this % xs(t) % scatter(iazi, ipol) % obj % init(& - temp_mult(iazi, ipol, :, :), & - scatt_coeffs(iazi, ipol, :, :, :)) + temp_mult(:, :, iazi, ipol), & + scatt_coeffs(:, :, :, iazi, ipol)) end do end do @@ -1402,10 +1402,10 @@ module mgxs_header do ipol = 1, n_pol do iazi = 1, n_azi do gin = 1, groups - norm = sum(this % xs(t) % chi(iazi, ipol, :, gin)) + norm = sum(this % xs(t) % chi(:, gin, iazi, ipol)) if (norm > ZERO) then - this % xs(t) % chi(iazi, ipol, :, gin) = & - this % xs(t) % chi(iazi, ipol, :, gin) / norm + this % xs(t) % chi(:, gin, iazi, ipol) = & + this % xs(t) % chi(:, gin, iazi, ipol) / norm end if end do end do diff --git a/tests/input_set.py b/tests/input_set.py index e409fba58..2dcef059a 100644 --- a/tests/input_set.py +++ b/tests/input_set.py @@ -893,7 +893,7 @@ class MGInputSet(InputSet): self.settings.source = Source(space=Box([0.0, 0.0, 0.0], [10.0, 10.0, 2.0])) 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/test_mg_basic/inputs_true.dat b/tests/test_mg_basic/inputs_true.dat index bfb0cc09e..1f95579c7 100644 --- a/tests/test_mg_basic/inputs_true.dat +++ b/tests/test_mg_basic/inputs_true.dat @@ -1 +1 @@ -d90692c6bf8db3672d70103ded682326d7f14d416e79e18ec055bdeafe1dbc1dbe642e8410cad95bf247f27c907b10b1567127bd2868d466ce2586aacff0411f \ No newline at end of file +ed4d8a6c1a00d4dad10bc5522bf42d0c7a13ef5f86fc93a3f249e77681cda4424ce8879919015b05272c276ffea41e3aecef882592e8dbd97085273a356fb630 \ No newline at end of file diff --git a/tests/test_mg_max_order/inputs_true.dat b/tests/test_mg_max_order/inputs_true.dat index d827cfaa4..9b5d32ce6 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 +8752d3167989d876c6f29b4b1ca7eed4b91793d8579c92de85633fd90235c67d63ee76d49081006047e0078f6f86eb6e3420c1f8fe44564e7a1fb62e828587d0 \ No newline at end of file diff --git a/tests/test_mg_nuclide/inputs_true.dat b/tests/test_mg_nuclide/inputs_true.dat index 18811f285..93de08656 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 +10b64fa97cc4feb1b1b8ba401b25b68ab682aba55ad4303a76a9a293ae79cdfff2f65d74310eb917da0aac243c24713d91eafae7ec5f0c4ae535d49fc928a869 \ No newline at end of file diff --git a/tests/test_mg_tallies/inputs_true.dat b/tests/test_mg_tallies/inputs_true.dat index c74d7759f..5707fe6de 100644 --- a/tests/test_mg_tallies/inputs_true.dat +++ b/tests/test_mg_tallies/inputs_true.dat @@ -1 +1 @@ -707285b77a091904a69720e78bf87a6779f2223c0fa2a3725353d00ca30f2624c7d53af016d78c7ad30b70a24bb53eda7dea2f592499b098f541591825b67143 \ No newline at end of file +34af3b6ee8f65c6257d85a7c9594bc9bbabdabcb055e42bf6dd3ebfc0e41503367674223093363798950524e04f4377eae80f6d535301e55d268ff0c74e4261f \ No newline at end of file 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 baa54b018..a86f73796 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') @@ -85,7 +85,7 @@ class MGXSTestHarness(PyAPITestHarness): 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) From 88abdfb5ce54c9599d42ec3cbd6c76ae7074f36a Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 5 Sep 2016 21:18:17 -0400 Subject: [PATCH 10/42] Fixed most failing tests, ce_to_mg is next --- .gitignore | 1 + tests/1d_mgxs.h5 | Bin 0 -> 100568 bytes tests/run_tests.py | 2 +- .../test_mgxs_library_ce_to_mg.py | 1 - 4 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 tests/1d_mgxs.h5 diff --git a/.gitignore b/.gitignore index 2ca1c7d14..b1cb1a623 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ tests/ctestscript.run # HDF5 files *.h5 +!tests/1d_mgxs.h5 # Build files src/CMakeCache.txt diff --git a/tests/1d_mgxs.h5 b/tests/1d_mgxs.h5 new file mode 100644 index 0000000000000000000000000000000000000000..4b7b94cb45772879a531852ad5db9fdbe58a49d6 GIT binary patch literal 100568 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

vHL_hxQ3HPiI5iPC~;Lvu1 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 Date: Wed, 7 Sep 2016 04:23:05 -0400 Subject: [PATCH 11/42] Implemented new scatter MGXS library specification on python side and fixed python2 bug in writing strings to hdf5 file --- docs/source/io_formats/mgxs_library.rst | 85 ++++++++++------ openmc/mgxs_library.py | 129 ++++++++++++++++++++---- 2 files changed, 162 insertions(+), 52 deletions(-) diff --git a/docs/source/io_formats/mgxs_library.rst b/docs/source/io_formats/mgxs_library.rst index ccd68c184..4f6233aaf 100644 --- a/docs/source/io_formats/mgxs_library.rst +++ b/docs/source/io_formats/mgxs_library.rst @@ -56,17 +56,18 @@ data for the nuclide or material that it represents. 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 + - **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-type** (*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-type`) - used to describe the angular distribution associated with each group-to-group transfer probability. + - **scatter-type** (*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-type`) + used to describe the angular distribution associated with each + group-to-group transfer probability. **//kTs/** @@ -86,30 +87,6 @@ Temperature-dependent data, provided for temperature K. 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]. - - **scatter matrix** (*double[][][]* or *double[][][][][]*) -- - Scattering moment matrices. This dataset 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 `scatter-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 matrix** (*double[][]* or *double[][][][]*) -- - Scattering multiplicity matrices. - This dataset 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 is not repeated for - every Legendre moment or histogram/tabular bin. This matrix - follows the same arrangement as described for the `scatter` - dataset, with the exception of the data needed to provide the - scattering type information. - This dataset is optional, if it is not provided no multiplication - (i.e., values of 1.0) will be assumed. - **fission** (*double[]* or *double[][][]*) -- Fission cross section. This is a 1-D vector if `representation` is "isotropic", or a 3-D @@ -135,4 +112,46 @@ Temperature-dependent data, provided for temperature K. 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`. \ No newline at end of file + same dimensionality as `multiplicity matrix`. + +**//K/scatter data/** + +Data specific to neutron scattering for the temperature K + +:Datasets: - **g_out bounds** (*int[2]* or *int[][][2]) -- + Minimum (most energetic) and maximum (most thermal) outgoing groups + with non-zero values of the scattering matrix. These group numbers + use the standard ordering where the fastest neutron energy group + is group 1 while the most thermal neutron energy group is group G. + The dimensionality of `g_out bounds` is: + `g_out bounds][g_in][g_out]`, or + `g_out bounds[num-polar][num-azimuthal][g_in][g_out]`. + The former is used when `representation` is "isotropic", and the + latter when `representation` is "angle". + - **scatter matrix** (*double[][]* or *double[][][][]*) -- + Flattened representation of the scattering moment matrices where + the [g_in] and [g_out] indices are flattened. The pre-flattened + array is shaped as follows (in row-major format): + `scatter matrix[order(+1)][g_in][g_out]`, or + `scatter matrix[num-polar][num-azimuthal][order(+1)][g_in][g_out]` + The former is used when `representation` is "isotropic", and the + latter when `representation` is "angle". Note that if the value of + `scatter-type` is "legendre", the order dimension will be one + larger than the value of `order`, otherwise it will match `order`. + Finally, the g_out dimension has a dimensionality of + `g_out bounds`[0] to `g_out bounds`[1]. + - **multiplicity matrix** (*double[]*) -- Flattened representation of + the scattering moment matrices where the [g_in] and [g_out] indices + are flattened. 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 shaped as follows (in row-major format): + `multiplicity matrix[g_in][g_out]`, or + `multiplicity matrix[num-polar][num-azimuthal][g_in][g_out]` + The former is used when `representation` is "isotropic", and the + latter when `representation` is "angle". Finally, the g_out + dimension has a dimensionality of `g_out bounds`[0] to + `g_out bounds`[1]. \ No newline at end of file diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index ad60a5779..687e2d693 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1137,14 +1137,15 @@ class XSdata(object): if self.fissionable is not None: grp.attrs['fissionable'] = self.fissionable if self.representation is not None: - grp.attrs['representation'] = np.string_(self.representation) + grp.attrs['representation'] = np.array(self.representation, + dtype='S') 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_type is not None: - grp.attrs['scatter-type'] = np.string_(self.scatter_type) + grp.attrs['scatter-type'] = np.array(self.scatter_type, dtype='S') if self.order is not None: grp.attrs['order'] = self.order @@ -1157,20 +1158,16 @@ class XSdata(object): # Create the temperature datasets for i, temperature in enumerate(self.temperatures): xsgrp = grp.create_group(str(int(np.round(temperature))) + "K") - if self._total[i] is not None: - xsgrp.create_dataset("total", data=self._total[i], - compression=compression) - if self._absorption[i] is not None: - xsgrp.create_dataset("absorption", data=self._absorption[i], - compression=compression) - if self._scatter_matrix[i] is not None: - xsgrp.create_dataset("scatter matrix", - data=self._scatter_matrix[i], - compression=compression) - if self._multiplicity_matrix[i] is not None: - xsgrp.create_dataset("multiplicity matrix", - data=self._multiplicity_matrix[i], - compression=compression) + if self._total[i] is None: + raise ValueError('total data must be provided when writing ' + 'the HDF5 library') + xsgrp.create_dataset("total", data=self._total[i], + compression=compression) + if self._absorption[i] is None: + raise ValueError('absorption data must be provided when ' + 'writing the HDF5 library') + xsgrp.create_dataset("absorption", data=self._absorption[i], + compression=compression) if self.fissionable: if self._fission[i] is not None: xsgrp.create_dataset("fission", data=self._fission[i], @@ -1182,9 +1179,103 @@ class XSdata(object): if self._chi[i] is not None: xsgrp.create_dataset("chi", data=self._chi[i], compression=compression) - if self._nu_fission[i] is not None: - xsgrp.create_dataset("nu-fission", - data=self._nu_fission[i], + if self._nu_fission[i] is None: + raise ValueError('nu-fission data must be provided when ' + 'writing the HDF5 library') + xsgrp.create_dataset("nu-fission", + data=self._nu_fission[i], + compression=compression) + + if self._scatter_matrix[i] is None: + raise ValueError('Scatter matrix must be provided when ' + 'writing the HDF5 library') + # Get the sparse scattering data to print to the library + G = self.energy_groups.num_groups + if self.representation is '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] + g_out_bounds[g_in, 1] = nz[-1] + # Now create the flattened scatter matrix array + flat_scatt = [] + for l in range(self._scatter_matrix[i].shape[0]): + for g_in in range(G): + matrix = self._scatter_matrix[i][l, g_in, :] + for g_out in range(g_out_bounds[g_in, 0], + g_out_bounds[g_in, 1] + 1): + flat_scatt.append(matrix[g_out]) + # And write it. + scatt_grp = xsgrp.create_group('scatter data') + scatt_grp.create_dataset("scatter matrix", + data=np.array(flat_scatt), + compression=compression) + # Repeat for multiplicity + if self._multiplicity_matrix[i] is not None: + # Now create the flattened scatter matrix array + flat_mult = [] + for g_in in range(G): + matrix = self._multiplicity_matrix[i][g_in, :] + for g_out in range(g_out_bounds[g_in, 0], + g_out_bounds[g_in, 1] + 1): + flat_mult.append(matrix[g_out]) + scatt_grp.create_dataset("multiplicity matrix", + data=np.array(flat_mult), + compression=compression) + # And finally, adjust g_out_bounds for 1-based group counting + # and write it. + g_out_bounds[:, :] += 1 + scatt_grp.create_dataset("g_out bounds", data=g_out_bounds, + compression=compression) + + else: + 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] + g_out_bounds[p, a, g_in, 1] = nz[-1] + # Now create the flattened scatter matrix array + flat_scatt = [[[] for a in range(Na)] for p in range(Np)] + for p in range(Np): + for a in range(Na): + for l in range(self._scatter_matrix[i].shape[2]): + for g_in in range(G): + matrix = \ + self._scatter_matrix[i][p, a, 0, g_in, :] + for g_out in range(g_out_bounds[p, a, g_in, 0], + g_out_bounds[p, a, g_in, 1] + + 1): + flat_scatt[p][a].append(matrix[g_out]) + # And write it. + scatt_grp = xsgrp.create_group('scatter data') + scatt_grp.create_dataset("scatter matrix", + data=np.array(flat_scatt).flatten(), + compression=compression) + # Repeat for multiplicity + if self._multiplicity_matrix[i] is not None: + # Now create the flattened scatter matrix array + flat_mult = [[[] for a in range(Na)] for p in range(Np)] + for p in range(Np): + for a in range(Na): + for l in range(self._scatter_matrix[i].shape[2]): + for g_in in range(G): + matrix = \ + self._multiplicity_matrix[i][p, a, g_in, :] + for g_out in range(g_out_bounds[p, a, g_in, 0], + g_out_bounds[p, a, g_in, 1] + 1): + flat_mult[p][a].append(matrix[g_out]) + scatt_grp.create_dataset("multiplicity matrix", + data=np.array(flat_mult).flatten(), + compression=compression) + # And finally, adjust g_out_bounds for 1-based group counting + # and write it. + g_out_bounds[:, :, :, :] += 1 + scatt_grp.create_dataset("g_out bounds", data=g_out_bounds, compression=compression) From 0cc5f06114aca33af769bc6318a74ca9b64f2c69 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 7 Sep 2016 18:39:10 -0400 Subject: [PATCH 12/42] Updated fortran side of the sparse scattering matrices, almost --- docs/source/io_formats/mgxs_library.rst | 42 +++-- openmc/mgxs_library.py | 16 +- src/mgxs_header.F90 | 217 +++++++++++++++--------- src/scattdata_header.F90 | 50 +++--- 4 files changed, 193 insertions(+), 132 deletions(-) diff --git a/docs/source/io_formats/mgxs_library.rst b/docs/source/io_formats/mgxs_library.rst index 4f6233aaf..0a02431f6 100644 --- a/docs/source/io_formats/mgxs_library.rst +++ b/docs/source/io_formats/mgxs_library.rst @@ -118,20 +118,27 @@ Temperature-dependent data, provided for temperature K. Data specific to neutron scattering for the temperature K -:Datasets: - **g_out bounds** (*int[2]* or *int[][][2]) -- - Minimum (most energetic) and maximum (most thermal) outgoing groups - with non-zero values of the scattering matrix. These group numbers - use the standard ordering where the fastest neutron energy group - is group 1 while the most thermal neutron energy group is group G. +:Datasets: - **g_min** (*int[]* or *int[][][]) -- + Minimum (most energetic) outgoing groups with non-zero values of + the scattering matrix. 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_out bounds` is: - `g_out bounds][g_in][g_out]`, or - `g_out bounds[num-polar][num-azimuthal][g_in][g_out]`. + `g_min[g_in]`, or `g_min[num-polar][num-azimuthal][g_in]`. The former is used when `representation` is "isotropic", and the latter when `representation` is "angle". - - **scatter matrix** (*double[][]* or *double[][][][]*) -- - Flattened representation of the scattering moment matrices where - the [g_in] and [g_out] indices are flattened. The pre-flattened - array is shaped as follows (in row-major format): + - **g_max** (*int[]* or *int[][][]) -- + Maximum (least energetic) outgoing groups with non-zero values of + the scattering matrix. 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_out bounds` is: + `g_max[g_in]`, or `g_max[num-polar][num-azimuthal][g_in]`. + The former is used when `representation` is "isotropic", and the + latter when `representation` is "angle". + - **scatter matrix** (*double[]*) -- Flattened representation of the + scattering moment matrices. The pre-flattened array is shaped as + follows (in row-major format): `scatter matrix[order(+1)][g_in][g_out]`, or `scatter matrix[num-polar][num-azimuthal][order(+1)][g_in][g_out]` The former is used when `representation` is "isotropic", and the @@ -141,13 +148,12 @@ Data specific to neutron scattering for the temperature K Finally, the g_out dimension has a dimensionality of `g_out bounds`[0] to `g_out bounds`[1]. - **multiplicity matrix** (*double[]*) -- Flattened representation of - the scattering moment matrices where the [g_in] and [g_out] indices - are flattened. 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 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 shaped as follows (in row-major format): `multiplicity matrix[g_in][g_out]`, or `multiplicity matrix[num-polar][num-azimuthal][g_in][g_out]` diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 687e2d693..eaf66d120 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1225,7 +1225,9 @@ class XSdata(object): # And finally, adjust g_out_bounds for 1-based group counting # and write it. g_out_bounds[:, :] += 1 - scatt_grp.create_dataset("g_out bounds", data=g_out_bounds, + scatt_grp.create_dataset("g_min", data=g_out_bounds[:, 0], + compression=compression) + scatt_grp.create_dataset("g_max", data=g_out_bounds[:, 1], compression=compression) else: @@ -1240,7 +1242,7 @@ class XSdata(object): g_out_bounds[p, a, g_in, 0] = nz[0] g_out_bounds[p, a, g_in, 1] = nz[-1] # Now create the flattened scatter matrix array - flat_scatt = [[[] for a in range(Na)] for p in range(Np)] + flat_scatt = [] for p in range(Np): for a in range(Na): for l in range(self._scatter_matrix[i].shape[2]): @@ -1250,16 +1252,16 @@ class XSdata(object): for g_out in range(g_out_bounds[p, a, g_in, 0], g_out_bounds[p, a, g_in, 1] + 1): - flat_scatt[p][a].append(matrix[g_out]) + flat_scatt.append(matrix[g_out]) # And write it. scatt_grp = xsgrp.create_group('scatter data') scatt_grp.create_dataset("scatter matrix", - data=np.array(flat_scatt).flatten(), + data=np.array(flat_scatt), compression=compression) # Repeat for multiplicity if self._multiplicity_matrix[i] is not None: # Now create the flattened scatter matrix array - flat_mult = [[[] for a in range(Na)] for p in range(Np)] + flat_mult = [] for p in range(Np): for a in range(Na): for l in range(self._scatter_matrix[i].shape[2]): @@ -1268,9 +1270,9 @@ class XSdata(object): self._multiplicity_matrix[i][p, a, g_in, :] for g_out in range(g_out_bounds[p, a, g_in, 0], g_out_bounds[p, a, g_in, 1] + 1): - flat_mult[p][a].append(matrix[g_out]) + flat_mult.append(matrix[g_out]) scatt_grp.create_dataset("multiplicity matrix", - data=np.array(flat_mult).flatten(), + data=np.array(flat_mult), compression=compression) # And finally, adjust g_out_bounds for 1-based group counting # and write it. diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 73a11476c..7ed7f090c 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -381,16 +381,17 @@ module mgxs_header ! in that conversion character(MAX_LINE_LEN) :: temp_str - integer(HID_T) :: xsdata_grp + integer(HID_T) :: xsdata_grp, scatt_grp 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, imu + integer :: order, order_dim, gin, gout, l, imu, length type(VectorInt) :: temps_to_read integer :: t + type(Jagged2D) :: input_scatt(:) + type(Jagged1D) :: 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, & @@ -488,84 +489,134 @@ module mgxs_header end if ! Get scattering data - ! 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_dataset(xsdata_grp, "scatter matrix")) then - call read_dataset(input_scatt, xsdata_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_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 xs is also - ! the default behavior), convert that now. - if (this % scatter_type == ANGLE_LEGENDRE .and. legendre_to_tabular) then - ! Convert input parameters to what we need for the rest. - this % scatter_type = ANGLE_TABULAR - order_dim = legendre_to_tabular_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 ! 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(:, gout, gin) = scatt_coeffs(:, gout, gin) * & - temp_scatt(gout, gin, 1) / norm - end if - end do ! gout - end do ! gin - else - ! Sticking with current representation, carry forward but change - ! the array ordering - allocate(scatt_coeffs(order_dim, groups, groups)) - do gin = 1, groups - do gout = 1, groups - do l = 1, order_dim - scatt_coeffs(l, gout, gin) = temp_scatt(gout, gin, l) - end do - end do - end do - end if - deallocate(temp_scatt) + if (.not. check_group(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 (check_dataset(xsdata_grp, "g_min")) then + allocate(g_min(groups)) + call read_dataset(g_min, scatt_grp, "g_min") else - call fatal_error("Must provide scatter matrix!") + call fatal_error("'g_min' for the scatter matrix must be provided") end if + if (check_dataset(xsdata_grp, "g_max")) then + allocate(g_max(groups)) + call read_dataset(g_max, scatt_grp, "g_max") + else + call fatal_error("'g_max' for the scatter matrix 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 * (g_max(gin) - gmin(gin) + 1) + end do + ! Allocate flattened array + allocate(temp_arr(length)) + jf (.not. check_dataset(scatt_grp, 'scatter matrix') & + call fatal_error("'scatter matrix' must be provided") + call read_dataset(temp_arr, scatt_grp, "scatter matrix") + + ! 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 l = 1, order_dim + do gout = gmin(gin), gmax(gin) + 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 + ! Compare the number of orders given with the maximum order of the + ! problem. Strip off the supefluous orders if needed. + if (this % scatter_type == ANGLE_LEGENDRE) then + order = min(order_dim - 1, max_order) + order_dim = order + 1 + end if + + allocate(scatt_coeffs(gin)) + + if (this % scatter_type == ANGLE_LEGENDRE .and. & + legendre_to_tabular) then + this % scatter_type = 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, groups)) + 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(i:, gout) = & + scatt_coeffs(gin) % data(:, gout) * & + input_scatt(gin) % data(1, gout) + end if + end do ! gout + end do ! gin + else + ! Sticking with current representation, carry forward but change + ! the array ordering + do gin = 1, groups + allocate(scatt_coeffs(gin) % data(order_dim, groups)) + scatt_coeffs(gin) % data(:, :) = input_scatt(gin) % data(:, :) + end do + end if + deallocate(input_scatt) + + ! Now get the multiplication matrix + ! Now use this information to find the length of a container array + ! to hold the flattened data + length = 0 + do gin = 1, groups + length = length + (g_max(gin) - gmin(gin) + 1) + end do + ! Allocate flattened array + allocate(temp_arr(length)) + jf (.not. check_dataset(scatt_grp, 'multiplicity matrix') & + call fatal_error("'multiplicity matrix' must be provided") + call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") + + ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing + ! to ScattData + allocate(temp_mult(groups)) + index = 1 + do gin = 1, groups + allocate(temp_mult(gin) % data(gmin(gin):gmax(gin))) + do gout = gmin(gin), gmax(gin) + temp_mult(gin) % data(gout) = temp_arr(index) + index = index + 1 + end do + end do + deallocate(temp_arr) ! Allocate and initialize our ScattData Object. if (this % scatter_type == ANGLE_HISTOGRAM) then @@ -577,7 +628,7 @@ module mgxs_header end if ! Initialize the ScattData Object - call xs % scatter % init(temp_mult, scatt_coeffs) + 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 @@ -1168,7 +1219,7 @@ module mgxs_header end do ! Initialize the ScattData Object - call this % xs(t) % scatter % init(temp_mult, scatt_coeffs) + call this % xs(t) % scatter % init_from_dense(temp_mult, scatt_coeffs) ! Now normalize chi if (mat % fissionable) then @@ -1391,7 +1442,7 @@ module mgxs_header ! Initialize the ScattData Object do ipol = 1, n_pol do iazi = 1, n_azi - call this % xs(t) % scatter(iazi, ipol) % obj % init(& + call this % xs(t) % scatter(iazi, ipol) % obj % init_from_dense(& temp_mult(:, :, iazi, ipol), & scatt_coeffs(:, :, :, iazi, ipol)) end do diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index d4643a072..3bd29bb26 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -42,18 +42,20 @@ module scattdata_header contains procedure(scattdata_init_), deferred :: init ! Initializes ScattData + ! Initializes ScattData from a dense matrix + procedure(scattdata_init_dense_), deferred :: init_from_dense 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) + subroutine scattdata_init_dense_(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 - end subroutine scattdata_init_ + end subroutine scattdata_init_dense_ pure function scattdata_calc_f_(this, gin, gout, mu) result(f) import ScattData @@ -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_from_dense => scattdatalegendre_init_from_dense + 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_from_dense => scattdatahistogram_init_from_dense + 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_from_dense => scattdatatabular_init_from_dense + procedure :: calc_f => scattdatatabular_calc_f + procedure :: sample => scattdatatabular_sample + procedure :: get_matrix => scattdatatabular_get_matrix end type ScattDataTabular !=============================================================================== @@ -122,7 +124,7 @@ contains ! SCATTDATA*_INIT builds the scattdata object !=============================================================================== - subroutine scattdata_init(this, order, energy, mult) + subroutine scattdata_init_from_dense(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 @@ -167,9 +169,9 @@ contains this % gmin(gin) = gmin this % gmax(gin) = gmax end do - end subroutine scattdata_init + end subroutine scattdata_init_from_dense - subroutine scattdatalegendre_init(this, mult, coeffs) + subroutine scattdatalegendre_init_from_dense(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 @@ -206,7 +208,7 @@ contains end do end do - call scattdata_init(this, order, energy, mult) + call scattdata_init_from_dense(this, order, energy, mult) allocate(this % max_val(groups)) ! Set dist values from matrix and initialize max_val @@ -244,9 +246,9 @@ contains this % max_val(gin) % data(gout) * 1.1_8 end do end do - end subroutine scattdatalegendre_init + end subroutine scattdatalegendre_init_from_dense - subroutine scattdatahistogram_init(this, mult, coeffs) + subroutine scattdatahistogram_init_from_dense(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 @@ -283,7 +285,7 @@ contains end do end do - call scattdata_init(this, order, energy, mult) + call scattdata_init_from_dense(this, order, energy, mult) allocate(this % mu(order)) this % dmu = TWO / real(order, 8) @@ -321,9 +323,9 @@ contains end do end do - end subroutine scattdatahistogram_init + end subroutine scattdatahistogram_init_from_dense - subroutine scattdatatabular_init(this, mult, coeffs) + subroutine scattdatatabular_init_from_dense(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 @@ -378,7 +380,7 @@ contains energy(gout, gin) = norm end do end do - call scattdata_init(this, order, energy, mult) + call scattdata_init_from_dense(this, order, energy, mult) ! Calculate f(mu) and integrate it so we can avoid rejection sampling allocate(this % fmu(groups)) @@ -415,7 +417,7 @@ contains end if end do end do - end subroutine scattdatatabular_init + end subroutine scattdatatabular_init_from_dense !=============================================================================== ! SCATTDATA_*_CALC_F Calculates the value of f given mu (and gin,gout pair) From 3b6f836ec4509296d4793e8dcfbc774a75ac9d93 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Thu, 8 Sep 2016 05:15:58 -0400 Subject: [PATCH 13/42] Revised the mgxs_combine procedure to work with the sparse format of scattering data --- src/mgxs_header.F90 | 461 ++++++++++++++++++++++++--------------- src/scattdata_header.F90 | 395 +++++++++++++++++++++------------ 2 files changed, 543 insertions(+), 313 deletions(-) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 7ed7f090c..298602402 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -380,18 +380,16 @@ module mgxs_header 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 - real(8), allocatable :: temp_arr(:), temp_2d(:, :) - real(8), allocatable :: scatt_coeffs(:, :, :) - real(8), allocatable :: temp_scatt(:, :, :) - real(8) :: dmu, mu, norm - integer :: order, order_dim, gin, gout, l, imu, length - type(VectorInt) :: temps_to_read - integer :: t - type(Jagged2D) :: input_scatt(:) - type(Jagged1D) :: temp_mult(:) - integer, allocatable :: gmin(:), gmax(:) + 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, & @@ -480,28 +478,20 @@ module mgxs_header call fatal_error("Must provide absorption!") end if - ! Get multiplication data if present - allocate(temp_mult(groups, groups)) - if (check_dataset(xsdata_grp, "multiplicity matrix")) then - call read_dataset(temp_mult, xsdata_grp, "multiplicity matrix") - else - temp_mult(:, :) = ONE - end if - ! Get scattering data if (.not. check_group(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 (check_dataset(xsdata_grp, "g_min")) then - allocate(g_min(groups)) - call read_dataset(g_min, scatt_grp, "g_min") + allocate(gmin(groups)) + call read_dataset(gmin, scatt_grp, "g_min") else call fatal_error("'g_min' for the scatter matrix must be provided") end if if (check_dataset(xsdata_grp, "g_max")) then - allocate(g_max(groups)) - call read_dataset(g_max, scatt_grp, "g_max") + allocate(gmax(groups)) + call read_dataset(gmax, scatt_grp, "g_max") else call fatal_error("'g_max' for the scatter matrix must be provided") end if @@ -510,11 +500,11 @@ module mgxs_header ! to hold the flattened data length = 0 do gin = 1, groups - length = length + order_dim * (g_max(gin) - gmin(gin) + 1) + length = length + order_dim * (gmax(gin) - gmin(gin) + 1) end do ! Allocate flattened array allocate(temp_arr(length)) - jf (.not. check_dataset(scatt_grp, 'scatter matrix') & + if (.not. check_dataset(scatt_grp, 'scatter matrix')) & call fatal_error("'scatter matrix' must be provided") call read_dataset(temp_arr, scatt_grp, "scatter matrix") @@ -542,7 +532,6 @@ module mgxs_header end if allocate(scatt_coeffs(gin)) - if (this % scatter_type == ANGLE_LEGENDRE .and. & legendre_to_tabular) then this % scatter_type = ANGLE_TABULAR @@ -576,7 +565,7 @@ module mgxs_header ! 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(i:, gout) = & + scatt_coeffs(gin) % data(:, gout) = & scatt_coeffs(gin) % data(:, gout) * & input_scatt(gin) % data(1, gout) end if @@ -597,11 +586,11 @@ module mgxs_header ! to hold the flattened data length = 0 do gin = 1, groups - length = length + (g_max(gin) - gmin(gin) + 1) + length = length + (gmax(gin) - gmin(gin) + 1) end do ! Allocate flattened array allocate(temp_arr(length)) - jf (.not. check_dataset(scatt_grp, 'multiplicity matrix') & + if (.not. check_dataset(scatt_grp, 'multiplicity matrix')) & call fatal_error("'multiplicity matrix' must be provided") call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") @@ -674,17 +663,16 @@ module mgxs_header 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 - 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 - integer :: order, order_dim, gin, gout, l, imu, ipol, iazi - type(VectorInt) :: temps_to_read - integer :: t + character(MAX_LINE_LEN) :: temp_str + integer(HID_T) :: xsdata_grp, scatt_grp + 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, & @@ -807,115 +795,167 @@ module mgxs_header 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_dataset(xsdata_grp, "multiplicity matrix")) then - call read_dataset(temp_mult, xsdata_grp, "multiplicity matrix") - else - temp_mult(:, :, :, :) = ONE - end if - ! Get scattering data - ! 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_dataset(xsdata_grp, "scatter matrix")) then - allocate(temp_arr(groups * groups * order_dim * this % n_azi * & - this % n_pol)) - call read_dataset(temp_arr, xsdata_grp, "scatter matrix") - 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 % scatter_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 xs is also - ! the default behavior), convert that now. - if (this % scatter_type == ANGLE_LEGENDRE .and. legendre_to_tabular) then - - ! Convert input parameters to what we need for the rest. - this % scatter_type = ANGLE_TABULAR - order_dim = legendre_to_tabular_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) + if (.not. check_group(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 (check_dataset(xsdata_grp, "g_min")) then + allocate(gmin(groups, this % n_azi, this % n_pol)) + call read_dataset(gmin, scatt_grp, "g_min") else - call fatal_error("Must provide scatter matrix!") + call fatal_error("'g_min' for the scatter matrix must be provided") + end if + if (check_dataset(xsdata_grp, "g_max")) then + allocate(gmax(groups, this % n_azi, this % n_pol)) + call read_dataset(gmax, scatt_grp, "g_max") + else + call fatal_error("'g_max' for the scatter matrix 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. check_dataset(scatt_grp, 'scatter matrix')) & + call fatal_error("'scatter matrix' must be provided") + call read_dataset(temp_arr, scatt_grp, "scatter matrix") + + ! 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 l = 1, order_dim + do gout = gmin(gin, iazi, ipol), gmax(gin, iazi, ipol) + 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 + ! Compare the number of orders given with the maximum order of the + ! problem. Strip off the supefluous orders if needed. + if (this % scatter_type == ANGLE_LEGENDRE) then + order = min(order_dim - 1, max_order) + order_dim = order + 1 + end if + + allocate(scatt_coeffs(gin, this % n_azi, this % n_pol)) + if (this % scatter_type == ANGLE_LEGENDRE .and. & + legendre_to_tabular) then + this % scatter_type = 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, groups)) + 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) + end if + end do ! gout + end do ! gin + end do ! iazi + end do ! ipol + else + ! Sticking with current representation, carry forward but change + ! the array ordering + 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, groups)) + scatt_coeffs(gin, iazi, ipol) % data(:, :) = & + input_scatt(gin, iazi, ipol) % data(:, :) + end do + end do + end do + end if + deallocate(input_scatt) + + ! Now get the multiplication matrix + ! Now use this information to find the length of a container array + ! to hold the flattened data + length = 0 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + length = length + (gmax(gin, iazi, ipol) - gmin(gin, iazi, ipol) + 1) + end do + end do + end do + ! Allocate flattened array + allocate(temp_arr(length)) + if (.not. check_dataset(scatt_grp, 'multiplicity matrix')) & + call fatal_error("'multiplicity matrix' must be provided") + call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") + + ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing + ! to ScattData + allocate(temp_mult(groups, this % n_azi, this % n_pol)) + index = 1 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + allocate(temp_mult(gin, iazi, ipol) % data( & + gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) + do gout = gmin(gin, iazi, ipol), gmax(gin, iazi, ipol) + temp_mult(gin, iazi, ipol) % data(gout) = temp_arr(index) + index = index + 1 + end do + end do + end do + end do + deallocate(temp_arr) + + ! 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 @@ -929,9 +969,22 @@ module mgxs_header end if ! Initialize the ScattData Object - call xs % scatter(iazi, ipol) % obj % init(& - temp_mult(:, :, iazi, ipol), & - scatt_coeffs(:, :, :, iazi, ipol)) + 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 @@ -947,6 +1000,18 @@ module mgxs_header end do end if + ! Finally, 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 + ! Close the groups we have opened and deallocate call close_group(xsdata_grp) deallocate(input_scatt, scatt_coeffs, temp_mult) @@ -1087,6 +1152,10 @@ module mgxs_header integer :: nuc_t real(8) :: temp_actual, temp_desired integer :: scatter_type + 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_type, & @@ -1170,7 +1239,13 @@ module mgxs_header end if end if - ! Get the multiplication matrix + ! We will next gather the multiplicaity 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'})) @@ -1199,10 +1274,18 @@ module mgxs_header ! Get the complete scattering matrix nuc_order_dim = size(nuc % xs(nuc_t) % 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 % xs(nuc_t) % scatter % get_matrix(min(nuc_order_dim, order_dim)) + 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 * nuc_matrix(gin) % data(1:nuc_order_dim, gout) + end do + end do + type is (MgxsAngle) call fatal_error("Invalid passing of MgxsAngle to MgxsIso object") end select @@ -1218,8 +1301,13 @@ module mgxs_header end do end do + ! Now create our jagged data from the dense data + call jagged_from_dense_2D(scatt_coeffs, jagged_scatt) + call jagged_from_dense_1D(temp_mult, jagged_mult, gmin, gmax) + ! Initialize the ScattData Object - call this % xs(t) % scatter % init_from_dense(temp_mult, scatt_coeffs) + call this % xs(t) % scatter % init(gmin, gmax, jagged_mult, & + jagged_scatt) ! Now normalize chi if (mat % fissionable) then @@ -1232,7 +1320,8 @@ module mgxs_header end if ! Deallocate temporaries - deallocate(scatt_coeffs, temp_mult, mult_num, mult_denom) + 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 @@ -1262,6 +1351,10 @@ module mgxs_header integer :: nuc_t real(8) :: temp_actual, temp_desired integer :: scatter_type + 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_type, & @@ -1375,7 +1468,13 @@ module mgxs_header end if end if - ! Get the multiplication matrix + ! We will next gather the multiplicaity 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'})) @@ -1411,20 +1510,31 @@ module mgxs_header ! Get the complete scattering matrix nuc_order_dim = & - size(nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % dist(1) % data, dim=1) - 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 % xs(nuc_t) % scatter(iazi, ipol) % obj % get_matrix(min(nuc_order_dim, order_dim)) - end do - end do + 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 * nuc_matrix(gin) % data(1:nuc_order_dim, gout) + end do ! gout + end do ! gin + end do ! iazi + end do ! ipol type is (MgxsIso) call fatal_error("Invalid passing of MgxsIso to MgxsAngle object") end select - ! Obtain temp_mult + ! 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 @@ -1436,15 +1546,17 @@ module mgxs_header 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 % xs(t) % scatter(iazi, ipol) % obj % init_from_dense(& - temp_mult(:, :, iazi, ipol), & - scatt_coeffs(:, :, :, iazi, ipol)) + ! Create the Jagged arrays + call jagged_from_dense_2D(scatt_coeffs(:, :, :, iazi, ipol), & + jagged_scatt) + call jagged_from_dense_1D(temp_mult(:, :, iazi, ipol), & + jagged_mult, gmin, gmax) + + ! Initialize the ScattData Object + ! Initialize the ScattData Object + call this % xs(t) % scatter(iazi, ipol) % obj % init(gmin, & + gmax, jagged_mult, jagged_scatt) end do end do @@ -1464,7 +1576,8 @@ module mgxs_header end if ! Deallocate temporaries - deallocate(scatt_coeffs, temp_mult, mult_num, mult_denom) + 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 diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index 3bd29bb26..6dd104d5c 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -41,21 +41,21 @@ module scattdata_header real(8), allocatable :: scattxs(:) ! Isotropic Sigma_{s,g_{in}} contains - procedure(scattdata_init_), deferred :: init ! Initializes ScattData - ! Initializes ScattData from a dense matrix - procedure(scattdata_init_dense_), deferred :: init_from_dense + 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_dense_(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 - end subroutine scattdata_init_dense_ + 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) import ScattData @@ -81,7 +81,7 @@ module scattdata_header ! Maximal value for rejection sampling from rectangle type(Jagged1D), allocatable :: max_val(:) ! (Gin % data(Gout)) contains - procedure :: init_from_dense => scattdatalegendre_init_from_dense + procedure :: init => scattdatalegendre_init procedure :: calc_f => scattdatalegendre_calc_f procedure :: sample => scattdatalegendre_sample end type ScattDataLegendre @@ -92,7 +92,7 @@ module scattdata_header ! Histogram of f(mu) (dist has CDF) type(Jagged2D), allocatable :: fmu(:) ! (Gin % data(Order/Nmu x Gout) contains - procedure :: init_from_dense => scattdatahistogram_init_from_dense + procedure :: init => scattdatahistogram_init procedure :: calc_f => scattdatahistogram_calc_f procedure :: sample => scattdatahistogram_sample procedure :: get_matrix => scattdatahistogram_get_matrix @@ -104,7 +104,7 @@ module scattdata_header ! PDF of f(mu) (dist has CDF) type(Jagged2D), allocatable :: fmu(:) ! (Gin % data(Order/Nmu x Gout) contains - procedure :: init_from_dense => scattdatatabular_init_from_dense + procedure :: init => scattdatatabular_init procedure :: calc_f => scattdatatabular_calc_f procedure :: sample => scattdatatabular_sample procedure :: get_matrix => scattdatatabular_get_matrix @@ -124,13 +124,15 @@ contains ! SCATTDATA*_INIT builds the scattdata object !=============================================================================== - subroutine scattdata_init_from_dense(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) @@ -140,83 +142,79 @@ 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(:) = mult(gin) % data(:) + 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_from_dense + end subroutine scattdata_init - subroutine scattdatalegendre_init_from_dense(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_from_dense(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 @@ -225,7 +223,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,46 +244,52 @@ contains this % max_val(gin) % data(gout) * 1.1_8 end do end do - end subroutine scattdatalegendre_init_from_dense + end subroutine scattdatalegendre_init - subroutine scattdatahistogram_init_from_dense(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 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_from_dense(this, order, energy, mult) + call scattdata_init(this, order, gmin, gmax, energy, mult) allocate(this % mu(order)) this % dmu = TWO / real(order, 8) @@ -298,17 +302,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,24 +326,29 @@ contains end do end do - end subroutine scattdatahistogram_init_from_dense + end subroutine scattdatahistogram_init - subroutine scattdatatabular_init_from_dense(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)) @@ -358,39 +366,39 @@ 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 + 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_from_dense(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 @@ -417,7 +425,7 @@ contains end if end do end do - end subroutine scattdatatabular_init_from_dense + end subroutine scattdatatabular_init !=============================================================================== ! SCATTDATA_*_CALC_F Calculates the value of f given mu (and gin,gout pair) @@ -642,10 +650,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 @@ -653,66 +661,175 @@ 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 + + if (present(key_)) then + key = key_ + else + key = ZERO + end if + + if (present(lo_bounds)) then + if (allocated(lo_bounds)) deallocate(lo_bounds) + allocate(lo_bounds(size(dense, dim=2))) + end if + if (present(hi_bounds)) then + if (allocated(hi_bounds)) deallocate(hi_bounds) + allocate(hi_bounds(size(dense, dim=2))) + end if + + 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) + + if (present(lo_bounds)) lo_bounds(i) = jmin + if (present(hi_bounds)) hi_bounds(i) = jmax + end do + + 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 + + if (present(key_)) then + key = key_ + else + key = ZERO + end if + + if (present(lo_bounds)) then + if (allocated(lo_bounds)) deallocate(lo_bounds) + allocate(lo_bounds(size(dense, dim=3))) + end if + if (present(hi_bounds)) then + if (allocated(hi_bounds)) deallocate(hi_bounds) + allocate(hi_bounds(size(dense, dim=3))) + end if + + 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=1) + if (sum(dense(:, jmin, i)) > key) exit + end do + do jmax = size(dense, dim=1), 1, -1 + if (sum(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) + + if (present(lo_bounds)) lo_bounds(i) = jmin + if (present(hi_bounds)) hi_bounds(i) = jmax + end do + + end subroutine jagged_from_dense_2D end module scattdata_header From a235aa8cbad878a7e0b4c995287a0e399ed06efc Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 9 Sep 2016 20:39:05 -0400 Subject: [PATCH 14/42] Progressively fixing bugs, last one seems to be tabular representation doesnt produce correct results anymore --- .../pythonapi/examples/mgxs-part-iv.ipynb | 213 ++++++++++-------- openmc/mgxs_library.py | 61 +++-- openmc/settings.py | 5 +- src/mgxs_header.F90 | 61 ++--- src/scattdata_header.F90 | 83 ++++--- tests/1d_mgxs.h5 | Bin 100568 -> 123864 bytes 6 files changed, 226 insertions(+), 197 deletions(-) diff --git a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb index 301bbf015..a4f406951 100644 --- a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb @@ -431,7 +431,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "" ] @@ -577,7 +577,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/romano/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" ] } @@ -734,8 +734,8 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | fbebf7bf709fe2fe1813af95bff9b29c0d59312c\n", - " Date/Time | 2016-08-31 10:48:01\n", + " Git SHA1 | 6cf7f7fa48d70d26165403f8067aedb598534990\n", + " Date/Time | 2016-09-08 20:16:34\n", " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", @@ -746,12 +746,12 @@ " Reading geometry XML file...\n", " Reading cross sections XML file...\n", " Reading materials XML file...\n", - " Reading U235 from /home/romano/openmc/data/nndc_hdf5/U235.h5\n", - " Reading U238 from /home/romano/openmc/data/nndc_hdf5/U238.h5\n", - " Reading O16 from /home/romano/openmc/data/nndc_hdf5/O16.h5\n", - " Reading Zr90 from /home/romano/openmc/data/nndc_hdf5/Zr90.h5\n", - " Reading H1 from /home/romano/openmc/data/nndc_hdf5/H1.h5\n", - " Reading B10 from /home/romano/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", @@ -822,20 +822,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 4.2200E-01 seconds\n", - " Reading cross sections = 2.8800E-01 seconds\n", - " Total time in simulation = 4.1409E+01 seconds\n", - " Time in transport only = 4.1265E+01 seconds\n", - " Time in inactive batches = 4.6120E+00 seconds\n", - " Time in active batches = 3.6797E+01 seconds\n", - " Time synchronizing fission bank = 9.0000E-03 seconds\n", - " Sampling source sites = 6.0000E-03 seconds\n", - " SEND/RECV source sites = 3.0000E-03 seconds\n", + " Total time for initialization = 3.2700E-01 seconds\n", + " Reading cross sections = 2.1500E-01 seconds\n", + " Total time in simulation = 2.2139E+01 seconds\n", + " Time in transport only = 2.1970E+01 seconds\n", + " Time in inactive batches = 2.6960E+00 seconds\n", + " Time in active batches = 1.9443E+01 seconds\n", + " Time synchronizing fission bank = 2.0000E-03 seconds\n", + " Sampling source sites = 1.0000E-03 seconds\n", + " SEND/RECV source sites = 1.0000E-03 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 4.1869E+01 seconds\n", - " Calculation Rate (inactive) = 10841.3 neutrons/second\n", - " Calculation Rate (active) = 5435.23 neutrons/second\n", + " Total time elapsed = 2.2488E+01 seconds\n", + " Calculation Rate (inactive) = 18546.0 neutrons/second\n", + " Calculation Rate (active) = 10286.5 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -973,13 +973,26 @@ "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(array([0, 1]),)\n", + "(array([0, 1]),)\n", + "(array([0, 1]),)\n", + "(array([0, 1]),)\n", + "(array([0, 1]),)\n", + "(array([0, 1]),)\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()" + "mgxs_file.export_to_hdf5()" ] }, { @@ -1051,7 +1064,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", @@ -1108,8 +1121,8 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | fbebf7bf709fe2fe1813af95bff9b29c0d59312c\n", - " Date/Time | 2016-08-31 10:48:43\n", + " Git SHA1 | 6cf7f7fa48d70d26165403f8067aedb598534990\n", + " Date/Time | 2016-09-08 20:16:57\n", " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", @@ -1118,14 +1131,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", @@ -1134,56 +1147,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.68770 \n", + " 2/1 0.71454 \n", + " 3/1 0.69764 \n", + " 4/1 0.68400 \n", + " 5/1 0.69412 \n", + " 6/1 0.70489 \n", + " 7/1 0.70203 \n", + " 8/1 0.70721 \n", + " 9/1 0.69408 \n", + " 10/1 0.70103 \n", + " 11/1 0.69351 \n", + " 12/1 0.71450 0.70401 +/- 0.01049\n", + " 13/1 0.70298 0.70366 +/- 0.00607\n", + " 14/1 0.69351 0.70113 +/- 0.00499\n", + " 15/1 0.70901 0.70270 +/- 0.00417\n", + " 16/1 0.70364 0.70286 +/- 0.00341\n", + " 17/1 0.68831 0.70078 +/- 0.00355\n", + " 18/1 0.69861 0.70051 +/- 0.00309\n", + " 19/1 0.71634 0.70227 +/- 0.00324\n", + " 20/1 0.70641 0.70268 +/- 0.00293\n", + " 21/1 0.69300 0.70180 +/- 0.00279\n", + " 22/1 0.70086 0.70172 +/- 0.00255\n", + " 23/1 0.68664 0.70056 +/- 0.00262\n", + " 24/1 0.70558 0.70092 +/- 0.00245\n", + " 25/1 0.70057 0.70090 +/- 0.00228\n", + " 26/1 0.68193 0.69971 +/- 0.00244\n", + " 27/1 0.69492 0.69943 +/- 0.00231\n", + " 28/1 0.68723 0.69875 +/- 0.00228\n", + " 29/1 0.71304 0.69950 +/- 0.00228\n", + " 30/1 0.69086 0.69907 +/- 0.00221\n", + " 31/1 0.71083 0.69963 +/- 0.00218\n", + " 32/1 0.69658 0.69949 +/- 0.00208\n", + " 33/1 0.70807 0.69987 +/- 0.00202\n", + " 34/1 0.71266 0.70040 +/- 0.00201\n", + " 35/1 0.69799 0.70030 +/- 0.00193\n", + " 36/1 0.67602 0.69937 +/- 0.00207\n", + " 37/1 0.72219 0.70021 +/- 0.00217\n", + " 38/1 0.71427 0.70072 +/- 0.00215\n", + " 39/1 0.71017 0.70104 +/- 0.00210\n", + " 40/1 0.69683 0.70090 +/- 0.00203\n", + " 41/1 0.71530 0.70137 +/- 0.00202\n", + " 42/1 0.69487 0.70116 +/- 0.00197\n", + " 43/1 0.69785 0.70106 +/- 0.00191\n", + " 44/1 0.72084 0.70165 +/- 0.00194\n", + " 45/1 0.69741 0.70152 +/- 0.00189\n", + " 46/1 0.70040 0.70149 +/- 0.00183\n", + " 47/1 0.71724 0.70192 +/- 0.00183\n", + " 48/1 0.70980 0.70213 +/- 0.00180\n", + " 49/1 0.70660 0.70224 +/- 0.00175\n", + " 50/1 0.69329 0.70202 +/- 0.00172\n", " Creating state point statepoint.50.h5...\n", "\n", " ===========================================================================\n", @@ -1193,27 +1206,27 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 4.1000E-02 seconds\n", - " Reading cross sections = 4.0000E-03 seconds\n", - " Total time in simulation = 3.1713E+01 seconds\n", - " Time in transport only = 3.1522E+01 seconds\n", - " Time in inactive batches = 3.8940E+00 seconds\n", - " Time in active batches = 2.7819E+01 seconds\n", - " Time synchronizing fission bank = 2.1000E-02 seconds\n", - " Sampling source sites = 1.2000E-02 seconds\n", - " SEND/RECV source sites = 9.0000E-03 seconds\n", + " Total time for initialization = 3.5000E-02 seconds\n", + " Reading cross sections = 6.0000E-03 seconds\n", + " Total time in simulation = 3.7004E+01 seconds\n", + " Time in transport only = 3.6761E+01 seconds\n", + " Time in inactive batches = 3.6530E+00 seconds\n", + " Time in active batches = 3.3351E+01 seconds\n", + " Time synchronizing fission bank = 7.0000E-03 seconds\n", + " Sampling source sites = 6.0000E-03 seconds\n", + " SEND/RECV source sites = 1.0000E-03 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 3.1791E+01 seconds\n", - " Calculation Rate (inactive) = 12840.3 neutrons/second\n", - " Calculation Rate (active) = 7189.33 neutrons/second\n", + " Total time elapsed = 3.7062E+01 seconds\n", + " Calculation Rate (inactive) = 13687.4 neutrons/second\n", + " Calculation Rate (active) = 5996.82 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) = 0.70328 +/- 0.00159\n", + " k-effective (Track-length) = 0.70202 +/- 0.00172\n", + " k-effective (Absorption) = 0.70409 +/- 0.00106\n", + " Combined k-effective = 0.70345 +/- 0.00102\n", " Leakage Fraction = 0.00000 +/- 0.00000\n", "\n" ] @@ -1295,8 +1308,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 = 0.703447\n", + "bias [pcm]: 32084.7\n" ] } ], @@ -1393,7 +1406,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 40, @@ -1402,9 +1415,9 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index eaf66d120..2079b8801 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1191,20 +1191,20 @@ class XSdata(object): 'writing the HDF5 library') # Get the sparse scattering data to print to the library G = self.energy_groups.num_groups - if self.representation is 'isotropic': + 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] - g_out_bounds[g_in, 1] = nz[-1] + 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 l in range(self._scatter_matrix[i].shape[0]): - for g_in in range(G): - matrix = self._scatter_matrix[i][l, g_in, :] - for g_out in range(g_out_bounds[g_in, 0], - g_out_bounds[g_in, 1] + 1): - flat_scatt.append(matrix[g_out]) + 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 = xsgrp.create_group('scatter data') scatt_grp.create_dataset("scatter matrix", @@ -1213,12 +1213,12 @@ class XSdata(object): # 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): - matrix = self._multiplicity_matrix[i][g_in, :] for g_out in range(g_out_bounds[g_in, 0], g_out_bounds[g_in, 1] + 1): - flat_mult.append(matrix[g_out]) + flat_mult.append(matrix[g_in, g_out]) scatt_grp.create_dataset("multiplicity matrix", data=np.array(flat_mult), compression=compression) @@ -1230,7 +1230,7 @@ class XSdata(object): scatt_grp.create_dataset("g_max", data=g_out_bounds[:, 1], compression=compression) - else: + elif self.representation == 'angle': Np = self.num_polar Na = self.num_azimuthal g_out_bounds = np.zeros((Np, Na, G, 2), dtype=np.int) @@ -1239,20 +1239,18 @@ class XSdata(object): 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] - g_out_bounds[p, a, g_in, 1] = nz[-1] + 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): - for l in range(self._scatter_matrix[i].shape[2]): - for g_in in range(G): - matrix = \ - self._scatter_matrix[i][p, a, 0, g_in, :] - for g_out in range(g_out_bounds[p, a, g_in, 0], - g_out_bounds[p, a, g_in, 1] - + 1): - flat_scatt.append(matrix[g_out]) + 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 = xsgrp.create_group('scatter data') scatt_grp.create_dataset("scatter matrix", @@ -1264,20 +1262,17 @@ class XSdata(object): flat_mult = [] for p in range(Np): for a in range(Na): - for l in range(self._scatter_matrix[i].shape[2]): - for g_in in range(G): - matrix = \ - self._multiplicity_matrix[i][p, a, g_in, :] - 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_out]) - scatt_grp.create_dataset("multiplicity matrix", - data=np.array(flat_mult), - compression=compression) + 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 finally, adjust g_out_bounds for 1-based group counting # and write it. g_out_bounds[:, :, :, :] += 1 - scatt_grp.create_dataset("g_out bounds", data=g_out_bounds, + scatt_grp.create_dataset("g_min", data=g_out_bounds[:, :, :, 0], + compression=compression) + scatt_grp.create_dataset("g_max", data=g_out_bounds[:, :, :, 1], compression=compression) diff --git a/openmc/settings.py b/openmc/settings.py index 4a9e05042..14d89543f 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -1079,8 +1079,9 @@ class Settings(object): element = ET.SubElement(self._settings_file, "tabular_legendre") subelement = ET.SubElement(element, "enable") subelement.text = str(self._tabular_legendre['enable']).lower() - subelement = ET.SubElement(element, "num_points") - subelement.text = str(self._tabular_legendre['num_points']) + 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: diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 298602402..51fb1384c 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -403,7 +403,7 @@ module mgxs_header xsdata_grp = open_group(xs_id, trim(temp_str)) if (this % fissionable) then allocate(xs % nu_fission(groups)) - allocate(xs % chi(groups,groups)) + allocate(xs % chi(groups, groups)) if (check_dataset(xsdata_grp, "chi")) then ! Chi was provided, that means we need chi and nu-fission vectors ! Get chi @@ -483,13 +483,13 @@ module mgxs_header call fatal_error("Must provide 'scatter data'") scatt_grp = open_group(xsdata_grp, 'scatter data') ! First get the outgoing group boundary indices - if (check_dataset(xsdata_grp, "g_min")) then + if (check_dataset(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 matrix must be provided") end if - if (check_dataset(xsdata_grp, "g_max")) then + if (check_dataset(scatt_grp, "g_max")) then allocate(gmax(groups)) call read_dataset(gmax, scatt_grp, "g_max") else @@ -514,8 +514,8 @@ module mgxs_header index = 1 do gin = 1, groups allocate(input_scatt(gin) % data(order_dim, gmin(gin):gmax(gin))) - do l = 1, order_dim - do gout = 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 @@ -531,7 +531,7 @@ module mgxs_header order_dim = order + 1 end if - allocate(scatt_coeffs(gin)) + allocate(scatt_coeffs(groups)) if (this % scatter_type == ANGLE_LEGENDRE .and. & legendre_to_tabular) then this % scatter_type = ANGLE_TABULAR @@ -539,7 +539,7 @@ module mgxs_header order = order_dim dmu = TWO / real(order - 1, 8) do gin = 1, groups - allocate(scatt_coeffs(gin) % data(order_dim, 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 @@ -572,10 +572,9 @@ module mgxs_header end do ! gout end do ! gin else - ! Sticking with current representation, carry forward but change - ! the array ordering + ! Sticking with current representation do gin = 1, groups - allocate(scatt_coeffs(gin) % data(order_dim, groups)) + allocate(scatt_coeffs(gin) % data(order_dim, gmin(gin):gmax(gin))) scatt_coeffs(gin) % data(:, :) = input_scatt(gin) % data(:, :) end do end if @@ -642,7 +641,7 @@ module mgxs_header ! Close the groups we have opened and deallocate call close_group(xsdata_grp) - deallocate(input_scatt, scatt_coeffs, temp_mult) + deallocate(scatt_coeffs, temp_mult) end associate ! xs end do ! Temperatures end subroutine mgxsiso_from_hdf5 @@ -685,6 +684,8 @@ module mgxs_header temp_str = trim(to_str(temps_to_read % data(t))) // "K" xsdata_grp = open_group(xs_id, trim(temp_str)) if (this % fissionable) then + allocate(xs % nu_fission(groups, this % n_azi, this % n_pol)) + allocate(xs % chi(groups, groups, this % n_azi, this % n_pol)) if (check_dataset(xsdata_grp, "chi")) then ! Chi was provided, that means we need chi and nu-fission vectors ! Get chi @@ -783,9 +784,6 @@ module mgxs_header &kappa-fission tallies in tallies.xml file!") end if end if - else - xs % nu_fission(:, :, :) = ZERO - xs % chi(:, :, :, :) = ZERO end if if (check_dataset(xsdata_grp, "absorption")) then @@ -800,13 +798,13 @@ module mgxs_header call fatal_error("Must provide 'scatter data'") scatt_grp = open_group(xsdata_grp, 'scatter data') ! First get the outgoing group boundary indices - if (check_dataset(xsdata_grp, "g_min")) then + if (check_dataset(scatt_grp, "g_min")) then allocate(gmin(groups, this % n_azi, this % n_pol)) call read_dataset(gmin, scatt_grp, "g_min") else call fatal_error("'g_min' for the scatter matrix must be provided") end if - if (check_dataset(xsdata_grp, "g_max")) then + if (check_dataset(scatt_grp, "g_max")) then allocate(gmax(groups, this % n_azi, this % n_pol)) call read_dataset(gmax, scatt_grp, "g_max") else @@ -839,8 +837,8 @@ module mgxs_header do gin = 1, groups allocate(input_scatt(gin, iazi, ipol) % data(order_dim, & gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) - do l = 1, order_dim - do gout = 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 @@ -859,7 +857,7 @@ module mgxs_header order_dim = order + 1 end if - allocate(scatt_coeffs(gin, this % n_azi, this % n_pol)) + allocate(scatt_coeffs(groups, this % n_azi, this % n_pol)) if (this % scatter_type == ANGLE_LEGENDRE .and. & legendre_to_tabular) then this % scatter_type = ANGLE_TABULAR @@ -870,7 +868,8 @@ module mgxs_header do iazi = 1, this % n_azi do gin = 1, groups allocate(scatt_coeffs(gin, iazi, ipol) % data(& - order_dim, groups)) + 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 @@ -906,12 +905,12 @@ module mgxs_header end do ! iazi end do ! ipol else - ! Sticking with current representation, carry forward but change - ! the array ordering + ! 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, 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(:, :) end do @@ -1014,7 +1013,7 @@ module mgxs_header ! Close the groups we have opened and deallocate call close_group(xsdata_grp) - deallocate(input_scatt, scatt_coeffs, temp_mult) + deallocate(scatt_coeffs, temp_mult) end associate ! xs end do ! Temperatures end subroutine mgxsang_from_hdf5 @@ -1063,6 +1062,7 @@ module mgxs_header ! Determine the scattering type of our data and ensure all scattering orders ! are the same. scatter_type = nuclides(mat % nuclide(1)) % obj % scatter_type +write(*,*) 'scatter_type', scatter_type select type(nuc => nuclides(mat % nuclide(1)) % obj) type is (MgxsIso) order = size(nuc % xs(1) % scatter % dist(1) % data, dim=1) @@ -1125,7 +1125,7 @@ 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 + order_dim = order end if end subroutine mgxs_combine @@ -1185,6 +1185,7 @@ module mgxs_header allocate(scatt_coeffs(order_dim,groups,groups)) scatt_coeffs(:, :, :) = ZERO + this % scatter_type = scatter_type if (scatter_type == ANGLE_LEGENDRE) then allocate(ScattDataLegendre :: this % xs(t) % scatter) else if (scatter_type == ANGLE_TABULAR) then @@ -1302,8 +1303,8 @@ module mgxs_header end do ! Now create our jagged data from the dense data - call jagged_from_dense_2D(scatt_coeffs, jagged_scatt) - call jagged_from_dense_1D(temp_mult, jagged_mult, gmin, gmax) + 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, & @@ -1319,6 +1320,8 @@ module mgxs_header end do end if + write(*,*) this % scatter_type + ! Deallocate temporaries deallocate(jagged_mult, jagged_scatt, gmin, gmax, scatt_coeffs, & temp_mult, mult_num, mult_denom) @@ -1557,6 +1560,7 @@ module mgxs_header ! 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 @@ -1576,8 +1580,7 @@ module mgxs_header end if ! Deallocate temporaries - deallocate(jagged_mult, jagged_scatt, gmin, gmax, scatt_coeffs, & - temp_mult, mult_num, mult_denom) + deallocate(scatt_coeffs, temp_mult, mult_num, mult_denom) end associate ! nuc end do NUC_LOOP end do TEMP_LOOP diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index 6dd104d5c..6004cbd19 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -155,7 +155,8 @@ contains 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(:) = mult(gin) % data(:) + 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 end do @@ -280,6 +281,7 @@ contains ! 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(gin) % data(:, gout)) energy(gin) % data(gout) = norm @@ -379,6 +381,7 @@ contains allocate(energy(groups)) ! Build energy transfer probability matrix from data in matrix do gin = 1, groups + allocate(energy(gin) % data(gmin(gin):gmax(gin))) do gout = gmin(gin), gmax(gin) norm = ZERO do imu = 2, order @@ -732,15 +735,16 @@ contains ! default is ZERO !=============================================================================== - subroutine jagged_from_dense_1D(dense, jagged, lo_bounds, hi_bounds, key_) + 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(:) + 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_ @@ -748,23 +752,18 @@ contains key = ZERO end if - if (present(lo_bounds)) then - if (allocated(lo_bounds)) deallocate(lo_bounds) - allocate(lo_bounds(size(dense, dim=2))) - end if - if (present(hi_bounds)) then - if (allocated(hi_bounds)) deallocate(hi_bounds) - allocate(hi_bounds(size(dense, dim=2))) - 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 + if (dense(jmin, i) /= key) exit end do do jmax = size(dense, dim=1), 1, -1 - if (dense(jmax, i) > key) exit + if (dense(jmax, i) /= key) exit end do ! Treat the case of all values matching the key if (jmin > jmax) then @@ -776,21 +775,33 @@ contains allocate(jagged(i) % data(jmin:jmax)) jagged(i) % data(jmin:jmax) = dense(jmin:jmax, i) - if (present(lo_bounds)) lo_bounds(i) = jmin - if (present(hi_bounds)) hi_bounds(i) = jmax + 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_) + 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(:) + 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_ @@ -798,23 +809,18 @@ contains key = ZERO end if - if (present(lo_bounds)) then - if (allocated(lo_bounds)) deallocate(lo_bounds) - allocate(lo_bounds(size(dense, dim=3))) - end if - if (present(hi_bounds)) then - if (allocated(hi_bounds)) deallocate(hi_bounds) - allocate(hi_bounds(size(dense, dim=3))) - 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=1) - if (sum(dense(:, jmin, i)) > key) exit + do jmin = 1, size(dense, dim=2) + if (any(dense(:, jmin, i) /= key)) exit end do - do jmax = size(dense, dim=1), 1, -1 - if (sum(dense(:, jmax, i)) > key) exit + 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 @@ -826,10 +832,21 @@ contains allocate(jagged(i) % data(size(dense, dim=1), jmin:jmax)) jagged(i) % data(:, jmin:jmax) = dense(:, jmin:jmax, i) - if (present(lo_bounds)) lo_bounds(i) = jmin - if (present(hi_bounds)) hi_bounds(i) = jmax + 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/tests/1d_mgxs.h5 b/tests/1d_mgxs.h5 index 4b7b94cb45772879a531852ad5db9fdbe58a49d6..38bb500677ae2d95948a7992f0c580130546e90c 100644 GIT binary patch literal 123864 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�iaN{9 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�uEruq>4F9SMjUXj8)QAS ziw9wbq@yMa36T4_wfxYVM7Tjc=1aSr3f-$g{%4&tVNmbv%-P#F!IjhBWshk-WQD80 zI2>C5m#gR!j2;$2=W#}1F_uy|%&d^lD~VTn?HgG-+*1j*M+iTtm)=%`llMN6bAM|= zRCYR>dA$x!a_HOJU{3f**tuIZrwQn2W-8VQO<*FR`lRbDS6LBL40-d;Su8yMag3zc40_3pd^xrHh2+O^+Cl?T!S~JI0Ib`=dZVIK^ON zb2KOu*w#YA-b91xPrf}dQojY=h9iKwVt74yF#;USy&n(!jRcyysfyG=l!uwcXmqP)N5jDK z_m!tVW1w-DMq(tU$H_BB9#Xz>z-B1_vlBT=DShwEUZS<2>OkK^mas&4Ev{1zlvGe+ z(xsnS&HzR!-A}0sHzD@2sK>j_`Ec1;RybX)0Fv0ryr-S9ABg0VJVPx3`t6|etgQ?* zTxLHj8WSo((8TF_ie)tv{KE=wsRe1nX8)&nBAU@Bhw(5pz%Y+})C@F%zRYR4D3K<( z(*2!uZLcr*Ye}bVdK(VL9)ayf+7S>^o6H{h3QgB@HJu#LK&L@0X!I|H!{?7lQY+OF zAY>@#xUVMy$m=CUV>}rz4DFY>La0X6ORVRVl6y2%9X7DM{v-z4-%oXOv{8W9Hkur& z90#sz$6F27v5Z%7v+P38;be706 zYp>*i!_FnzMZp4ip8iI$Ub_emu8*#d`j$X%u4s@yr3|SD` zbFbu%tXg=pduyh4QXPc!`?*F=)q^$%_nrL$O)&A~&-N{}P2j%RbT@_57dn^T%)P&h zM7x~>8mjxz9@0O4*`+QF*jJbC-*pLxhY7nGwD{3hiaMg-l7xmC3w3tiaw34(I7sqs z#%oihe-e6*$Dyv<$a|M!@qOui2meGyl`M`|OlEV!uItP5DZE(UAAc@d?El4KqwXFiu^d z0H^5gJ??K}fuy}JOAVR)w0p1mXdrw0*4|xQ=~9WHGPUrfNHP_Kwsu;U`e(pWVUED2 z`W#T+c6g`x{XEE7pUHXffeIBZ7d+Z%i(qerV;ASa61esC;!64nLK!d^@zP!Hu7Hv3 zFZ7oru;!zmIqOVxQ0I#qlr$yJD>aVLJ}WqIrs-dW`Z6-lXIA{oF^_2 zFFmQ>b(Y{23E$lx#4w+Z0>L-_0m_@AK~_LQ=eSi2uu3@$4(L)~TqNM8IGU$Sv}~KK z@j}mWA@Q03xdf2*GL`y`b-}hktrdB$R9IR|J=bt01JaAqKd=|&z=po1$M%*yI6lsJ z`ou65XuP|g5xy2e-8^^455W@XFPkS5cFLE*-dO4i70ctxT#tpn-Km0>$PZCCcY~B! zAEpAMI@o%U)V-5h54~z8O$_+#_X}~WL^NQhL>$;3^415O27Zf}B_P7lb6)&5Rz8e5 zoU8e0tVcKY`S(s4G*N5|9-ct*MY!+YbZxT;$O~QkM8U2ZQt}8@A04r2Jo-9q5?7!+ zTt$@+i$swzT1o5kF`zBgBGht>0)H#YJ-NHEOWu9i-~f6JU)VFg{R&z)mM!Y*3h*Vu zUxxekvbX{_SWkWWc0L36>b6M7#pXbXh=y`ibsn&-$XZ-|MFopSbJ5i=h2Zn!=Vb%F z5*Ru}pb|92%b=}!YHW9X1^Dl$pDS*zg2UnqX*wpgFc;oe^ir!1Y+X%m&m`BwTv0>$ z`L0ITdo!teqofhOxrlw6?DT=lZ+?pv1c$@w7OvwNENGU-k;}Cfh6KEn9E$%5#QS!w zJAdv*I;z3mN`1WuP%k*Iw}4f$F~N4b_sOeRL|VpQ^issOxjlK9ekbOFDQ`()yl?}N|@DWbtu( Date: Fri, 9 Sep 2016 21:25:05 -0400 Subject: [PATCH 15/42] Possibly have a fix --- src/mgxs_header.F90 | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 51fb1384c..47081eb5a 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -567,7 +567,7 @@ module mgxs_header if (norm > ZERO) then scatt_coeffs(gin) % data(:, gout) = & scatt_coeffs(gin) % data(:, gout) * & - input_scatt(gin) % data(1, gout) + input_scatt(gin) % data(1, gout) / norm end if end do ! gout end do ! gin @@ -1062,7 +1062,6 @@ module mgxs_header ! Determine the scattering type of our data and ensure all scattering orders ! are the same. scatter_type = nuclides(mat % nuclide(1)) % obj % scatter_type -write(*,*) 'scatter_type', scatter_type select type(nuc => nuclides(mat % nuclide(1)) % obj) type is (MgxsIso) order = size(nuc % xs(1) % scatter % dist(1) % data, dim=1) @@ -1320,8 +1319,6 @@ write(*,*) 'scatter_type', scatter_type end do end if - write(*,*) this % scatter_type - ! Deallocate temporaries deallocate(jagged_mult, jagged_scatt, gmin, gmax, scatt_coeffs, & temp_mult, mult_num, mult_denom) @@ -1901,7 +1898,7 @@ write(*,*) 'scatter_type', scatter_type ! sqrt(temperature), (with temperature in units of MeV) !=============================================================================== - pure subroutine mgxs_find_temperature(this, sqrtkT) + subroutine mgxs_find_temperature(this, sqrtkT) class(Mgxs), intent(inout) :: this real(8), intent(in) :: sqrtkT ! Temperature (in units of of MeV) From 61feb8cc6de0bcac0bab46876f2c7fe978d9fe46 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 10 Sep 2016 08:40:04 -0400 Subject: [PATCH 16/42] Updated mgxs-part-iv --- .../pythonapi/examples/mgxs-part-iv.ipynb | 193 ++++++++---------- 1 file changed, 90 insertions(+), 103 deletions(-) diff --git a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb index a4f406951..b36020691 100644 --- a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb @@ -431,7 +431,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "" ] @@ -734,8 +734,8 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 6cf7f7fa48d70d26165403f8067aedb598534990\n", - " Date/Time | 2016-09-08 20:16:34\n", + " Git SHA1 | 84df6a1f10c7811eed59e4ea04cddf2afd42ef75\n", + " Date/Time | 2016-09-10 08:37:58\n", " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", @@ -822,20 +822,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 3.2700E-01 seconds\n", - " Reading cross sections = 2.1500E-01 seconds\n", - " Total time in simulation = 2.2139E+01 seconds\n", - " Time in transport only = 2.1970E+01 seconds\n", - " Time in inactive batches = 2.6960E+00 seconds\n", - " Time in active batches = 1.9443E+01 seconds\n", - " Time synchronizing fission bank = 2.0000E-03 seconds\n", - " Sampling source sites = 1.0000E-03 seconds\n", - " SEND/RECV source sites = 1.0000E-03 seconds\n", + " Total time for initialization = 3.3600E-01 seconds\n", + " Reading cross sections = 2.1200E-01 seconds\n", + " Total time in simulation = 2.1540E+01 seconds\n", + " Time in transport only = 2.1352E+01 seconds\n", + " Time in inactive batches = 2.4040E+00 seconds\n", + " Time in active batches = 1.9136E+01 seconds\n", + " Time synchronizing fission bank = 6.0000E-03 seconds\n", + " Sampling source sites = 3.0000E-03 seconds\n", + " SEND/RECV source sites = 3.0000E-03 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 2.2488E+01 seconds\n", - " Calculation Rate (inactive) = 18546.0 neutrons/second\n", - " Calculation Rate (active) = 10286.5 neutrons/second\n", + " Total time elapsed = 2.1898E+01 seconds\n", + " Calculation Rate (inactive) = 20798.7 neutrons/second\n", + " Calculation Rate (active) = 10451.5 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -973,25 +973,12 @@ "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(array([0, 1]),)\n", - "(array([0, 1]),)\n", - "(array([0, 1]),)\n", - "(array([0, 1]),)\n", - "(array([0, 1]),)\n", - "(array([0, 1]),)\n" - ] - } - ], + "outputs": [], "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", + "# Write the file to disk using the default filename of `mgxs.h5`\n", "mgxs_file.export_to_hdf5()" ] }, @@ -1121,8 +1108,8 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 6cf7f7fa48d70d26165403f8067aedb598534990\n", - " Date/Time | 2016-09-08 20:16:57\n", + " Git SHA1 | 84df6a1f10c7811eed59e4ea04cddf2afd42ef75\n", + " Date/Time | 2016-09-10 08:38:20\n", " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", @@ -1147,56 +1134,56 @@ "\n", " Bat./Gen. k Average k \n", " ========= ======== ==================== \n", - " 1/1 0.68770 \n", - " 2/1 0.71454 \n", - " 3/1 0.69764 \n", - " 4/1 0.68400 \n", - " 5/1 0.69412 \n", - " 6/1 0.70489 \n", - " 7/1 0.70203 \n", - " 8/1 0.70721 \n", - " 9/1 0.69408 \n", - " 10/1 0.70103 \n", - " 11/1 0.69351 \n", - " 12/1 0.71450 0.70401 +/- 0.01049\n", - " 13/1 0.70298 0.70366 +/- 0.00607\n", - " 14/1 0.69351 0.70113 +/- 0.00499\n", - " 15/1 0.70901 0.70270 +/- 0.00417\n", - " 16/1 0.70364 0.70286 +/- 0.00341\n", - " 17/1 0.68831 0.70078 +/- 0.00355\n", - " 18/1 0.69861 0.70051 +/- 0.00309\n", - " 19/1 0.71634 0.70227 +/- 0.00324\n", - " 20/1 0.70641 0.70268 +/- 0.00293\n", - " 21/1 0.69300 0.70180 +/- 0.00279\n", - " 22/1 0.70086 0.70172 +/- 0.00255\n", - " 23/1 0.68664 0.70056 +/- 0.00262\n", - " 24/1 0.70558 0.70092 +/- 0.00245\n", - " 25/1 0.70057 0.70090 +/- 0.00228\n", - " 26/1 0.68193 0.69971 +/- 0.00244\n", - " 27/1 0.69492 0.69943 +/- 0.00231\n", - " 28/1 0.68723 0.69875 +/- 0.00228\n", - " 29/1 0.71304 0.69950 +/- 0.00228\n", - " 30/1 0.69086 0.69907 +/- 0.00221\n", - " 31/1 0.71083 0.69963 +/- 0.00218\n", - " 32/1 0.69658 0.69949 +/- 0.00208\n", - " 33/1 0.70807 0.69987 +/- 0.00202\n", - " 34/1 0.71266 0.70040 +/- 0.00201\n", - " 35/1 0.69799 0.70030 +/- 0.00193\n", - " 36/1 0.67602 0.69937 +/- 0.00207\n", - " 37/1 0.72219 0.70021 +/- 0.00217\n", - " 38/1 0.71427 0.70072 +/- 0.00215\n", - " 39/1 0.71017 0.70104 +/- 0.00210\n", - " 40/1 0.69683 0.70090 +/- 0.00203\n", - " 41/1 0.71530 0.70137 +/- 0.00202\n", - " 42/1 0.69487 0.70116 +/- 0.00197\n", - " 43/1 0.69785 0.70106 +/- 0.00191\n", - " 44/1 0.72084 0.70165 +/- 0.00194\n", - " 45/1 0.69741 0.70152 +/- 0.00189\n", - " 46/1 0.70040 0.70149 +/- 0.00183\n", - " 47/1 0.71724 0.70192 +/- 0.00183\n", - " 48/1 0.70980 0.70213 +/- 0.00180\n", - " 49/1 0.70660 0.70224 +/- 0.00175\n", - " 50/1 0.69329 0.70202 +/- 0.00172\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.03277 1.02864 +/- 0.00294\n", + " 33/1 1.00167 1.02746 +/- 0.00305\n", + " 34/1 1.01791 1.02707 +/- 0.00294\n", + " 35/1 1.03889 1.02754 +/- 0.00286\n", + " 36/1 1.02693 1.02752 +/- 0.00275\n", + " 37/1 1.02346 1.02737 +/- 0.00265\n", + " 38/1 1.00974 1.02674 +/- 0.00263\n", + " 39/1 1.01456 1.02632 +/- 0.00257\n", + " 40/1 1.02217 1.02618 +/- 0.00249\n", + " 41/1 0.99130 1.02505 +/- 0.00266\n", + " 42/1 1.05167 1.02588 +/- 0.00271\n", + " 43/1 1.01675 1.02561 +/- 0.00264\n", + " 44/1 1.00496 1.02500 +/- 0.00263\n", + " 45/1 1.00466 1.02442 +/- 0.00262\n", + " 46/1 1.01644 1.02420 +/- 0.00255\n", + " 47/1 1.01033 1.02382 +/- 0.00251\n", + " 48/1 1.02299 1.02380 +/- 0.00245\n", + " 49/1 1.01468 1.02357 +/- 0.00239\n", + " 50/1 1.02616 1.02363 +/- 0.00233\n", " Creating state point statepoint.50.h5...\n", "\n", " ===========================================================================\n", @@ -1206,27 +1193,27 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 3.5000E-02 seconds\n", - " Reading cross sections = 6.0000E-03 seconds\n", - " Total time in simulation = 3.7004E+01 seconds\n", - " Time in transport only = 3.6761E+01 seconds\n", - " Time in inactive batches = 3.6530E+00 seconds\n", - " Time in active batches = 3.3351E+01 seconds\n", + " Total time for initialization = 4.0000E-02 seconds\n", + " Reading cross sections = 8.0000E-03 seconds\n", + " Total time in simulation = 1.5523E+01 seconds\n", + " Time in transport only = 1.5428E+01 seconds\n", + " Time in inactive batches = 1.6880E+00 seconds\n", + " Time in active batches = 1.3835E+01 seconds\n", " Time synchronizing fission bank = 7.0000E-03 seconds\n", - " Sampling source sites = 6.0000E-03 seconds\n", - " SEND/RECV source sites = 1.0000E-03 seconds\n", + " Sampling source sites = 5.0000E-03 seconds\n", + " SEND/RECV source sites = 2.0000E-03 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 3.7062E+01 seconds\n", - " Calculation Rate (inactive) = 13687.4 neutrons/second\n", - " Calculation Rate (active) = 5996.82 neutrons/second\n", + " Total time elapsed = 1.5587E+01 seconds\n", + " Calculation Rate (inactive) = 29620.9 neutrons/second\n", + " Calculation Rate (active) = 14456.1 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", - " k-effective (Collision) = 0.70328 +/- 0.00159\n", - " k-effective (Track-length) = 0.70202 +/- 0.00172\n", - " k-effective (Absorption) = 0.70409 +/- 0.00106\n", - " Combined k-effective = 0.70345 +/- 0.00102\n", + " k-effective (Collision) = 1.02217 +/- 0.00260\n", + " k-effective (Track-length) = 1.02363 +/- 0.00233\n", + " k-effective (Absorption) = 1.02649 +/- 0.00171\n", + " Combined k-effective = 1.02638 +/- 0.00171\n", " Leakage Fraction = 0.00000 +/- 0.00000\n", "\n" ] @@ -1308,8 +1295,8 @@ "output_type": "stream", "text": [ "Continuous-Energy keff = 1.024295\n", - "Multi-Group keff = 0.703447\n", - "bias [pcm]: 32084.7\n" + "Multi-Group keff = 1.026377\n", + "bias [pcm]: -208.3\n" ] } ], @@ -1406,7 +1393,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 40, @@ -1415,9 +1402,9 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\nj6+jc35fUPaoKtihatHMSnmsV8q32daN9/Gl728Wag6s807/rKprWalq0fFFZ/mFYT6/uueOUHPw\nQTdnpr9F1qc1EtZebMAfjK8axiZV+y34/Ru/Osxn14eiLx+w6Eufxdi2BM2Qeo7V21WwYdWCn799\n5OLFNXW4ws5q8oDeIN++sWBw9Igq2Ltqwc+Lf9k/LOtuPyjUjKnYITb68Nj317vt9cXWza66hi5V\nJy34PXFcfH7QJi7r9c3WCzVHcUuouZ5jF1t3XdVMTqxaMM6OZcj6YknCf/hRqBniJ4SacXeUMIj4\nH3XqZ3wVbFK16LoRszKz6Nu3LSNHrljUt5ujy6UP8La7T07faR1K8iBPiNaOfFu0aJojoHdj0W9B\nTKVh34EQoqUi3xYtmuboQ6/vVqD+e7FRVQv/X65zM5jSvLSr3KbcJjSYVSo3jUUtjZUqQ8mU6glM\nrW72sSyl+/aIqoX/t2t9vr18K/TtrSvblduEhrFKZYnCUdT2ab7zTvYcJM0R0KeSfJCnlrUo9nGe\nun3mrYzWGdC/V24TGs7KlaFk7cr1Wbty4Scynh/UkE+Xl0zpvl3QZ94aaVfZJxa1MLapbB+LWhIl\nB/Qd0gV69GjLhAnFnyE1R5fLi0APM1vHkg/AH0zywXwhWjvybdGiafIWurvPN7OTSUYs1r7a9UZT\nlyPE0ka+LVo6zfIeurs/SsNmJRKiVSDfFi2ZZgnoJXNrkL5HCXl8XYKmhPmRtnk/a2KfhNHdsmal\nSpjMuqFm/mbx5Op3sG9m+hZedw6CxTnnP38ONcM/jL8Ie/r+9X12fVGe6bd9qHn6D7uGmiMe/muo\n6ctjoeaKUNG8rHfM4u9213KPH1g0rZYxv/5hXMh18Xvf3Y5/J9QUnUungPW3fC3UvD1ti1Dz5Qpx\nYS8smzVjW5rPrA6h5hIGhJoevFuCJq7DcW1KeA/9k1iy6MRJ9ZG93xr6L4QQOUEBXQghcoICuhBC\n5AQFdCGEyAkK6EIIkRMU0IUQIicooAshRE5QQBdCiJxQtjlFzcy5K/sD9BWV8TzHx3cdEmqunvW7\n2KCZ8YAH23B+qDnBrgw1r9T0DDXPWmVm+sHhqCy4a+IxocbWi/fJr4oHQv2sfzwbyUOv7B9qVtjw\no1DTr8PDoeYeO7pZZiwqBTPzR2uKT5yw2zIPxJlc1CmUzD0+bo/NaxNXQbsOsQ+Mt3hiihk1XUPN\n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\nAwmwhqwYOz+DAAAAAElFTkSuQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1447,7 +1434,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." ] }, { From 255aba1fc0ca9f576b9784acda8c7778927e4210 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 10 Sep 2016 11:28:08 -0400 Subject: [PATCH 17/42] Updated ipython notebook, fixed minor corrections throughout, and added h5 wrapper functions in hdf5_interface so the various from_hdf5 routines dont have to call low-level functions directly --- .../pythonapi/examples/mgxs-part-iv.ipynb | 112 ++++++------ docs/source/usersguide/input.rst | 2 +- openmc/mesh.py | 4 + openmc/mgxs_library.py | 6 +- src/hdf5_interface.F90 | 22 +++ src/mgxs_header.F90 | 169 ++++++++++-------- src/nuclide_header.F90 | 37 ++-- src/reaction_header.F90 | 17 +- src/sab_header.F90 | 16 +- src/secondary_uncorrelated.F90 | 17 +- 10 files changed, 206 insertions(+), 196 deletions(-) diff --git a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb index b36020691..f384afb55 100644 --- a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb @@ -431,7 +431,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "" ] @@ -734,8 +734,8 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 84df6a1f10c7811eed59e4ea04cddf2afd42ef75\n", - " Date/Time | 2016-09-10 08:37:58\n", + " Git SHA1 | 61feb8cc6de0bcac0bab46876f2c7fe978d9fe46\n", + " Date/Time | 2016-09-10 09:22:09\n", " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", @@ -822,20 +822,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 3.3600E-01 seconds\n", - " Reading cross sections = 2.1200E-01 seconds\n", - " Total time in simulation = 2.1540E+01 seconds\n", - " Time in transport only = 2.1352E+01 seconds\n", - " Time in inactive batches = 2.4040E+00 seconds\n", - " Time in active batches = 1.9136E+01 seconds\n", - " Time synchronizing fission bank = 6.0000E-03 seconds\n", - " Sampling source sites = 3.0000E-03 seconds\n", - " SEND/RECV source sites = 3.0000E-03 seconds\n", + " Total time for initialization = 2.9000E-01 seconds\n", + " Reading cross sections = 1.7200E-01 seconds\n", + " Total time in simulation = 1.9592E+01 seconds\n", + " Time in transport only = 1.9464E+01 seconds\n", + " Time in inactive batches = 2.3150E+00 seconds\n", + " Time in active batches = 1.7277E+01 seconds\n", + " Time synchronizing fission bank = 1.0000E-02 seconds\n", + " Sampling source sites = 5.0000E-03 seconds\n", + " SEND/RECV source sites = 5.0000E-03 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 2.1898E+01 seconds\n", - " Calculation Rate (inactive) = 20798.7 neutrons/second\n", - " Calculation Rate (active) = 10451.5 neutrons/second\n", + " Total time elapsed = 1.9904E+01 seconds\n", + " Calculation Rate (inactive) = 21598.3 neutrons/second\n", + " Calculation Rate (active) = 11576.1 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -1108,8 +1108,8 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 84df6a1f10c7811eed59e4ea04cddf2afd42ef75\n", - " Date/Time | 2016-09-10 08:38:20\n", + " Git SHA1 | 61feb8cc6de0bcac0bab46876f2c7fe978d9fe46\n", + " Date/Time | 2016-09-10 09:22:29\n", " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", @@ -1165,25 +1165,25 @@ " 29/1 1.02831 1.02797 +/- 0.00336\n", " 30/1 1.02643 1.02789 +/- 0.00319\n", " 31/1 1.03939 1.02844 +/- 0.00308\n", - " 32/1 1.03277 1.02864 +/- 0.00294\n", - " 33/1 1.00167 1.02746 +/- 0.00305\n", - " 34/1 1.01791 1.02707 +/- 0.00294\n", - " 35/1 1.03889 1.02754 +/- 0.00286\n", - " 36/1 1.02693 1.02752 +/- 0.00275\n", - " 37/1 1.02346 1.02737 +/- 0.00265\n", - " 38/1 1.00974 1.02674 +/- 0.00263\n", - " 39/1 1.01456 1.02632 +/- 0.00257\n", - " 40/1 1.02217 1.02618 +/- 0.00249\n", - " 41/1 0.99130 1.02505 +/- 0.00266\n", - " 42/1 1.05167 1.02588 +/- 0.00271\n", - " 43/1 1.01675 1.02561 +/- 0.00264\n", - " 44/1 1.00496 1.02500 +/- 0.00263\n", - " 45/1 1.00466 1.02442 +/- 0.00262\n", - " 46/1 1.01644 1.02420 +/- 0.00255\n", - " 47/1 1.01033 1.02382 +/- 0.00251\n", - " 48/1 1.02299 1.02380 +/- 0.00245\n", - " 49/1 1.01468 1.02357 +/- 0.00239\n", - " 50/1 1.02616 1.02363 +/- 0.00233\n", + " 32/1 1.03282 1.02864 +/- 0.00294\n", + " 33/1 1.00098 1.02744 +/- 0.00306\n", + " 34/1 1.01763 1.02703 +/- 0.00296\n", + " 35/1 1.01412 1.02651 +/- 0.00288\n", + " 36/1 1.01564 1.02609 +/- 0.00280\n", + " 37/1 1.02255 1.02596 +/- 0.00270\n", + " 38/1 1.04764 1.02674 +/- 0.00271\n", + " 39/1 1.03299 1.02695 +/- 0.00263\n", + " 40/1 1.01040 1.02640 +/- 0.00260\n", + " 41/1 1.03493 1.02667 +/- 0.00253\n", + " 42/1 1.00289 1.02593 +/- 0.00256\n", + " 43/1 1.01429 1.02558 +/- 0.00250\n", + " 44/1 1.04207 1.02606 +/- 0.00248\n", + " 45/1 1.03141 1.02622 +/- 0.00241\n", + " 46/1 1.02055 1.02606 +/- 0.00235\n", + " 47/1 1.03659 1.02634 +/- 0.00230\n", + " 48/1 1.04200 1.02676 +/- 0.00228\n", + " 49/1 1.02003 1.02658 +/- 0.00222\n", + " 50/1 1.04396 1.02702 +/- 0.00221\n", " Creating state point statepoint.50.h5...\n", "\n", " ===========================================================================\n", @@ -1193,27 +1193,27 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 4.0000E-02 seconds\n", - " Reading cross sections = 8.0000E-03 seconds\n", - " Total time in simulation = 1.5523E+01 seconds\n", - " Time in transport only = 1.5428E+01 seconds\n", - " Time in inactive batches = 1.6880E+00 seconds\n", - " Time in active batches = 1.3835E+01 seconds\n", - " Time synchronizing fission bank = 7.0000E-03 seconds\n", + " Total time for initialization = 3.1000E-02 seconds\n", + " Reading cross sections = 6.0000E-03 seconds\n", + " Total time in simulation = 1.4773E+01 seconds\n", + " Time in transport only = 1.4743E+01 seconds\n", + " Time in inactive batches = 1.4380E+00 seconds\n", + " Time in active batches = 1.3335E+01 seconds\n", + " Time synchronizing fission bank = 5.0000E-03 seconds\n", " Sampling source sites = 5.0000E-03 seconds\n", - " SEND/RECV source sites = 2.0000E-03 seconds\n", + " SEND/RECV source sites = 0.0000E+00 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 1.5587E+01 seconds\n", - " Calculation Rate (inactive) = 29620.9 neutrons/second\n", - " Calculation Rate (active) = 14456.1 neutrons/second\n", + " Total time elapsed = 1.4827E+01 seconds\n", + " Calculation Rate (inactive) = 34770.5 neutrons/second\n", + " Calculation Rate (active) = 14998.1 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", - " k-effective (Collision) = 1.02217 +/- 0.00260\n", - " k-effective (Track-length) = 1.02363 +/- 0.00233\n", - " k-effective (Absorption) = 1.02649 +/- 0.00171\n", - " Combined k-effective = 1.02638 +/- 0.00171\n", + " k-effective (Collision) = 1.02681 +/- 0.00251\n", + " k-effective (Track-length) = 1.02702 +/- 0.00221\n", + " k-effective (Absorption) = 1.02734 +/- 0.00171\n", + " Combined k-effective = 1.02733 +/- 0.00150\n", " Leakage Fraction = 0.00000 +/- 0.00000\n", "\n" ] @@ -1295,8 +1295,8 @@ "output_type": "stream", "text": [ "Continuous-Energy keff = 1.024295\n", - "Multi-Group keff = 1.026377\n", - "bias [pcm]: -208.3\n" + "Multi-Group keff = 1.027328\n", + "bias [pcm]: -303.3\n" ] } ], @@ -1393,7 +1393,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 40, @@ -1402,9 +1402,9 @@ }, { "data": { - "image/png": "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\nj6+jc35fUPaoKtihatHMSnmsV8q32daN9/Gl728Wag6s807/rKprWalq0fFFZ/mFYT6/uueOUHPw\nQTdnpr9F1qc1EtZebMAfjK8axiZV+y34/Ru/Osxn14eiLx+w6Eufxdi2BM2Qeo7V21WwYdWCn799\n5OLFNXW4ws5q8oDeIN++sWBw9Igq2Ltqwc+Lf9k/LOtuPyjUjKnYITb68Nj317vt9cXWza66hi5V\nJy34PXFcfH7QJi7r9c3WCzVHcUuouZ5jF1t3XdVMTqxaMM6OZcj6YknCf/hRqBniJ4SacXeUMIj4\nH3XqZ3wVbFK16LoRszKz6Nu3LSNHrljUt5ujy6UP8La7T07faR1K8iBPiNaOfFu0aJojoHdj0W9B\nTKVh34EQoqUi3xYtmuboQ6/vVqD+e7FRVQv/X65zM5jSvLSr3KbcJjSYVSo3jUUtjZUqQ8mU6glM\nrW72sSyl+/aIqoX/t2t9vr18K/TtrSvblduEhrFKZYnCUdT2ab7zTvYcJM0R0KeSfJCnlrUo9nGe\nun3mrYzWGdC/V24TGs7KlaFk7cr1Wbty4Scynh/UkE+Xl0zpvl3QZ94aaVfZJxa1MLapbB+LWhIl\nB/Qd0gV69GjLhAnFnyE1R5fLi0APM1vHkg/AH0zywXwhWjvybdGiafIWurvPN7OTSUYs1r7a9UZT\nlyPE0ka+LVo6zfIeurs/SsNmJRKiVSDfFi2ZZgnoJXNrkL5HCXl8XYKmhPmRtnk/a2KfhNHdsmal\nSpjMuqFm/mbx5Op3sG9m+hZedw6CxTnnP38ONcM/jL8Ie/r+9X12fVGe6bd9qHn6D7uGmiMe/muo\n6ctjoeaKUNG8rHfM4u9213KPH1g0rZYxv/5hXMh18Xvf3Y5/J9QUnUungPW3fC3UvD1ti1Dz5Qpx\nYS8smzVjW5rPrA6h5hIGhJoevFuCJq7DcW1KeA/9k1iy6MRJ9ZG93xr6L4QQOUEBXQghcoICuhBC\n5AQFdCGEyAkK6EIIkRMU0IUQIicooAshRE5QQBdCiJxQtjlFzcy5K/sD9BWV8TzHx3cdEmqunvW7\n2KCZ8YAH23B+qDnBrgw1r9T0DDXPWmVm+sHhqCy4a+IxocbWi/fJr4oHQv2sfzwbyUOv7B9qVtjw\no1DTr8PDoeYeO7pZZiwqBTPzR2uKT5yw2zIPxJlc1CmUzD0+bo/NaxNXQbsOsQ+Mt3hiihk1XUPN\n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\nAwmwhqwYOz+DAAAAAElFTkSuQmCC\n", + "image/png": "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\ngg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index 08444f23a..b6e66c85a 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -737,7 +737,7 @@ coefficients. This element has the following attributes/sub-elements: *Default*: 33 - .. note:: This element is not used in the multi-group :ref:`energy_mode`. + .. note:: This element is only used in the multi-group :ref:`energy_mode`. .. _temperature_default: diff --git a/openmc/mesh.py b/openmc/mesh.py index 43ac7aef0..d2a911262 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -291,6 +291,10 @@ class Mesh(object): # Would prefer to have the z ranges be the max supported float, but # these values are apparently different between python and Fortran. # Choosing a safe and sane default. + # Values of +/-1000 are used here as there seems to be an + # inconsistency between what numpy uses as the max float and what + # Fortran expects for a real(8), so this avoids code complication + # and achieves the same goal. zplanes = [openmc.ZPlane(z0=-1000., boundary_type='reflective'), openmc.ZPlane(z0=1000., diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 2079b8801..a15aa51ae 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -14,14 +14,10 @@ if sys.version_info[0] >= 3: basestring = str # Supported incoming particle MGXS angular treatment representations -_REPRESENTATION_ISOTROPIC = 1 -_REPRESENTATION_ANGLE = 2 -_SCATTER_TYPE_TABULAR = 3 -_SCATTER_TYPE_LEGENDRE = 4 -_SCATTER_TYPE_HISTOGRAM = 5 _REPRESENTATIONS = ['isotropic', 'angle'] _SCATTER_TYPES = ['tabular', 'legendre', 'histogram'] + class XSdata(object): """A multi-group cross section data set providing all the multi-group data necessary for a multi-group OpenMC calculation. diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index 2ac06595b..0eafd49b3 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -102,6 +102,7 @@ module hdf5_interface public :: write_attribute_string public :: get_groups public :: get_datasets + public :: get_name contains @@ -333,6 +334,27 @@ contains end subroutine get_datasets +!=============================================================================== +! GET_NAME Obtains the name of the current group in group_id +!=============================================================================== + + function get_name(group_id, name_len_) result(name) + integer(HID_T), intent(in) :: group_id + integer(SIZE_T), optional, intent(in) :: name_len_ + + character(len=255) :: name ! name of group + integer(SIZE_T) :: name_len, name_file_len + integer :: hdf5_err ! HDF5 error code + + if (present(name_len_)) then + name_len = name_len_ + else + name_len = 255 + end if + + call h5iget_name_f(group_id, name, name_len, name_file_len, hdf5_err) + end function get_name + !=============================================================================== ! OPEN_GROUP opens an existing HDF5 group !=============================================================================== diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 47081eb5a..e3cc09bd7 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -3,8 +3,7 @@ module mgxs_header use, intrinsic :: ISO_FORTRAN_ENV use, intrinsic :: ISO_C_BINDING - use hdf5, only: HID_T, HSIZE_T, SIZE_T, h5iget_name_f - use h5lt, only: h5ltpath_valid_f + use hdf5, only: HID_T, HSIZE_T, SIZE_T use algorithm, only: find, sort use constants, only: MAX_FILE_LEN, ZERO, ONE, TWO, PI @@ -212,8 +211,7 @@ module mgxs_header type(VectorInt), intent(out) :: temps_to_read ! Temperatures to read integer, intent(out) :: order_dim ! Scattering data order size - integer :: hdf5_err - integer(SIZE_T) :: name_len, name_file_len + integer(SIZE_T) :: name_len integer(HID_T) :: kT_group character(MAX_FILE_LEN), allocatable :: dset_names(:) real(8), allocatable :: temps_available(:) ! temperatures available @@ -225,7 +223,7 @@ module mgxs_header ! Get name of dataset from group name_len = len(this % name) - call h5iget_name_f(xs_id, this % name, name_len, name_file_len, hdf5_err) + this % name = get_name(xs_id, name_len) ! Get rid of leading '/' this % name = trim(this % name(2:)) @@ -452,8 +450,8 @@ module mgxs_header ! If we have a need* for the fission and kappa-fission x/s, get them ! (*Need is defined as will be using it to tally) if (get_fiss) then - allocate(xs % fission(groups)) if (check_dataset(xsdata_grp, "fission")) then + allocate(xs % fission(groups)) call read_dataset(xs % fission, xsdata_grp, "fission") else call fatal_error("Fission data missing, required due to fission& @@ -461,8 +459,8 @@ module mgxs_header end if end if if (get_kfiss) then - allocate(xs % k_fission(groups)) if (check_dataset(xsdata_grp, "kappa-fission")) then + allocate(xs % k_fission(groups)) call read_dataset(xs % k_fission, xsdata_grp, "kappa-fission") else call fatal_error("kappa-fission data missing, required due to & @@ -471,8 +469,8 @@ module mgxs_header end if end if - allocate(xs % absorption(groups)) if (check_dataset(xsdata_grp, "absorption")) then + allocate(xs % absorption(groups)) call read_dataset(xs % absorption, xsdata_grp, "absorption") else call fatal_error("Must provide absorption!") @@ -581,30 +579,37 @@ module mgxs_header deallocate(input_scatt) ! Now get the multiplication matrix - ! Now use this information to find the length of a container array - ! to hold the flattened data - length = 0 - do gin = 1, groups - length = length + (gmax(gin) - gmin(gin) + 1) - end do - ! Allocate flattened array - allocate(temp_arr(length)) - if (.not. check_dataset(scatt_grp, 'multiplicity matrix')) & - call fatal_error("'multiplicity matrix' must be provided") - call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") - - ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing - ! to ScattData - allocate(temp_mult(groups)) - index = 1 - do gin = 1, groups - allocate(temp_mult(gin) % data(gmin(gin):gmax(gin))) - do gout = gmin(gin), gmax(gin) - temp_mult(gin) % data(gout) = temp_arr(index) - index = index + 1 + if (check_dataset(scatt_grp, 'multiplicity matrix')) then + ! Now use this information to find the length of a container array + ! to hold the flattened data + length = 0 + do gin = 1, groups + length = length + (gmax(gin) - gmin(gin) + 1) end do - end do - deallocate(temp_arr) + ! Allocate flattened array + allocate(temp_arr(length)) + call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") + + ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing + ! to ScattData + allocate(temp_mult(groups)) + index = 1 + do gin = 1, groups + allocate(temp_mult(gin) % data(gmin(gin):gmax(gin))) + do gout = gmin(gin), gmax(gin) + temp_mult(gin) % data(gout) = temp_arr(index) + index = index + 1 + end do + end do + deallocate(temp_arr) + else + ! Default to multiplicities of 1.0 + allocate(temp_mult(groups)) + do gin = 1, groups + allocate(temp_mult(gin) % data(gmin(gin):gmax(gin))) + temp_mult(gin) % data = ONE + end do + end if ! Allocate and initialize our ScattData Object. if (this % scatter_type == ANGLE_HISTOGRAM) then @@ -641,6 +646,7 @@ module mgxs_header ! Close the groups we have opened and deallocate call close_group(xsdata_grp) + call close_group(scatt_grp) deallocate(scatt_coeffs, temp_mult) end associate ! xs end do ! Temperatures @@ -689,7 +695,7 @@ module mgxs_header if (check_dataset(xsdata_grp, "chi")) then ! Chi was provided, that means we need chi and nu-fission vectors ! Get chi - allocate(temp_arr(1 * groups * this % n_azi * this % n_pol)) + allocate(temp_arr(groups * this % n_azi * this % n_pol)) call read_dataset(temp_arr, xsdata_grp, "chi") ! Initialize counter for temp_arr l = 0 @@ -920,39 +926,50 @@ module mgxs_header deallocate(input_scatt) ! Now get the multiplication matrix - ! Now use this information to find the length of a container array - ! to hold the flattened data - length = 0 - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gin = 1, groups - length = length + (gmax(gin, iazi, ipol) - gmin(gin, iazi, ipol) + 1) - end do - end do - end do - ! Allocate flattened array - allocate(temp_arr(length)) - if (.not. check_dataset(scatt_grp, 'multiplicity matrix')) & - call fatal_error("'multiplicity matrix' must be provided") - call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") - - ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing - ! to ScattData - allocate(temp_mult(groups, this % n_azi, this % n_pol)) - index = 1 - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gin = 1, groups - allocate(temp_mult(gin, iazi, ipol) % data( & - gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) - do gout = gmin(gin, iazi, ipol), gmax(gin, iazi, ipol) - temp_mult(gin, iazi, ipol) % data(gout) = temp_arr(index) - index = index + 1 + if (check_dataset(scatt_grp, 'multiplicity matrix')) then + ! Now use this information to find the length of a container array + ! to hold the flattened data + length = 0 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + length = length + (gmax(gin, iazi, ipol) - gmin(gin, iazi, ipol) + 1) end do end do end do - end do - deallocate(temp_arr) + ! Allocate flattened array + allocate(temp_arr(length)) + call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") + ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing + ! to ScattData + allocate(temp_mult(groups, this % n_azi, this % n_pol)) + index = 1 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + allocate(temp_mult(gin, iazi, ipol) % data( & + gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) + do gout = gmin(gin, iazi, ipol), gmax(gin, iazi, ipol) + temp_mult(gin, iazi, ipol) % data(gout) = temp_arr(index) + index = index + 1 + end do + end do + end do + end do + deallocate(temp_arr) + else + allocate(temp_mult(groups, this % n_azi, this % n_pol)) + ! Default to multiplicities of 1.0 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + allocate(temp_mult(gin, iazi, ipol) % data( & + gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) + temp_mult(gin, iazi, ipol) % data = ONE + end do + end do + end do + end if ! Allocate and initialize our ScattData Object. allocate(xs % scatter(this % n_azi, this % n_pol)) @@ -1013,6 +1030,7 @@ module mgxs_header ! Close the groups we have opened and deallocate call close_group(xsdata_grp) + call close_group(scatt_grp) deallocate(scatt_coeffs, temp_mult) end associate ! xs end do ! Temperatures @@ -1220,22 +1238,22 @@ module mgxs_header type is (MgxsIso) ! Perform our operations which depend upon the type ! Add contributions to total, absorption, and fission data (if necessary) - this % xs(t) % total(:) = this % xs(t) % total(:) + & - atom_density * nuc % xs(nuc_t) % total(:) - this % xs(t) % absorption(:) = this % xs(t) % absorption(:) + & - atom_density * nuc % xs(nuc_t) % absorption(:) + this % xs(t) % total = this % xs(t) % total + & + atom_density * nuc % xs(nuc_t) % total + this % xs(t) % absorption = this % xs(t) % absorption + & + atom_density * nuc % xs(nuc_t) % absorption if (nuc % fissionable) then - this % xs(t) % chi(:, :) = this % xs(t) % chi(:, :) + & - atom_density * nuc % xs(nuc_t) % chi(:, :) - this % xs(t) % nu_fission(:) = this % xs(t) % nu_fission(:) + & - atom_density * nuc % xs(nuc_t) % nu_fission(:) + this % xs(t) % chi = this % xs(t) % chi + & + atom_density * nuc % xs(nuc_t) % chi + this % xs(t) % nu_fission = this % xs(t) % nu_fission + & + atom_density * nuc % xs(nuc_t) % nu_fission if (allocated(nuc % xs(nuc_t) % fission)) then - this % xs(t) % fission(:) = this % xs(t) % fission(:) + & - atom_density * nuc % xs(nuc_t) % fission(:) + this % xs(t) % fission = this % xs(t) % fission + & + atom_density * nuc % xs(nuc_t) % fission end if if (allocated(nuc % xs(nuc_t) % k_fission)) then - this % xs(t) % k_fission(:) = this % xs(t) % k_fission(:) + & - atom_density * nuc % xs(nuc_t) % k_fission(:) + this % xs(t) % k_fission = this % xs(t) % k_fission + & + atom_density * nuc % xs(nuc_t) % k_fission end if end if @@ -1547,13 +1565,12 @@ module mgxs_header end do end do - ! Create the Jagged arrays + ! Now create our jagged data from the dense data call jagged_from_dense_2D(scatt_coeffs(:, :, :, iazi, ipol), & jagged_scatt) call jagged_from_dense_1D(temp_mult(:, :, iazi, ipol), & jagged_mult, gmin, gmax) - ! Initialize the ScattData Object ! Initialize the ScattData Object call this % xs(t) % scatter(iazi, ipol) % obj % init(gmin, & gmax, jagged_mult, jagged_scatt) diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 1fbd691ee..07b8a99b7 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -3,9 +3,7 @@ module nuclide_header use, intrinsic :: ISO_FORTRAN_ENV use, intrinsic :: ISO_C_BINDING - use hdf5, only: HID_T, HSIZE_T, SIZE_T, h5iget_name_f, h5gget_info_f, & - h5lget_name_by_idx_f, H5_INDEX_NAME_F, H5_ITER_INC_F - use h5lt, only: h5ltpath_valid_f + use hdf5, only: HID_T, HSIZE_T, SIZE_T use algorithm, only: sort, find use constants @@ -14,7 +12,8 @@ module nuclide_header use endf_header, only: Function1D, Polynomial, Tabulated1D use error, only: fatal_error, warning use hdf5_interface, only: read_attribute, open_group, close_group, & - open_dataset, read_dataset, close_dataset, get_shape, get_datasets + open_dataset, read_dataset, close_dataset, get_shape, get_datasets, & + check_group, get_name, get_groups use list_header, only: ListInt use math, only: evaluate_legendre use multipole_header, only: MultipoleArray @@ -194,10 +193,6 @@ module nuclide_header real(8), intent(in) :: tolerance integer :: i - integer :: storage_type - integer :: max_corder - integer :: n_links - integer :: hdf5_err integer :: i_closest integer :: n_temperature integer(HID_T) :: urr_group, nu_group @@ -208,21 +203,21 @@ module nuclide_header integer(HID_T) :: total_nu integer(HID_T) :: fer_group ! fission_energy_release group integer(HID_T) :: fer_dset - integer(SIZE_T) :: name_len, name_file_len + integer(SIZE_T) :: name_len integer(HSIZE_T) :: j integer(HSIZE_T) :: dims(1) character(MAX_WORD_LEN) :: temp_str character(MAX_FILE_LEN), allocatable :: dset_names(:) + character(MAX_FILE_LEN), allocatable :: grp_names(:) real(8), allocatable :: temps_available(:) ! temperatures available real(8) :: temp_desired real(8) :: temp_actual - logical :: exists type(VectorInt) :: MTs type(VectorInt) :: temps_to_read ! Get name of nuclide from group name_len = len(this % name) - call h5iget_name_f(group_id, this % name, name_len, name_file_len, hdf5_err) + this % name = get_name(group_id, name_len) ! Get rid of leading '/' this % name = trim(this % name(2:)) @@ -305,12 +300,10 @@ module nuclide_header ! Get MT values based on group names rxs_group = open_group(group_id, 'reactions') - call h5gget_info_f(rxs_group, storage_type, n_links, max_corder, hdf5_err) - do j = 0, n_links - 1 - call h5lget_name_by_idx_f(rxs_group, ".", H5_INDEX_NAME_F, H5_ITER_INC_F, & - j, temp_str, hdf5_err, name_len) - if (starts_with(temp_str, "reaction_")) then - call MTs % push_back(int(str_to_int(temp_str(10:12)))) + call get_groups(rxs_group, grp_names) + do j = 1, size(grp_names) + if (starts_with(grp_names(j), "reaction_")) then + call MTs % push_back(int(str_to_int(grp_names(j)(10:12)))) end if end do @@ -326,8 +319,7 @@ module nuclide_header call close_group(rxs_group) ! Read unresolved resonance probability tables if present - call h5ltpath_valid_f(group_id, 'urr', .true., exists, hdf5_err) - if (exists) then + if (check_group(group_id, 'urr')) then this % urr_present = .true. allocate(this % urr_data(n_temperature)) @@ -368,8 +360,7 @@ module nuclide_header end if ! Check for nu-total - call h5ltpath_valid_f(group_id, 'total_nu', .true., exists, hdf5_err) - if (exists) then + if (check_group(group_id, 'total_nu')) then nu_group = open_group(group_id, 'total_nu') ! Read total nu data @@ -388,9 +379,7 @@ module nuclide_header end if ! Read fission energy release data if present - call h5ltpath_valid_f(group_id, 'fission_energy_release', .true., exists, & - hdf5_err) - if (exists) then + if (check_group(group_id, 'fission_energy_release')) then fer_group = open_group(group_id, 'fission_energy_release') ! Check to see if this is polynomial or tabulated data diff --git a/src/reaction_header.F90 b/src/reaction_header.F90 index a7896e9ff..12b3888c4 100644 --- a/src/reaction_header.F90 +++ b/src/reaction_header.F90 @@ -5,7 +5,7 @@ module reaction_header use constants, only: MAX_WORD_LEN use hdf5_interface, only: read_attribute, open_group, close_group, & - open_dataset, read_dataset, close_dataset, get_shape + open_dataset, read_dataset, close_dataset, get_shape, get_groups use product_header, only: ReactionProduct use stl_vector, only: VectorInt use string, only: to_str, starts_with @@ -42,17 +42,12 @@ contains integer :: i integer :: cm integer :: n_product - integer :: storage_type - integer :: max_corder - integer :: n_links - integer :: hdf5_err integer(HID_T) :: pgroup integer(HID_T) :: xs, temp_group - integer(SIZE_T) :: name_len integer(HSIZE_T) :: dims(1) integer(HSIZE_T) :: j - character(MAX_WORD_LEN) :: name character(MAX_WORD_LEN) :: temp_str ! temperature dataset name, e.g. '294K' + character(MAX_WORD_LEN), allocatable :: grp_names(:) call read_attribute(this % Q_value, group_id, 'Q_value') call read_attribute(this % MT, group_id, 'mt') @@ -74,12 +69,10 @@ contains end do ! Determine number of products - call h5gget_info_f(group_id, storage_type, n_links, max_corder, hdf5_err) n_product = 0 - do j = 0, n_links - 1 - call h5lget_name_by_idx_f(group_id, ".", H5_INDEX_NAME_F, H5_ITER_INC_F, & - j, name, hdf5_err, name_len) - if (starts_with(name, "product_")) n_product = n_product + 1 + call get_groups(group_id, grp_names) + do j = 1, size(grp_names) + if (starts_with(grp_names(j), "product_")) n_product = n_product + 1 end do ! Read products diff --git a/src/sab_header.F90 b/src/sab_header.F90 index 147643065..5f49fdc42 100644 --- a/src/sab_header.F90 +++ b/src/sab_header.F90 @@ -8,9 +8,9 @@ module sab_header use distribution_univariate, only: Tabular use error, only: warning, fatal_error use hdf5, only: HID_T, HSIZE_T, SIZE_T - use h5lt, only: h5ltpath_valid_f, h5iget_name_f use hdf5_interface, only: read_attribute, get_shape, open_group, close_group, & - open_dataset, read_dataset, close_dataset, get_datasets + open_dataset, read_dataset, close_dataset, get_datasets, check_group, & + get_name use secondary_correlated, only: CorrelatedAngleEnergy use stl_vector, only: VectorInt, VectorReal use string, only: to_str, str_to_int @@ -91,8 +91,7 @@ contains integer :: n_energy, n_energy_out, n_mu integer :: i_closest integer :: n_temperature - integer :: hdf5_err - integer(SIZE_T) :: name_len, name_file_len + integer(SIZE_T) :: name_len integer(HID_T) :: T_group integer(HID_T) :: elastic_group integer(HID_T) :: inelastic_group @@ -102,7 +101,6 @@ contains integer(HSIZE_T) :: dims3(3) real(8), allocatable :: temp(:,:) character(20) :: type - logical :: exists type(CorrelatedAngleEnergy) :: correlated_dist character(MAX_WORD_LEN) :: temp_str @@ -114,7 +112,7 @@ contains ! Get name of table from group name_len = len(this % name) - call h5iget_name_f(group_id, this % name, name_len, name_file_len, hdf5_err) + this % name = get_name(group_id, name_len) ! Get rid of leading '/' this % name = trim(this % name(2:)) @@ -180,8 +178,7 @@ contains T_group = open_group(group_id, temp_str) ! Coherent elastic data - call h5ltpath_valid_f(T_group, 'elastic', .true., exists, hdf5_err) - if (exists) then + if (check_group(T_group, 'elastic')) then ! Read cross section data elastic_group = open_group(T_group, 'elastic') dset_id = open_dataset(elastic_group, 'xs') @@ -223,8 +220,7 @@ contains end if ! Inelastic data - call h5ltpath_valid_f(T_group, 'inelastic', .true., exists, hdf5_err) - if (exists) then + if (check_group(T_group, 'inelastic')) then ! Read type of inelastic data inelastic_group = open_group(T_group, 'inelastic') diff --git a/src/secondary_uncorrelated.F90 b/src/secondary_uncorrelated.F90 index fc215484a..756ff83df 100644 --- a/src/secondary_uncorrelated.F90 +++ b/src/secondary_uncorrelated.F90 @@ -1,6 +1,5 @@ module secondary_uncorrelated - use h5lt, only: h5ltpath_valid_f use hdf5, only: HID_T use angle_distribution, only: AngleDistribution @@ -9,7 +8,7 @@ module secondary_uncorrelated use energy_distribution, only: EnergyDistribution, LevelInelastic, & ContinuousTabular, MaxwellEnergy, Evaporation, WattEnergy, DiscretePhoton use error, only: warning - use hdf5_interface, only: read_attribute, open_group, close_group + use hdf5_interface, only: read_attribute, open_group, close_group, check_group use random_lcg, only: prn !=============================================================================== @@ -56,25 +55,19 @@ contains class(UncorrelatedAngleEnergy), intent(inout) :: this integer(HID_T), intent(in) :: group_id - logical :: exists - integer :: hdf5_err integer(HID_T) :: energy_group integer(HID_T) :: angle_group character(MAX_WORD_LEN) :: type - ! Check if energy group is present - call h5ltpath_valid_f(group_id, 'angle', .true., exists, hdf5_err) - - if (exists) then + ! Check if angle group is present & read + if (check_group(group_id, 'angle')) then angle_group = open_group(group_id, 'angle') call this%angle%from_hdf5(angle_group) call close_group(angle_group) end if - ! Check if energy group is present - call h5ltpath_valid_f(group_id, 'energy', .true., exists, hdf5_err) - - if (exists) then + ! Check if energy group is present & read + if (check_group(group_id, 'energy')) then energy_group = open_group(group_id, 'energy') call read_attribute(type, energy_group, 'type') select case (type) From e8c8fb7aa8f84400ed304268479cea296b3fe638 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 10 Sep 2016 11:35:26 -0400 Subject: [PATCH 18/42] Updated example pincell_multigroup problem to use h5 library --- .gitignore | 1 + examples/xml/pincell_multigroup/mgxs.h5 | Bin 0 -> 59616 bytes examples/xml/pincell_multigroup/settings.xml | 2 +- 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 examples/xml/pincell_multigroup/mgxs.h5 diff --git a/.gitignore b/.gitignore index b1cb1a623..724e13703 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,7 @@ tests/ctestscript.run # HDF5 files *.h5 !tests/1d_mgxs.h5 +!examples/xml/pincell_multigroup/mgxs.h5 # Build files src/CMakeCache.txt diff --git a/examples/xml/pincell_multigroup/mgxs.h5 b/examples/xml/pincell_multigroup/mgxs.h5 new file mode 100644 index 0000000000000000000000000000000000000000..ada3b1c71d8db394f330abf18d5a934544e44456 GIT binary patch literal 59616 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 literal 0 HcmV?d00001 diff --git a/examples/xml/pincell_multigroup/settings.xml b/examples/xml/pincell_multigroup/settings.xml index 1030762fa..ab716d9e4 100644 --- a/examples/xml/pincell_multigroup/settings.xml +++ b/examples/xml/pincell_multigroup/settings.xml @@ -34,6 +34,6 @@ false - ./mg_cross_sections.h5 + ./mgxs.h5 From 8c8e0a7174664fcfc75b6eacce35928076595ecd Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 10 Sep 2016 15:04:07 -0400 Subject: [PATCH 19/42] Updating failing tests --- openmc/mgxs_library.py | 4 +++ src/mgxs_header.F90 | 45 ++++++++++++++++++++------ tests/1d_mgxs.h5 | Bin 123864 -> 123864 bytes tests/test_mg_basic/inputs_true.dat | 2 +- tests/test_mg_tallies/inputs_true.dat | 2 +- 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index a15aa51ae..a5968e299 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1263,6 +1263,10 @@ class XSdata(object): 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), + compression=compression) # And finally, adjust g_out_bounds for 1-based group counting # and write it. g_out_bounds[:, :, :, :] += 1 diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index e3cc09bd7..04fab444a 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -726,7 +726,11 @@ module mgxs_header ! Get nu_fission (as a vector) if (check_dataset(xsdata_grp, "nu-fission")) then - call read_dataset(xs % nu_fission, xsdata_grp, "nu-fission") + 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 @@ -774,8 +778,12 @@ module mgxs_header ! (*Need is defined as will be using it to tally) if (get_fiss) then if (check_dataset(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)) - call read_dataset(xs % fission, xsdata_grp, "fission") + 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!") @@ -783,8 +791,12 @@ module mgxs_header end if if (get_kfiss) then if (check_dataset(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)) - call read_dataset(xs % k_fission, xsdata_grp, "kappa-fission") + 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!") @@ -793,8 +805,12 @@ module mgxs_header end if if (check_dataset(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)) - call read_dataset(xs % absorption, xsdata_grp, "absorption") + xs % absorption = reshape(temp_arr, (/groups, this % n_azi, & + this % n_pol/)) + deallocate(temp_arr) else call fatal_error("Must provide absorption!") end if @@ -805,14 +821,20 @@ module mgxs_header scatt_grp = open_group(xsdata_grp, 'scatter data') ! First get the outgoing group boundary indices if (check_dataset(scatt_grp, "g_min")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call read_dataset(temp_arr, scatt_grp, "g_min") allocate(gmin(groups, this % n_azi, this % n_pol)) - call read_dataset(gmin, scatt_grp, "g_min") + gmin = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) + deallocate(temp_arr) else call fatal_error("'g_min' for the scatter matrix must be provided") end if if (check_dataset(scatt_grp, "g_max")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call read_dataset(temp_arr, scatt_grp, "g_max") allocate(gmax(groups, this % n_azi, this % n_pol)) - call read_dataset(gmax, scatt_grp, "g_max") + gmax = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) + deallocate(temp_arr) else call fatal_error("'g_max' for the scatter matrix must be provided") end if @@ -857,7 +879,7 @@ module mgxs_header ! Finally convert the legendre to tabular if needed ! Compare the number of orders given with the maximum order of the - ! problem. Strip off the supefluous orders if needed. + ! problem. Strip off the superfluous orders if needed. if (this % scatter_type == ANGLE_LEGENDRE) then order = min(order_dim - 1, max_order) order_dim = order + 1 @@ -904,7 +926,8 @@ module mgxs_header 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) + input_scatt(gin, iazi, ipol) % data(1, gout) / & + norm end if end do ! gout end do ! gin @@ -1006,7 +1029,11 @@ module mgxs_header allocate(xs % total(groups, this % n_azi, this % n_pol)) if (check_dataset(xsdata_grp, "total")) then - call read_dataset(xs % total, xsdata_grp, "total") + 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 diff --git a/tests/1d_mgxs.h5 b/tests/1d_mgxs.h5 index 38bb500677ae2d95948a7992f0c580130546e90c..d764cb69fbf7d76401c15d7224f62b9d2a28942d 100644 GIT binary patch delta 30608 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 literal 123864 zcmeHQcR&+K7Y`r`R&0o3i49Rt#d@fxFJkW~7Hkv&4GMx31slDH4Y7eDf(1|y#RB5l zuw%Is4Pro4PEJHDVEL4@@oh3QAR9wg1TL`2ANlRfzMXyZ_RV{5%FeDHHEcw^+AV5x zL_ak(P7RKR_>lY+;-4@}Nt{K}1(g&vHs{w!)$AS&LJbqsE!Q9*%k99%BagR#@A_ZnozAmd>z-($-&ve$=Sh*(~t{A*Y~Nz=~IZ?iINg32{$XM zrF`$#hevVny%SrW(W5$YIEr@oU2#|2OwtaGaSe%G zH^latRD9tSsxeT%Uj6%w6(MN{JW-+yKcfi~hl$!6A77gjj}Az=IjJbEmWD7G(+PVZ z3PP7?ijFeP5t7zY(7a@MnVoR~zaZq{Bw>J*m$MX|P+Nx31=D4IKnH|QtpKHUvEPcu zbcqp&g3#sQwAx;j!^L!F2Izp$`Qvo-FigM@h&|H~887Omho4(rjv=;7bvZhe1)68= z=xA-X$b7Dim6%S8GB~1pi|iZXL5(wF$T%a)X>+Dbo+<+I3Bn)2x*UC6ZUd@RHI9Ro zy@Qpb)gmWzC#rZ3r!hsSjxH4!VeM$=?N_Y^~BdZT9`XISvhobaqQj}5RK$`zB7FB}!xnTP! z%Z`rHMD!xwML&fdMRH)vKi!TJI~0udhsc3$KSz-hWkh60m5ZW;z-Fi*(tZ+fT8Ql- z(N8_B--M2??`34C%3h|#sflb37KoDA3KiQS6)Lt9ost&MsZ#W!^UBJ~;u6#_y^7MP z`ba25@+j5loAPgex;?$Pr-jb{*Z*Gq#tg9TGHY-(uM~ z&}}my{_>%LQK9P?>;2%eHZdrmwh(+f{{5nrS`@@CZ=IttWgF;gZ)s|m>Id3M?br8P zz7m9sK3vwDXA3bV8w72Y@&Svx$le#-H`HVLi-Q8VHh=Rr)$CcYq;>aDtv~@d$JFTf z_r!fr|MyOsyY6fS%dc@=XY{j&HVqqf%`jUCqsGkInVvZf(*18Lb>c`bzw2mAo`Z58 zoE~^;>g2X-HN1=~iBdi7B=4OUsq8kMj#5rp@*TBN&sLG;w&x2#%kKG$d; zOuB44w5a}4`DZFOKaXj>zk0z1$EWsVZhAr6W?7E{j#KGS!Qf*DykJJI+xqcGykK9r z%A8u~ykO976A!PuUZAbqW&q@S!K1={`D--1VY_LpU$S=C?^7jV+ z@OyzFe|Q6T)tK7--gtv^qm!S_yZJy(=T0UkZG6Bpw{!fyI4ZqTb!cIs4_ugHt9fjK zFQ~--Z(dfEFIX1*qWhbQ9~9^WO;=gu2YU>oxK@w-VEneIMQiQ+;e>iX_x0MV;bNh- z;Sx>&)VFdBPV2q~{{6DL&%(QF;lt=({dj#hfUsfbPp#){gr|vDytX&m3_V(|SH80_ z_=okt;7FYdCm(shFlS|#yLCN4siw(*2);X5k3M*NTZ$XZv=Xe^r|ky3$?aWiLRLY_ z*g0ys16DzUl{??OEL;iMVe^w?p00%D%I@uiuUEp_36pNcG+za-`x_tKXR->cQ|peL za&Z-0d|{%Xfp*;U_Jejora$Uv^uc^X}07{DY3K3_Re1_YBv4H#}ft zGw$M`Ii6r2SflfV0#EQ7lheufuot9Xh{#@R?G1(RS8Vs_;{!(V*Jkd~_62RPUu~k= z`N7slX};mp{K2>FGqqONSHrO2Y(rbSh;6AhYsOZ(Ow4F!)wT}Y8>gCfLj0gt%{LC&2%EncMXepP1^RO9EwGLYhD#Hb zU;L353PU?QY5Dv7aJauFJ#hWT-SB(!-FMf>xy>-%ZYx$XAF zN|)2%fn2aZnzlMmB6=;)@wxfq?Mhg8xa z;nhR^D}M{&QTOxLTm317!k{UU!54+Ff7hw;<39_*O;g?Zz^*iSH|XQWoDu18=A^pX zhm>^4%M8$;HR?W`J9oxlQsjLY7yMw-!ngOKaOAnnk-aluaNRK-8uK&YQ)tk`FF_d~ zY$W)H}J*dQFBpN5t9rCqRN;78L#!*@a70h5RRwmuAO^RMrWi`xm_Z|B^dcq$ZH zFIP?;c60}s_`%$f*-y1)gs?? z>mmMj_`=i)>!8!&7kI0-*o8fx{bKqwHelnKAVTtp<;rHF1%et3m1d z7QNNht0De=vtV$p1a}^ z0s~cF^W9BCp+UgSm`-oPz(qGWEFvTv?#BEw`2FSxm{<3z$EEqZq4%rgPMwjO}f{7qpi5ILqI#7hWAqZuIW(ULgLKjwr4qQ4oitU+=$; zNUG-jrS&iAak;GirI|LWKZzn0{mZJU4`t<=^eA3iGLaWm0^zdn6o6_lc_;d~z9gydw(H5oku-*`RV%P#-P)SgEdSzTC^s4gY zVWyA=rQ^lpGkk?SO31^$ipWFc$%_45(L4yvzR8NK_#KhKBX&>`S0Q<@<)6e=#<;>f zjE2}h5;@>`Dz2@$lY=!Cg4jCSI9c1-xfW$o#PdyUtrsCQ7ey+>?`n~PXy|0; zWNt&{na_2!bFfEqXd)6kU&pcFTZ^w)nfPq^|H<-CWV)DO z+2cSLY=20kgX$tVUM`aEfA>RiU=3o3GVV}1 zoxGowrB_6+36@>2qN|8sqt8Pjjga2o(h#?O`aHPw`KVZia&VUm)%kJ#_)&QzR4IAL zif0V5p&|A`5zokl8dn+<^mvB&6D}SHB8-&xdM*-w)7M#*_c|oPe|1}jB&%IV_d+#S zv}>XP>_U3G*1**-ppDm7^!lRw-sr|89@FZB()#@n68+@j@kBzGAZ2_RSEJg4WE_Je zMdVZVxHget{NgWHGN#Wj2KSUJ_Nojs(&lsM?NXM1N&FR6nY3R;+*oB)pj;TG`xi1^ zVT|oMxrwy#Drw_Uy5vGBC}|gE^>@p<4l{|Noph1HY2{=iyQoq$zo^!~^!sx0X{`b1 zfcO(0PMiIP@=3dnr9Dr4d9{Pe)2rkvp;yxU1YJ*L`H7rCCG|<+C#qf3DYZg$Kf%M) z?%2+di-|udulW*L?U~Fw5G;EEt=#s5L5l6^{x>p(#^f-d}og~`(&lNRKL4V&`F;77rJ$Vu& zT@t1BBm74oy68~|Wwn17@h$>nZwKGURP=mC;y83C65r+E zwAw_JPogz5tlxx=uJ43jwxDEOgd|1eQ}#HS%P=1Dmn%`z=QH?Yomk^J|Oi?eekqXXhk zG>lMMZz@94uH9+R6JK8KK+@l$I9>X>(6Y{x=~W56lIADqdLqkDBup!*PYOR#?V3)h z6{7nI9;P}nmaeF2n5YuY`a=X!(eoO?;@y;s+fgD;XU<0)5dGB0`c2v!UEc}6Y(dHR2uX^_r|k0@ z?hNB1f4LGheO`k{Hu9D$F6EyYY5s-YE@k-_yd4DIJy7&aEL>IgY7mPvDE>_g|vp+*S=~9xxN=_lWSiBEh?1Iu6(8Z^d zMVq~p^5f!ji3>|1qE3hXmn>e|_!$|mqkktsx8&s#DM@>WBIxpe z-zJ%%{d1Avu`)A|y(`|AF5Iv5yL0jBe7e8IW;{6n5s-F0%BS@5s>|8R(<@<>&?}kt ze{D%UQP}_L(h``}gKqzM__BO#KS(LW&R5ocb6k95f@P0?GjTgD>XL{{mbdX}WdDo5 zcayjQ3qT4GKOMVX3IWb0<5J=4N~bIG6KhJRllQZgXa6%BB3Tg0p_IJo)sM^LN9Q?m z7|Ow2E>x%D<&j^-aE^gnl>_C19qF2~~65?e|f^G*$ z@Xf>eLj+OL^AP$w(4ENmxfxEo??m}TKZTo1($V#u@XHpIjE|6{h#bq_4=Z387x~MT zsOj?%nZa_!UX@`+nt!3UOIiL!Z5OICX}^j%v&yJIxiCuiFJv4f9NTqrld3yk!D&=d z!%<4!#ue!E6^7wN^4~`;&Nhoc2gINF<8<^Mluz1q0quF>%c~to`didSDu4>;zfI&i@@ft^^!_%8Da0V-Y=R4T?BIF4Vo!n4rfIMf!yGh%i!7^BT$f z(H-&+A}sHD4bl%Q-uJBm^^Ue0$HB_p!OGEUk(0TTwH>v$MPrIkm12R=n=hJgBiiz+ z_&6EwXg5D!#6!_`Y@ymR6#BO1qz^?&wD}fTT;JwEoMe zLx_%#?TIYAqkjz1E9_25`LZQNw>uiR;{I5Fh#V?<9>x7Qx)W(X(KwwHkMfCra7VYvW(m! zI&?tnrL_FA+fhAiM~gy3@eL)%IgBw!6$8jF7VmQxe6sZW=;G4}r%I>e;?vQ8luoCI zPbXa}osNf33ooMs@?1DqP@0SNhS(F{34B2%fgI^o6I|sY5sA{3tygj+kERNFe7g@` z(rI~+2jU?g*oqHa&v$ib6$MT;2A+?89tkTuH98xxBNDD{Kk#sU_egl`{dfABP5Yqp zxwhtl`+K48Z>Gw7YVU>R16?vAyYGP-{AK9{V|PRP*bke`mqx&zr(V;BoC=3WtD7}G z{!2I%jJPzP5WI zXt*ZN;zbk;zp>2HC*dF{FWxtJlha{{kF`0a;c^5%*0k8ZTm2Z+%gLShg?}8#0!Bb3T{AZnBuwG z`46)H6arK18oFlo#lM8W6z|qwnz8P-5SXIN(XT@jD0-$?Q{WJ+c}ECLF=0zfw^O$$ z`^gaHCq7I%BML-Ve=voo)=pYCp29cJ{e)%|c3AJb(~-h%>+Lq1Qy62i zK_I&S>x-eEYEsyDp6#Lkaq?lg=cOedC|rATq58iRzN20P&Ik9t-}EDe zS+^q7-cU&B3EsbR{O)@y|8CQj6Gb>>`rsRHDa@SQ`Swc+$wN~hQVq7rVY8ajiTC#e zaNv@yc2=qY+-tUR>`h@-gkzNYT>%*S+P_Rp7C>0uu+YH21h8!R6{mYi0?0Y&n&fz1 z0OpfdtT2cdz_YXc55J8PK>t6~W~pu#z~tEp+~&&!pz?6)q~kLLaH;OtIU z(pDEhmtXY;1*i!iS<^eV-Dv>?&++0kR8N8Aume{HHcf%SQQ4a|)=q(ta4U0{j{+F_ zhLbV=g#e7RZdsnm6u`mBPloIe3gBFu+R=Q00J6JvPpol^O1GF6b@GM)2J^3V^ri4^ zg4?!7*9EY_z&d@+H35v7@a0t&g~N8;o^YJ1N1uQEa_6_0246FrY_sc61DE)K*u$-+ zLH6jwn|aw&;eh$@1D7sO1(Ue>E&aAmg&PMa$DOm93Z4;r+BR!56}o-4+cF|$3Ur*) z%2P9F3S7xL;yZw6rYXcybRV z{sIfo?caIzfPEIwD4=7C-UAD;+hTkoS=AEKhwvi@Hn9Yypav6ddsxEhoVKawhFOB= z>hWpj11;h1gZe$3d6v-q_b(Hh8d!qkz}&E|lpScId**sy3P1GE3hzweuOZ4=T_{xT znH<-H!g}2=oD|XZoiWNvl=gPm*t6R==eN(ZA0x{D7;m<}JB8D)ZVl)~p_5BYXHmI3 z_Vm81Pod57Qyu$L7@7HKnjVEYYF*ydq3~GyWoJeB@Wx7qCKPTs+9y(z!oBlm3~5DS zVBQBkE`@7)B_3!)Vb5K)?ugQlea@=3r|?Qj)I3qz;j2!Qb`}_a@d#E9Vuj6dsoz#Zs+OW?ba6)lzkrdN7q*;{fUDT@@T|K$++AM zlT|E8#*LLOkH2sYSb{_x_EsE;kTmJMdzfV zJE-CNmG`=6!hi8PVa2*=)Yf@o(GVlWbX~M8d!n0(B(AV0NDgfKr`r<^EC3hU`mu^$ z?`;1!x-rr3V4P0KLit2LHSqc-LMLs#8(W^EWc-9AMdVZVaW*~8l9ER$$vDwpu0%~= z@2vGmuGp(G%t)J;qqj?0{)P7hRhhJ3MZ8*NRG?fKrTZ5$enAwrdP>W)a22Kla;Mk()k~; zCjh1xU-+-(+z|p`iqnp?{WGYI0GML;{CYOM-roVH$nAGgFz)RgV2aJ-P5#KH~+o~TL4TkqTlYh{i%6$rl=XGay97+rJoG3ppIW& z{XYc26x&>RxS;J30WifrmVXBxJwVNqGepzV%|tg_mCqFacw}1lE2W=I(PHy;|7%oznc|?=4@bWV$pw#r zK^Nl;qJ2J0df0BwhT8eCtbuaEvfMn# zy`VonEh!KD`ixz*BQ_5Pv|F*f`OZAJ*=vSo*Y$beFeB5~(LWD%?;G7cBGwI#hs~Ys zmgokjdV0V7-y=6zwbkMHJT-S1mbx+GP$zfzm=QZj%g`M-6TbB9=;01A6Z31vopy&` zTR%}xQt^Nl6S+RqW_iG7s~Hn*u6lru?u>|*lRaTa!&-Hh*7t(^#Vy}XZ|n`7wA*h# z7w7{aOS&`;TE*F=BFeRIrB?YSTH zH1O1Uvc(VT>1PQwqD|9yVehKIhebkNuL{CHn5&JA{|x5*biShSD6 zvBVda^y=KEr-d&(_&35ed6F-9=*>K@Jmifhu3468{_1;=aOLIxe0w7f%u(KA4{@W-s>Zf z-&Exo;@cz#q61=->EFpQ!*tPjpE*KD-*?U*)7iH`6of7qrxRMD9HQ?zcs!cWX^1vy zqkejL)PeYGy;&%q&>7>j%N&&dU;Q`aXozpER)9Fr#m`N#&IHMWi=fKvznAm{F`QF~ zP?r5pK+`99j)lWf*l+y6SpszXjjVxa9}i-wkRU30Jqo7=x*xf#E>4fCiE@a&4afRT z=;->+lE+q5P06?xNs7p)?BnP9)nYwLv=Wg-k;oJW3?v|Jo{`=zW%-xnTD10y;|mfO zFUyq`tUVbaKk92DzIznxT z)An^y4)M#0wC7n=P&GS{^tV4du2$A{PW(4mwB*r9O#>-8wVtZ4U6I4c*JB6nG;Nt$UcFvT_^`0mzBK&bAc&(TwQt7>mW7%$`HRS{NL}Xw{n3g4*nYa;rPc~ zV2arvZkVU`cn(a_PQCpCGiv^qDQ@XptH~^SDfZH6`c8M=Yha4C-|`%2zb{!^0uL?nUoUyo8C`ec>pS3jA{wZ#fd>;(Cap&sTk5kD1K;|R%}QLTs_QH�iaN{9 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 Date: Sun, 11 Sep 2016 05:43:45 -0400 Subject: [PATCH 20/42] bug fixes --- src/hdf5_interface.F90 | 13 +++++---- src/input_xml.F90 | 2 +- src/mgxs_header.F90 | 60 ++++++++++++++++++++++-------------------- src/nuclide_header.F90 | 4 +-- src/sab_header.F90 | 4 +-- 5 files changed, 42 insertions(+), 41 deletions(-) diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index 0eafd49b3..7e4f16f26 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -218,12 +218,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) @@ -302,11 +301,11 @@ contains 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 @@ -342,14 +341,14 @@ contains integer(HID_T), intent(in) :: group_id integer(SIZE_T), optional, intent(in) :: name_len_ - character(len=255) :: name ! name of group + 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 = 255 + name_len = 150 end if call h5iget_name_f(group_id, name, name_len, name_file_len, hdf5_err) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index d755f2168..1820350aa 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -4640,7 +4640,7 @@ contains logical :: file_exists ! does mgxs.h5 exist? integer(HID_T) :: file_id real(8), allocatable :: rev_energy_bins(:) - character(len=255), allocatable :: names(:) + character(len=MAX_WORD_LEN), allocatable :: names(:) ! Check if mgxs.h5 exists inquire(FILE=path_cross_sections, EXIST=file_exists) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 04fab444a..46c4bcb50 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -6,7 +6,7 @@ module mgxs_header use hdf5, only: HID_T, HSIZE_T, SIZE_T use algorithm, only: find, sort - use constants, only: MAX_FILE_LEN, ZERO, ONE, TWO, PI + use constants, only: MAX_WORD_LEN, ZERO, ONE, TWO, PI use error, only: fatal_error use hdf5_interface use material_header, only: material @@ -49,9 +49,9 @@ module mgxs_header !=============================================================================== type, abstract :: Mgxs - character(len=104) :: name ! name of dataset, e.g. 92235.03c - real(8) :: awr ! Atomic Weight Ratio - real(8), allocatable :: kTs(:) ! 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? @@ -213,7 +213,7 @@ module mgxs_header integer(SIZE_T) :: name_len integer(HID_T) :: kT_group - 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 @@ -506,6 +506,13 @@ module mgxs_header 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_type == 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)) @@ -522,13 +529,6 @@ module mgxs_header deallocate(temp_arr) ! Finally convert the legendre to tabular if needed - ! Compare the number of orders given with the maximum order of the - ! problem. Strip off the supefluous orders if needed. - if (this % scatter_type == ANGLE_LEGENDRE) then - order = min(order_dim - 1, max_order) - order_dim = order + 1 - end if - allocate(scatt_coeffs(groups)) if (this % scatter_type == ANGLE_LEGENDRE .and. & legendre_to_tabular) then @@ -573,7 +573,8 @@ module mgxs_header ! 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(:, :) + scatt_coeffs(gin) % data(:, :) = & + input_scatt(gin) % data(1:order_dim, :) end do end if deallocate(input_scatt) @@ -670,6 +671,7 @@ module mgxs_header 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 @@ -821,20 +823,20 @@ module mgxs_header scatt_grp = open_group(xsdata_grp, 'scatter data') ! First get the outgoing group boundary indices if (check_dataset(scatt_grp, "g_min")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call read_dataset(temp_arr, scatt_grp, "g_min") + 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(temp_arr, (/groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) + gmin = reshape(int_arr, (/groups, this % n_azi, this % n_pol/)) + deallocate(int_arr) else call fatal_error("'g_min' for the scatter matrix must be provided") end if if (check_dataset(scatt_grp, "g_max")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call read_dataset(temp_arr, scatt_grp, "g_max") + 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(temp_arr, (/groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) + gmax = reshape(int_arr, (/groups, this % n_azi, this % n_pol/)) + deallocate(int_arr) else call fatal_error("'g_max' for the scatter matrix must be provided") end if @@ -856,6 +858,13 @@ module mgxs_header 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_type == 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)) @@ -878,13 +887,6 @@ module mgxs_header deallocate(temp_arr) ! Finally convert the legendre to tabular if needed - ! Compare the number of orders given with the maximum order of the - ! problem. Strip off the superfluous orders if needed. - if (this % scatter_type == ANGLE_LEGENDRE) then - order = min(order_dim - 1, max_order) - order_dim = order + 1 - end if - allocate(scatt_coeffs(groups, this % n_azi, this % n_pol)) if (this % scatter_type == ANGLE_LEGENDRE .and. & legendre_to_tabular) then @@ -941,7 +943,7 @@ module mgxs_header 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(:, :) + input_scatt(gin, iazi, ipol) % data(1:order_dim, :) end do end do end do diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 07b8a99b7..f5365fc04 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -207,8 +207,8 @@ module nuclide_header integer(HSIZE_T) :: j integer(HSIZE_T) :: dims(1) character(MAX_WORD_LEN) :: temp_str - character(MAX_FILE_LEN), allocatable :: dset_names(:) - character(MAX_FILE_LEN), allocatable :: grp_names(:) + 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 diff --git a/src/sab_header.F90 b/src/sab_header.F90 index 5f49fdc42..8eaff0167 100644 --- a/src/sab_header.F90 +++ b/src/sab_header.F90 @@ -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 @@ -104,7 +104,7 @@ contains 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 From 26244eabcf4d164ed209693dc2608d4e863720f6 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 11 Sep 2016 06:22:40 -0400 Subject: [PATCH 21/42] argh. The failing ce_to_mg test was only because of precision of the xs in the xml and h5 datasets... when you convert the xml lib to h5 (per the script), the answer is then passing. groan. --- scripts/openmc-update-mgxs.py | 70 +++++++++---------- .../results_true.dat | 2 +- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/scripts/openmc-update-mgxs.py b/scripts/openmc-update-mgxs.py index fc9bad30f..5aea89883 100755 --- a/scripts/openmc-update-mgxs.py +++ b/scripts/openmc-update-mgxs.py @@ -60,6 +60,20 @@ def parse_args(): # Parse and return commandline arguments. return args +def get_data(element, entry): + try: + value = element.find(entry).text + except: + if entry in element.attrib: + value = element.attrib[entry] + else: + value = None + + if value is not None: + value = value.strip() + + return value + if __name__ == '__main__': args = parse_args() @@ -68,9 +82,6 @@ if __name__ == '__main__': tree = ET.parse(args['input']) root = tree.getroot() - if root.tag != 'library': - raise ValueError("Invalid XML file type") - # Get old metadata temp = tree.find('group_structure').text.strip() temp = np.array(temp.split()) @@ -89,38 +100,34 @@ if __name__ == '__main__': # Now move on to the cross section data itself for xsdata_elem in root.iter('xsdata'): - name = xsdata_elem.find('name').text.strip() + name = get_data(xsdata_elem, 'name') - temperature = xsdata_elem.find('kT') + temperature = get_data(xsdata_elem, 'kT') if temperature is not None: temperature = \ - float(temperature.text.strip()) / openmc.data.K_BOLTZMANN + float(temperature) / openmc.data.K_BOLTZMANN else: temperature = 294. temperatures = [temperature] - awr = xsdata_elem.find('awr') + awr = get_data(xsdata_elem, 'awr') if awr is not None: - awr = float(awr.text.strip()) + awr = float(awr) - representation = xsdata_elem.find('representation') - if representation is not None: - representation = representation.text.strip() - else: + representation = get_data(xsdata_elem, 'representation') + if representation is None: representation = 'isotropic' if representation == 'angle': - n_azi = int(xsdata_elem.find('num_azimuthal').text.strip()) - n_pol = int(xsdata_elem.find('num_polar').text.strip()) + n_azi = int(get_data(xsdata_elem, 'num_azimuthal')) + n_pol = int(get_data(xsdata_elem, 'num_polar')) - scatter_type = xsdata_elem.find('scatt_type') - if scatter_type is not None: - scatter_type = scatter_type.text.strip() - else: + scatter_type = get_data(xsdata_elem, 'scatt_type') + if scatter_type is None: scatter_type = 'legendre' - order = int(xsdata_elem.find('order').text.strip()) + order = int(get_data(xsdata_elem, 'order')) - tab_leg = xsdata_elem.find('tabular_legendre') + 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') @@ -128,7 +135,6 @@ if __name__ == '__main__': # 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) @@ -155,53 +161,48 @@ if __name__ == '__main__': if i != -1: xsd[i].add_temperature(temperature) - temp = xsdata_elem.find('total') + temp = get_data(xsdata_elem, 'total') if temp is not None: - temp = temp.text.strip() temp = np.array(temp.split()) total = temp.astype(np.float) total = np.reshape(total, xsd[i].vector_shape) xsd[i].set_total(total, temperature) - temp = xsdata_elem.find('absorption').text.strip() + temp = get_data(xsdata_elem, 'absorption') temp = np.array(temp.split()) absorption = temp.astype(np.float) absorption = np.reshape(absorption, xsd[i].vector_shape) xsd[i].set_absorption(absorption, temperature) - temp = xsdata_elem.find('scatter').text.strip() + temp = get_data(xsdata_elem, 'scatter') temp = np.array(temp.split()) temp = temp.astype(np.float) scatter = np.reshape(temp, xsd[i].pn_matrix_shape) xsd[i].set_scatter_matrix(scatter, temperature) - temp = xsdata_elem.find('multiplicity') + temp = get_data(xsdata_elem, 'multiplicity') if temp is not None: - temp = temp.text.strip() temp = np.array(temp.split()) temp = temp.astype(np.float) multiplicity = np.reshape(temp, xsd[i].matrix_shape) xsd[i].set_multiplicity_matrix(multiplicity, temperature) - temp = xsdata_elem.find('fission') + temp = get_data(xsdata_elem, 'fission') if temp is not None: - temp = temp.text.strip() temp = np.array(temp.split()) fission = temp.astype(np.float) fission = np.reshape(fission, xsd[i].vector_shape) xsd[i].set_fission(fission, temperature) - temp = xsdata_elem.find('kappa_fission') + temp = get_data(xsdata_elem, 'kappa_fission') if temp is not None: - temp = temp.text.strip() temp = np.array(temp.split()) kappa_fission = temp.astype(np.float) kappa_fission = np.reshape(kappa_fission, xsd[i].vector_shape) xsd[i].set_kappa_fission(kappa_fission, temperature) - temp = xsdata_elem.find('chi') + temp = get_data(xsdata_elem, 'chi') if temp is not None: - temp = temp.text.strip() temp = np.array(temp.split()) chi = temp.astype(np.float) chi = np.reshape(chi, xsd[i].vector_shape) @@ -209,9 +210,8 @@ if __name__ == '__main__': else: chi = None - temp = xsdata_elem.find('nu_fission') + temp = get_data(xsdata_elem, 'nu_fission') if temp is not None: - temp = temp.text.strip() temp = np.array(temp.split()) temp = temp.astype(np.float) if chi is not None: 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 6710c82be..0b73724c9 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 From f4731567e137ccf5850ac5b5ee77255174e8aea1 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 11 Sep 2016 06:29:45 -0400 Subject: [PATCH 22/42] Updated ipython notebook and some poor indentation --- .../pythonapi/examples/mgxs-part-iv.ipynb | 122 +++++++++--------- src/mgxs_header.F90 | 4 +- 2 files changed, 62 insertions(+), 64 deletions(-) diff --git a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb index f384afb55..478a35d8b 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": [ "" ] @@ -734,8 +732,8 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 61feb8cc6de0bcac0bab46876f2c7fe978d9fe46\n", - " Date/Time | 2016-09-10 09:22:09\n", + " Git SHA1 | e97aed325c45f5c79d64befd32e25cf1cbb0d15a\n", + " Date/Time | 2016-09-11 06:25:46\n", " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", @@ -822,20 +820,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 2.9000E-01 seconds\n", - " Reading cross sections = 1.7200E-01 seconds\n", - " Total time in simulation = 1.9592E+01 seconds\n", - " Time in transport only = 1.9464E+01 seconds\n", - " Time in inactive batches = 2.3150E+00 seconds\n", - " Time in active batches = 1.7277E+01 seconds\n", - " Time synchronizing fission bank = 1.0000E-02 seconds\n", - " Sampling source sites = 5.0000E-03 seconds\n", - " SEND/RECV source sites = 5.0000E-03 seconds\n", + " Total time for initialization = 3.1300E-01 seconds\n", + " Reading cross sections = 2.0000E-01 seconds\n", + " Total time in simulation = 1.9923E+01 seconds\n", + " Time in transport only = 1.9810E+01 seconds\n", + " Time in inactive batches = 2.3950E+00 seconds\n", + " Time in active batches = 1.7528E+01 seconds\n", + " Time synchronizing fission bank = 6.0000E-03 seconds\n", + " Sampling source sites = 6.0000E-03 seconds\n", + " SEND/RECV source sites = 0.0000E+00 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 1.9904E+01 seconds\n", - " Calculation Rate (inactive) = 21598.3 neutrons/second\n", - " Calculation Rate (active) = 11576.1 neutrons/second\n", + " Total time elapsed = 2.0258E+01 seconds\n", + " Calculation Rate (inactive) = 20876.8 neutrons/second\n", + " Calculation Rate (active) = 11410.3 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -1108,8 +1106,8 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 61feb8cc6de0bcac0bab46876f2c7fe978d9fe46\n", - " Date/Time | 2016-09-10 09:22:29\n", + " Git SHA1 | e97aed325c45f5c79d64befd32e25cf1cbb0d15a\n", + " Date/Time | 2016-09-11 06:26:07\n", " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", @@ -1163,27 +1161,27 @@ " 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.02255 1.02596 +/- 0.00270\n", - " 38/1 1.04764 1.02674 +/- 0.00271\n", - " 39/1 1.03299 1.02695 +/- 0.00263\n", - " 40/1 1.01040 1.02640 +/- 0.00260\n", - " 41/1 1.03493 1.02667 +/- 0.00253\n", - " 42/1 1.00289 1.02593 +/- 0.00256\n", - " 43/1 1.01429 1.02558 +/- 0.00250\n", - " 44/1 1.04207 1.02606 +/- 0.00248\n", - " 45/1 1.03141 1.02622 +/- 0.00241\n", - " 46/1 1.02055 1.02606 +/- 0.00235\n", - " 47/1 1.03659 1.02634 +/- 0.00230\n", - " 48/1 1.04200 1.02676 +/- 0.00228\n", - " 49/1 1.02003 1.02658 +/- 0.00222\n", - " 50/1 1.04396 1.02702 +/- 0.00221\n", + " 30/1 1.02692 1.02792 +/- 0.00319\n", + " 31/1 1.00070 1.02662 +/- 0.00330\n", + " 32/1 1.02954 1.02675 +/- 0.00315\n", + " 33/1 1.01082 1.02606 +/- 0.00308\n", + " 34/1 1.00925 1.02536 +/- 0.00304\n", + " 35/1 1.03836 1.02588 +/- 0.00296\n", + " 36/1 1.03738 1.02632 +/- 0.00288\n", + " 37/1 1.03579 1.02667 +/- 0.00279\n", + " 38/1 1.01886 1.02639 +/- 0.00270\n", + " 39/1 1.02478 1.02634 +/- 0.00261\n", + " 40/1 0.99992 1.02546 +/- 0.00267\n", + " 41/1 1.02050 1.02530 +/- 0.00259\n", + " 42/1 1.04066 1.02578 +/- 0.00255\n", + " 43/1 1.03999 1.02621 +/- 0.00251\n", + " 44/1 1.04462 1.02675 +/- 0.00249\n", + " 45/1 1.01079 1.02629 +/- 0.00246\n", + " 46/1 1.04428 1.02679 +/- 0.00245\n", + " 47/1 1.04993 1.02742 +/- 0.00246\n", + " 48/1 1.02245 1.02729 +/- 0.00240\n", + " 49/1 1.04914 1.02785 +/- 0.00240\n", + " 50/1 1.01745 1.02759 +/- 0.00236\n", " Creating state point statepoint.50.h5...\n", "\n", " ===========================================================================\n", @@ -1193,27 +1191,27 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 3.1000E-02 seconds\n", - " Reading cross sections = 6.0000E-03 seconds\n", - " Total time in simulation = 1.4773E+01 seconds\n", - " Time in transport only = 1.4743E+01 seconds\n", - " Time in inactive batches = 1.4380E+00 seconds\n", - " Time in active batches = 1.3335E+01 seconds\n", - " Time synchronizing fission bank = 5.0000E-03 seconds\n", - " Sampling source sites = 5.0000E-03 seconds\n", - " SEND/RECV source sites = 0.0000E+00 seconds\n", + " Total time for initialization = 2.4000E-02 seconds\n", + " Reading cross sections = 4.0000E-03 seconds\n", + " Total time in simulation = 1.5027E+01 seconds\n", + " Time in transport only = 1.4990E+01 seconds\n", + " Time in inactive batches = 1.4270E+00 seconds\n", + " Time in active batches = 1.3600E+01 seconds\n", + " Time synchronizing fission bank = 6.0000E-03 seconds\n", + " Sampling source sites = 3.0000E-03 seconds\n", + " SEND/RECV source sites = 3.0000E-03 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 1.4827E+01 seconds\n", - " Calculation Rate (inactive) = 34770.5 neutrons/second\n", - " Calculation Rate (active) = 14998.1 neutrons/second\n", + " Total time elapsed = 1.5074E+01 seconds\n", + " Calculation Rate (inactive) = 35038.5 neutrons/second\n", + " Calculation Rate (active) = 14705.9 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", - " k-effective (Collision) = 1.02681 +/- 0.00251\n", - " k-effective (Track-length) = 1.02702 +/- 0.00221\n", - " k-effective (Absorption) = 1.02734 +/- 0.00171\n", - " Combined k-effective = 1.02733 +/- 0.00150\n", + " k-effective (Collision) = 1.02564 +/- 0.00242\n", + " k-effective (Track-length) = 1.02759 +/- 0.00236\n", + " k-effective (Absorption) = 1.02487 +/- 0.00175\n", + " Combined k-effective = 1.02586 +/- 0.00175\n", " Leakage Fraction = 0.00000 +/- 0.00000\n", "\n" ] @@ -1295,8 +1293,8 @@ "output_type": "stream", "text": [ "Continuous-Energy keff = 1.024295\n", - "Multi-Group keff = 1.027328\n", - "bias [pcm]: -303.3\n" + "Multi-Group keff = 1.025860\n", + "bias [pcm]: -156.6\n" ] } ], @@ -1393,7 +1391,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 40, @@ -1402,9 +1400,9 @@ }, { "data": { - "image/png": "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\ngg==\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAADDCAYAAACS2+oqAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnXmYFdW1t98FgggyqoAM4gQ4RRAVpxjbCYc4RXGMI2rM\nF6PJ9cbZSGuMQzRGjfpdE40jhgzqdY7EaBvnKCoaZyOjCCKgOESi9Lp/VDUcmj5n1aH7cLrL3/s8\n/fQ5Z/9q71W7Vq2q2lWrtrk7Qggh2j7tqm2AEEKIlkEBXQghcoICuhBC5AQFdCGEyAkK6EIIkRMU\n0IUQIie0uoBuZv80s29V246vM2b2gJkd0Yzl/7+Znd2SNn0dMbN6M1u3RHlu9xX54HLi7uEfcBjw\nHPAJ8B5wP7BdlmWDem8Ezm9uPdX8S9dhIbAg/fsEeLHadmWweyzwnwKbFwA/qbZdZdg8D3gC2LqM\n5R8FxqwAO6cAXwC9Gv3+ElAPrJWxnkXAugV+Vta+AnQAzgXeSLfx9HTf3bXa27KJ7SkfbIG/8Azd\nzE4BLgcuAHoDawHXAvtEy36NuMTdu6V/Xd19s5ZuwMzat3SdwPgCm7u5+2UVaKOlGe/u3YDVgTrg\nT9U1p0kcmAwc2vCDmW0CdErLsmLNtOMOYG/gcKAnsA5wJbBnk41Vxsci5IMtSXA06UZy5Ny/hKYj\ncAXJmfsM4FdAh7RsB5KzglOA2anm6LTseJIj3RckR7u7098nAzsVHA3/ANycal4BRhS0XU96BpN+\nX+osJm3jbeBD4H+BNdPfB6XLtmvqyAmsR7KhPgI+AH5fYv2LnjkVtHMkMDWt66yCcgPOAN4B5gDj\ngR6Nlh2TLluX/n4kyRngHOCchv4C+gCfAT0L6t88bbN9kTONW6KziFJ9kW7r2WnZS8BG5WyHgm14\nAvAWMBe4Ojg7uqXg+4YkZ7Grpd97APemds5NP/dLyy4AvgI+T33pqvT3DYAJqf514MCC+vcEXk31\n04FTMp6FTQbOAv5R8NulwJmpvWs1dbYGHAU83ti/ybCvNGHDLqk/rJnB1tOAScC/SYZhN0xtm0+y\nz+3dlG+UsPkk4F/pdvhF1u0pH2y+D0Zn6NsAK6cdUIxzgJHApsCw9PM5BeV9ga5AP+A44Boz6+7u\nvwXGkWzwbu6+b5H69wZuB7qnnXNNQVnRsx0z2wm4EBgNrAlMIwmY4bLAz4CH3L0HMAD4dQltFrYD\nBpPsZOea2dD09x+RXOlsT9I/80mufgr5FskG383MNiRZ/0NJ1ql7uhzuPptkJzioYNnvkjj/ombY\n3mRfmNko4JvA+mnZwSQOuRQZtgPAt0kOPsOBg9K6S2JmHUmCyVySfoMkGP0OGEhyJfk5qb+4+znA\n48APU3872cw6k+xIt5GcbR0KXJv2M8D1wPGenI1tAjwS2VXAM0BXMxtqZu1ItsttxGfdy/hlGftK\nITsDz7r7+xm0hwB7kASjdsA9wF+ANYCTgXFmNrgMm/cDRqR/+5rZmAw2lEI+mNEHo4C+GvChu9eX\n0BwGnOfuc919LnAeUHgz4z/Az9x9kbs/CHwKDG2inmI84e4PeXK4upXkwNFAqZ3jMOAGd5/k7l+S\nnB1tY2ZrZWjzS2CQmfV39/+4+1OB/lQzm2dm89P/NxaUOVCb1vMyyZnQsLTse8DZ7v5+auP5wOg0\nADQsO9bd/+3uC0kc8h53f9rdvyIZHy3kFtK+T+s4lKTPinFwI7v7ltEXX5IcqDcyM3P3N9ODSmOy\nbIeL3P0Td59OclAaHtlMsqMcC4xu8E93n+fud7n7Qnf/DLiI5IBYjL2Aye5+iye8RDJMMTot/w+w\nsZl1dfeP0/JyuJVkh9+VZBx7ZpnLN4fVgVkNX8ysZ7qdPzKzfzfSXunuM1Mf2xro4u6XuPtX7v4o\ncB8Fw0cZuDjtrxkkV++llpUPtqAPRgF9LrB6QYBpin4kR7wGpqa/La6j0QHhc2DVoN1CZhV8/hzo\nFNhTaNfUhi9p584F+mdY9lSSvvmHmb1iZscAmNmZZvaJmS0ws8Iz6UvdvZe790z/H9OovkInK1z/\nQcBdqSPPA14jcdI+BfoZjdZpesE6/Zulz0juBjY0s7WBUcBH7v58ifX8QyO7ZzWhabIv0h39apKz\nj1lm9j9m1tR2zbIdivVPUZtJ7uf8E9iiocDMVjGz68xsipl9BDwG9DCzYgf+QcDWDf1vZvNJdv6G\n/j+A5Mxtqpk9amZbl7CrKW5L6zua5GBbMVK/bPDNASR9vGZDubvPd/eeJGehHRstXtTHUqaSbb9p\nqr7G8aAx8sEW9MEoMD5NMm63XwnNe6lRhQZmPRMp5wZRU3wOdC74Xnh0n1lol5l1IbnimEEytkix\nZd39A3f/nrv3B75Pcgm0rrtf5Etu3vygmbZDciDcI3XkBqfu0ugyubCP3ie55GxYp1XSdWqweyHw\nR5KbYIdT+uw8E8X6Ii272t23ADYmueo6tYkqSm2H5tg1L7Wn1swanP+/SYa2tkwvwRvOjBp2psb+\nNp3k3kRh/3dz9x+mbUx09/1Ihh7uJunbcmycRjJGvQdwZxOSzyjuv8tUF7TVtcA3ZwB/A7Y0s6aC\naePgUlj3TJLhgkLWItnPs9pcuPxaNPPKRD6Y3QdLBnR3X0ByE+AaM9s3PfqsZGZ7mNnFqWw8cI6Z\nrW5mqwM/JXsgmU1y06ccCp3xReAwM2tnZruT3IRt4HbgGDPb1MxWJhlDe8bdp7v7hyQOeni67BiS\nGy9JA2ajzazh6P0RyU2T5R2HLjUsdB1wYcOln5mtYWaFTw81XvbPwN5mtrWZdSAZ3mrMrSRnhHuT\nnCE2i2J9YWZbmNlIM1uJ5GbaFzTdR0W3Q3Ntc/c3ScZ6T09/6prassDMegG1jRZp7G/3AUPM7PDU\nrzuk67VB+vkwM+vmyT2IT0huaJXLGJIbl42HOSC5ibd/ul+tT3L5Xoyy9hV3/yvJ0MH/ptupQ7qt\ntqH0weFZ4DMzOy3tkxqSYYHfl2HzqWbWw8wGktwnajxeXRbywew+GA5duPuvSJ5SOYfkzu004Acs\nuVF6AfA80DA+/Dzw81JVFny+gWR8aJ6Z3dlEebT8j0luKs4nGae7q8DuR0gOLneSBO91SG7+NHA8\nyd39D0nuVD9ZULYl8KyZLUjX82R3n0pxTksvdRekl70fFLG38fcrSY66E8zsY+ApkpvKTS7r7q+R\nPEHwB5Kzjo9JtsnCAs1TJA7/QnqGuDwUtlusL7oBvyV5FncyST8u88hZhu1Qqn+ycBlwfHoycQXJ\n2eOHJH35QCPtlcCBZjbXzK5w909JhqYOIenPmcDFLBmSOAKYnF46f4/kJnMWFq+Du0929xeaKiN5\nQuNLkmHFG1n2ANzcfWV/koBxG8k+8i7JfrJbkTZIx5j3IXm64kOSIY0j3P3tjDZD4tMTgRdIHmT4\nXWBnU8gHE8ryQXNv7qiHqBbppeNHJHf5pxb8/jdgnLsvz44kxHJjZvUk/vhutW35OtLqUv9Facxs\nr/RytwvwS+DlRsF8S2AzkrN4IcTXCAX0tse+JJdlM0jG/RdfOprZTSTPtP4ovZMvxIpGl/xVREMu\nQgiRE3SGLoQQOWGlSlSaPkJ4BckB4wZ3v6QJjS4NREVx9+a+3GoZ5NuiNVDMt1t8yMWSLM63SN4l\nMZPktbuHuPsbjXTO6QVtP1EL36xdurIst/WyvJtt7Xgdn99841BzUKNn+ufVXkuv2qXzi87yC8N6\njvvjuFBzyME3lix/i1Kv1kgYuEzCH7xRewcb1B6w+PtJfnVYzy73R28+YOmHPouxVQbNdU1sq7dr\nYXDt4q8/fvDiZTWNuMLOavGAXo5vH+BLEkNfq72TjWr3X/z92gw5aX2e+iQ2aOUMRj8W+37dKctu\nmBtr3+OY2iWJlNvPfy6s5/Ce14eacXOOCzXv9e4Val5nw2V+u6V2GkfWLsnmX5P4NTZPsW2ombgk\nEbQoWaLow77zUt/n115Lz0bxY3K7Um9ZgVGjVmXChPWK+nYlhlxGAm+7+9T0mdbxJDfyhGjryLdF\nq6YSAb0/S78LYgblvQdCiNaKfFu0aioxht7UpUDTVyRP1C75vHKPCphSWVap2bLaJpTN6jXLXqq2\nenrVhJLpde8yo67iuSyZffu12iWvbunQo3NTklbN8Jqu1TahbIbVdK+2CWXRKXP8eI4kAR/eeafx\ne9WWphIBfQbJC3kaGECxl/M0HjNvY7TNgL5RtU0on9VqQsnAmnUZWLPkFRnPnlfOq8szk9m3C8fM\n2yKb1XSrtgll09YCevb4sWX6B+uvvyrvvntVUWUlhlyeA9Y3s0GWvAD+EJIX5gvR1pFvi1ZNi5+h\nu/siM/shScZiw6Ndr7d0O0KsaOTborVTkefQ3f0vlDcrkRBtAvm2aM1ULfXfzJy+QdvfzlDRjhk0\nW8TraKs29brqpXmhf6lZqRKm+tqhZu9XHw414zYpPQY73RvPQbAs5/z9l6Fm0QfxRO+nj64NNU95\n/Dzvkz/bJdQcee7/hJpDLE5Q2NMeq0hiURbMzB/wHYqWf8jqYR2X+U9CzcvTRoSah9baOdQ8bduE\nmuEZZt/bnImhZsCx80KNXxBKeK7fJqHmQfYINaN8QqjZ9tgXY4PO/TLWjOwQSrac/feS5VvRk6vb\nDVuhz6ELIYSoAgroQgiRExTQhRAiJyigCyFETlBAF0KInKCALoQQOUEBXQghcoICuhBC5ITqJhb9\nvvTL3NvVxPMcn9DnulBz9bw4SYO5cQ6KDV4Uar5vV4aaSfXDQs3TVlOy/BBuDuv4/eQxocbWidfJ\nr4qTj/Y5OU72uX/S6FCz6uA5oWbPLg+Emj/aMVVNLHq+vvhbLbdof0Vcx+NxEtaCzeNElc6vZ0iq\nGx77AJPic79Jw+JJV4bxZmzPDXFb9etk2F93iterfl7s2ytNjuvZYPM4+eiNCzcLNW+evVbJ8s58\ni4F2uxKLhBAi7yigCyFETlBAF0KInKCALoQQOUEBXQghcoICuhBC5AQFdCGEyAkVmbEoM4eVfpa0\n/qx4tvTeF54aamxR6efdAbbs9USoGcnlsT18GGrusu+EGq5cULL49wfEVdSuc3qsuS1+DveWkw4M\nNfcSP2Pu98RtnfvTM0JNlokLqs1E27xo2b6LYh+5zAeEmi72VQZD4nO2N4avE2pmDosnwbiUeF98\nYHLsA08eGz+vvd018XPfD+4at7VHv1BC/fRY8wPqQs0bB8cT5NRSW7L8G/QHbi9arjN0IYTICQro\nQgiRExTQhRAiJyigCyFETlBAF0KInKCALoQQOUEBXQghcoICuhBC5ITqTnDxSumEn3rPcLyJ5zqA\n7hnmOdgw7ocvtoirmdJlUKg5l/NDzWn+i5LlH9EjrGNNez/U3ODHhpp17d1Q87JvGmpO5OpQM5bz\nQs09vzgk1HBGu6pOcFF/R/HyL+Muhymx5K2u64aaje+Lt92pe8f+eOGCc2N7usf2fFDfO9RstNIz\noea1r7YONTtuGtdj80MJvn/sRn5SXE/7K+KJMk69tvS2GMJ6HG9HaIILIYTIOwroQgiRExTQhRAi\nJyigCyFETlBAF0KInKCALoQQOUEBXQghcoICuhBC5ISKJBaZ2RTgY6Ae+NLdRzahcW4qnVjUcc+P\nw7a+WL17qJmdIQmnzwOfhBr2jBMDxlk8c087j2dQOpQ7SwvOi4/Fd48dFWr25S+hZqr1CTU3+HGh\n5nx+Hmqu5vhQc/KY60MNN1lFEouy+vbri9YqWseQbeMpcOzp2NfG236hxuvjLjjU7go1XBT7m38n\nbss2iNfrsy/imYY6nxBKsJvjthgTr9eC33QINd1WWhhqzvLaUHPx2aU1owbDhGOLJ81Vagq6eqDG\n3TPkYQnRppBvi1ZLpYZcrIJ1C1FN5Nui1VIpx3TgITN7zszia2gh2g7ybdFqqdSQy7buPsvM1gD+\namavu/sTFWpLiBWJfFu0WioS0N19Vvp/jpndBYwElnX6u2qXfN6gBjasqYQ54uvA+3Uwq67izWT1\n7avP+2jx55E7dGJkTaeK2yZyytQ6mFYHwDuvlZa2eEA3s85AO3f/1My6AKOgyDtRv1Pb0s2Lrytr\n1iR/DUyKX8NbLuX49g/Hxk9WCZGJQTXJH7D+YHj3nuKv2K3EGXof4C4z87T+ce4+oQLtCLGikW+L\nVk2LB3R3nwwMb+l6hag28m3R2qnujEVWOsGi13/ier7R/pVQ05dZoWb8zDGhxmdmyFPpGvfn/UN3\nDDV73lRXsvydo/uHdTxmO4Savfy+ULPI4kSPLPys/qeh5jcv/Ciu6MoM2+G2yiQWZcHM/CY/sGh5\njT8a1jHwpbmhZtrw1UPNoAfnhJqJe2wUas7golBzTobEsZs4KtRMIE6IOz2Y0Qvg5KviBDRbJ95f\nM0zGBR9lmNUowyjct9f+c8nyEfTmwnbba8YiIYTIOwroQgiRExTQhRAiJyigCyFETlBAF0KInKCA\nLoQQOUEBXQghcoICuhBC5ISqJhb9qv57JTUPsVtYT397L9Qc4HeEmt3HPRZqxn93n1BzyJR7Qs0X\nvUMJ93beq2T57XZoWMfJ/DrUrMu/Qs3bPiTU7DL5yVDDG7Fkwh7bh5rd7/h7XNGB1U0suqN+96Ll\n33k1niWKXrHkyX6bhZr3PU5Au8f2DjUneexLGy0M3hwFdFgYx5t9ugezdQE3cXSomedxJ35InJy1\nzcfPhZrp3fuGmsGnxLGqywUflizfuX1H7l6lpxKLhBAi7yigCyFETlBAF0KInKCALoQQOUEBXQgh\ncoICuhBC5AQFdCGEyAkK6EIIkROqmlhkbywqqTllSDwDyqWcEzf2SIbj1lEZclCml7YX4JX2cVub\nHBe3ZdcFba0ft+OnZmjnhHidbuHgUHPkn0rPtALAgXFb72fIqOl/2Py4rfHVTSz6dX3xGbBOnHBj\nXMmouK++z5Wh5tp5p4Sadr3itq6yE0LN+/X9Qs1FNja255FQwvY7xVO5PpZh5qPn+Uao2eSzOGGq\nU5e4D7clnqmqHzNLlg9jTca220WJRUIIkXcU0IUQIicooAshRE5QQBdCiJyggC6EEDlBAV0IIXKC\nAroQQuQEBXQhhMgJK1Wz8SuGlE5WOOWDy8M6hvQ+MtT8Y6erQk3H6f8JNZ/w21CzxaLjQ807TA81\n+01oX7L8srdPDOs4bdI1oab+W6XbAdj58Z6hZv7ojqGmxx5xWzc9eHKoYXxtrKkyJ078XdGyR0dt\nHS6/gOIzHjUwwOKkmON6xTMNXUqXUHM7D4Sabds9FWom+dBQM22neaFm0CMfhBofGPvbA4N/Emq2\nuPzVuK0D47YO26B4slkDJ59bOsZ8un7p5XWGLoQQOUEBXQghcoICuhBC5AQFdCGEyAkK6EIIkRMU\n0IUQIicooAshRE5QQBdCiJyw3DMWmdkNwF7AbHffNP2tJ/AHYBAwBTjI3T8usrzbw6Vn+fivnS4M\n7Rht8Uw5g3kr1Bzsfwg1f52zT6i5LkOi0xY+MdQM+7h0MsMDPeLZWJ707ULNL26LZ5D5cu9Qwivx\nREOM6B1r3pg1KNR8128NNS+2+9Zyz1jUEr7ts4rXn8Wqm3sfFGomZJiRZy/uDTXrMjnUfOlxDuLI\nBS+GmrO7nxdqZtMn1DzsO4eamScHWTjAGb+O/X+ovxlqjpkzPtT81xpxPLtmbumEwV07tOfBHqtW\nZMaiG4HdGv12BvCwuw8FHgHObEb9QlQL+bZokyx3QHf3J4DGkzvuC9ycfr4Z2G956xeiWsi3RVul\npcfQe7v7bABPLjrXaOH6hagW8m3R6tFNUSGEyAkt/bbF2WbWx91nm1lfoOQr0fzmghskw3bAhte0\nsDni68IndS/yaV18U64ZlOXbtZcu+VyzLdTE96eFaJL6Jx/Hn3wCgLfblb6j3tyAbulfA/cARwOX\nAEcBd5dc+Kj4DrMQWehasxldazZb/H3W+Tc1t8pm+Xbtqc1tXoiEdtttD9ttD8DgDu1555KLimuX\ntxEzux14ChhiZtPM7BjgYmBXM3sT2CX9LkSbQr4t2irLfYbu7ocVKdpleesUojUg3xZtleVOLGp2\nw2Y+oL70A/vX8v/Cevbi4bixkfGFyM8nxtkeZy8qnQgFwGlxW2//YkCoGcy0kuXz6BzWscpnC2NN\nl3idXmO9ULPhelNCjf0rbuuLz+P+e6nLsFCzrU1a7sSi5mJm/rP6U4qW//iLK8I6unT6KtRMsnj2\nn1X901CzHu+Fml0zJChNGBg/yWnTYx9YsGjlUNPp07h/OnaP23rBNg41WZKYTiOeFe0xi2eq+rMf\nULJ8A9bmpHYHVySxSAghRCtCAV0IIXKCAroQQuQEBXQhhMgJCuhCCJETFNCFECInKKALIUROUEAX\nQoicUNXEojm+SknNLRwV1rNN/dOxZtdJocZ/GkpgXoY8lVXj/hy/azzz0cFblU7kuPXZ0WEdR078\nU6jxd+N1mn9gnOix2vNfhJr6DP138agfhZqzz7081HBBu6omFtkqxZNanvxsRFjHHZROMAGYbgND\nzQlcF2rme89Q847FyWX13j7UHJFhtqn+M+aFmgx5TrBLhs2/a4b41yGW+Li4rTe3WivUbDSt9Oxq\nozoZE/p2VGKREELkHQV0IYTICQroQgiRExTQhRAiJyigCyFETlBAF0KInKCALoQQOUEBXQghckJz\nJ4luFr9jTMny13yjsI4fXx4nTvjD9bExF8XHtifO3CzUjOaOUDORzUON3Vs64eFzK52UBTB+8ziB\n6dDX7wk1PQ+PZz7y2+I+bh/nd8GEDJqvqpIvVBbf+fT2omXbHfBCuPx377g+1Iz3OPGO948JJc/0\ni2eA+iebhJoBNiPUnGDx/nrTwKNDTfsfxDMW9Xwy9tvzZsS+NDbDTGXvs1qoGfrX0rOQAfBokMU0\nuHSxztCFECInKKALIUROUEAXQoicoIAuhBA5QQFdCCFyggK6EELkBAV0IYTICQroQgiRE6o6Y9H5\n/t8lNbdyeFjPxX5mqNnv+odCzfPHbhxqtrSXQw3PxsdIHx0nM9j00skM13NEWMexexRPblnczoNx\n0oTPi9fpll4HhZqXGB5qHvUdQ83L7bcKNVDdGYsYXSLR6s8Ztv/VcaLWom4Z8gJ7xRL2jH3gftsl\n1IzwOGFqTeLZiOZZ51Bzno8NNVdyeqjh3Qz76wnx9hr/cJzEd5/vHWreo3/J8i1ZjV+2G6kZi4QQ\nIu8ooAshRE5QQBdCiJyggC6EEDlBAV0IIXKCAroQQuQEBXQhhMgJCuhCCJETljuxyMxuAPYCZrv7\npulvY4HjgQ9S2Vnu/pciy/sAf7NkGwtZObRjHSaHmq6+INT8hu/FbT32Qaix7hn6c3wsqQ+SGf62\n7rZhHev5O6Fm7Q/idVq4arxOb3YeEmo2e+2NULPjRveHmkcHfzvU8K/lTyxqCd8+pP6GovWPf++w\n2IgPY9+/adjBoWYm/ULN39gp1Bxu40JNHTuEmin164Sax+dsH2o6dopnI+rbbXao2Yt7Q80R3BZq\nDufWUPPO2ZuGmjkXdilZ3oFd6G73VSSx6EZgtyZ+v9zdR6R/TTq8EK0c+bZokyx3QHf3J4D5TRS1\n/gkfhSiBfFu0VSoxhn6imb1kZtebWfcK1C9EtZBvi1ZNhrf7lMW1wPnu7mZ2AXA5cGwx8ce1v178\neeWakXSqyfLSJSGa4N91yV/lKMu3X6m9e/Hn3jVD6VOzQSVtEznmibpFPFmXvKytPaXvO7ZoQHf3\nOQVffwul7zh0rz2pJZsXX2dWqUn+Gph/fotWX65vf6N23xZtX3x9+WZNe75Z0x6ADgzl4vPeLqpt\n7pCLUTCuaGZ9C8r2B/7ZzPqFqBbybdHmWO4zdDO7HagBVjOzacBYYEczGw7UA1OAE1rARiFWKPJt\n0VZZ7oDu7k09THtjM2wRolUg3xZtlarOWMQzpWdlGbbVM2E9B3BHqLmDA0LNbsSzGo30f4SaA/94\nX6jZ66A/hZpLgtlWnrX4BvKV/CjUXOY/CTW11Iaa4fZiqPnKO4SaPy6KZz6a1+H1UAOjqjtjkf2m\nuGCH4+JKajKYvna87/Y96t1QM8SLj8k28PcDmnosf2nWuHNaqNnQ42339zFxW9x8XijpNC++R/fF\nNRmmdBoQS7Jo9tjpzlDzE7usZHkvtmIzu1IzFgkhRN5RQBdCiJyggC6EEDlBAV0IIXJC6wnoE+uq\nbUHZ/LNubrVNKJtP6l6otgll8+VjT1fbhOYRvFW0NfJR3cvVNqF8fEq1LSiLuXUtn8rQegL6C3XV\ntqBsXq2bV20TyubTuvhplNZGmw/oQbp2a6RNBnSmVNuAsphX92qL19l6AroQQohm0dIv5yqLEZ2X\nfJ7ZAfp1Xrp8CKVf9g7Ql/6hZsMM9fRnzVDTg/WX+t6Jucv8NqJnWA3rEYs6sUnJ8tWIJwpoar2/\nosNSv3dlaFjPELqGmoH0CTVfZXC3YSz7rPpk2rFOwe8fj4jteaHKI0sjRqy++PPMmZ3p12/JdwZn\nqCB2R8jwCPVqdAw1g+i2zG+fsDJDCn7/dN24rZ4Z2lqnibYa8+mguC1GLNtBM2euSr9+S35fuX37\nsJqFfUNJpn7OsIuwPj2W+j6XTsv8Fu2PqwTxrrqJRUJUkKomFglRQYr5dtUCuhBCiJZFY+hCCJET\nFNCFECIntIqAbma7m9kbZvaWmZV+K1UrwcymmNkkM3vRzOK3dlUBM7vBzGab2csFv/U0swlm9qaZ\nPdSaplIrYu9YM5thZi+kf7tX08ZyaWu+Lb+uDCvKt6se0M2sHXA1ySzrGwOHmllbmK+rHqhx983c\nfWS1jSlCU7PXnwE87O5DgUeAM1e4VcVpyl6Ay919RPr3lxVt1PLSRn1bfl0ZVohvVz2gAyOBt919\nqrt/CYwH2sL8XUbr6L+iFJm9fl/g5vTzzcB+K9SoEhSxFwpmDmpjtEXfll9XgBXl261hw/UHphd8\nn5H+1tpx4CEze87Mjq+2MWXQ291nA7j7LGCNKtuThRPN7CUzu761XUoHtEXfll+vWFrUt1tDQG/q\nCNUWnqXaT6e4AAABQElEQVTc1t23APYk2SjfrLZBOeVaYD13Hw7MAi6vsj3l0BZ9W3694mhx324N\nAX0GsFbB9wHAzCrZkpn0LKBhNvi7SC6v2wKzzawPLJ74+IMq21MSd5/jS5IlfgtsWU17yqTN+bb8\nesVRCd9uDQH9OWB9MxtkZh2BQ4B7qmxTScyss5mtmn7uAoyi9c4Cv9Ts9SR9e3T6+Sjg7hVtUMBS\n9qY7ZwP703r7uSnalG/LrytOxX27qu9yAXD3RWb2Q2ACyQHmBvcMEw9Wlz7AXWmK90rAOHefUGWb\nlqHI7PUXA38yszHANODA6lm4NEXs3dHMhpM8fTEFOKFqBpZJG/Rt+XWFWFG+rdR/IYTICa1hyEUI\nIUQLoIAuhBA5QQFdCCFyggK6EELkBAV0IYTICQroQgiRExTQhRAiJyigCyFETvg/x/buHexobAUA\nAAAASUVORK5CYII=\n", "text/plain": [ - "" + "" ] }, "metadata": {}, diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 46c4bcb50..62a212f91 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -531,7 +531,7 @@ module mgxs_header ! Finally convert the legendre to tabular if needed allocate(scatt_coeffs(groups)) if (this % scatter_type == ANGLE_LEGENDRE .and. & - legendre_to_tabular) then + legendre_to_tabular) then this % scatter_type = ANGLE_TABULAR order_dim = legendre_to_tabular_points order = order_dim @@ -889,7 +889,7 @@ module mgxs_header ! Finally convert the legendre to tabular if needed allocate(scatt_coeffs(groups, this % n_azi, this % n_pol)) if (this % scatter_type == ANGLE_LEGENDRE .and. & - legendre_to_tabular) then + legendre_to_tabular) then this % scatter_type = ANGLE_TABULAR order_dim = legendre_to_tabular_points order = order_dim From fd69421a5bc2bbd51870f4f5f2ae4bd90f43ae3a Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 12 Sep 2016 19:45:52 -0400 Subject: [PATCH 23/42] Resolved @samuelshaner comments --- .gitignore | 4 ++++ openmc/mgxs/library.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 724e13703..21db60397 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,7 @@ docs/source/pythonapi/examples/mgxs docs/source/pythonapi/examples/tracks docs/source/pythonapi/examples/fission-rates docs/source/pythonapi/examples/plots + +# VSCode workspace directory +.vscode +.vscode/* diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index a04ec8c55..f63d77327 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -1006,7 +1006,7 @@ class Library(object): 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 te library will be + of nested temperature tables. Every dataset in the library will be treated as if it was at the same default temperature. Parameters @@ -1105,7 +1105,7 @@ class Library(object): 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 te library will be treated as if it was at the same + Every dataset in the library will be treated as if it was at the same default temperature. Parameters From 697dfb09c431f190ccebc7d7c307ce347c8c4474 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Thu, 15 Sep 2016 20:49:03 -0400 Subject: [PATCH 24/42] Merged with latest changes and added interpolation to the MG library --- src/mgxs_header.F90 | 420 +++++++++++------- .../results_true.dat | 14 +- .../results_true.dat | 14 +- tests/test_mgxs_library_hdf5/results_true.dat | 24 +- tests/test_mgxs_library_mesh/results_true.dat | 52 +-- .../results_true.dat | 26 +- 6 files changed, 321 insertions(+), 229 deletions(-) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 62a212f91..56fbb5965 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -94,7 +94,7 @@ module mgxs_header 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(in) :: method ! Type of temperature access + 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? @@ -206,7 +206,7 @@ module mgxs_header 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(in) :: method ! Type of temperature access + 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 @@ -244,6 +244,16 @@ module mgxs_header ! 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 select case (method) case (TEMPERATURE_NEAREST) @@ -264,8 +274,28 @@ module mgxs_header end do TEMP_LOOP case (TEMPERATURE_INTERPOLATION) - ! TODO: Get bounding temperatures - call fatal_error("Temperature interpolation not yet implemented") + ! 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 @@ -369,7 +399,7 @@ module mgxs_header 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(in) :: method ! Type of temperature access + 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? @@ -660,7 +690,7 @@ module mgxs_header 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(in) :: method ! Type of temperature access + 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? @@ -1196,7 +1226,8 @@ module mgxs_header real(8), allocatable :: temp_mult(:, :), mult_num(:, :), mult_denom(:, :) real(8), allocatable :: scatt_coeffs(:, :, :) integer :: nuc_t - real(8) :: temp_actual, temp_desired + integer, allocatable :: nuc_ts(:) + real(8) :: temp_actual, temp_desired, interp integer :: scatter_type type(Jagged2D), allocatable :: nuc_matrix(:) integer, allocatable :: gmin(:), gmax(:) @@ -1243,12 +1274,16 @@ module mgxs_header ! 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) - nuc_t = minloc(abs(nuc % kTs - temp_desired), dim=1) - temp_actual = nuc % kTs(nuc_t) + 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) >= tolerance) then call fatal_error("MGXS library does not contain cross sections & &for " // trim(this % name) // " at or near " // & @@ -1256,80 +1291,106 @@ module mgxs_header end if case (TEMPERATURE_INTERPOLATION) - ! TODO: Get bounding temperatures - call fatal_error("Temperature interpolation not yet implemented") - end select + ! 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 - ! Copy atom density of nuclide in material - atom_density = mat % atom_density(i) + 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.") + end select select type(nuc) type is (MgxsIso) - ! Perform our operations which depend upon the type - ! Add contributions to total, absorption, and fission data (if necessary) - this % xs(t) % total = this % xs(t) % total + & - atom_density * nuc % xs(nuc_t) % total - this % xs(t) % absorption = this % xs(t) % absorption + & - atom_density * nuc % xs(nuc_t) % absorption - if (nuc % fissionable) then - this % xs(t) % chi = this % xs(t) % chi + & - atom_density * nuc % xs(nuc_t) % chi - this % xs(t) % nu_fission = this % xs(t) % nu_fission + & - atom_density * nuc % xs(nuc_t) % nu_fission - if (allocated(nuc % xs(nuc_t) % fission)) then - this % xs(t) % fission = this % xs(t) % fission + & - atom_density * nuc % xs(nuc_t) % fission + 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 - 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 - end if - end if - ! We will next gather the multiplicaity 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 - 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) - else - ! Avoid division by zero - mult_denom(gout, gin) = mult_denom(gout,gin) + atom_density + ! 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 - end do - end do + 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 - ! 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 * nuc_matrix(gin) % data(1:nuc_order_dim, gout) + ! We will next gather the multiplicaity 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 @@ -1396,7 +1457,8 @@ module mgxs_header real(8), allocatable :: temp_mult(:, :, :, :), mult_num(:, :, :, :) real(8), allocatable :: mult_denom(:, :, :, :), scatt_coeffs(:, :, :, :, :) integer :: nuc_t - real(8) :: temp_actual, temp_desired + integer, allocatable :: nuc_ts(:) + real(8) :: temp_actual, temp_desired, interp integer :: scatter_type type(Jagged2D), allocatable :: nuc_matrix(:) integer, allocatable :: gmin(:), gmax(:) @@ -1472,107 +1534,137 @@ module mgxs_header ! 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) - nuc_t = minloc(abs(nuc % kTs - temp_desired), dim=1) - temp_actual = nuc % kTs(nuc_t) - if (abs(temp_actual - temp_desired) >= 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) - ! TODO: Get bounding temperatures - call fatal_error("Temperature interpolation not yet implemented") - end select + 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) >= 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.") + end select ! Copy atom density of nuclide in material atom_density = mat % atom_density(i) select type(nuc) type is (MgxsAngle) - ! Perform our operations which depend upon the type - ! Add contributions to total, absorption, and fission data (if necessary) - this % xs(t) % total = this % xs(t) % total + & - atom_density * nuc % xs(nuc_t) % total - this % xs(t) % absorption = this % xs(t) % absorption + & - atom_density * nuc % xs(nuc_t) % absorption - if (nuc % fissionable) then - this % xs(t) % chi = this % xs(t) % chi + & - atom_density * nuc % xs(nuc_t) % chi - this % xs(t) % nu_fission = this % xs(t) % nu_fission + & - atom_density * nuc % xs(nuc_t) % nu_fission - if (allocated(nuc % xs(nuc_t) % fission)) then - this % xs(t) % fission = this % xs(t) % fission + & - atom_density * nuc % xs(nuc_t) % fission + 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 - 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 + ! 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 - end if - ! We will next gather the multiplicaity 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. + ! We will next gather the multiplicaity 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 - 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 * & - 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 - end if + ! 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 - 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 * nuc_matrix(gin) % data(1:nuc_order_dim, gout) - end do ! gout - end do ! gin - end do ! iazi - end do ! ipol + ! 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 diff --git a/tests/test_mgxs_library_condense/results_true.dat b/tests/test_mgxs_library_condense/results_true.dat index cd84d0a3a..5b02ce3db 100644 --- a/tests/test_mgxs_library_condense/results_true.dat +++ b/tests/test_mgxs_library_condense/results_true.dat @@ -61,13 +61,13 @@ 3 10000 4 1 total 0.002752 0.000240 4 10000 5 1 total 0.001231 0.000105 5 10000 6 1 total 0.000512 0.000044 - material delayedgroup group in nuclide mean std. dev. -0 10000 1 1 total 0.000000 0.000000 -1 10000 2 1 total 0.032739 0.028454 -2 10000 3 1 total 0.120780 0.170809 -3 10000 4 1 total 0.302780 0.109110 -4 10000 5 1 total 0.000000 0.000000 -5 10000 6 1 total 0.000000 0.000000 + material delayedgroup group in nuclide mean std. dev. +0 10000 1 1 total 0.000000e+00 0.000000e+00 +1 10000 2 1 total 3.273900e-10 2.845437e-10 +2 10000 3 1 total 1.207800e-09 1.708087e-09 +3 10000 4 1 total 3.027800e-09 1.091095e-09 +4 10000 5 1 total 0.000000e+00 0.000000e+00 +5 10000 6 1 total 0.000000e+00 0.000000e+00 material group in nuclide mean std. dev. 0 10001 1 total 0.311594 0.013793 material group in nuclide mean std. dev. diff --git a/tests/test_mgxs_library_distribcell/results_true.dat b/tests/test_mgxs_library_distribcell/results_true.dat index 87f18db1c..dba6ae60d 100644 --- a/tests/test_mgxs_library_distribcell/results_true.dat +++ b/tests/test_mgxs_library_distribcell/results_true.dat @@ -61,10 +61,10 @@ 3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 4 1 total 0.002727 0.000135 4 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 5 1 total 0.001210 0.000058 5 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 6 1 total 0.000504 0.000024 - avg(distribcell) delayedgroup group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 0.000000 0.000000 -1 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 2 1 total 0.032739 0.046300 -2 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 3 1 total 0.120780 0.170809 -3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 4 1 total 0.000000 0.000000 -4 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 5 1 total 0.000000 0.000000 -5 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 6 1 total 2.853000 4.034751 + avg(distribcell) delayedgroup group in nuclide mean std. dev. +0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 0.000000e+00 0.000000e+00 +1 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 2 1 total 3.273900e-10 4.629994e-10 +2 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 3 1 total 1.207800e-09 1.708087e-09 +3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 4 1 total 0.000000e+00 0.000000e+00 +4 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 5 1 total 0.000000e+00 0.000000e+00 +5 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 6 1 total 2.853000e-08 4.034751e-08 diff --git a/tests/test_mgxs_library_hdf5/results_true.dat b/tests/test_mgxs_library_hdf5/results_true.dat index 8cec5c629..0e57dbaf3 100644 --- a/tests/test_mgxs_library_hdf5/results_true.dat +++ b/tests/test_mgxs_library_hdf5/results_true.dat @@ -112,18 +112,18 @@ domain=10000 type=beta [ 1.82980497e-04 4.50738567e-04] [ 7.48899920e-05 1.88812772e-04]] domain=10000 type=decay-rate -[[ 0. 0. ] - [ 0. 0.032739] - [ 0. 0.12078 ] - [ 0. 0.30278 ] - [ 0. 0. ] - [ 0. 0. ]] -[[ 0. 0. ] - [ 0. 0.02845437] - [ 0. 0.17080871] - [ 0. 0.10910951] - [ 0. 0. ] - [ 0. 0. ]] +[[ 0.00000000e+00 0.00000000e+00] + [ 0.00000000e+00 3.27390000e-10] + [ 0.00000000e+00 1.20780000e-09] + [ 0.00000000e+00 3.02780000e-09] + [ 0.00000000e+00 0.00000000e+00] + [ 0.00000000e+00 0.00000000e+00]] +[[ 0.00000000e+00 0.00000000e+00] + [ 0.00000000e+00 2.84543737e-10] + [ 0.00000000e+00 1.70808714e-09] + [ 0.00000000e+00 1.09109511e-09] + [ 0.00000000e+00 0.00000000e+00] + [ 0.00000000e+00 0.00000000e+00]] domain=10001 type=total [ 0.31373767 0.3008214 ] [ 0.0155819 0.02805245] diff --git a/tests/test_mgxs_library_mesh/results_true.dat b/tests/test_mgxs_library_mesh/results_true.dat index 8ad0f2eee..bf34b196d 100644 --- a/tests/test_mgxs_library_mesh/results_true.dat +++ b/tests/test_mgxs_library_mesh/results_true.dat @@ -208,29 +208,29 @@ 21 2 2 1 4 1 total 0.002143 0.001028 22 2 2 1 5 1 total 0.001026 0.000492 23 2 2 1 6 1 total 0.000408 0.000196 - mesh 1 delayedgroup group in nuclide mean std. dev. - x y z -0 1 1 1 1 1 total 0.00000 0.000000 -1 1 1 1 2 1 total 0.00000 0.000000 -2 1 1 1 3 1 total 0.00000 0.000000 -3 1 1 1 4 1 total 0.30278 0.428196 -4 1 1 1 5 1 total 0.00000 0.000000 -5 1 1 1 6 1 total 0.00000 0.000000 -6 1 2 1 1 1 total 0.00000 0.000000 -7 1 2 1 2 1 total 0.00000 0.000000 -8 1 2 1 3 1 total 0.00000 0.000000 -9 1 2 1 4 1 total 0.00000 0.000000 -10 1 2 1 5 1 total 0.00000 0.000000 -11 1 2 1 6 1 total 0.00000 0.000000 -12 2 1 1 1 1 total 0.00000 0.000000 -13 2 1 1 2 1 total 0.00000 0.000000 -14 2 1 1 3 1 total 0.00000 0.000000 -15 2 1 1 4 1 total 0.00000 0.000000 -16 2 1 1 5 1 total 0.00000 0.000000 -17 2 1 1 6 1 total 0.00000 0.000000 -18 2 2 1 1 1 total 0.00000 0.000000 -19 2 2 1 2 1 total 0.00000 0.000000 -20 2 2 1 3 1 total 0.00000 0.000000 -21 2 2 1 4 1 total 0.00000 0.000000 -22 2 2 1 5 1 total 0.00000 0.000000 -23 2 2 1 6 1 total 0.00000 0.000000 + mesh 1 delayedgroup group in nuclide mean std. dev. + x y z +0 1 1 1 1 1 total 0.000000e+00 0.000000e+00 +1 1 1 1 2 1 total 0.000000e+00 0.000000e+00 +2 1 1 1 3 1 total 0.000000e+00 0.000000e+00 +3 1 1 1 4 1 total 3.027800e-09 4.281956e-09 +4 1 1 1 5 1 total 0.000000e+00 0.000000e+00 +5 1 1 1 6 1 total 0.000000e+00 0.000000e+00 +6 1 2 1 1 1 total 0.000000e+00 0.000000e+00 +7 1 2 1 2 1 total 0.000000e+00 0.000000e+00 +8 1 2 1 3 1 total 0.000000e+00 0.000000e+00 +9 1 2 1 4 1 total 0.000000e+00 0.000000e+00 +10 1 2 1 5 1 total 0.000000e+00 0.000000e+00 +11 1 2 1 6 1 total 0.000000e+00 0.000000e+00 +12 2 1 1 1 1 total 0.000000e+00 0.000000e+00 +13 2 1 1 2 1 total 0.000000e+00 0.000000e+00 +14 2 1 1 3 1 total 0.000000e+00 0.000000e+00 +15 2 1 1 4 1 total 0.000000e+00 0.000000e+00 +16 2 1 1 5 1 total 0.000000e+00 0.000000e+00 +17 2 1 1 6 1 total 0.000000e+00 0.000000e+00 +18 2 2 1 1 1 total 0.000000e+00 0.000000e+00 +19 2 2 1 2 1 total 0.000000e+00 0.000000e+00 +20 2 2 1 3 1 total 0.000000e+00 0.000000e+00 +21 2 2 1 4 1 total 0.000000e+00 0.000000e+00 +22 2 2 1 5 1 total 0.000000e+00 0.000000e+00 +23 2 2 1 6 1 total 0.000000e+00 0.000000e+00 diff --git a/tests/test_mgxs_library_no_nuclides/results_true.dat b/tests/test_mgxs_library_no_nuclides/results_true.dat index 961ae9ba9..e4e562032 100644 --- a/tests/test_mgxs_library_no_nuclides/results_true.dat +++ b/tests/test_mgxs_library_no_nuclides/results_true.dat @@ -123,19 +123,19 @@ 6 10000 4 2 total 0.011426 0.001099 8 10000 5 2 total 0.004684 0.000451 10 10000 6 2 total 0.001962 0.000189 - material delayedgroup group in nuclide mean std. dev. -1 10000 1 1 total 0.000000 0.000000 -3 10000 2 1 total 0.000000 0.000000 -5 10000 3 1 total 0.000000 0.000000 -7 10000 4 1 total 0.000000 0.000000 -9 10000 5 1 total 0.000000 0.000000 -11 10000 6 1 total 0.000000 0.000000 -0 10000 1 2 total 0.000000 0.000000 -2 10000 2 2 total 0.032739 0.028454 -4 10000 3 2 total 0.120780 0.170809 -6 10000 4 2 total 0.302780 0.109110 -8 10000 5 2 total 0.000000 0.000000 -10 10000 6 2 total 0.000000 0.000000 + material delayedgroup group in nuclide mean std. dev. +1 10000 1 1 total 0.000000e+00 0.000000e+00 +3 10000 2 1 total 0.000000e+00 0.000000e+00 +5 10000 3 1 total 0.000000e+00 0.000000e+00 +7 10000 4 1 total 0.000000e+00 0.000000e+00 +9 10000 5 1 total 0.000000e+00 0.000000e+00 +11 10000 6 1 total 0.000000e+00 0.000000e+00 +0 10000 1 2 total 0.000000e+00 0.000000e+00 +2 10000 2 2 total 3.273900e-10 2.845437e-10 +4 10000 3 2 total 1.207800e-09 1.708087e-09 +6 10000 4 2 total 3.027800e-09 1.091095e-09 +8 10000 5 2 total 0.000000e+00 0.000000e+00 +10 10000 6 2 total 0.000000e+00 0.000000e+00 material group in nuclide mean std. dev. 1 10001 1 total 0.313738 0.015582 0 10001 2 total 0.300821 0.028052 From 1c3d1a38da18e6234463b34577d4834ef26dd7da Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 18 Sep 2016 12:39:50 -0400 Subject: [PATCH 25/42] Updated results after I realized I needed new NNDC data for the shakes to seconds thing --- .../results_true.dat | 14 ++--- .../results_true.dat | 14 ++--- tests/test_mgxs_library_hdf5/results_true.dat | 24 ++++----- tests/test_mgxs_library_mesh/results_true.dat | 52 +++++++++---------- .../results_true.dat | 26 +++++----- 5 files changed, 65 insertions(+), 65 deletions(-) diff --git a/tests/test_mgxs_library_condense/results_true.dat b/tests/test_mgxs_library_condense/results_true.dat index 5b02ce3db..cd84d0a3a 100644 --- a/tests/test_mgxs_library_condense/results_true.dat +++ b/tests/test_mgxs_library_condense/results_true.dat @@ -61,13 +61,13 @@ 3 10000 4 1 total 0.002752 0.000240 4 10000 5 1 total 0.001231 0.000105 5 10000 6 1 total 0.000512 0.000044 - material delayedgroup group in nuclide mean std. dev. -0 10000 1 1 total 0.000000e+00 0.000000e+00 -1 10000 2 1 total 3.273900e-10 2.845437e-10 -2 10000 3 1 total 1.207800e-09 1.708087e-09 -3 10000 4 1 total 3.027800e-09 1.091095e-09 -4 10000 5 1 total 0.000000e+00 0.000000e+00 -5 10000 6 1 total 0.000000e+00 0.000000e+00 + material delayedgroup group in nuclide mean std. dev. +0 10000 1 1 total 0.000000 0.000000 +1 10000 2 1 total 0.032739 0.028454 +2 10000 3 1 total 0.120780 0.170809 +3 10000 4 1 total 0.302780 0.109110 +4 10000 5 1 total 0.000000 0.000000 +5 10000 6 1 total 0.000000 0.000000 material group in nuclide mean std. dev. 0 10001 1 total 0.311594 0.013793 material group in nuclide mean std. dev. diff --git a/tests/test_mgxs_library_distribcell/results_true.dat b/tests/test_mgxs_library_distribcell/results_true.dat index dba6ae60d..87f18db1c 100644 --- a/tests/test_mgxs_library_distribcell/results_true.dat +++ b/tests/test_mgxs_library_distribcell/results_true.dat @@ -61,10 +61,10 @@ 3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 4 1 total 0.002727 0.000135 4 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 5 1 total 0.001210 0.000058 5 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 6 1 total 0.000504 0.000024 - avg(distribcell) delayedgroup group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 0.000000e+00 0.000000e+00 -1 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 2 1 total 3.273900e-10 4.629994e-10 -2 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 3 1 total 1.207800e-09 1.708087e-09 -3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 4 1 total 0.000000e+00 0.000000e+00 -4 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 5 1 total 0.000000e+00 0.000000e+00 -5 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 6 1 total 2.853000e-08 4.034751e-08 + avg(distribcell) delayedgroup group in nuclide mean std. dev. +0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 0.000000 0.000000 +1 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 2 1 total 0.032739 0.046300 +2 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 3 1 total 0.120780 0.170809 +3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 4 1 total 0.000000 0.000000 +4 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 5 1 total 0.000000 0.000000 +5 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 6 1 total 2.853000 4.034751 diff --git a/tests/test_mgxs_library_hdf5/results_true.dat b/tests/test_mgxs_library_hdf5/results_true.dat index 0e57dbaf3..8cec5c629 100644 --- a/tests/test_mgxs_library_hdf5/results_true.dat +++ b/tests/test_mgxs_library_hdf5/results_true.dat @@ -112,18 +112,18 @@ domain=10000 type=beta [ 1.82980497e-04 4.50738567e-04] [ 7.48899920e-05 1.88812772e-04]] domain=10000 type=decay-rate -[[ 0.00000000e+00 0.00000000e+00] - [ 0.00000000e+00 3.27390000e-10] - [ 0.00000000e+00 1.20780000e-09] - [ 0.00000000e+00 3.02780000e-09] - [ 0.00000000e+00 0.00000000e+00] - [ 0.00000000e+00 0.00000000e+00]] -[[ 0.00000000e+00 0.00000000e+00] - [ 0.00000000e+00 2.84543737e-10] - [ 0.00000000e+00 1.70808714e-09] - [ 0.00000000e+00 1.09109511e-09] - [ 0.00000000e+00 0.00000000e+00] - [ 0.00000000e+00 0.00000000e+00]] +[[ 0. 0. ] + [ 0. 0.032739] + [ 0. 0.12078 ] + [ 0. 0.30278 ] + [ 0. 0. ] + [ 0. 0. ]] +[[ 0. 0. ] + [ 0. 0.02845437] + [ 0. 0.17080871] + [ 0. 0.10910951] + [ 0. 0. ] + [ 0. 0. ]] domain=10001 type=total [ 0.31373767 0.3008214 ] [ 0.0155819 0.02805245] diff --git a/tests/test_mgxs_library_mesh/results_true.dat b/tests/test_mgxs_library_mesh/results_true.dat index bf34b196d..8ad0f2eee 100644 --- a/tests/test_mgxs_library_mesh/results_true.dat +++ b/tests/test_mgxs_library_mesh/results_true.dat @@ -208,29 +208,29 @@ 21 2 2 1 4 1 total 0.002143 0.001028 22 2 2 1 5 1 total 0.001026 0.000492 23 2 2 1 6 1 total 0.000408 0.000196 - mesh 1 delayedgroup group in nuclide mean std. dev. - x y z -0 1 1 1 1 1 total 0.000000e+00 0.000000e+00 -1 1 1 1 2 1 total 0.000000e+00 0.000000e+00 -2 1 1 1 3 1 total 0.000000e+00 0.000000e+00 -3 1 1 1 4 1 total 3.027800e-09 4.281956e-09 -4 1 1 1 5 1 total 0.000000e+00 0.000000e+00 -5 1 1 1 6 1 total 0.000000e+00 0.000000e+00 -6 1 2 1 1 1 total 0.000000e+00 0.000000e+00 -7 1 2 1 2 1 total 0.000000e+00 0.000000e+00 -8 1 2 1 3 1 total 0.000000e+00 0.000000e+00 -9 1 2 1 4 1 total 0.000000e+00 0.000000e+00 -10 1 2 1 5 1 total 0.000000e+00 0.000000e+00 -11 1 2 1 6 1 total 0.000000e+00 0.000000e+00 -12 2 1 1 1 1 total 0.000000e+00 0.000000e+00 -13 2 1 1 2 1 total 0.000000e+00 0.000000e+00 -14 2 1 1 3 1 total 0.000000e+00 0.000000e+00 -15 2 1 1 4 1 total 0.000000e+00 0.000000e+00 -16 2 1 1 5 1 total 0.000000e+00 0.000000e+00 -17 2 1 1 6 1 total 0.000000e+00 0.000000e+00 -18 2 2 1 1 1 total 0.000000e+00 0.000000e+00 -19 2 2 1 2 1 total 0.000000e+00 0.000000e+00 -20 2 2 1 3 1 total 0.000000e+00 0.000000e+00 -21 2 2 1 4 1 total 0.000000e+00 0.000000e+00 -22 2 2 1 5 1 total 0.000000e+00 0.000000e+00 -23 2 2 1 6 1 total 0.000000e+00 0.000000e+00 + mesh 1 delayedgroup group in nuclide mean std. dev. + x y z +0 1 1 1 1 1 total 0.00000 0.000000 +1 1 1 1 2 1 total 0.00000 0.000000 +2 1 1 1 3 1 total 0.00000 0.000000 +3 1 1 1 4 1 total 0.30278 0.428196 +4 1 1 1 5 1 total 0.00000 0.000000 +5 1 1 1 6 1 total 0.00000 0.000000 +6 1 2 1 1 1 total 0.00000 0.000000 +7 1 2 1 2 1 total 0.00000 0.000000 +8 1 2 1 3 1 total 0.00000 0.000000 +9 1 2 1 4 1 total 0.00000 0.000000 +10 1 2 1 5 1 total 0.00000 0.000000 +11 1 2 1 6 1 total 0.00000 0.000000 +12 2 1 1 1 1 total 0.00000 0.000000 +13 2 1 1 2 1 total 0.00000 0.000000 +14 2 1 1 3 1 total 0.00000 0.000000 +15 2 1 1 4 1 total 0.00000 0.000000 +16 2 1 1 5 1 total 0.00000 0.000000 +17 2 1 1 6 1 total 0.00000 0.000000 +18 2 2 1 1 1 total 0.00000 0.000000 +19 2 2 1 2 1 total 0.00000 0.000000 +20 2 2 1 3 1 total 0.00000 0.000000 +21 2 2 1 4 1 total 0.00000 0.000000 +22 2 2 1 5 1 total 0.00000 0.000000 +23 2 2 1 6 1 total 0.00000 0.000000 diff --git a/tests/test_mgxs_library_no_nuclides/results_true.dat b/tests/test_mgxs_library_no_nuclides/results_true.dat index e4e562032..961ae9ba9 100644 --- a/tests/test_mgxs_library_no_nuclides/results_true.dat +++ b/tests/test_mgxs_library_no_nuclides/results_true.dat @@ -123,19 +123,19 @@ 6 10000 4 2 total 0.011426 0.001099 8 10000 5 2 total 0.004684 0.000451 10 10000 6 2 total 0.001962 0.000189 - material delayedgroup group in nuclide mean std. dev. -1 10000 1 1 total 0.000000e+00 0.000000e+00 -3 10000 2 1 total 0.000000e+00 0.000000e+00 -5 10000 3 1 total 0.000000e+00 0.000000e+00 -7 10000 4 1 total 0.000000e+00 0.000000e+00 -9 10000 5 1 total 0.000000e+00 0.000000e+00 -11 10000 6 1 total 0.000000e+00 0.000000e+00 -0 10000 1 2 total 0.000000e+00 0.000000e+00 -2 10000 2 2 total 3.273900e-10 2.845437e-10 -4 10000 3 2 total 1.207800e-09 1.708087e-09 -6 10000 4 2 total 3.027800e-09 1.091095e-09 -8 10000 5 2 total 0.000000e+00 0.000000e+00 -10 10000 6 2 total 0.000000e+00 0.000000e+00 + material delayedgroup group in nuclide mean std. dev. +1 10000 1 1 total 0.000000 0.000000 +3 10000 2 1 total 0.000000 0.000000 +5 10000 3 1 total 0.000000 0.000000 +7 10000 4 1 total 0.000000 0.000000 +9 10000 5 1 total 0.000000 0.000000 +11 10000 6 1 total 0.000000 0.000000 +0 10000 1 2 total 0.000000 0.000000 +2 10000 2 2 total 0.032739 0.028454 +4 10000 3 2 total 0.120780 0.170809 +6 10000 4 2 total 0.302780 0.109110 +8 10000 5 2 total 0.000000 0.000000 +10 10000 6 2 total 0.000000 0.000000 material group in nuclide mean std. dev. 1 10001 1 total 0.313738 0.015582 0 10001 2 total 0.300821 0.028052 From c5dc4fad3d183491a71164895dea0b23a5e944b5 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 19 Sep 2016 20:44:06 -0400 Subject: [PATCH 26/42] Updating to resolve @samuelshaner comments --- docs/source/io_formats/mgxs_library.rst | 11 +- examples/xml/pincell_multigroup/mgxs.h5 | Bin 59616 -> 16496 bytes openmc/mesh.py | 12 +- openmc/mgxs/library.py | 4 +- openmc/mgxs_library.py | 300 ++++++++++-------------- openmc/settings.py | 2 +- scripts/openmc-update-mgxs.py | 18 +- src/global.F90 | 5 +- src/hdf5_interface.F90 | 1 + src/input_xml.F90 | 18 +- src/mgxs_data.F90 | 4 +- src/mgxs_header.F90 | 116 +++++---- src/tally.F90 | 14 +- tests/1d_mgxs.h5 | Bin 123864 -> 123864 bytes 14 files changed, 243 insertions(+), 262 deletions(-) diff --git a/docs/source/io_formats/mgxs_library.rst b/docs/source/io_formats/mgxs_library.rst index 0a02431f6..04474c01b 100644 --- a/docs/source/io_formats/mgxs_library.rst +++ b/docs/source/io_formats/mgxs_library.rst @@ -32,9 +32,6 @@ MGXS Library Specification - **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. - - **inverse velocities** (*double[]*) -- Average inverse velocitiy - for each of the groups in the library. This is an optional - attribute. **//** @@ -60,12 +57,12 @@ data for the nuclide or material that it represents. that the polar angular domain is subdivided if the `representation` attribute is "angle". This parameter is ignored otherwise. - - **scatter-type** (*char[]*) -- The representation of the + - **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-type`) + 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. @@ -113,6 +110,8 @@ Temperature-dependent data, provided for temperature K. 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. **//K/scatter data/** @@ -143,7 +142,7 @@ Data specific to neutron scattering for the temperature K `scatter matrix[num-polar][num-azimuthal][order(+1)][g_in][g_out]` The former is used when `representation` is "isotropic", and the latter when `representation` is "angle". Note that if the value of - `scatter-type` is "legendre", the order dimension will be one + `scatter-format` is "legendre", the order dimension will be one larger than the value of `order`, otherwise it will match `order`. Finally, the g_out dimension has a dimensionality of `g_out bounds`[0] to `g_out bounds`[1]. diff --git a/examples/xml/pincell_multigroup/mgxs.h5 b/examples/xml/pincell_multigroup/mgxs.h5 index ada3b1c71d8db394f330abf18d5a934544e44456..cbe338c1c7de692a9bed69901f1da186bc1d3348 100644 GIT binary patch delta 578 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 diff --git a/openmc/mesh.py b/openmc/mesh.py index 9fc36f75a..af65a2a16 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -286,10 +286,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=1000., boundary_type='reflective'), + openmc.YPlane(y0=1000., boundary_type='reflective')] else: yplanes = [openmc.YPlane(y0=self.lower_left[1], boundary_type=bc[2]), @@ -304,10 +302,8 @@ class Mesh(object): # inconsistency between what numpy uses as the max float and what # Fortran expects for a real(8), so this avoids code complication # and achieves the same goal. - zplanes = [openmc.ZPlane(z0=-1000., - boundary_type='reflective'), - openmc.ZPlane(z0=1000., - boundary_type='reflective')] + zplanes = [openmc.ZPlane(z0=-1000., boundary_type='reflective'), + openmc.ZPlane(z0=1000., 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 f63d77327..02c63f50b 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -827,7 +827,7 @@ class Library(object): data set for eventual combination in to an openmc.MGXSLibrary object (i.e., the library). 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. + XSdata object will be left at the default value of 300K. Parameters ---------- @@ -908,7 +908,7 @@ class Library(object): xsdata.order = min(order, self.legendre_order) # Right now only 'legendre' data and isotropic weighting is supported - self.scatter_type = 'legendre' + self.scatter_format = 'legendre' self.representation = 'isotropic' if nuclide is not 'total': diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index a5968e299..cba5c20a1 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -27,7 +27,7 @@ class XSdata(object): 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' @@ -49,7 +49,7 @@ class XSdata(object): Energy group structure fissionable : bool Whether or not this is a fissionable data set. - scatter_type : {'legendre', 'histogram', or 'tabular'} + scatter_format : {'legendre', 'histogram', or 'tabular'} Angular distribution representation (legendre, histogram, or tabular) order : int Either the Legendre order, number of bins, or number of points used to @@ -78,79 +78,53 @@ class XSdata(object): 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_matrix : numpy.ndarray + 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 ``scatter_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_matrix : 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 + ``nu_fission`` attribute instead. + nu_fission : dict of 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. + 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 ``representation`` as well as the number of + Legendre or other angular dimensions as described by ``order``. The + ``vector_shape``, ``matrix_shape``, and ``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 """ @@ -163,7 +137,7 @@ class XSdata(object): self.representation = representation self._awr = None self._fissionable = False - self._scatter_type = 'legendre' + self._scatter_format = 'legendre' self._order = None self._num_polar = None self._num_azimuthal = None @@ -176,6 +150,7 @@ class XSdata(object): 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): @@ -202,8 +177,8 @@ class XSdata(object): return self._temperatures @property - def scatter_type(self): - return self._scatter_type + def scatter_format(self): + return self._scatter_format @property def order(self): @@ -256,7 +231,7 @@ class XSdata(object): @property def num_orders(self): if self._order is not None: - if self._scatter_type in (None, 'legendre'): + if self._scatter_format in (None, 'legendre'): return self._order + 1 else: return self._order @@ -327,19 +302,18 @@ class XSdata(object): def temperatures(self, temperatures): check_type('temperatures', temperatures, Iterable, expected_iter_type=Real) - # Convert to a numpy array so we can easily get the shape for - # checking + # Convert to a numpy array so we can easily get the shape for checking nptemperatures = np.asarray(temperatures) check_value('temperatures dimensionality', nptemperatures.ndim, [1]) self._temperatures = nptemperatures - @scatter_type.setter - def scatter_type(self, scatter_type): + @scatter_format.setter + def scatter_format(self, scatter_format): # check to see it is of a valid type and value - check_value('scatter_type', scatter_type, _SCATTER_TYPES) - self._scatter_type = scatter_type + check_value('scatter_format', scatter_format, _SCATTER_TYPES) + self._scatter_format = scatter_format @order.setter def order(self, order): @@ -390,6 +364,7 @@ class XSdata(object): 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 @@ -397,7 +372,7 @@ class XSdata(object): Parameters ---------- - total: nd.nparray + total: np.ndarray Total Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults @@ -409,8 +384,7 @@ class XSdata(object): """ check_type('total', total, Iterable, expected_iter_type=Real) - # Convert to a numpy array so we can easily get the shape for - # checking + # 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]) check_type('temperature', temperature, Real) @@ -425,7 +399,7 @@ class XSdata(object): Parameters ---------- - absorption: nd.nparray + absorption: np.ndarray Absorption Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults @@ -437,8 +411,7 @@ class XSdata(object): """ check_type('absorption', absorption, Iterable, expected_iter_type=Real) - # Convert to a numpy array so we can easily get the shape for - # checking + # 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]) @@ -454,7 +427,7 @@ class XSdata(object): Parameters ---------- - fission: nd.nparray + fission: np.ndarray Fission Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults @@ -466,8 +439,7 @@ class XSdata(object): """ check_type('fission', fission, Iterable, expected_iter_type=Real) - # Convert to a numpy array so we can easily get the shape for - # checking + # 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]) check_type('temperature', temperature, Real) @@ -485,7 +457,7 @@ class XSdata(object): Parameters ---------- - kappa_fission: nd.nparray + kappa_fission: np.ndarray Kappa-Fission Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults @@ -498,8 +470,7 @@ class XSdata(object): """ 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 + # Convert to a numpy array so we can easily get the shape for checking npkappa_fission = np.asarray(kappa_fission) check_value('kappa fission shape', npkappa_fission.shape, [self.vector_shape]) @@ -518,7 +489,7 @@ class XSdata(object): Parameters ---------- - chi: nd.nparray + chi: np.ndarray Fission Spectrum temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults @@ -536,8 +507,7 @@ class XSdata(object): 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 + # Convert to a numpy array so we can easily get the shape for checking npchi = np.asarray(chi) # Check the shape if npchi.shape != self.vector_shape: @@ -558,7 +528,7 @@ class XSdata(object): Parameters ---------- - scatter: nd.nparray + scatter: np.ndarray Scattering Matrix Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults @@ -569,8 +539,7 @@ class XSdata(object): openmc.mgxs_library.set_scatter_matrix_mgxs() """ - # Convert to a numpy array so we can easily get the shape for - # checking + # 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)) @@ -587,7 +556,7 @@ class XSdata(object): Parameters ---------- - multiplicity: nd.nparray + multiplicity: np.ndarray Multiplicity Matrix Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults @@ -598,8 +567,7 @@ class XSdata(object): openmc.mgxs_library.set_multiplicity_matrix_mgxs() """ - # Convert to a numpy array so we can easily get the shape for - # checking + # 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)) @@ -617,7 +585,7 @@ class XSdata(object): Parameters ---------- - nu_fission: nd.nparray + nu_fission: np.ndarray Nu-fission Cross Section temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults @@ -638,8 +606,7 @@ 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 + # Convert to a numpy array so we can easily get the shape for checking npnu_fission = np.asarray(nu_fission) check_iterable_type('nu_fission', npnu_fission, Real, @@ -669,6 +636,31 @@ class XSdata(object): if np.sum(npnu_fission) > 0.0: self._fissionable = True + 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 units of Kelvin) of the provided dataset. Defaults + to 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 + npinv_vel = np.asarray(inv_vel) + check_value('inverse velocities shape', npinv_vel.shape, + [self.vector_shape]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) + + i = self.temperatures.tolist().index(temperature) + self._inverse_velocities[i] = npinv_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 @@ -1009,7 +1001,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - if (self.scatter_type != 'legendre'): + if (self.scatter_format != 'legendre'): msg = 'Anisotropic scattering representations other than ' \ 'Legendre expansions have not yet been implemented in ' \ 'openmc.mgxs.' @@ -1121,12 +1113,7 @@ class XSdata(object): self._multiplicity_matrix[i] = \ np.nan_to_num(self._multiplicity_matrix[i]) - def _get_xsdata_group(self, file, compression): - if compression is not None: - check_type("compression", compression, Integral) - check_greater_than("compression", compression, 0, equality=True) - check_less_than("compression", compression, 9, equality=True) - + def _get_xsdata_group(self, file): grp = file.create_group(self.name) if self.awr is not None: grp.attrs['awr'] = self.awr @@ -1140,8 +1127,9 @@ class XSdata(object): grp.attrs['num-azimuthal'] = self.num_azimuthal if self.num_polar is not None: grp.attrs['num-polar'] = self.num_polar - if self.scatter_type is not None: - grp.attrs['scatter-type'] = np.array(self.scatter_type, dtype='S') + if self.scatter_format is not None: + grp.attrs['scatter-format'] = np.array(self.scatter_format, + dtype='S') if self.order is not None: grp.attrs['order'] = self.order @@ -1153,38 +1141,32 @@ class XSdata(object): # Create the temperature datasets for i, temperature in enumerate(self.temperatures): - xsgrp = grp.create_group(str(int(np.round(temperature))) + "K") + 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') - xsgrp.create_dataset("total", data=self._total[i], - compression=compression) + 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') - xsgrp.create_dataset("absorption", data=self._absorption[i], - compression=compression) + xs_grp.create_dataset("absorption", data=self._absorption[i]) if self.fissionable: if self._fission[i] is not None: - xsgrp.create_dataset("fission", data=self._fission[i], - compression=compression) + xs_grp.create_dataset("fission", data=self._fission[i]) if self._kappa_fission[i] is not None: - xsgrp.create_dataset("kappa-fission", - data=self._kappa_fission[i], - compression=compression) + xs_grp.create_dataset("kappa-fission", + data=self._kappa_fission[i]) if self._chi[i] is not None: - xsgrp.create_dataset("chi", data=self._chi[i], - compression=compression) + 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') - xsgrp.create_dataset("nu-fission", - data=self._nu_fission[i], - compression=compression) + xs_grp.create_dataset("nu-fission", data=self._nu_fission[i]) if self._scatter_matrix[i] is None: raise ValueError('Scatter matrix must be provided when ' 'writing the HDF5 library') + # Get the sparse scattering data to print to the library G = self.energy_groups.num_groups if self.representation == 'isotropic': @@ -1202,10 +1184,9 @@ class XSdata(object): for l in range(len(matrix[:, g_in, g_out])): flat_scatt.append(matrix[l, g_in, g_out]) # And write it. - scatt_grp = xsgrp.create_group('scatter data') + scatt_grp = xs_grp.create_group('scatter data') scatt_grp.create_dataset("scatter matrix", - data=np.array(flat_scatt), - compression=compression) + data=np.array(flat_scatt)) # Repeat for multiplicity if self._multiplicity_matrix[i] is not None: # Now create the flattened scatter matrix array @@ -1216,15 +1197,13 @@ class XSdata(object): 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), - compression=compression) + data=np.array(flat_mult)) + # 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], - compression=compression) - scatt_grp.create_dataset("g_max", data=g_out_bounds[:, 1], - compression=compression) + scatt_grp.create_dataset("g_min", data=g_out_bounds[:, 0]) + scatt_grp.create_dataset("g_max", data=g_out_bounds[:, 1]) elif self.representation == 'angle': Np = self.num_polar @@ -1248,10 +1227,9 @@ class XSdata(object): for l in range(len(matrix[:, g_in, g_out])): flat_scatt.append(matrix[l, g_in, g_out]) # And write it. - scatt_grp = xsgrp.create_group('scatter data') + scatt_grp = xs_grp.create_group('scatter data') scatt_grp.create_dataset("scatter matrix", - data=np.array(flat_scatt), - compression=compression) + data=np.array(flat_scatt)) # Repeat for multiplicity if self._multiplicity_matrix[i] is not None: # Now create the flattened scatter matrix array @@ -1265,15 +1243,18 @@ class XSdata(object): flat_mult.append(matrix[g_in, g_out]) # And write it. scatt_grp.create_dataset("multiplicity matrix", - data=np.array(flat_mult), - compression=compression) + data=np.array(flat_mult)) + # 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], - compression=compression) - scatt_grp.create_dataset("g_max", data=g_out_bounds[:, :, :, 1], - compression=compression) + scatt_grp.create_dataset("g_min", data=g_out_bounds[:, :, :, 0]) + scatt_grp.create_dataset("g_max", data=g_out_bounds[:, :, :, 1]) + + # 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): @@ -1284,27 +1265,20 @@ class MGXSLibrary(object): Parameters ---------- energy_groups : openmc.mgxs.EnergyGroups - Energygroup structure + 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._inverse_velocities = None self._xsdatas = [] - @property - def inverse_velocities(self): - return self._inverse_velocities - @property def energy_groups(self): return self._energy_groups @@ -1317,13 +1291,6 @@ class MGXSLibrary(object): 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) @@ -1379,35 +1346,24 @@ class MGXSLibrary(object): self._xsdatas.remove(xsdata) - def export_to_hdf5(self, filename='mgxs.h5', compression=None): - """Create an mgxs.h5 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 - Filename of file, default is mgxs.xml. - compression : None or int - The compression level to use in the datasets within the hdf5 file. - A value of None implies no compression, numbers between 0 and 9 - refer to the compression level using the gzip algorithm. - Defaults to None. + Filename of file, default is mgxs.h5. """ check_type('filename', filename, basestring) - if compression is not None: - check_type("compression", compression, Integral) - check_greater_than("compression", compression, 0, equality=True) - check_less_than("compression", compression, 9, equality=True) # 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 - if self.inverse_velocities is not None: - file.attrs['inverse velocities'] = self.inverse_velocities for xsdata in self._xsdatas: - xsdata._get_xsdata_group(file, compression) + xsdata._get_xsdata_group(file) file.close() diff --git a/openmc/settings.py b/openmc/settings.py index b320a429e..a1b029d4b 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -104,7 +104,7 @@ class Settings(object): 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 + 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. diff --git a/scripts/openmc-update-mgxs.py b/scripts/openmc-update-mgxs.py index 5aea89883..e3fd1bd2f 100755 --- a/scripts/openmc-update-mgxs.py +++ b/scripts/openmc-update-mgxs.py @@ -60,6 +60,7 @@ def parse_args(): # Parse and return commandline arguments. return args + def get_data(element, entry): try: value = element.find(entry).text @@ -121,9 +122,9 @@ if __name__ == '__main__': n_azi = int(get_data(xsdata_elem, 'num_azimuthal')) n_pol = int(get_data(xsdata_elem, 'num_polar')) - scatter_type = get_data(xsdata_elem, 'scatt_type') - if scatter_type is None: - scatter_type = 'legendre' + scatter_format = get_data(xsdata_elem, 'scatt_type') + if scatter_format is None: + scatter_format = 'legendre' order = int(get_data(xsdata_elem, 'order')) @@ -149,11 +150,11 @@ if __name__ == '__main__': if representation == 'angle': xsd[-1].num_azimuthal = n_azi xsd[-1].num_polar = n_pol - xsd[-1].scatter_type = scatter_type + xsd[-1].scatter_format = scatter_format xsd[-1].order = order names.append(name) - if scatter_type == 'legendre': + if scatter_format == 'legendre': order_dim = order + 1 else: order_dim = order @@ -168,6 +169,9 @@ if __name__ == '__main__': total = np.reshape(total, 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) @@ -222,9 +226,7 @@ if __name__ == '__main__': # Build library as we go, but first we have enough to initialize it lib = openmc.MGXSLibrary(energy_groups) - if inverse_velocities is not None: - lib.inverse_velocities = inverse_velocities lib.add_xsdatas(xsd) - lib.export_to_hdf5(args['output'], compression=args['compression']) + lib.export_to_hdf5(args['output']) diff --git a/src/global.F90 b/src/global.F90 index 6e804c90a..ca376e642 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -122,13 +122,10 @@ 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 no to convert Legendres to tabulars + ! Whether or not to convert Legendres to tabulars logical :: legendre_to_tabular = .True. ! Number of points to use in the Legendre to tabular conversion diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index 7e4f16f26..262bbc232 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -2571,6 +2571,7 @@ contains 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. diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 1aa3a8a87..2959e876d 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -4618,10 +4618,10 @@ contains real(8), allocatable :: rev_energy_bins(:) character(len=MAX_WORD_LEN), allocatable :: names(:) - ! Check if mgxs.h5 exists + ! Check if MGXS Library exists inquire(FILE=path_cross_sections, EXIST=file_exists) if (.not. file_exists) then - ! Could not find mgxs.h5 file + ! Could not find MGXS Library file call fatal_error("Cross sections HDF5 file '" & // trim(path_cross_sections) // "' does not exist!") end if @@ -4655,20 +4655,6 @@ contains energy_bin_avg(i) = HALF * (energy_bins(i) + energy_bins(i + 1)) end do - allocate(inverse_velocities(energy_groups)) - if (check_attribute(file_id, "inverse velocities")) then - ! Get inverse velocities - call read_attribute(inverse_velocities, file_id, "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) diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 45737ff1d..724bfa837 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -38,10 +38,10 @@ contains 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 + ! Could not find MGXS Library file call fatal_error("Cross sections HDF5 file '" & &// trim(path_cross_sections) // "' does not exist!") end if diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 56fbb5965..dd34dbee0 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -30,6 +30,7 @@ module mgxs_header 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 @@ -42,6 +43,7 @@ module mgxs_header 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 !=============================================================================== @@ -55,7 +57,7 @@ module mgxs_header ! Fission information logical :: fissionable ! mgxs object is fissionable? - integer :: scatter_type ! either legendre, histogram, or tabular. + integer :: scatter_format ! either legendre, histogram, or tabular. ! Caching information integer :: index_temp ! temperature index for nuclide @@ -322,20 +324,20 @@ module mgxs_header end select ! Load the remaining metadata - if (check_attribute(xs_id, "scatter-type")) then - call read_attribute(temp_str, xs_id, "scatter-type") + if (check_attribute(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_type = ANGLE_LEGENDRE + this % scatter_format = ANGLE_LEGENDRE else if (to_lower(temp_str) == 'histogram') then - this % scatter_type = ANGLE_HISTOGRAM + this % scatter_format = ANGLE_HISTOGRAM else if (to_lower(temp_str) == 'tabular') then - this % scatter_type = ANGLE_TABULAR + this % scatter_format = ANGLE_TABULAR else - call fatal_error("Invalid scatter-type option!") + call fatal_error("Invalid scatter-format option!") end if else - this % scatter_type = ANGLE_LEGENDRE + this % scatter_format = ANGLE_LEGENDRE end if if (check_attribute(xs_id, "fissionable")) then call read_attribute(this % fissionable, xs_id, "fissionable") @@ -355,7 +357,7 @@ module mgxs_header ! 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 % scatter_type == ANGLE_LEGENDRE) then + if (this % scatter_format == ANGLE_LEGENDRE) then order_dim = order_dim + 1 else order_dim = order_dim @@ -538,7 +540,7 @@ module mgxs_header ! Compare the number of orders given with the maximum order of the ! problem. Strip off the supefluous orders if needed. - if (this % scatter_type == ANGLE_LEGENDRE) then + if (this % scatter_format == ANGLE_LEGENDRE) then order = min(order_dim - 1, max_order) order_dim = order + 1 end if @@ -560,9 +562,9 @@ module mgxs_header ! Finally convert the legendre to tabular if needed allocate(scatt_coeffs(groups)) - if (this % scatter_type == ANGLE_LEGENDRE .and. & + if (this % scatter_format == ANGLE_LEGENDRE .and. & legendre_to_tabular) then - this % scatter_type = ANGLE_TABULAR + this % scatter_format = ANGLE_TABULAR order_dim = legendre_to_tabular_points order = order_dim dmu = TWO / real(order - 1, 8) @@ -643,11 +645,11 @@ module mgxs_header end if ! Allocate and initialize our ScattData Object. - if (this % scatter_type == ANGLE_HISTOGRAM) then + if (this % scatter_format == ANGLE_HISTOGRAM) then allocate(ScattDataHistogram :: xs % scatter) - else if (this % scatter_type == ANGLE_TABULAR) then + else if (this % scatter_format == ANGLE_TABULAR) then allocate(ScattDataTabular :: xs % scatter) - else if (this % scatter_type == ANGLE_LEGENDRE) then + else if (this % scatter_format == ANGLE_LEGENDRE) then allocate(ScattDataLegendre :: xs % scatter) end if @@ -669,12 +671,18 @@ module mgxs_header xs % total(:) = xs % absorption(:) + xs % scatter % scattxs(:) end if - ! Finally, check sigT to ensure it is not 0 since it is + ! 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 (check_dataset(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) @@ -890,7 +898,7 @@ module mgxs_header ! Compare the number of orders given with the maximum order of the ! problem. Strip off the superfluous orders if needed. - if (this % scatter_type == ANGLE_LEGENDRE) then + if (this % scatter_format == ANGLE_LEGENDRE) then order = min(order_dim - 1, max_order) order_dim = order + 1 end if @@ -918,9 +926,9 @@ module mgxs_header ! Finally convert the legendre to tabular if needed allocate(scatt_coeffs(groups, this % n_azi, this % n_pol)) - if (this % scatter_type == ANGLE_LEGENDRE .and. & + if (this % scatter_format == ANGLE_LEGENDRE .and. & legendre_to_tabular) then - this % scatter_type = ANGLE_TABULAR + this % scatter_format = ANGLE_TABULAR order_dim = legendre_to_tabular_points order = order_dim dmu = TWO / real(order - 1, 8) @@ -1031,11 +1039,11 @@ module mgxs_header do ipol = 1, this % n_pol do iazi = 1, this % n_azi ! Allocate and initialize our ScattData Object. - if (this % scatter_type == ANGLE_HISTOGRAM) then + if (this % scatter_format == ANGLE_HISTOGRAM) then allocate(ScattDataHistogram :: xs % scatter(iazi, ipol) % obj) - else if (this % scatter_type == ANGLE_TABULAR) then + else if (this % scatter_format == ANGLE_TABULAR) then allocate(ScattDataTabular :: xs % scatter(iazi, ipol) % obj) - else if (this % scatter_type == ANGLE_LEGENDRE) then + else if (this % scatter_format == ANGLE_LEGENDRE) then allocate(ScattDataLegendre :: xs % scatter(iazi, ipol) % obj) end if @@ -1075,8 +1083,8 @@ module mgxs_header end do end if - ! Finally, check sigT to ensure it is not 0 since it is - ! often divided by in the tally routines + ! 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 @@ -1087,6 +1095,16 @@ module mgxs_header end do end do + ! Get kinetics data + if (check_dataset(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) @@ -1100,13 +1118,13 @@ module mgxs_header !=============================================================================== subroutine mgxs_combine(this, temps, mat, nuclides, max_order, & - scatter_type, order_dim) + 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 type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from integer, intent(in) :: max_order ! Maximum requested order - integer, intent(out) :: scatter_type ! Type of scatter + integer, intent(out) :: scatter_format ! Type of scatter integer, intent(out) :: order_dim ! Scattering data order size integer :: t, mat_max_order, order @@ -1138,7 +1156,7 @@ module mgxs_header ! Determine the scattering type of our data and ensure all scattering orders ! are the same. - scatter_type = nuclides(mat % nuclide(1)) % obj % scatter_type + scatter_format = nuclides(mat % nuclide(1)) % obj % scatter_format select type(nuc => nuclides(mat % nuclide(1)) % obj) type is (MgxsIso) order = size(nuc % xs(1) % scatter % dist(1) % data, dim=1) @@ -1146,7 +1164,7 @@ module mgxs_header 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 (scatter_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) @@ -1162,7 +1180,7 @@ module mgxs_header end do ! Ok, got our order, store the dimensionality order_dim = order - else if (scatter_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) @@ -1178,7 +1196,7 @@ module mgxs_header end do ! Ok, got our order, store the dimensionality order_dim = order - else if (scatter_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 @@ -1228,14 +1246,14 @@ module mgxs_header integer :: nuc_t integer, allocatable :: nuc_ts(:) real(8) :: temp_actual, temp_desired, interp - integer :: scatter_type + 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_type, & + call mgxs_combine(this, temps, mat, nuclides, max_order, scatter_format, & order_dim) ! Create the Xs Data for each temperature @@ -1253,6 +1271,8 @@ module mgxs_header 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)) @@ -1262,12 +1282,12 @@ module mgxs_header allocate(scatt_coeffs(order_dim,groups,groups)) scatt_coeffs(:, :, :) = ZERO - this % scatter_type = scatter_type - if (scatter_type == ANGLE_LEGENDRE) then + this % scatter_format = scatter_format + if (scatter_format == ANGLE_LEGENDRE) then allocate(ScattDataLegendre :: this % xs(t) % scatter) - else if (scatter_type == ANGLE_TABULAR) then + else if (scatter_format == ANGLE_TABULAR) then allocate(ScattDataTabular :: this % xs(t) % scatter) - else if (scatter_type == ANGLE_HISTOGRAM) then + else if (scatter_format == ANGLE_HISTOGRAM) then allocate(ScattDataHistogram :: this % xs(t) % scatter) end if @@ -1342,6 +1362,10 @@ module mgxs_header 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 multiplicaity and scattering matrices. ! To avoid multiple re-allocations as we resize the storage @@ -1459,14 +1483,14 @@ module mgxs_header integer :: nuc_t integer, allocatable :: nuc_ts(:) real(8) :: temp_actual, temp_desired, interp - integer :: scatter_type + 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_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 @@ -1506,6 +1530,8 @@ module mgxs_header 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)) @@ -1518,13 +1544,13 @@ module mgxs_header allocate(this % xs(t) % scatter(n_azi, n_pol)) do ipol = 1, n_pol do iazi = 1, n_azi - if (scatter_type == ANGLE_LEGENDRE) then + if (scatter_format == ANGLE_LEGENDRE) then allocate(ScattDataLegendre :: & this % xs(t) % scatter(iazi, ipol) % obj) - else if (scatter_type == ANGLE_TABULAR) then + else if (scatter_format == ANGLE_TABULAR) then allocate(ScattDataTabular :: & this % xs(t) % scatter(iazi, ipol) % obj) - else if (scatter_type == ANGLE_HISTOGRAM) then + else if (scatter_format == ANGLE_HISTOGRAM) then allocate(ScattDataHistogram :: & this % xs(t) % scatter(iazi, ipol) % obj) end if @@ -1589,6 +1615,10 @@ module mgxs_header 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 @@ -1811,6 +1841,8 @@ module mgxs_header ! 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 @@ -1905,6 +1937,8 @@ module mgxs_header ! 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 diff --git a/src/tally.F90 b/src/tally.F90 index 3c008e30e..81f02d631 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -1222,11 +1222,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 diff --git a/tests/1d_mgxs.h5 b/tests/1d_mgxs.h5 index d764cb69fbf7d76401c15d7224f62b9d2a28942d..65dcf36cf7ee6c22d854c4fbcf2160e63209280f 100644 GIT binary patch delta 1526 zcmZ{kZAep57{@zKbC$L~gxa9gftZpxZl+Sn$_N$(3#5=6fJIJ?Gwg7I)k)&vQ8E{Ql4XdCrZ@ zW=3W+ebf3ahIM-JyWHexZ@(avU*v^WM>`7W|D@}duf<@n$%Cw$hO^fa6g8emlU6Ow z3254GQev(^jq3_Y%(spDi{d(I&ywIloyD(!bc>}VLkghHoq${^*=_Hb@|STsO*Jr} z7htTk5Jk%O%c{KSDR*5;kfoZc5{byXw^Bu})KX;7!XW(z3DV{sfQ!0Z)LD04n~Q!P zR$TC+zN3_9IIi;i^$ad_lH%?(Fu1FySX>@Da@vss7ie516$P7$GbG=lM$tEy>|1jV zG0@gR1A8kC__l6xa!HUoRPq&;xg|2Px#j&G1L>L$qt&hj)!EM8GbFK8dyw-6#aHy* zSDkgmtrJ4rWQghMw!BoyR4%1TYqqNjDR{j{hHG1!z#6nNTnR*rg zt`zk=e#CUnipHrsnBKO89nc)_hukwFnB)WS&`c4TSM2c2tw--?CiHR+%~|>A*K1{< zhmh;dOVW>ux3yW)WbZ#RoP36^mDL0O8^fc|ZXt zM!swX#66LW1tZv;t%-$!#v#0;1hgmvhHG}p?5H`39q%78Rnl8&k4CsX|1H#2u?t!G zI93H{TSS+zbsw0Q9Ki)=S-G5@9_v}SiDP!~F@@aKuDkeLDh!=d){sTx>HB7KpIUmYa8GH;Mhy38!Mlzd%2Tuk7c{!MW UuCiU8xeyM$0ON(yMn3HN2Si7@>Hq)$ delta 1526 zcmZ{kZAep57{@(MbCzZwV%nh8ftZpxZl+Sn$_N$(3nY6fJIJ?Gwg7I)k)&vQ8E{Ql4XdCm>b zXN2c7W@oh9vs1LfccsbJ(b4QI>*&7JoRWh4+COQUyY-7O(Bwwut)p2R35w`Xr;4kl zmN+!*GRQHPuf(+lB<9=4eT6ZNxM#)bMqNd(fOw0kI9&{&#TAEK3E6G!oc5J+8dWvW zuXVy`NdXF%9g^RXRV5IS@j!)wT&tnTfQdo+ju529H3XM6I@DErQJsr^ z9+O@0pn(&Vmvc(t`RW*4u%6;>H!!%XXINY=I)2uc1m|yDClv*niqb{jB6`6$hvZvJ zHZjoBN&{;f4fyt6a&pBfb*T6&EOm)wWN}IRJBQL#9Y*UtONz5y{pUzxs&XUyb&4+^ zxUV>CzbUQWVoEg(v!&|L_u*vDHjdI#t>d)R4OZR+y)|<0oybB@yi7gI4@f;ZQ?#D^ z>7FF@JbuJ<&Wya&9ZYXq!8T}&4MOf25lr$Scyz9i%qzCJ7dD~ybCX&rhsMl2^y{@e z&?Ct4<|XMz`P-UIakBXk71p=3PhFTi$_<~HQLc_sfsq(1Pyo(;qw^Kf_al3Jk#J1E zi^vP&LqA~MD$&e`THwsI4y~;k($$;1_pf3K4yFPE#e4=xq~gPyfr7Bl!yBM^}1BR>jNbHC)fgKwhGgQ!9X^+OZ{r@f0R Date: Mon, 19 Sep 2016 20:53:29 -0400 Subject: [PATCH 27/42] minor typo --- src/mgxs_header.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index dd34dbee0..f9d54093e 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -1367,7 +1367,7 @@ module mgxs_header atom_density * nuc % xs(nuc_t) % inv_vel * interp end if - ! We will next gather the multiplicaity and scattering matrices. + ! 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 @@ -1634,7 +1634,7 @@ module mgxs_header end if end if - ! We will next gather the multiplicaity and scattering matrices. + ! 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 From 9d769378838a8404a7e878a65a6bf7f9fb8e083d Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 23 Sep 2016 15:59:47 -0400 Subject: [PATCH 28/42] Fixes to kT vs K --- src/mgxs_data.F90 | 2 +- src/mgxs_header.F90 | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 724bfa837..2fbfdfd42 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -23,7 +23,7 @@ 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_xsdata ! index in xsdata_dict integer :: i_nuclide ! index in nuclides array character(20) :: name ! name of library to load integer :: representation ! Data representation diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index f9d54093e..193f337f1 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -198,9 +198,8 @@ 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 xs_id 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_from_hdf5(this, xs_id, temperature, method, tolerance, & @@ -1304,7 +1303,7 @@ module mgxs_header 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) >= tolerance) then + 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.") @@ -1326,7 +1325,7 @@ module mgxs_header 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.") + trim(to_str(nint(temp_desired / K_BOLTZMANN))) // " K.") end select select type(nuc) @@ -1568,7 +1567,7 @@ module mgxs_header 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) >= tolerance) then + 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.") @@ -1590,7 +1589,7 @@ module mgxs_header 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.") + trim(to_str(nint(temp_desired / K_BOLTZMANN))) // " K.") end select ! Copy atom density of nuclide in material From 935d72af0dc9c81532239f875862381d91f92167 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 10 Oct 2016 15:19:47 -0400 Subject: [PATCH 29/42] Resolution of @paulromano comments --- .gitignore | 6 - docs/source/io_formats/mgxs_library.rst | 52 +++--- openmc/mesh.py | 6 +- openmc/mgxs/library.py | 2 +- openmc/mgxs_library.py | 95 +++++----- scripts/openmc-update-mgxs.py | 232 ------------------------ src/geometry_header.F90 | 78 +++++++- src/hdf5_interface.F90 | 33 +--- src/input_xml.F90 | 87 ++------- src/mgxs_data.F90 | 56 +----- src/mgxs_header.F90 | 114 ++++++------ src/nuclide_header.F90 | 8 +- src/sab_header.F90 | 6 +- src/secondary_uncorrelated.F90 | 7 +- 14 files changed, 254 insertions(+), 528 deletions(-) delete mode 100755 scripts/openmc-update-mgxs.py diff --git a/.gitignore b/.gitignore index 21db60397..2ca1c7d14 100644 --- a/.gitignore +++ b/.gitignore @@ -50,8 +50,6 @@ tests/ctestscript.run # HDF5 files *.h5 -!tests/1d_mgxs.h5 -!examples/xml/pincell_multigroup/mgxs.h5 # Build files src/CMakeCache.txt @@ -91,7 +89,3 @@ docs/source/pythonapi/examples/mgxs docs/source/pythonapi/examples/tracks docs/source/pythonapi/examples/fission-rates docs/source/pythonapi/examples/plots - -# VSCode workspace directory -.vscode -.vscode/* diff --git a/docs/source/io_formats/mgxs_library.rst b/docs/source/io_formats/mgxs_library.rst index 04474c01b..e9b59a20f 100644 --- a/docs/source/io_formats/mgxs_library.rst +++ b/docs/source/io_formats/mgxs_library.rst @@ -38,8 +38,8 @@ MGXS Library Specification The data within contains the temperature-dependent multi-group data for the nuclide or material that it represents. -:Attributes: - **awr** (*double*) -- The atomic weight ratio (optional, i.e. it - is not meaningful for material-wise data) +:Attributes: - **atomic_weight_ratio** (*double*) -- The atomic weight ratio (optional, + i.e. it is not meaningful for material-wise data) - **fissionable** (*int*) -- Whether the dataset is fissionable (1) or not (0). - **representation** (*char[]*) -- The method used to generate and @@ -49,26 +49,27 @@ data for the nuclide or material that it represents. 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 + - **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 + - **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 + - **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`) + 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. **//kTs/** -:Datasets: - **K** (*double*) -- kT values (in MeV) for each Temperature +:Datasets: + - **K** (*double*) -- kT values (in MeV) for each Temperature TTT (in Kelvin), rounded to the nearest integer **//K/** @@ -109,44 +110,44 @@ Temperature-dependent data, provided for temperature K. 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 + same dimensionality as `multiplicity_matrix`. + - **inverse_velocities** (*double[]*) -- Average inverse velocity for each of the groups in the library. This dataset is optional. -**//K/scatter data/** +**//K/scatter_data/** Data specific to neutron scattering for the temperature K -:Datasets: - **g_min** (*int[]* or *int[][][]) -- +:Datasets: - **g_min** (*int[]* or *int[][][]*) -- Minimum (most energetic) outgoing groups with non-zero values of the scattering matrix. 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_out bounds` is: - `g_min[g_in]`, or `g_min[num-polar][num-azimuthal][g_in]`. + The dimensionality of `g_min` is: + `g_min[g_in]`, or `g_min[num_polar][num_azimuthal][g_in]`. The former is used when `representation` is "isotropic", and the latter when `representation` is "angle". - - **g_max** (*int[]* or *int[][][]) -- + - **g_max** (*int[]* or *int[][][]*) -- Maximum (least energetic) outgoing groups with non-zero values of the scattering matrix. 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_out bounds` is: - `g_max[g_in]`, or `g_max[num-polar][num-azimuthal][g_in]`. + The dimensionality of `g_max` is: + `g_max[g_in]`, or `g_max[num_polar][num_azimuthal][g_in]`. The former is used when `representation` is "isotropic", and the latter when `representation` is "angle". - - **scatter matrix** (*double[]*) -- Flattened representation of the + - **scatter_matrix** (*double[]*) -- Flattened representation of the scattering moment matrices. The pre-flattened array is shaped as follows (in row-major format): - `scatter matrix[order(+1)][g_in][g_out]`, or - `scatter matrix[num-polar][num-azimuthal][order(+1)][g_in][g_out]` + `scatter_matrix[order(+1)][g_in][g_out]`, or + `scatter_matrix[num_polar][num_azimuthal][order(+1)][g_in][g_out]` The former is used when `representation` is "isotropic", and the latter when `representation` is "angle". Note that if the value of - `scatter-format` is "legendre", the order dimension will be one + `scatter_format` is "legendre", the order dimension will be one larger than the value of `order`, otherwise it will match `order`. Finally, the g_out dimension has a dimensionality of - `g_out bounds`[0] to `g_out bounds`[1]. - - **multiplicity matrix** (*double[]*) -- Flattened representation 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 @@ -154,9 +155,8 @@ Data specific to neutron scattering for the temperature K optional, if it is not provided no multiplication (i.e., values of 1.0) will be assumed. The pre-flattened array is shaped as follows (in row-major format): - `multiplicity matrix[g_in][g_out]`, or - `multiplicity matrix[num-polar][num-azimuthal][g_in][g_out]` + `multiplicity_matrix[g_in][g_out]`, or + `multiplicity_matrix[num_polar][num_azimuthal][g_in][g_out]` The former is used when `representation` is "isotropic", and the latter when `representation` is "angle". Finally, the g_out - dimension has a dimensionality of `g_out bounds`[0] to - `g_out bounds`[1]. \ No newline at end of file + dimension has a dimensionality of `g_min` to `g_max`. \ No newline at end of file diff --git a/openmc/mesh.py b/openmc/mesh.py index af65a2a16..2d5fda09b 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -298,12 +298,12 @@ class Mesh(object): # Would prefer to have the z ranges be the max supported float, but # these values are apparently different between python and Fortran. # Choosing a safe and sane default. - # Values of +/-1000 are used here as there seems to be an + # 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=-1000., boundary_type='reflective'), - openmc.ZPlane(z0=1000., boundary_type='reflective')] + 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 02c63f50b..c4515c969 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -912,7 +912,7 @@ class Library(object): self.representation = 'isotropic' if nuclide is not 'total': - xsdata.awr = self._nuclides[nuclide][1] + xsdata.atomic_weight_ratio = self._nuclides[nuclide][1] if subdomain is None: subdomain = 'all' diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index cba5c20a1..2bc320b7b 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -31,7 +31,7 @@ class XSdata(object): representation : {'isotropic', 'angle'}, optional Method used in generating the MGXS (isotropic or angle-dependent flux weighting). Defaults to 'isotropic' - temperatures : numpy.ndarray + temperatures : Iterable of float Temperatures (in units of Kelvin) of the provided datasets. Defaults to a single temperature at 294K. @@ -39,7 +39,7 @@ class XSdata(object): ---------- name : str 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. temperatures : numpy.ndarray @@ -60,24 +60,26 @@ class XSdata(object): 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``. + value of :attr:`XSdata.representation`. total : dict of numpy.ndarray Group-wise total cross section. absorption : dict of numpy.ndarray @@ -101,20 +103,22 @@ class XSdata(object): 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`` attribute instead. + :attr:`XSdata.nu_fission` attribute instead. nu_fission : dict of numpy.ndarray - Group-wise fission production cross section vector (i.e., if ``chi`` is - provided), or is the group-wise fission production matrix. + 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 ``representation`` as well as the number of - Legendre or other angular dimensions as described by ``order``. The - ``vector_shape``, ``matrix_shape``, and ``pn_matrix_shape`` properties are - provided to obtain the dimensionality of the data for each temperature. + 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: @@ -135,7 +139,7 @@ class XSdata(object): self.energy_groups = energy_groups self.temperatures = temperatures self.representation = representation - self._awr = None + self._atomic_weight_ratio = None self._fissionable = False self._scatter_format = 'legendre' self._order = None @@ -165,8 +169,8 @@ class XSdata(object): return self._representation @property - def awr(self): - return self._awr + def atomic_weight_ratio(self): + return self._atomic_weight_ratio @property def fissionable(self): @@ -286,12 +290,12 @@ class XSdata(object): check_value('representation', representation, _REPRESENTATIONS) self._representation = representation - @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 + @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 @fissionable.setter def fissionable(self, fissionable): @@ -300,14 +304,9 @@ class XSdata(object): @temperatures.setter def temperatures(self, temperatures): - check_type('temperatures', temperatures, Iterable, - expected_iter_type=Real) - # Convert to a numpy array so we can easily get the shape for checking - nptemperatures = np.asarray(temperatures) + check_iterable_type('temperatures', temperatures, Real) - check_value('temperatures dimensionality', nptemperatures.ndim, [1]) - - self._temperatures = nptemperatures + self._temperatures = temperatures @scatter_format.setter def scatter_format(self, scatter_format): @@ -1113,10 +1112,18 @@ class XSdata(object): self._multiplicity_matrix[i] = \ np.nan_to_num(self._multiplicity_matrix[i]) - def _get_xsdata_group(self, file): + def to_hdf5(self, file): + """Write XSdata to an HDF5 file + + Parameters + ---------- + file : h5py.File + HDF5 File (a root Group) to write to + + """ grp = file.create_group(self.name) - if self.awr is not None: - grp.attrs['awr'] = self.awr + 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: @@ -1124,11 +1131,11 @@ class XSdata(object): dtype='S') if self.representation == 'angle': if self.num_azimuthal is not None: - grp.attrs['num-azimuthal'] = self.num_azimuthal + grp.attrs['num_azimuthal'] = self.num_azimuthal if self.num_polar is not None: - grp.attrs['num-polar'] = self.num_polar + grp.attrs['num_polar'] = self.num_polar if self.scatter_format is not None: - grp.attrs['scatter-format'] = np.array(self.scatter_format, + grp.attrs['scatter_format'] = np.array(self.scatter_format, dtype='S') if self.order is not None: grp.attrs['order'] = self.order @@ -1184,8 +1191,8 @@ class XSdata(object): 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", + 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: @@ -1196,7 +1203,7 @@ class XSdata(object): 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", + scatt_grp.create_dataset("multiplicity_matrix", data=np.array(flat_mult)) # And finally, adjust g_out_bounds for 1-based group counting @@ -1227,8 +1234,8 @@ class XSdata(object): 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", + 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: @@ -1242,7 +1249,7 @@ class XSdata(object): 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", + scatt_grp.create_dataset("multiplicity_matrix", data=np.array(flat_mult)) # And finally, adjust g_out_bounds for 1-based group counting @@ -1253,7 +1260,7 @@ class XSdata(object): # Add the kinetics data if self._inverse_velocities[i] is not None: - xs_grp.create_dataset("inverse-velocities", + xs_grp.create_dataset("inverse_velocities", data=self._inverse_velocities[i]) @@ -1364,6 +1371,6 @@ class MGXSLibrary(object): file.attrs['group structure'] = self.energy_groups.group_edges for xsdata in self._xsdatas: - xsdata._get_xsdata_group(file) + xsdata.to_hdf5(file) file.close() diff --git a/scripts/openmc-update-mgxs.py b/scripts/openmc-update-mgxs.py deleted file mode 100755 index e3fd1bd2f..000000000 --- a/scripts/openmc-update-mgxs.py +++ /dev/null @@ -1,232 +0,0 @@ -#!/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 -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') - parser.add_argument('-c', '--compression', type=int, - help='HDF5 Compression Level') - args = vars(parser.parse_args()) - - if args['output'] == '': - filename = args['input'].name - extension = filename[filename.rfind('.'):] - if extension == '.xml': - filename = filename[:filename.rfind('.')] + '.h5' - args['output'] = filename - - # Parse and return commandline arguments. - return args - - -def get_data(element, entry): - try: - value = element.find(entry).text - except: - if entry in element.attrib: - value = element.attrib[entry] - else: - value = None - - if value is not None: - value = value.strip() - - 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: - # 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].awr = 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()) - total = temp.astype(np.float) - total = np.reshape(total, 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 = np.reshape(absorption, xsd[i].vector_shape) - xsd[i].set_absorption(absorption, temperature) - - temp = get_data(xsdata_elem, 'scatter') - temp = np.array(temp.split()) - temp = temp.astype(np.float) - scatter = np.reshape(temp, 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()) - temp = temp.astype(np.float) - multiplicity = np.reshape(temp, 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 = np.reshape(fission, 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 = np.reshape(kappa_fission, 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 = np.reshape(chi, 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()) - temp = temp.astype(np.float) - if chi is not None: - nu_fission = np.reshape(temp, xsd[i].vector_shape) - else: - nu_fission = np.reshape(temp, 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/src/geometry_header.F90 b/src/geometry_header.F90 index 1d1826fbf..3b489ece7 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/hdf5_interface.F90 b/src/hdf5_interface.F90 index 262bbc232..ce689afa3 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -85,17 +85,16 @@ module hdf5_interface public :: write_dataset public :: read_dataset - public :: check_attribute + public :: attribute_exists public :: write_attribute public :: read_attribute public :: file_create public :: file_open public :: file_close public :: create_group - public :: check_group + public :: object_exists public :: open_group public :: close_group - public :: check_dataset public :: open_dataset public :: close_dataset public :: get_shape @@ -253,7 +252,7 @@ contains ! CHECK_ATTRIBUTE Checks to see if an attribute exists in the object !=============================================================================== - function check_attribute(object_id, name) result(exists) + function attribute_exists(object_id, name) result(exists) integer(HID_T), intent(in) :: object_id character(*), intent(in) :: name ! name of group logical :: exists @@ -263,13 +262,13 @@ contains ! Check if attribute exists call h5aexists_by_name_f(object_id, '.', trim(name), exists, hdf5_err) - end function check_attribute + end function attribute_exists !=============================================================================== ! CHECK_GROUP Checks to see if a group exists in the object !=============================================================================== - function check_group(object_id, name) result(exists) + function object_exists(object_id, name) result(exists) integer(HID_T), intent(in) :: object_id character(*), intent(in) :: name ! name of group logical :: exists @@ -279,21 +278,7 @@ contains ! Check if group exists call h5ltpath_valid_f(object_id, trim(name), .true., exists, hdf5_err) - end function check_group - -!=============================================================================== -! CHECK_DATASET Checks to see if a dataset exists in the object -!=============================================================================== - - function check_dataset(object_id, name) result(exists) - integer(HID_T), intent(in) :: object_id - character(*), intent(in) :: name ! name of group - logical :: exists - - ! Wrap check_group since the method used there will work here too - exists = check_group(object_id, name) - - end function check_dataset + end function object_exists !=============================================================================== ! GET_DATASETS Gets a list of all the datasets in a given location. @@ -367,7 +352,7 @@ contains integer :: hdf5_err ! HDF5 error code ! Check if group exists - exists = check_group(group_id, name) + exists = object_exists(group_id, name) ! open group if it exists if (exists) then @@ -390,7 +375,7 @@ contains logical :: exists ! does the group exist ! Check if group exists - exists = check_group(group_id, name) + exists = object_exists(group_id, name) ! create group if (exists) then @@ -428,7 +413,7 @@ contains integer :: hdf5_err ! HDF5 error code ! Check if group exists - exists = check_group(group_id, name) + exists = object_exists(group_id, name) ! open group if it exists if (exists) then diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 2959e876d..8d5628567 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -1,17 +1,15 @@ 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 @@ -61,6 +59,9 @@ contains call time_read_xs % stop() end if + ! Normalize atom/weight percents + if (run_mode /= MODE_PLOTTING) call normalize_ao() + end subroutine read_input_xml !=============================================================================== @@ -2097,7 +2098,9 @@ 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 @@ -2106,9 +2109,6 @@ contains 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 @@ -4631,7 +4631,7 @@ contains ! Open file for reading file_id = file_open(path_cross_sections, 'r', parallel=.true.) - if (check_attribute(file_id, "groups")) then + if (attribute_exists(file_id, "groups")) then ! Get neutron group count call read_attribute(energy_groups, file_id, "groups") else @@ -4640,7 +4640,7 @@ contains allocate(rev_energy_bins(energy_groups + 1)) allocate(energy_bins(energy_groups + 1)) - if (check_attribute(file_id, "group structure")) then + if (attribute_exists(file_id, "group structure")) then ! Get neutron group structure call read_attribute(energy_bins, file_id, "group structure") else @@ -5621,7 +5621,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 @@ -5646,7 +5646,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 @@ -5910,67 +5910,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 2fbfdfd42..857b2ded0 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -3,8 +3,9 @@ module mgxs_data use constants use algorithm, only: find use error, only: fatal_error + use geometry_header, only: get_temperatures use global - use hdf5 + use hdf5_interface use material_header, only: Material use mgxs_header use output, only: write_message @@ -49,7 +50,8 @@ contains call write_message("Loading Cross Section Data...", 5) ! Get temperatures - call get_temperatures(temps) + call get_temperatures(cells, materials, material_dict, nuclide_dict, & + n_nuclides_total, temps) ! Open file for reading file_id = file_open(path_cross_sections, 'r', parallel=.true.) @@ -94,7 +96,7 @@ contains call write_message("Loading " // trim(name) // " Data...", 5) ! Check to make sure cross section set exists in the library - if (check_group(file_id, trim(name))) then + 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 "& @@ -102,7 +104,7 @@ contains end if ! First find out the data representation - if (check_attribute(xsdata_group, "representation")) 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 @@ -236,51 +238,5 @@ contains end subroutine get_mat_kTs -!=============================================================================== -! GET_TEMPERATURES returns a list of temperatures that each MGXS 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(temps) - type(VectorReal), allocatable, intent(out) :: temps(:) - - integer :: i, j, k - integer :: i_nuclide ! index in nuclides array - integer :: i_material - real(8) :: temperature ! temperature in Kelvin - - allocate(temps(n_nuclides_total)) - - 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 temps array - i_nuclide = nuclide_dict % get_key(to_lower(mat % names(k))) - - ! Add temperature if it hasn't already been added - if (find(temps(i_nuclide), temperature) == -1) then - call temps(i_nuclide) % push_back(temperature) - end if - end do NUC_NAMES_LOOP - end associate - end do - end do - - end subroutine get_temperatures - end module mgxs_data diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 193f337f1..ddce50be3 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -229,8 +229,8 @@ module mgxs_header ! Get rid of leading '/' this % name = trim(this % name(2:)) - if (check_attribute(xs_id, "awr")) then - call read_attribute(this % awr, xs_id, "awr") + 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 @@ -323,8 +323,8 @@ module mgxs_header end select ! Load the remaining metadata - if (check_attribute(xs_id, "scatter-format")) then - call read_attribute(temp_str, xs_id, "scatter-format") + 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 @@ -333,19 +333,19 @@ module mgxs_header else if (to_lower(temp_str) == 'tabular') then this % scatter_format = ANGLE_TABULAR else - call fatal_error("Invalid scatter-format option!") + call fatal_error("Invalid scatter_format option!") end if else this % scatter_format = ANGLE_LEGENDRE end if - if (check_attribute(xs_id, "fissionable")) then + 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 ! Get the library's value for the order - if (check_attribute(xs_id, "order")) then + if (attribute_exists(xs_id, "order")) then call read_attribute(order_dim, xs_id, "order") else call fatal_error("Order must be provided!") @@ -366,16 +366,16 @@ module mgxs_header ! information therein select type(this) type is (MgxsAngle) - if (check_attribute(xs_id, "num-polar")) then - call read_attribute(this % n_pol, xs_id, "num-polar") + if (attribute_exists(xs_id, "num_polar")) then + call read_attribute(this % n_pol, xs_id, "num_polar") else - call fatal_error("num-polar must be provided!") + call fatal_error("num_polar must be provided!") end if - if (check_attribute(xs_id, "num-azimuthal")) then - call read_attribute(this % n_azi, xs_id, "num-azimuthal") + 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!") + call fatal_error("num_azimuthal must be provided!") end if ! Set angle data to use equally-spaced bins @@ -433,7 +433,7 @@ module mgxs_header if (this % fissionable) then allocate(xs % nu_fission(groups)) allocate(xs % chi(groups, groups)) - if (check_dataset(xsdata_grp, "chi")) 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)) @@ -448,7 +448,7 @@ module mgxs_header deallocate(temp_arr) ! Get nu_fission (as a vector) - if (check_dataset(xsdata_grp, "nu-fission")) then + 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!") @@ -457,7 +457,7 @@ module mgxs_header else ! chi isnt provided but is within nu_fission, existing as a matrix ! So, get nu_fission (as a matrix) - if (check_dataset(xsdata_grp, "nu-fission")) then + if (object_exists(xsdata_grp, "nu-fission")) then allocate(temp_2d(groups, groups)) call read_dataset(temp_2d, xsdata_grp, "nu-fission") else @@ -481,7 +481,7 @@ module mgxs_header ! If we have a need* for the fission and kappa-fission x/s, get them ! (*Need is defined as will be using it to tally) if (get_fiss) then - if (check_dataset(xsdata_grp, "fission")) then + if (object_exists(xsdata_grp, "fission")) then allocate(xs % fission(groups)) call read_dataset(xs % fission, xsdata_grp, "fission") else @@ -490,7 +490,7 @@ module mgxs_header end if end if if (get_kfiss) then - if (check_dataset(xsdata_grp, "kappa-fission")) 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 @@ -500,7 +500,7 @@ module mgxs_header end if end if - if (check_dataset(xsdata_grp, "absorption")) then + if (object_exists(xsdata_grp, "absorption")) then allocate(xs % absorption(groups)) call read_dataset(xs % absorption, xsdata_grp, "absorption") else @@ -508,21 +508,21 @@ module mgxs_header end if ! Get scattering data - if (.not. check_group(xsdata_grp, "scatter data")) & - call fatal_error("Must provide 'scatter data'") - scatt_grp = open_group(xsdata_grp, 'scatter 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 (check_dataset(scatt_grp, "g_min")) then + 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 matrix must be provided") + call fatal_error("'g_min' for the scatter_data must be provided") end if - if (check_dataset(scatt_grp, "g_max")) then + 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 matrix must be provided") + 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 @@ -533,9 +533,9 @@ module mgxs_header end do ! Allocate flattened array allocate(temp_arr(length)) - if (.not. check_dataset(scatt_grp, 'scatter matrix')) & - call fatal_error("'scatter matrix' must be provided") - call read_dataset(temp_arr, scatt_grp, "scatter matrix") + 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. @@ -611,7 +611,7 @@ module mgxs_header deallocate(input_scatt) ! Now get the multiplication matrix - if (check_dataset(scatt_grp, 'multiplicity matrix')) then + 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 @@ -620,7 +620,7 @@ module mgxs_header end do ! Allocate flattened array allocate(temp_arr(length)) - call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") + call read_dataset(temp_arr, scatt_grp, "multiplicity_matrix") ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing ! to ScattData @@ -664,7 +664,7 @@ module mgxs_header ! Get, or infer, total xs data. allocate(xs % total(groups)) - if (check_dataset(xsdata_grp, "total")) then + if (object_exists(xsdata_grp, "total")) then call read_dataset(xs % total, xsdata_grp, "total") else xs % total(:) = xs % absorption(:) + xs % scatter % scattxs(:) @@ -677,9 +677,9 @@ module mgxs_header end do ! Get kinetics data - if (check_dataset(xsdata_grp, "inverse-velocities")) then + if (object_exists(xsdata_grp, "inverse_velocities")) then allocate(xs % inv_vel(groups)) - call read_dataset(xs % inv_vel, xsdata_grp, "inverse-velocities") + call read_dataset(xs % inv_vel, xsdata_grp, "inverse_velocities") end if ! Close the groups we have opened and deallocate @@ -731,7 +731,7 @@ module mgxs_header if (this % fissionable) then allocate(xs % nu_fission(groups, this % n_azi, this % n_pol)) allocate(xs % chi(groups, groups, this % n_azi, this % n_pol)) - if (check_dataset(xsdata_grp, "chi")) 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)) @@ -764,7 +764,7 @@ module mgxs_header deallocate(temp_arr) ! Get nu_fission (as a vector) - if (check_dataset(xsdata_grp, "nu-fission")) then + 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, & @@ -777,7 +777,7 @@ module mgxs_header else ! chi isnt provided but is within nu_fission, existing as a matrix ! So, get nu_fission (as a matrix) - if (check_dataset(xsdata_grp, "nu-fission")) then + 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)) @@ -816,7 +816,7 @@ module mgxs_header ! If we have a need* for the fission and kappa-fission x/s, get them ! (*Need is defined as will be using it to tally) if (get_fiss) then - if (check_dataset(xsdata_grp, "fission")) 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)) @@ -829,7 +829,7 @@ module mgxs_header end if end if if (get_kfiss) then - if (check_dataset(xsdata_grp, "kappa-fission")) 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)) @@ -843,7 +843,7 @@ module mgxs_header end if end if - if (check_dataset(xsdata_grp, "absorption")) then + 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)) @@ -855,27 +855,27 @@ module mgxs_header end if ! Get scattering data - if (.not. check_group(xsdata_grp, "scatter data")) & - call fatal_error("Must provide 'scatter data'") - scatt_grp = open_group(xsdata_grp, 'scatter 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 (check_dataset(scatt_grp, "g_min")) then + 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 matrix must be provided") + call fatal_error("'g_min' for the scatter_data must be provided") end if - if (check_dataset(scatt_grp, "g_max")) then + 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 matrix must be provided") + 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 @@ -891,9 +891,9 @@ module mgxs_header end do ! Allocate flattened array allocate(temp_arr(length)) - if (.not. check_dataset(scatt_grp, 'scatter matrix')) & - call fatal_error("'scatter matrix' must be provided") - call read_dataset(temp_arr, scatt_grp, "scatter matrix") + 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. @@ -988,7 +988,7 @@ module mgxs_header deallocate(input_scatt) ! Now get the multiplication matrix - if (check_dataset(scatt_grp, 'multiplicity matrix')) then + 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 @@ -1001,7 +1001,7 @@ module mgxs_header end do ! Allocate flattened array allocate(temp_arr(length)) - call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") + 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)) @@ -1067,7 +1067,7 @@ module mgxs_header end do allocate(xs % total(groups, this % n_azi, this % n_pol)) - if (check_dataset(xsdata_grp, "total")) then + 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, & @@ -1095,10 +1095,10 @@ module mgxs_header end do ! Get kinetics data - if (check_dataset(xsdata_grp, "inverse-velocities")) then + 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") + 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) @@ -1372,7 +1372,7 @@ module mgxs_header ! dense matrix for this storage, with a reduction to the sparse ! format at the end. - ! Get the multiplicity matrix + ! 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'})) @@ -1639,7 +1639,7 @@ module mgxs_header ! dense matrix for this storage, with a reduction to the sparse ! format at the end. - ! Get the multiplicity matrix + ! 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'})) diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 16d0a6b98..ed6600405 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -13,7 +13,7 @@ module nuclide_header 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, & - check_group, get_name, get_groups + object_exists, get_name, get_groups use list_header, only: ListInt use math, only: evaluate_legendre use multipole_header, only: MultipoleArray @@ -350,7 +350,7 @@ module nuclide_header call close_group(rxs_group) ! Read unresolved resonance probability tables if present - if (check_group(group_id, 'urr')) then + if (object_exists(group_id, 'urr')) then this % urr_present = .true. allocate(this % urr_data(n_temperature)) @@ -391,7 +391,7 @@ module nuclide_header end if ! Check for nu-total - if (check_group(group_id, 'total_nu')) then + if (object_exists(group_id, 'total_nu')) then nu_group = open_group(group_id, 'total_nu') ! Read total nu data @@ -410,7 +410,7 @@ module nuclide_header end if ! Read fission energy release data if present - if (check_group(group_id, 'fission_energy_release')) 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/sab_header.F90 b/src/sab_header.F90 index df2089dde..fbb981b88 100644 --- a/src/sab_header.F90 +++ b/src/sab_header.F90 @@ -9,7 +9,7 @@ module sab_header use error, only: warning, fatal_error use hdf5, only: HID_T, HSIZE_T, SIZE_T use hdf5_interface, only: read_attribute, get_shape, open_group, close_group, & - open_dataset, read_dataset, close_dataset, get_datasets, check_group, & + open_dataset, read_dataset, close_dataset, get_datasets, object_exists, & get_name use secondary_correlated, only: CorrelatedAngleEnergy use stl_vector, only: VectorInt, VectorReal @@ -209,7 +209,7 @@ contains T_group = open_group(group_id, temp_str) ! Coherent elastic data - if (check_group(T_group, 'elastic')) 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') @@ -251,7 +251,7 @@ contains end if ! Inelastic data - if (check_group(T_group, 'inelastic')) then + if (object_exists(T_group, 'inelastic')) then ! Read type of inelastic data inelastic_group = open_group(T_group, 'inelastic') diff --git a/src/secondary_uncorrelated.F90 b/src/secondary_uncorrelated.F90 index 756ff83df..40aa827da 100644 --- a/src/secondary_uncorrelated.F90 +++ b/src/secondary_uncorrelated.F90 @@ -8,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, check_group + use hdf5_interface, only: read_attribute, open_group, close_group, & + object_exists use random_lcg, only: prn !=============================================================================== @@ -60,14 +61,14 @@ contains character(MAX_WORD_LEN) :: type ! Check if angle group is present & read - if (check_group(group_id, 'angle')) then + 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 & read - if (check_group(group_id, 'energy')) then + if (object_exists(group_id, 'energy')) then energy_group = open_group(group_id, 'energy') call read_attribute(type, energy_group, 'type') select case (type) From a00a880b88c03bbd79db3b17965590c649151988 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 10 Oct 2016 15:20:03 -0400 Subject: [PATCH 30/42] Forgot to include file --- scripts/openmc-update-mgxs | 233 +++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100755 scripts/openmc-update-mgxs diff --git a/scripts/openmc-update-mgxs b/scripts/openmc-update-mgxs new file mode 100755 index 000000000..5d9591627 --- /dev/null +++ b/scripts/openmc-update-mgxs @@ -0,0 +1,233 @@ +#!/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') + parser.add_argument('-c', '--compression', type=int, + help='HDF5 Compression Level') + 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): + try: + value = element.find(entry).text + except: + if entry in element.attrib: + value = element.attrib[entry] + else: + value = None + + if value is not None: + value = value.strip() + + 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: + # 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']) From c446f10e5add8af9020ae42c0010fedaab3946e6 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 10 Oct 2016 15:33:14 -0400 Subject: [PATCH 31/42] Last @paulromano comment I held off on. Didnt update all mgxs h5 libraries yet as future comments from others will require I do that anyways. --- openmc/mesh.py | 4 ++-- openmc/mgxs_library.py | 2 +- scripts/openmc-update-mgxs | 14 ++++++-------- tests/1d_mgxs.h5 | Bin 123864 -> 123864 bytes 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/openmc/mesh.py b/openmc/mesh.py index 2d5fda09b..014cbc467 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -302,8 +302,8 @@ class Mesh(object): # 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')] + 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 2bc320b7b..8e6089a1a 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -306,7 +306,7 @@ class XSdata(object): def temperatures(self, temperatures): check_iterable_type('temperatures', temperatures, Real) - self._temperatures = temperatures + self._temperatures = np.array(temperatures) @scatter_format.setter def scatter_format(self, scatter_format): diff --git a/scripts/openmc-update-mgxs b/scripts/openmc-update-mgxs index 5d9591627..f16ad9d1b 100755 --- a/scripts/openmc-update-mgxs +++ b/scripts/openmc-update-mgxs @@ -63,17 +63,15 @@ def parse_args(): def get_data(element, entry): - try: - value = element.find(entry).text - except: + value = element.find(entry) + if value is not None: + value = value.text.strip() + else: if entry in element.attrib: - value = element.attrib[entry] + value = element.attrib[entry].strip() else: value = None - if value is not None: - value = value.strip() - return value @@ -140,7 +138,7 @@ if __name__ == '__main__': try: # It is in our list, so store that entry i = names.index(name) - except: + except ValueError: # It is not in our list, so add it i = -1 xsd.append(openmc.XSdata(name, energy_groups, diff --git a/tests/1d_mgxs.h5 b/tests/1d_mgxs.h5 index 65dcf36cf7ee6c22d854c4fbcf2160e63209280f..401fe02fc54bedac6d1b5443db23a923de30c5f0 100644 GIT binary patch delta 1643 zcmZvcUr19?9LG8SUuE_XYChyYR1(E8O0ATcLKp=T#E>GcwwHvwCZy~-2hq z7$^tQ&TVW6Zbs1_*YYHp*T<~qaFOx8ZQ8JUP|<+55{ z^`P!-&;uvxIZtJ)OiVVRDkSTw-lOWN38{K6a@B{mg6geHqG}R4ce$CUD)wwJh^nL} z+AVUMv!W@zH-&iBpn268&rCBl@q=`YALQo1zjpV)u2zbJwp+FIa=yY`D{qVIOqbk_dP0B>I!vJfB=^f0{oIHa3A!Yg`5g>JXT+;kkK$Aum@pV4b5VS@LV zIvJ&wELk&>XZuB$byfhItni@bI#6{S=DlZ6V0s&J5cOXhp~TS zonG^9h@eDx=9?g_u7Pcn4Wu`v8(I8IOwIT!i!GhJ`~z0+vR>rnM)-U(5e0Uq{^!)_ zpO91769H5V#U2AF2$o|(I0-J>2f|U5xOfm`!GUq^Z=l3l>&(1W`u9P@EivCyG~{z#JSZ&BnPWqK%d*7N~xj(4g&$-)s)UZ{u&8zmH)=tbdfg3f!+dABp`=Hy;fdlEaw>8nbw*t^>aiOXM1N)U1@2km zc{0pVARX3c9U{+;)*Ixxll6<<+P1lnBl|s|b&a_(^Z-rvO=vjE?wi{tJ$c4xP=Lw{ z7F8HGdS#f8CUv@sX4utYjzr{;{-mI{HC6+IrOhF=U>R5Q8U;1aX{Khf_rZ#5nJ>Z=W_`Yv$QhjoJL&5NRH3OakKg{aET959Hg z&CRr1{$q_ZjC*Ho<8;~C1UG+^;Zvs z_A{Mg`^o5sQ!$;jzcawwHxF4gH0WV?<#AXyb%a;+j|$yxjd|%fOpOaYZakycP|^hN zF>O*qdW5B`M)GW5t>i(czZ8P5LgUQ-ZOlt;;|8c-?}difyf6CR2Ph|SA`uY2`IzZ zzrIGV`PW5IB0T+F5LVW}vB3t?uj@wE%|)hW{GH8~PFng2Yj#;L(oz$AKADVyyD$Fd z)aakEQ`i>;6b#uJ3n&Pd;y@$`E>8fFC~|xv2(jQ`B49B1O9}|lY|38`17|*WxkChU0raR1}FHw5d2yBvRAl z(Ua52W9uAnnT$IX9rY#>Iw16osfhRk*MrRCmm$EQ?6?lEUfAXp^QYJxH$?>6tB2}B{Wp3jk8Zg8?7%`p!z9J ylQb>RV4nxHC6J9|f9DFx#2ZdRRvk~g1#C01G#e&qbS?O>?;RLVr@J97HU0%r Date: Mon, 10 Oct 2016 16:10:39 -0400 Subject: [PATCH 32/42] Resolved @wbinventor comments --- docs/source/io_formats/mgxs_library.rst | 8 +- openmc/mgxs/library.py | 88 ++++++++-------- openmc/mgxs_library.py | 127 ++++++++++++------------ scripts/openmc-update-mgxs | 12 +-- src/input_xml.F90 | 2 +- 5 files changed, 118 insertions(+), 119 deletions(-) diff --git a/docs/source/io_formats/mgxs_library.rst b/docs/source/io_formats/mgxs_library.rst index e9b59a20f..9262a234e 100644 --- a/docs/source/io_formats/mgxs_library.rst +++ b/docs/source/io_formats/mgxs_library.rst @@ -6,7 +6,7 @@ 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, the multi-group meta-data and the nuclear data itself is contained within an ``mgxs.h5``. This portion of @@ -89,19 +89,19 @@ Temperature-dependent data, provided for temperature K. 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 data set + [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 data set + [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 data set + [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. diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index c4515c969..5535f8485 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -186,14 +186,14 @@ class Library(object): @property def domains(self): - if self._domains == 'all': - if self.domain_type == 'material': + if self._domains is 'all': + if self.domain_type is 'material': return self.openmc_geometry.get_all_materials() elif self.domain_type in ['cell', 'distribcell']: return self.openmc_geometry.get_all_material_cells() - elif self.domain_type == 'universe': + elif self.domain_type is 'universe': return self.openmc_geometry.get_all_universes() - elif self.domain_type == 'mesh': + elif self.domain_type is 'mesh': raise ValueError('Unable to get domains for Mesh domain type') else: raise ValueError('Unable to get domains without a domain type') @@ -265,7 +265,7 @@ class Library(object): @mgxs_types.setter def mgxs_types(self, mgxs_types): all_mgxs_types = openmc.mgxs.MGXS_TYPES + openmc.mgxs.MDGXS_TYPES - if mgxs_types == 'all': + if mgxs_types is 'all': self._mgxs_types = all_mgxs_types else: cv.check_iterable_type('mgxs_types', mgxs_types, basestring) @@ -277,7 +277,7 @@ class Library(object): def by_nuclide(self, by_nuclide): cv.check_type('by_nuclide', by_nuclide, bool) - if by_nuclide == True and self.domain_type == 'mesh': + if by_nuclide == True and self.domain_type is 'mesh': raise ValueError('Unable to create MGXS library by nuclide with ' 'mesh domain') @@ -287,7 +287,7 @@ class Library(object): def domain_type(self, domain_type): cv.check_value('domain type', domain_type, openmc.mgxs.DOMAIN_TYPES) - if self.by_nuclide == True and domain_type == 'mesh': + if self.by_nuclide == True and domain_type is 'mesh': raise ValueError('Unable to create MGXS library by nuclide with ' 'mesh domain') @@ -297,21 +297,21 @@ class Library(object): def domains(self, domains): # Use all materials, cells or universes in the geometry as domains - if domains == 'all': + if domains is 'all': self._domains = domains # User specified a list of material, cell or universe domains else: - if self.domain_type == 'material': + if self.domain_type is 'material': cv.check_iterable_type('domain', domains, openmc.Material) all_domains = self.openmc_geometry.get_all_materials() elif self.domain_type in ['cell', 'distribcell']: cv.check_iterable_type('domain', domains, openmc.Cell) all_domains = self.openmc_geometry.get_all_material_cells() - elif self.domain_type == 'universe': + elif self.domain_type is 'universe': cv.check_iterable_type('domain', domains, openmc.Universe) all_domains = self.openmc_geometry.get_all_universes() - elif self.domain_type == 'mesh': + elif self.domain_type is 'mesh': cv.check_iterable_type('domain', domains, openmc.Mesh) # The mesh and geometry are independent, so set all_domains @@ -355,7 +355,7 @@ class Library(object): def correction(self, correction): cv.check_value('correction', correction, ('P0', None)) - if correction == 'P0' and self.legendre_order > 0: + if correction is 'P0' and self.legendre_order > 0: warn('The P0 correction will be ignored since the scattering ' 'order "{}" is greater than zero'.format(self.legendre_order)) @@ -367,7 +367,7 @@ class Library(object): cv.check_greater_than('legendre_order', legendre_order, 0, equality=True) cv.check_less_than('legendre_order', legendre_order, 10, equality=True) - if self.correction == 'P0' and legendre_order > 0: + if self.correction is 'P0' and legendre_order > 0: msg = 'The P0 correction will be ignored since the scattering ' \ 'order {} is greater than zero'.format(self.legendre_order) warn(msg, RuntimeWarning) @@ -505,7 +505,7 @@ class Library(object): self._openmc_geometry = statepoint.summary.openmc_geometry self._nuclides = statepoint.summary.nuclides - if statepoint.run_mode == 'k-eigenvalue': + if statepoint.run_mode is 'k-eigenvalue': self._keff = statepoint.k_combined[0] # Load tallies for each MGXS for each domain and mgxs type @@ -543,13 +543,13 @@ class Library(object): """ - if self.domain_type == 'material': + if self.domain_type is 'material': cv.check_type('domain', domain, (openmc.Material, Integral)) - elif self.domain_type == 'cell' or self.domain_type == 'distribcell': + elif self.domain_type is 'cell' or self.domain_type is 'distribcell': cv.check_type('domain', domain, (openmc.Cell, Integral)) - elif self.domain_type == 'universe': + elif self.domain_type is 'universe': cv.check_type('domain', domain, (openmc.Universe, Integral)) - elif self.domain_type == 'mesh': + elif self.domain_type is 'mesh': cv.check_type('domain', domain, (openmc.Mesh, Integral)) # Check that requested domain is included in library @@ -662,7 +662,7 @@ class Library(object): # Clone this Library to initialize the subdomain-averaged version subdomain_avg_library = copy.deepcopy(self) - if subdomain_avg_library.domain_type == 'distribcell': + if subdomain_avg_library.domain_type is 'distribcell': subdomain_avg_library.domain_type = 'cell' else: return subdomain_avg_library @@ -671,7 +671,7 @@ class Library(object): for domain in self.domains: for mgxs_type in self.mgxs_types: mgxs = subdomain_avg_library.get_mgxs(domain, mgxs_type) - if mgxs.domain_type == 'distribcell': + if mgxs.domain_type is 'distribcell': avg_mgxs = mgxs.get_subdomain_avg_xs() subdomain_avg_library.all_mgxs[domain.id][mgxs_type] = avg_mgxs @@ -751,7 +751,7 @@ class Library(object): for mgxs_type in self.mgxs_types: mgxs = self.all_mgxs[domain.id][mgxs_type] - if subdomains == 'avg': + if subdomains is 'avg': mgxs = mgxs.get_subdomain_avg_xs() mgxs.build_hdf5_store(filename, directory, xs_type=xs_type, @@ -824,8 +824,9 @@ class Library(object): def get_xsdata(self, domain, xsdata_name, nuclide='total', xs_type='macro', 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). Note that this method does not build an XSdata + 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. @@ -856,7 +857,7 @@ class Library(object): Returns ------- xsdata : openmc.XSdata - Multi-Group Cross Section data set object. + Multi-Group Cross Section dataset object. Raises ------ @@ -920,7 +921,7 @@ class Library(object): subdomain = [subdomain] # Now get xs data itself - if 'nu-transport' in self.mgxs_types and self.correction == 'P0': + if 'nu-transport' in self.mgxs_types and self.correction is 'P0': mymgxs = self.get_mgxs(domain, 'nu-transport') xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], subdomains=subdomain) @@ -995,7 +996,7 @@ class Library(object): # scattering multiplication (nu-scatter) must be # accounted for approximately by using an adjusted # absorption cross section. - if 'total' in self.mgxs_types: + 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( @@ -1005,9 +1006,11 @@ class Library(object): 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. + 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 ---------- @@ -1053,7 +1056,7 @@ class Library(object): # Initialize file mgxs_file = openmc.MGXSLibrary(self.energy_groups) - if self.domain_type == 'mesh': + if self.domain_type is 'mesh': # Create the xsdata objects and add to the mgxs_file i = 0 for domain in self.domains: @@ -1099,14 +1102,15 @@ class Library(object): 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. - 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. + 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 ---------- @@ -1155,14 +1159,14 @@ class Library(object): # the multiple meshes could be overlapping or in disparate regions # of the continuous energy model. The next step makes sure there is # only one before continuing. - if self.domain_type == 'mesh': + if self.domain_type is 'mesh': cv.check_length("domains", self.domains, 1, 1) # Get the MGXS File Data mgxs_file = self.create_mg_library('macro', xsdata_names) # Now move on the creating the geometry and assigning materials - if self.domain_type == 'mesh': + if self.domain_type is 'mesh': root = openmc.Universe(name='root', universe_id=0) # Add cells representative of the mesh with reflective BC @@ -1208,13 +1212,13 @@ class Library(object): materials.append(material) # Differentiate Geometry with new Material - if self.domain_type == 'material': + if self.domain_type is 'material': # Fill all appropriate Cells with new Material for cell in all_cells: if cell.fill.id == domain.id: cell.fill = material - elif self.domain_type == 'cell': + elif self.domain_type is 'cell': for cell in all_cells: if cell.id == domain.id: cell.fill = material diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 8e6089a1a..67a9b01f4 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -242,28 +242,28 @@ class XSdata(object): @property def vector_shape(self): - if self.representation == 'isotropic': + if self.representation is 'isotropic': return (self.energy_groups.num_groups,) - elif self.representation == 'angle': + elif self.representation is 'angle': return (self.num_polar, self.num_azimuthal, self.energy_groups.num_groups) @property def matrix_shape(self): - if self.representation == 'isotropic': + if self.representation is 'isotropic': return (self.energy_groups.num_groups, self.energy_groups.num_groups) - elif self.representation == 'angle': + elif self.representation is 'angle': return (self.num_polar, self.num_azimuthal, self.energy_groups.num_groups, self.energy_groups.num_groups) @property def pn_matrix_shape(self): - if self.representation == 'isotropic': + if self.representation is 'isotropic': return (self.num_orders, self.energy_groups.num_groups, self.energy_groups.num_groups) - elif self.representation == 'angle': + elif self.representation is 'angle': return (self.num_polar, self.num_azimuthal, self.num_orders, self.energy_groups.num_groups, self.energy_groups.num_groups) @@ -297,11 +297,6 @@ class XSdata(object): check_greater_than('atomic_weight_ratio', atomic_weight_ratio, 0.0) self._atomic_weight_ratio = atomic_weight_ratio - @fissionable.setter - def fissionable(self, fissionable): - check_type('fissionable', fissionable, bool) - self._fissionable = fissionable - @temperatures.setter def temperatures(self, temperatures): check_iterable_type('temperatures', temperatures, Real) @@ -374,8 +369,8 @@ class XSdata(object): total: np.ndarray Total Cross Section temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). See also -------- @@ -389,7 +384,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) self._total[i] = nptotal def set_absorption(self, absorption, temperature=294.): @@ -401,8 +396,8 @@ class XSdata(object): absorption: np.ndarray Absorption Cross Section temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). See also -------- @@ -417,7 +412,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) self._absorption[i] = npabsorption def set_fission(self, fission, temperature=294.): @@ -429,8 +424,8 @@ class XSdata(object): fission: np.ndarray Fission Cross Section temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). See also -------- @@ -444,7 +439,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) self._fission[i] = npfission if np.sum(npfission) > 0.0: @@ -459,8 +454,8 @@ class XSdata(object): kappa_fission: np.ndarray Kappa-Fission Cross Section temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). See also -------- @@ -476,7 +471,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) self._kappa_fission[i] = npkappa_fission if np.sum(npkappa_fission) > 0.0: @@ -491,8 +486,8 @@ class XSdata(object): chi: np.ndarray Fission Spectrum temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). See also -------- @@ -515,7 +510,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) self._chi[i] = npchi if self.use_chi is not None: @@ -530,8 +525,8 @@ class XSdata(object): scatter: np.ndarray Scattering Matrix Cross Section temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). See also -------- @@ -546,7 +541,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) self._scatter_matrix[i] = npscatter def set_multiplicity_matrix(self, multiplicity, temperature=294.): @@ -558,8 +553,8 @@ class XSdata(object): multiplicity: np.ndarray Multiplicity Matrix Cross Section temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). See also -------- @@ -575,7 +570,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) self._multiplicity_matrix[i] = npmultiplicity def set_nu_fission(self, nu_fission, temperature=294.): @@ -587,8 +582,8 @@ class XSdata(object): nu_fission: np.ndarray Nu-fission Cross Section temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). See also -------- @@ -630,7 +625,7 @@ class XSdata(object): else: self.use_chi = False - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) self._nu_fission[i] = npnu_fission if np.sum(npnu_fission) > 0.0: self._fissionable = True @@ -644,8 +639,8 @@ class XSdata(object): inv_vel: np.ndarray Inverse velocities in units of sec/cm. temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). """ check_type('inverse velocities', inv_vel, Iterable, @@ -657,7 +652,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) self._inverse_velocities[i] = npinv_vel def set_total_mgxs(self, total, temperature=294., nuclide='total', @@ -672,8 +667,8 @@ class XSdata(object): MGXS Object containing the total or transport cross section for the domain of interest. temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + 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'. @@ -699,7 +694,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) if self.representation is 'isotropic': self._total[i] = total.get_xs(nuclides=nuclide, xs_type=xs_type, subdomains=subdomain) @@ -718,8 +713,8 @@ class XSdata(object): MGXS Object containing the absorption cross section for the domain of interest. temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + 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'. @@ -745,7 +740,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) if self.representation is 'isotropic': self._absorption[i] = absorption.get_xs(nuclides=nuclide, xs_type=xs_type, @@ -765,8 +760,8 @@ class XSdata(object): MGXS Object containing the fission cross section for the domain of interest. temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + 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'. @@ -792,7 +787,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) if self.representation is 'isotropic': self._fission[i] = fission.get_xs(nuclides=nuclide, xs_type=xs_type, @@ -812,8 +807,8 @@ class XSdata(object): MGXS Object containing the nu-fission cross section for the domain of interest. temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + 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'. @@ -840,7 +835,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) if self.representation is 'isotropic': self._nu_fission[i] = nu_fission.get_xs(nuclides=nuclide, xs_type=xs_type, @@ -870,8 +865,8 @@ class XSdata(object): MGXS Object containing the kappa-fission cross section for the domain of interest. temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + 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'. @@ -897,7 +892,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) if self.representation is 'isotropic': self._kappa_fission[i] = k_fission.get_xs(nuclides=nuclide, xs_type=xs_type, @@ -916,8 +911,8 @@ class XSdata(object): chi: openmc.mgxs.Chi MGXS Object containing chi for the domain of interest. temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + 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'. @@ -948,7 +943,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) if self.representation is 'isotropic': self._chi[i] = chi.get_xs(nuclides=nuclide, xs_type=xs_type, subdomains=subdomain) @@ -973,8 +968,8 @@ class XSdata(object): MGXS Object containing the scatter matrix cross section for the domain of interest. temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + 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'. @@ -1000,7 +995,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - if (self.scatter_format != 'legendre'): + if self.scatter_format is not 'legendre': msg = 'Anisotropic scattering representations other than ' \ 'Legendre expansions have not yet been implemented in ' \ 'openmc.mgxs.' @@ -1016,7 +1011,7 @@ class XSdata(object): check_value('legendre_order', scatter.legendre_order, [self.order]) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) if self.representation is 'isotropic': # Get the scattering orders in the outermost dimension self._scatter_matrix[i] = np.zeros((self.num_orders, @@ -1054,8 +1049,8 @@ class XSdata(object): MGXS Object containing the scattering matrix cross section for the domain of interest. temperature : float - Temperature (in units of Kelvin) of the provided dataset. Defaults - to 294K + 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'. @@ -1094,7 +1089,7 @@ class XSdata(object): check_value('domain_type', scatter.domain_type, ['universe', 'cell', 'material', 'mesh']) - i = self.temperatures.tolist().index(temperature) + i = np.where(self.temperatures == temperature) if self.representation is 'isotropic': nuscatt = nuscatter.get_xs(nuclides=nuclide, xs_type=xs_type, moment=0, @@ -1129,7 +1124,7 @@ class XSdata(object): if self.representation is not None: grp.attrs['representation'] = np.array(self.representation, dtype='S') - if self.representation == 'angle': + if self.representation is 'angle': if self.num_azimuthal is not None: grp.attrs['num_azimuthal'] = self.num_azimuthal if self.num_polar is not None: @@ -1176,7 +1171,7 @@ class XSdata(object): # Get the sparse scattering data to print to the library G = self.energy_groups.num_groups - if self.representation == 'isotropic': + if self.representation is '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, :]) @@ -1212,7 +1207,7 @@ class XSdata(object): scatt_grp.create_dataset("g_min", data=g_out_bounds[:, 0]) scatt_grp.create_dataset("g_max", data=g_out_bounds[:, 1]) - elif self.representation == 'angle': + elif self.representation is 'angle': Np = self.num_polar Na = self.num_azimuthal g_out_bounds = np.zeros((Np, Na, G, 2), dtype=np.int) diff --git a/scripts/openmc-update-mgxs b/scripts/openmc-update-mgxs index f16ad9d1b..6122ff626 100755 --- a/scripts/openmc-update-mgxs +++ b/scripts/openmc-update-mgxs @@ -51,10 +51,10 @@ def parse_args(): help='HDF5 Compression Level') args = vars(parser.parse_args()) - if args['output'] == '': + if args['output'] is '': filename = args['input'].name extension = filenameos.path.splitext() - if extension == '.xml': + if extension is '.xml': filename = filename[:filename.rfind('.')] + '.h5' args['output'] = filename @@ -75,7 +75,7 @@ def get_data(element, entry): return value -if __name__ == '__main__': +if __name__ is '__main__': args = parse_args() # Parse the XML data. @@ -117,7 +117,7 @@ if __name__ == '__main__': representation = get_data(xsdata_elem, 'representation') if representation is None: representation = 'isotropic' - if representation == 'angle': + if representation is 'angle': n_azi = int(get_data(xsdata_elem, 'num_azimuthal')) n_pol = int(get_data(xsdata_elem, 'num_polar')) @@ -146,14 +146,14 @@ if __name__ == '__main__': representation=representation)) if awr is not None: xsd[-1].atomic_weight_ratio = awr - if representation == 'angle': + if representation is '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': + if scatter_format is 'legendre': order_dim = order + 1 else: order_dim = order diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 8d5628567..fd8a33c68 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -4673,7 +4673,7 @@ contains libraries(i) % materials(1) = names(i) end do - ! Close MGXS HDF file + ! Close MGXS HDF5 file call file_close(file_id) end subroutine read_mg_cross_sections_header From 23049dc03cd86a03e1b82a5cbcd6eff83c619099 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 10 Oct 2016 16:23:38 -0400 Subject: [PATCH 33/42] Replaced nptotal with total (et al) per the request by @wbinventor --- openmc/mgxs_library.py | 79 +++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 67a9b01f4..c2246fa92 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -379,13 +379,13 @@ class XSdata(object): """ 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]) + total = np.asarray(total) + check_value('total shape', total.shape, [self.vector_shape]) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) i = np.where(self.temperatures == temperature) - self._total[i] = nptotal + self._total[i] = total def set_absorption(self, absorption, temperature=294.): """This method sets the cross section for this XSdata object at the @@ -406,14 +406,13 @@ class XSdata(object): """ 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]) + absorption = np.asarray(absorption) + check_value('absorption shape', absorption.shape, [self.vector_shape]) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) i = np.where(self.temperatures == temperature) - self._absorption[i] = npabsorption + self._absorption[i] = absorption def set_fission(self, fission, temperature=294.): """This method sets the cross section for this XSdata object at the @@ -434,15 +433,15 @@ class XSdata(object): """ 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]) + fission = np.asarray(fission) + check_value('fission shape', fission.shape, [self.vector_shape]) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) i = np.where(self.temperatures == temperature) - self._fission[i] = npfission + self._fission[i] = fission - if np.sum(npfission) > 0.0: + if np.sum(fission) > 0.0: self._fissionable = True def set_kappa_fission(self, kappa_fission, temperature=294.): @@ -465,16 +464,16 @@ class XSdata(object): 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, + 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) i = np.where(self.temperatures == temperature) - self._kappa_fission[i] = npkappa_fission + self._kappa_fission[i] = kappa_fission - if np.sum(npkappa_fission) > 0.0: + if np.sum(kappa_fission) > 0.0: self._fissionable = True def set_chi(self, chi, temperature=294.): @@ -502,16 +501,16 @@ class XSdata(object): 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) + 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) i = np.where(self.temperatures == temperature) - self._chi[i] = npchi + self._chi[i] = chi if self.use_chi is not None: self.use_chi = True @@ -534,15 +533,15 @@ class XSdata(object): """ # 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]) + 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) - self._scatter_matrix[i] = npscatter + 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 @@ -562,16 +561,16 @@ class XSdata(object): """ # 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, + 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) i = np.where(self.temperatures == temperature) - self._multiplicity_matrix[i] = npmultiplicity + self._multiplicity_matrix[i] = multiplicity def set_nu_fission(self, nu_fission, temperature=294.): """This method sets the cross section for this XSdata object at the @@ -601,33 +600,33 @@ class XSdata(object): # 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) + 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. - if npnu_fission.shape == self.vector_shape: + if nu_fission.shape == self.vector_shape: self.use_chi = True else: self.use_chi = False i = np.where(self.temperatures == temperature) - self._nu_fission[i] = npnu_fission - if np.sum(npnu_fission) > 0.0: + self._nu_fission[i] = nu_fission + if np.sum(nu_fission) > 0.0: self._fissionable = True def set_inverse_velocities(self, inv_vel, temperature=294.): @@ -646,14 +645,14 @@ class XSdata(object): 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 - npinv_vel = np.asarray(inv_vel) - check_value('inverse velocities shape', npinv_vel.shape, + 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) - self._inverse_velocities[i] = npinv_vel + self._inverse_velocities[i] = inv_vel def set_total_mgxs(self, total, temperature=294., nuclide='total', xs_type='macro', subdomain=None): From e85393936fef8d89f37bb9f04e119af7ab32a73d Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Thu, 13 Oct 2016 19:36:23 -0400 Subject: [PATCH 34/42] Fixed failing test_mgxs_library_ce_to_mg --- openmc/mgxs/library.py | 2 +- openmc/mgxs_library.py | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 5535f8485..64210606d 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -924,7 +924,7 @@ class Library(object): if 'nu-transport' in self.mgxs_types and self.correction is '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], diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index c2246fa92..edddd0bfa 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -384,7 +384,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] self._total[i] = total def set_absorption(self, absorption, temperature=294.): @@ -411,7 +411,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] self._absorption[i] = absorption def set_fission(self, fission, temperature=294.): @@ -438,7 +438,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] self._fission[i] = fission if np.sum(fission) > 0.0: @@ -470,7 +470,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] self._kappa_fission[i] = kappa_fission if np.sum(kappa_fission) > 0.0: @@ -509,7 +509,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] self._chi[i] = chi if self.use_chi is not None: @@ -540,7 +540,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] self._scatter_matrix[i] = scatter def set_multiplicity_matrix(self, multiplicity, temperature=294.): @@ -569,7 +569,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] self._multiplicity_matrix[i] = multiplicity def set_nu_fission(self, nu_fission, temperature=294.): @@ -624,7 +624,7 @@ class XSdata(object): else: self.use_chi = False - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] self._nu_fission[i] = nu_fission if np.sum(nu_fission) > 0.0: self._fissionable = True @@ -651,7 +651,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] self._inverse_velocities[i] = inv_vel def set_total_mgxs(self, total, temperature=294., nuclide='total', @@ -693,7 +693,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] if self.representation is 'isotropic': self._total[i] = total.get_xs(nuclides=nuclide, xs_type=xs_type, subdomains=subdomain) @@ -739,7 +739,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] if self.representation is 'isotropic': self._absorption[i] = absorption.get_xs(nuclides=nuclide, xs_type=xs_type, @@ -786,7 +786,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] if self.representation is 'isotropic': self._fission[i] = fission.get_xs(nuclides=nuclide, xs_type=xs_type, @@ -834,7 +834,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] if self.representation is 'isotropic': self._nu_fission[i] = nu_fission.get_xs(nuclides=nuclide, xs_type=xs_type, @@ -891,7 +891,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] if self.representation is 'isotropic': self._kappa_fission[i] = k_fission.get_xs(nuclides=nuclide, xs_type=xs_type, @@ -942,7 +942,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] if self.representation is 'isotropic': self._chi[i] = chi.get_xs(nuclides=nuclide, xs_type=xs_type, subdomains=subdomain) @@ -1010,7 +1010,7 @@ class XSdata(object): check_value('legendre_order', scatter.legendre_order, [self.order]) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] if self.representation is 'isotropic': # Get the scattering orders in the outermost dimension self._scatter_matrix[i] = np.zeros((self.num_orders, @@ -1088,7 +1088,7 @@ class XSdata(object): check_value('domain_type', scatter.domain_type, ['universe', 'cell', 'material', 'mesh']) - i = np.where(self.temperatures == temperature) + i = np.where(self.temperatures == temperature)[0][0] if self.representation is 'isotropic': nuscatt = nuscatter.get_xs(nuclides=nuclide, xs_type=xs_type, moment=0, From 7b3007d30ce967214b7640d5c441225433e3f9c4 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Thu, 13 Oct 2016 19:40:34 -0400 Subject: [PATCH 35/42] fixed source indentation issue --- src/geometry_header.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geometry_header.F90 b/src/geometry_header.F90 index 3b489ece7..9f4be90b9 100644 --- a/src/geometry_header.F90 +++ b/src/geometry_header.F90 @@ -378,7 +378,7 @@ contains end do NUC_NAMES_LOOP if (present(sab_temps) .and. present(sab_dict) .and. & - mat % n_sab > 0) then + 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))) From b005aace7e2014e0d6b211d760ab50b8e94ac3db Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 15 Oct 2016 11:33:00 -0400 Subject: [PATCH 36/42] Added a scatter_shape parameter to the library format and the ability to read/write it (but do nothing with it aside from check for the default value). Also converted back from is checks in the python for a string to ==, since is does not work for many cases --- docs/source/io_formats/mgxs_library.rst | 74 +++++++++++------------ openmc/mgxs/library.py | 62 ++++++++++---------- openmc/mgxs_library.py | 75 +++++++++++++++--------- scripts/openmc-update-mgxs | 14 ++--- src/mgxs_header.F90 | 7 +++ tests/1d_mgxs.h5 | Bin 123864 -> 124632 bytes 6 files changed, 128 insertions(+), 104 deletions(-) diff --git a/docs/source/io_formats/mgxs_library.rst b/docs/source/io_formats/mgxs_library.rst index 9262a234e..2a1e63d43 100644 --- a/docs/source/io_formats/mgxs_library.rst +++ b/docs/source/io_formats/mgxs_library.rst @@ -38,10 +38,10 @@ MGXS Library Specification The data within contains the temperature-dependent multi-group data for the nuclide or material that it represents. -:Attributes: - **atomic_weight_ratio** (*double*) -- The atomic weight ratio (optional, - i.e. it is not meaningful for material-wise data) - - **fissionable** (*int*) -- Whether the dataset is fissionable - (1) or not (0). +: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 @@ -65,6 +65,15 @@ data for the nuclide or material that it represents. 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. **//kTs/** @@ -79,29 +88,29 @@ Temperature-dependent data, provided for temperature K. :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]. + [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]. + [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 + [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 + [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 + [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. @@ -119,34 +128,30 @@ Temperature-dependent data, provided for temperature K. Data specific to neutron scattering for the temperature K :Datasets: - **g_min** (*int[]* or *int[][][]*) -- - Minimum (most energetic) outgoing groups with non-zero values of - the scattering matrix. These group numbers use the standard + 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_in]`, or `g_min[num_polar][num_azimuthal][g_in]`. + `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[][][]*) -- - Maximum (least energetic) outgoing groups with non-zero values of - the scattering matrix. 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_max` is: - `g_max[g_in]`, or `g_max[num_polar][num_azimuthal][g_in]`. - The former is used when `representation` is "isotropic", and the - latter when `representation` is "angle". + 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 is shaped as - follows (in row-major format): - `scatter_matrix[order(+1)][g_in][g_out]`, or - `scatter_matrix[num_polar][num_azimuthal][order(+1)][g_in][g_out]` - The former is used when `representation` is "isotropic", and the - latter when `representation` is "angle". Note that if the value of - `scatter_format` is "legendre", the order dimension will be one - larger than the value of `order`, otherwise it will match `order`. - Finally, the g_out dimension has a dimensionality of - `g_min` to `g_max`. + 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) @@ -154,9 +159,6 @@ Data specific to neutron scattering for the temperature K 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 shaped as follows (in row-major format): - `multiplicity_matrix[g_in][g_out]`, or - `multiplicity_matrix[num_polar][num_azimuthal][g_in][g_out]` - The former is used when `representation` is "isotropic", and the - latter when `representation` is "angle". Finally, the g_out - dimension has a dimensionality of `g_min` to `g_max`. \ No newline at end of file + 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/openmc/mgxs/library.py b/openmc/mgxs/library.py index 64210606d..c03aa7877 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -186,14 +186,14 @@ class Library(object): @property def domains(self): - if self._domains is 'all': - if self.domain_type is 'material': + if self._domains == 'all': + if self.domain_type == 'material': return self.openmc_geometry.get_all_materials() elif self.domain_type in ['cell', 'distribcell']: return self.openmc_geometry.get_all_material_cells() - elif self.domain_type is 'universe': + elif self.domain_type == 'universe': return self.openmc_geometry.get_all_universes() - elif self.domain_type is 'mesh': + elif self.domain_type == 'mesh': raise ValueError('Unable to get domains for Mesh domain type') else: raise ValueError('Unable to get domains without a domain type') @@ -265,7 +265,7 @@ class Library(object): @mgxs_types.setter def mgxs_types(self, mgxs_types): all_mgxs_types = openmc.mgxs.MGXS_TYPES + openmc.mgxs.MDGXS_TYPES - if mgxs_types is 'all': + if mgxs_types == 'all': self._mgxs_types = all_mgxs_types else: cv.check_iterable_type('mgxs_types', mgxs_types, basestring) @@ -277,7 +277,7 @@ class Library(object): def by_nuclide(self, by_nuclide): cv.check_type('by_nuclide', by_nuclide, bool) - if by_nuclide == True and self.domain_type is 'mesh': + if by_nuclide == True and self.domain_type == 'mesh': raise ValueError('Unable to create MGXS library by nuclide with ' 'mesh domain') @@ -287,7 +287,7 @@ class Library(object): def domain_type(self, domain_type): cv.check_value('domain type', domain_type, openmc.mgxs.DOMAIN_TYPES) - if self.by_nuclide == True and domain_type is 'mesh': + if self.by_nuclide == True and domain_type == 'mesh': raise ValueError('Unable to create MGXS library by nuclide with ' 'mesh domain') @@ -297,21 +297,21 @@ class Library(object): def domains(self, domains): # Use all materials, cells or universes in the geometry as domains - if domains is 'all': + if domains == 'all': self._domains = domains # User specified a list of material, cell or universe domains else: - if self.domain_type is 'material': + if self.domain_type == 'material': cv.check_iterable_type('domain', domains, openmc.Material) all_domains = self.openmc_geometry.get_all_materials() elif self.domain_type in ['cell', 'distribcell']: cv.check_iterable_type('domain', domains, openmc.Cell) all_domains = self.openmc_geometry.get_all_material_cells() - elif self.domain_type is 'universe': + elif self.domain_type == 'universe': cv.check_iterable_type('domain', domains, openmc.Universe) all_domains = self.openmc_geometry.get_all_universes() - elif self.domain_type is 'mesh': + elif self.domain_type == 'mesh': cv.check_iterable_type('domain', domains, openmc.Mesh) # The mesh and geometry are independent, so set all_domains @@ -355,7 +355,7 @@ class Library(object): def correction(self, correction): cv.check_value('correction', correction, ('P0', None)) - if correction is 'P0' and self.legendre_order > 0: + if correction == 'P0' and self.legendre_order > 0: warn('The P0 correction will be ignored since the scattering ' 'order "{}" is greater than zero'.format(self.legendre_order)) @@ -367,7 +367,7 @@ class Library(object): cv.check_greater_than('legendre_order', legendre_order, 0, equality=True) cv.check_less_than('legendre_order', legendre_order, 10, equality=True) - if self.correction is 'P0' and legendre_order > 0: + if self.correction == 'P0' and legendre_order > 0: msg = 'The P0 correction will be ignored since the scattering ' \ 'order {} is greater than zero'.format(self.legendre_order) warn(msg, RuntimeWarning) @@ -505,7 +505,7 @@ class Library(object): self._openmc_geometry = statepoint.summary.openmc_geometry self._nuclides = statepoint.summary.nuclides - if statepoint.run_mode is 'k-eigenvalue': + if statepoint.run_mode == 'k-eigenvalue': self._keff = statepoint.k_combined[0] # Load tallies for each MGXS for each domain and mgxs type @@ -543,13 +543,13 @@ class Library(object): """ - if self.domain_type is 'material': + if self.domain_type == 'material': cv.check_type('domain', domain, (openmc.Material, Integral)) - elif self.domain_type is 'cell' or self.domain_type is 'distribcell': + elif self.domain_type == 'cell' or self.domain_type == 'distribcell': cv.check_type('domain', domain, (openmc.Cell, Integral)) - elif self.domain_type is 'universe': + elif self.domain_type == 'universe': cv.check_type('domain', domain, (openmc.Universe, Integral)) - elif self.domain_type is 'mesh': + elif self.domain_type == 'mesh': cv.check_type('domain', domain, (openmc.Mesh, Integral)) # Check that requested domain is included in library @@ -662,7 +662,7 @@ class Library(object): # Clone this Library to initialize the subdomain-averaged version subdomain_avg_library = copy.deepcopy(self) - if subdomain_avg_library.domain_type is 'distribcell': + if subdomain_avg_library.domain_type == 'distribcell': subdomain_avg_library.domain_type = 'cell' else: return subdomain_avg_library @@ -671,7 +671,7 @@ class Library(object): for domain in self.domains: for mgxs_type in self.mgxs_types: mgxs = subdomain_avg_library.get_mgxs(domain, mgxs_type) - if mgxs.domain_type is 'distribcell': + if mgxs.domain_type == 'distribcell': avg_mgxs = mgxs.get_subdomain_avg_xs() subdomain_avg_library.all_mgxs[domain.id][mgxs_type] = avg_mgxs @@ -751,7 +751,7 @@ class Library(object): for mgxs_type in self.mgxs_types: mgxs = self.all_mgxs[domain.id][mgxs_type] - if subdomains is 'avg': + if subdomains == 'avg': mgxs = mgxs.get_subdomain_avg_xs() mgxs.build_hdf5_store(filename, directory, xs_type=xs_type, @@ -896,7 +896,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) @@ -912,7 +912,7 @@ class Library(object): self.scatter_format = 'legendre' self.representation = 'isotropic' - if nuclide is not 'total': + if nuclide != 'total': xsdata.atomic_weight_ratio = self._nuclides[nuclide][1] if subdomain is None: @@ -921,7 +921,7 @@ class Library(object): subdomain = [subdomain] # Now get xs data itself - if 'nu-transport' in self.mgxs_types and self.correction is 'P0': + 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], subdomain=subdomain) @@ -1056,7 +1056,7 @@ class Library(object): # Initialize file mgxs_file = openmc.MGXSLibrary(self.energy_groups) - if self.domain_type is 'mesh': + if self.domain_type == 'mesh': # Create the xsdata objects and add to the mgxs_file i = 0 for domain in self.domains: @@ -1089,7 +1089,7 @@ 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, @@ -1159,14 +1159,14 @@ class Library(object): # the multiple meshes could be overlapping or in disparate regions # of the continuous energy model. The next step makes sure there is # only one before continuing. - if self.domain_type is 'mesh': + if self.domain_type == 'mesh': cv.check_length("domains", self.domains, 1, 1) # Get the MGXS File Data mgxs_file = self.create_mg_library('macro', xsdata_names) # Now move on the creating the geometry and assigning materials - if self.domain_type is 'mesh': + if self.domain_type == 'mesh': root = openmc.Universe(name='root', universe_id=0) # Add cells representative of the mesh with reflective BC @@ -1212,13 +1212,13 @@ class Library(object): materials.append(material) # Differentiate Geometry with new Material - if self.domain_type is 'material': + if self.domain_type == 'material': # Fill all appropriate Cells with new Material for cell in all_cells: if cell.fill.id == domain.id: cell.fill = material - elif self.domain_type is 'cell': + elif self.domain_type == 'cell': for cell in all_cells: if cell.id == domain.id: cell.fill = material @@ -1283,7 +1283,7 @@ class Library(object): ('nu-transport' not in self.mgxs_types))): error_flag = True warn('A "nu-transport" MGXS type is required since a "P0" ' - 'correction is applied, but a "nu-transport" MGXS is ' + 'correction is applied, but a "nu-transport" MGXS == ' 'not provided.') elif (((self.correction is None) and ('total' not in self.mgxs_types))): diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index edddd0bfa..35dff1223 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -8,7 +8,7 @@ import h5py import openmc import openmc.mgxs from openmc.checkvalue import check_type, check_value, check_greater_than, \ - check_less_than, check_iterable_type + check_iterable_type if sys.version_info[0] >= 3: basestring = str @@ -16,6 +16,7 @@ if sys.version_info[0] >= 3: # Supported incoming particle MGXS angular treatment representations _REPRESENTATIONS = ['isotropic', 'angle'] _SCATTER_TYPES = ['tabular', 'legendre', 'histogram'] +_SCATTER_SHAPES = ["[Order][G][G']"] class XSdata(object): @@ -51,6 +52,8 @@ class XSdata(object): Whether or not this is a fissionable data set. 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 @@ -106,8 +109,8 @@ class XSdata(object): :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. + :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. @@ -142,6 +145,7 @@ class XSdata(object): self._atomic_weight_ratio = None self._fissionable = False self._scatter_format = 'legendre' + self._scatter_shape = "[Order][G][G']" self._order = None self._num_polar = None self._num_azimuthal = None @@ -184,6 +188,10 @@ class XSdata(object): def scatter_format(self): return self._scatter_format + @property + def scatter_shape(self): + return self._scatter_shape + @property def order(self): return self._order @@ -242,28 +250,28 @@ class XSdata(object): @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) @@ -309,6 +317,12 @@ class XSdata(object): 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): # Check type and value @@ -694,10 +708,10 @@ class XSdata(object): check_value('temperature', temperature, self.temperatures) i = np.where(self.temperatures == temperature)[0][0] - if self.representation is 'isotropic': + if self.representation == 'isotropic': self._total[i] = total.get_xs(nuclides=nuclide, xs_type=xs_type, subdomains=subdomain) - elif self.representation is 'angle': + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -740,11 +754,11 @@ class XSdata(object): check_value('temperature', temperature, self.temperatures) i = np.where(self.temperatures == temperature)[0][0] - if self.representation is 'isotropic': + if self.representation == 'isotropic': self._absorption[i] = absorption.get_xs(nuclides=nuclide, xs_type=xs_type, subdomains=subdomain) - elif self.representation is 'angle': + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -787,11 +801,11 @@ class XSdata(object): check_value('temperature', temperature, self.temperatures) i = np.where(self.temperatures == temperature)[0][0] - if self.representation is 'isotropic': + if self.representation == 'isotropic': self._fission[i] = fission.get_xs(nuclides=nuclide, xs_type=xs_type, subdomains=subdomain) - elif self.representation is 'angle': + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -835,11 +849,11 @@ class XSdata(object): check_value('temperature', temperature, self.temperatures) i = np.where(self.temperatures == temperature)[0][0] - if self.representation is 'isotropic': + if self.representation == 'isotropic': self._nu_fission[i] = nu_fission.get_xs(nuclides=nuclide, xs_type=xs_type, subdomains=subdomain) - elif self.representation is 'angle': + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -892,11 +906,11 @@ class XSdata(object): check_value('temperature', temperature, self.temperatures) i = np.where(self.temperatures == temperature)[0][0] - if self.representation is 'isotropic': + if self.representation == 'isotropic': self._kappa_fission[i] = k_fission.get_xs(nuclides=nuclide, xs_type=xs_type, subdomains=subdomain) - elif self.representation is 'angle': + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -943,10 +957,10 @@ class XSdata(object): check_value('temperature', temperature, self.temperatures) i = np.where(self.temperatures == temperature)[0][0] - if self.representation is 'isotropic': + if self.representation == 'isotropic': self._chi[i] = chi.get_xs(nuclides=nuclide, xs_type=xs_type, subdomains=subdomain) - elif self.representation is 'angle': + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -994,7 +1008,7 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - if self.scatter_format is not 'legendre': + if self.scatter_format != 'legendre': msg = 'Anisotropic scattering representations other than ' \ 'Legendre expansions have not yet been implemented in ' \ 'openmc.mgxs.' @@ -1011,7 +1025,7 @@ class XSdata(object): [self.order]) i = np.where(self.temperatures == temperature)[0][0] - if self.representation is 'isotropic': + if self.representation == 'isotropic': # Get the scattering orders in the outermost dimension self._scatter_matrix[i] = np.zeros((self.num_orders, self.energy_groups.num_groups, @@ -1021,7 +1035,7 @@ class XSdata(object): 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) @@ -1089,7 +1103,7 @@ class XSdata(object): ['universe', 'cell', 'material', 'mesh']) i = np.where(self.temperatures == temperature)[0][0] - if self.representation is 'isotropic': + if self.representation == 'isotropic': nuscatt = nuscatter.get_xs(nuclides=nuclide, xs_type=xs_type, moment=0, subdomains=subdomain) @@ -1100,7 +1114,7 @@ class XSdata(object): xs_type=xs_type, moment=0, subdomains=subdomain) self._multiplicity_matrix[i] = np.divide(nuscatt, scatt) - elif self.representation is 'angle': + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) self._multiplicity_matrix[i] = \ @@ -1123,7 +1137,7 @@ class XSdata(object): if self.representation is not None: grp.attrs['representation'] = np.array(self.representation, dtype='S') - if self.representation is 'angle': + 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: @@ -1131,6 +1145,9 @@ class XSdata(object): if self.scatter_format is not None: grp.attrs['scatter_format'] = np.array(self.scatter_format, dtype='S') + if self.scatter_shape is not None: + grp.attrs['scatter_shape'] = np.array(self.scatter_shape, + dtype='S') if self.order is not None: grp.attrs['order'] = self.order @@ -1170,7 +1187,7 @@ class XSdata(object): # Get the sparse scattering data to print to the library G = self.energy_groups.num_groups - if self.representation is 'isotropic': + 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, :]) @@ -1206,7 +1223,7 @@ class XSdata(object): scatt_grp.create_dataset("g_min", data=g_out_bounds[:, 0]) scatt_grp.create_dataset("g_max", data=g_out_bounds[:, 1]) - elif self.representation is 'angle': + elif self.representation == 'angle': Np = self.num_polar Na = self.num_azimuthal g_out_bounds = np.zeros((Np, Na, G, 2), dtype=np.int) diff --git a/scripts/openmc-update-mgxs b/scripts/openmc-update-mgxs index 6122ff626..658be9fef 100755 --- a/scripts/openmc-update-mgxs +++ b/scripts/openmc-update-mgxs @@ -47,14 +47,12 @@ def parse_args(): help='input XML file') parser.add_argument('-o', '--output', nargs='?', default='', help='output file, in HDF5 format') - parser.add_argument('-c', '--compression', type=int, - help='HDF5 Compression Level') args = vars(parser.parse_args()) - if args['output'] is '': + if args['output'] == '': filename = args['input'].name extension = filenameos.path.splitext() - if extension is '.xml': + if extension == '.xml': filename = filename[:filename.rfind('.')] + '.h5' args['output'] = filename @@ -75,7 +73,7 @@ def get_data(element, entry): return value -if __name__ is '__main__': +if __name__ == '__main__': args = parse_args() # Parse the XML data. @@ -117,7 +115,7 @@ if __name__ is '__main__': representation = get_data(xsdata_elem, 'representation') if representation is None: representation = 'isotropic' - if representation is 'angle': + if representation == 'angle': n_azi = int(get_data(xsdata_elem, 'num_azimuthal')) n_pol = int(get_data(xsdata_elem, 'num_polar')) @@ -146,14 +144,14 @@ if __name__ is '__main__': representation=representation)) if awr is not None: xsd[-1].atomic_weight_ratio = awr - if representation is 'angle': + 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 is 'legendre': + if scatter_format == 'legendre': order_dim = order + 1 else: order_dim = order diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index ddce50be3..cbdf470b0 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -338,6 +338,13 @@ module mgxs_header 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 diff --git a/tests/1d_mgxs.h5 b/tests/1d_mgxs.h5 index 401fe02fc54bedac6d1b5443db23a923de30c5f0..3befba194015f15f271447424bd93c7163e81324 100644 GIT binary patch delta 7975 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 delta 7769 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 From c1dd7df7dd83ff973ccbb2d080b3f686a48fe823 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 15 Oct 2016 15:15:50 -0400 Subject: [PATCH 37/42] Increased MG mode test coverage from 63% to 74%. --- src/mgxs_header.F90 | 2 +- src/tally.F90 | 2 + tests/input_set.py | 85 +- tests/test_mg_basic/inputs_true.dat | 2 +- tests/test_mg_basic/results_true.dat | 2 +- tests/test_mg_max_order/inputs_true.dat | 2 +- tests/test_mg_max_order/results_true.dat | 2 +- tests/test_mg_max_order/test_mg_max_order.py | 75 +- tests/test_mg_nuclide/inputs_true.dat | 2 +- tests/test_mg_nuclide/results_true.dat | 2 +- tests/test_mg_nuclide/test_mg_nuclide.py | 73 +- tests/test_mg_tallies/inputs_true.dat | 2 +- tests/test_mg_tallies/results_true.dat | 3604 ++++-------------- tests/test_mg_tallies/test_mg_tallies.py | 58 +- 14 files changed, 819 insertions(+), 3094 deletions(-) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index cbdf470b0..e22323858 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -1865,7 +1865,7 @@ module mgxs_header integer :: iazi, ipol, t - t = this % index_temp + t = this % index_temp if (present(uvw)) then call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) diff --git a/src/tally.F90 b/src/tally.F90 index 24c1b9495..b12bc0a97 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 diff --git a/tests/input_set.py b/tests/input_set.py index 62c4abd5e..c62fc5914 100644 --- a/tests/input_set.py +++ b/tests/input_set.py @@ -728,60 +728,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) + 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 = 5. / float(len(mats)) + for i in range(len(mats) - 1): + planes.append(openmc.ZPlane(z0=dz * (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,7 +790,7 @@ 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.h5" diff --git a/tests/test_mg_basic/inputs_true.dat b/tests/test_mg_basic/inputs_true.dat index e44aa66a5..31673c133 100644 --- a/tests/test_mg_basic/inputs_true.dat +++ b/tests/test_mg_basic/inputs_true.dat @@ -1 +1 @@ -002fff0d8ba33340c9039f7650ece41bd26324d2e5c2816acc232adb298ae9dbd0873c5e28520df33ebe5af4c58e2ad338547ca337b2b42f53d255bff1ae314b \ No newline at end of file +c657f05432d9668f56e671a463ba08aed47103a33072d3f893146ff24fce6711ec41ba49c7d14a70b076cccb9a526375a4d8c1241e64e8167b8e0e876ae6655c \ 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 7cdda73b5..a367c6026 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.034509E+00 4.099331E-02 diff --git a/tests/test_mg_max_order/inputs_true.dat b/tests/test_mg_max_order/inputs_true.dat index 9b5d32ce6..375a7fe21 100644 --- a/tests/test_mg_max_order/inputs_true.dat +++ b/tests/test_mg_max_order/inputs_true.dat @@ -1 +1 @@ -8752d3167989d876c6f29b4b1ca7eed4b91793d8579c92de85633fd90235c67d63ee76d49081006047e0078f6f86eb6e3420c1f8fe44564e7a1fb62e828587d0 \ No newline at end of file +b4adeb6b98d1d6310484c6623dde61ccfb02e0b8b9422c60d94cb65e556f3e2744c94cb3661a94aa365964acb463a6bd93cddf2dd954bfc36e316335b4a058f3 \ 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 4db04e089..1fa95fb90 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.099449E+00 1.956787E-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 da699316c..8c7948a32 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 93de08656..5950ad3e4 100644 --- a/tests/test_mg_nuclide/inputs_true.dat +++ b/tests/test_mg_nuclide/inputs_true.dat @@ -1 +1 @@ -10b64fa97cc4feb1b1b8ba401b25b68ab682aba55ad4303a76a9a293ae79cdfff2f65d74310eb917da0aac243c24713d91eafae7ec5f0c4ae535d49fc928a869 \ No newline at end of file +130e51d00cd4c00be14b4e722c285ef5725f7f7a25361f48524dc51bb70c0869149adb839199915fe6193273cb957414c073be2a9fda3ed03754967571b73f68 \ 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 7cdda73b5..a367c6026 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.034509E+00 4.099331E-02 diff --git a/tests/test_mg_nuclide/test_mg_nuclide.py b/tests/test_mg_nuclide/test_mg_nuclide.py index 89694eea2..b94af258f 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 ca92dcb09..6e1b5dd62 100644 --- a/tests/test_mg_tallies/inputs_true.dat +++ b/tests/test_mg_tallies/inputs_true.dat @@ -1 +1 @@ -615fe0688980afc02bc11f41ac065b9479d2f6618acf6d20fcb91cd78209aed1d8fbaf73b06f153368a16aa90249d6d3ce06f840d9071a40b2118d36178fd84f \ No newline at end of file +051fcc001b79dc016d74e339348e75d1dab0338f3246643fb0032a928dd3660574543e23a6f428ee3b1b174e7e5a9aa64b27a795fa42c80068d13e98cf42a294 \ 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 cb0498e51..09a041c7d 100644 --- a/tests/test_mg_tallies/results_true.dat +++ b/tests/test_mg_tallies/results_true.dat @@ -1,2906 +1,712 @@ k-combined: -1.047136E+00 2.765964E-02 +1.034509E+00 4.099331E-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 +1.353282E+01 +3.743930E+01 +1.143045E+00 +2.712580E-01 +3.307076E+01 +2.236038E+02 +6.526994E-01 +8.855821E-02 +1.648619E+00 +5.666321E-01 +1.383226E+01 +3.869052E+01 +1.052120E+00 +2.328236E-01 +3.370167E+01 +2.297761E+02 +6.050050E-01 +7.697403E-02 +1.750404E+00 +6.331758E-01 +1.318250E+01 +3.553429E+01 +1.062624E+00 +2.357887E-01 +3.213491E+01 +2.111574E+02 +6.132682E-01 +7.853526E-02 +1.383452E+00 +4.189022E-01 +1.092857E+01 +2.455197E+01 +4.110603E-01 +3.568350E-02 +3.208428E+01 +2.114259E+02 +2.256563E-01 +1.081356E-02 +4.632141E-01 +4.677570E-02 +9.784679E+00 +1.972964E+01 +4.012515E-02 +6.039914E-04 +3.181098E+01 +2.085498E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +9.927108E+00 +2.035984E+01 +1.000276E-02 +1.000553E-04 +3.229710E+01 +2.155043E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.610209E+01 +5.213849E+01 +1.305253E-01 +4.741512E-03 +3.129504E+01 +1.971406E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.036344E+01 +1.862702E+02 +4.715504E-01 +4.701859E-02 +3.127921E+01 +1.975072E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.325556E+01 +2.242288E+02 +3.406537E-01 +3.172189E-02 +3.424625E+01 +2.377838E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.437896E+01 +2.376465E+02 +3.508672E-01 +2.662723E-02 +3.547702E+01 +2.530698E+02 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 +1.368605E+01 +3.822585E+01 +1.165647E+00 +2.774076E-01 +3.332128E+01 +2.265711E+02 +6.732988E-01 +9.255825E-02 +1.668893E+00 +5.686505E-01 +1.351185E+01 +3.714397E+01 +1.145268E+00 +2.669523E-01 +3.292797E+01 +2.205691E+02 +6.612158E-01 +8.898397E-02 +1.639208E+00 +5.468718E-01 +1.338220E+01 +3.637873E+01 +1.131564E+00 +2.601061E-01 +3.262172E+01 +2.161754E+02 +6.530550E-01 +8.663476E-02 +1.619062E+00 +5.325002E-01 +1.124444E+01 +2.583638E+01 +4.143035E-01 +3.514380E-02 +3.293951E+01 +2.216808E+02 +2.172466E-01 +9.667606E-03 +5.386005E-01 +5.942191E-02 +1.039401E+01 +2.195361E+01 +5.776981E-02 +6.785830E-04 +3.380760E+01 +2.322412E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +9.968429E+00 +2.018883E+01 +5.522413E-02 +6.196056E-04 +3.243154E+01 +2.136942E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.599575E+01 +5.164848E+01 +1.369508E-01 +3.787900E-03 +3.062851E+01 +1.892971E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.984125E+01 +1.813760E+02 +3.150772E-01 +2.022590E-02 +3.078896E+01 +1.929299E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.239082E+01 +2.130115E+02 +3.421610E-01 +2.377195E-02 +3.338365E+01 +2.262151E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.394890E+01 +2.331951E+02 +3.584238E-01 +2.599332E-02 +3.503323E+01 +2.483295E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +tally 3: +1.127805E+01 +2.608571E+01 +1.002813E+00 +2.123979E-01 +2.754396E+01 +1.556374E+02 +5.744190E-01 +6.983035E-02 +1.301487E+00 +3.559715E-01 +1.027524E+01 +2.176770E+01 +1.027808E+01 +2.177975E+01 +1.147696E+01 +2.681957E+01 +8.617077E-01 +1.528009E-01 +2.799053E+01 +1.596017E+02 +4.924622E-01 +4.996879E-02 +1.463919E+00 +4.452955E-01 +1.061525E+01 +2.304844E+01 +1.061818E+01 +2.306116E+01 +1.112664E+01 +2.517898E+01 +9.122203E-01 +1.733772E-01 +2.712336E+01 +1.496225E+02 +5.264663E-01 +5.774755E-02 +1.333478E+00 +3.684793E-01 +1.021442E+01 +2.118539E+01 +1.021724E+01 +2.119710E+01 +1.090672E+01 +2.450876E+01 +8.720475E-01 +1.544308E-01 +2.658725E+01 +1.456398E+02 +5.032815E-01 +5.143697E-02 +1.146804E+00 +2.835726E-01 +1.003467E+01 +2.079465E+01 +1.003744E+01 +2.080615E+01 +8.331989E+00 +1.409000E+01 +3.010595E-02 +5.041231E-04 +2.708797E+01 +1.489409E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +8.301883E+00 +1.399250E+01 +8.302183E+00 +1.399351E+01 +8.140468E+00 +1.380373E+01 +3.007957E-02 +5.030779E-04 +2.646953E+01 +1.459652E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +8.110389E+00 +1.372142E+01 +8.110683E+00 +1.372241E+01 +8.082005E+00 +1.362698E+01 +1.000276E-02 +1.000553E-04 +2.629420E+01 +1.442386E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +8.072002E+00 +1.358172E+01 +8.072302E+00 +1.358273E+01 +8.452493E+00 +1.439819E+01 +3.016800E-02 +3.033748E-04 +2.749955E+01 +1.524016E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +8.422325E+00 +1.429746E+01 +8.422638E+00 +1.429853E+01 +2.414436E+01 +1.174474E+02 +2.911770E-01 +2.007223E-02 +2.492486E+01 +1.250988E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.385318E+01 +1.146286E+02 +2.385318E+01 +1.146286E+02 +2.670358E+01 +1.446298E+02 +4.109267E-01 +3.665787E-02 +2.742207E+01 +1.524808E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.629265E+01 +1.401748E+02 +2.629265E+01 +1.401748E+02 +2.805989E+01 +1.590823E+02 +2.605721E-01 +1.547273E-02 +2.895612E+01 +1.694067E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.779932E+01 +1.561607E+02 +2.779932E+01 +1.561607E+02 +2.858483E+01 +1.648682E+02 +3.007528E-01 +2.029929E-02 +2.949783E+01 +1.755681E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.828408E+01 +1.615023E+02 +2.828408E+01 +1.615023E+02 +tally 4: +1.127805E+01 +2.608571E+01 +9.413263E-01 +1.814958E-01 +2.754396E+01 +1.556374E+02 +5.422850E-01 +6.023145E-02 +1.344903E+00 +3.704722E-01 +1.147696E+01 +2.681957E+01 +9.663242E-01 +1.895497E-01 +2.799053E+01 +1.596017E+02 +5.573458E-01 +6.303283E-02 +1.381910E+00 +3.875298E-01 +1.112664E+01 +2.517898E+01 +9.408395E-01 +1.800284E-01 +2.712336E+01 +1.496225E+02 +5.429832E-01 +5.996291E-02 +1.346171E+00 +3.685618E-01 +1.090672E+01 +2.450876E+01 +9.222434E-01 +1.752364E-01 +2.658725E+01 +1.456398E+02 +5.322509E-01 +5.836681E-02 +1.319563E+00 +3.587514E-01 +8.331989E+00 +1.409000E+01 +4.665612E-02 +4.414425E-04 +2.708797E+01 +1.489409E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +8.140468E+00 +1.380373E+01 +4.513252E-02 +4.265760E-04 +2.646953E+01 +1.459652E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +8.082005E+00 +1.362698E+01 +4.477352E-02 +4.182191E-04 +2.629420E+01 +1.442386E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +8.452493E+00 +1.439819E+01 +4.682599E-02 +4.418878E-04 +2.749955E+01 +1.524016E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.414436E+01 +1.174474E+02 +2.549248E-01 +1.309686E-02 +2.492486E+01 +1.250988E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.670358E+01 +1.446298E+02 +2.827393E-01 +1.621660E-02 +2.742207E+01 +1.524808E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.805989E+01 +1.590823E+02 +2.962491E-01 +1.773226E-02 +2.895612E+01 +1.694067E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.858483E+01 +1.648682E+02 +3.017914E-01 +1.837719E-02 +2.949783E+01 +1.755681E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +tally 5: +1.140031E+01 +2.654804E+01 +9.714892E-01 +1.928147E-01 +2.775330E+01 +1.573327E+02 +5.611798E-01 +6.433919E-02 +1.390960E+00 +3.952699E-01 +1.042894E+01 +2.221679E+01 +1.141545E+01 +2.652638E+01 +9.688838E-01 +1.912040E-01 +2.781363E+01 +1.574484E+02 +5.594851E-01 +6.375914E-02 +1.386962E+00 +3.918154E-01 +1.129668E-01 +2.597945E-03 +1.104472E+01 +2.480364E+01 +9.339121E-01 +1.773447E-01 +2.692364E+01 +1.473920E+02 +5.389851E-01 +5.906905E-02 +1.336259E+00 +3.630677E-01 +1.011089E+01 +2.078670E+01 +1.117137E+01 +2.545891E+01 +9.446221E-01 +1.820299E-01 +2.723240E+01 +1.512859E+02 +5.451662E-01 +6.062956E-02 +1.351583E+00 +3.726594E-01 +1.105108E-01 +2.491359E-03 +8.516856E+00 +1.480571E+01 +4.746789E-02 +4.599371E-04 +2.769452E+01 +1.565558E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +8.469171E+00 +1.464039E+01 +8.669841E+00 +1.526679E+01 +4.817729E-02 +4.716776E-04 +2.820058E+01 +1.615173E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.126905E-01 +2.579568E-03 +8.322112E+00 +1.408773E+01 +4.610369E-02 +4.323598E-04 +2.707537E+01 +1.491155E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +8.275818E+00 +1.393144E+01 +8.001626E+00 +1.291919E+01 +4.432823E-02 +3.964967E-04 +2.603269E+01 +1.367468E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.037888E-01 +2.173599E-03 +2.420071E+01 +1.187334E+02 +2.553808E-01 +1.322410E-02 +2.499803E+01 +1.266325E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.394540E+01 +1.162412E+02 +2.599102E+01 +1.379786E+02 +2.747004E-01 +1.541805E-02 +2.675330E+01 +1.460654E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.544592E-02 +4.872035E-05 +2.723238E+01 +1.502761E+02 +2.875125E-01 +1.675068E-02 +2.810218E+01 +1.600291E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.694487E+01 +1.471198E+02 +2.839730E+01 +1.630916E+02 +2.998114E-01 +1.817916E-02 +2.930431E+01 +1.736763E+02 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.688140E-02 +5.763608E-05 +tally 6: +1.027524E+01 +2.176770E+01 +1.027808E+01 +2.177975E+01 +1.301487E+00 +3.559715E-01 +1.061525E+01 +2.304844E+01 +1.061818E+01 +2.306116E+01 +1.463919E+00 +4.452955E-01 +1.021442E+01 +2.118539E+01 +1.021724E+01 +2.119710E+01 +1.333478E+00 +3.684793E-01 +1.003467E+01 +2.079465E+01 +1.003744E+01 +2.080615E+01 +1.146804E+00 +2.835726E-01 +8.301883E+00 +1.399250E+01 +8.302183E+00 +1.399351E+01 +0.000000E+00 +0.000000E+00 +8.110389E+00 +1.372142E+01 +8.110683E+00 +1.372241E+01 +0.000000E+00 +0.000000E+00 +8.072002E+00 +1.358172E+01 +8.072302E+00 +1.358273E+01 +0.000000E+00 +0.000000E+00 +8.422325E+00 +1.429746E+01 +8.422638E+00 +1.429853E+01 +0.000000E+00 +0.000000E+00 +2.385318E+01 +1.146286E+02 +2.385318E+01 +1.146286E+02 +0.000000E+00 +0.000000E+00 +2.629265E+01 +1.401748E+02 +2.629265E+01 +1.401748E+02 +0.000000E+00 +0.000000E+00 +2.779932E+01 +1.561607E+02 +2.779932E+01 +1.561607E+02 +0.000000E+00 +0.000000E+00 +2.828408E+01 +1.615023E+02 +2.828408E+01 +1.615023E+02 +0.000000E+00 +0.000000E+00 diff --git a/tests/test_mg_tallies/test_mg_tallies.py b/tests/test_mg_tallies/test_mg_tallies.py index c9c5e95be..4e57120bd 100644 --- a/tests/test_mg_tallies/test_mg_tallies.py +++ b/tests/test_mg_tallies/test_mg_tallies.py @@ -9,32 +9,66 @@ import openmc class MGTalliesTestHarness(PyAPITestHarness): def _build_inputs(self): + """Write input XML files.""" + self._input_set.build_default_materials_and_geometry(as_macro=True) + 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'] + tallies = [] - tally2 = openmc.Tally(tally_id=2) - tally2.filters = [mat_filter, energy_filter, energyout_filter] - tally2.scores = ['scatter', 'nu-scatter'] + tallies.append(openmc.Tally()) + tallies[-1].filters = [mesh_filter] + tallies[-1].estimator = 'analog' + tallies[-1].scores = ['total', 'absorption', 'flux', + 'fission', 'nu-fission'] - self._input_set.tallies = openmc.Tallies([tally1, tally2]) + tallies.append(openmc.Tally()) + tallies[-1].filters = [mesh_filter] + tallies[-1].estimator = 'tracklength' + tallies[-1].scores = ['total', 'absorption', 'flux', + 'fission', 'nu-fission'] - super(MGTalliesTestHarness, self)._build_inputs() + tallies.append(openmc.Tally()) + tallies[-1].filters = [mat_filter, energy_filter] + tallies[-1].estimator = 'analog' + tallies[-1].scores = ['total', 'absorption', 'flux', + 'fission', 'nu-fission', 'scatter', + 'nu-scatter'] + + tallies.append(openmc.Tally()) + tallies[-1].filters = [mat_filter, energy_filter] + tallies[-1].estimator = 'collision' + tallies[-1].scores = ['total', 'absorption', 'flux', + 'fission', 'nu-fission'] + + tallies.append(openmc.Tally()) + tallies[-1].filters = [mat_filter, energy_filter] + tallies[-1].estimator = 'tracklength' + tallies[-1].scores = ['total', 'absorption', 'flux', + 'fission', 'nu-fission', 'scatter'] + + tallies.append(openmc.Tally()) + tallies[-1].filters = [mat_filter, energy_filter, + energyout_filter] + tallies[-1].scores = ['scatter', 'nu-scatter', 'nu-fission'] + + self._input_set.tallies = openmc.Tallies(tallies) + + self._input_set.export() def _cleanup(self): super(MGTalliesTestHarness, self)._cleanup() From ea0e706b7081709fbeb51d80119e7459c165795b Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 15 Oct 2016 16:15:17 -0400 Subject: [PATCH 38/42] Ok, fixed the extra whitespace (havent gotten my sublime settings all set since I got the new computer, and, as a bonus, I added nuclidic tallies to the test_mg_tallies test, including a few bugfixes along the way --- src/input_xml.F90 | 2 +- src/mgxs_header.F90 | 16 +- src/output.F90 | 9 +- src/state_point.F90 | 17 +- src/tally.F90 | 27 +- tests/input_set.py | 2 +- tests/test_mg_tallies/inputs_true.dat | 2 +- tests/test_mg_tallies/results_true.dat | 713 +---------------------- tests/test_mg_tallies/test_mg_tallies.py | 80 +-- 9 files changed, 98 insertions(+), 770 deletions(-) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 2719aa68f..e8b950d91 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -3301,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 diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index e22323858..feb4d46a8 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -437,9 +437,9 @@ module mgxs_header ! 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 - allocate(xs % nu_fission(groups)) - allocate(xs % chi(groups, groups)) if (object_exists(xsdata_grp, "chi")) then ! Chi was provided, that means we need chi and nu-fission vectors ! Get chi @@ -505,6 +505,9 @@ module mgxs_header &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 @@ -735,9 +738,9 @@ module mgxs_header ! 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 - allocate(xs % nu_fission(groups, this % n_azi, this % n_pol)) - allocate(xs % chi(groups, groups, this % n_azi, this % n_pol)) if (object_exists(xsdata_grp, "chi")) then ! Chi was provided, that means we need chi and nu-fission vectors ! Get chi @@ -848,6 +851,9 @@ module mgxs_header &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 @@ -1865,7 +1871,7 @@ module mgxs_header integer :: iazi, ipol, t - t = this % index_temp + t = this % index_temp if (present(uvw)) then call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) diff --git a/src/output.F90 b/src/output.F90 index 03496decb..8127725a6 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/state_point.F90 b/src/state_point.F90 index 39532652f..6b7a467d4 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 b12bc0a97..e1c5769d1 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -1865,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/tests/input_set.py b/tests/input_set.py index c62fc5914..e34927214 100644 --- a/tests/input_set.py +++ b/tests/input_set.py @@ -753,7 +753,7 @@ class MGInputSet(InputSet): mats[-1].set_density('atom/b-cm', 1.) mats[-1].add_nuclide(xs[-1].name, 1.0, 'ao') - # Define the materials file. + # Define the materials file self.xs_data = xs self.materials += mats diff --git a/tests/test_mg_tallies/inputs_true.dat b/tests/test_mg_tallies/inputs_true.dat index 6e1b5dd62..4b1863929 100644 --- a/tests/test_mg_tallies/inputs_true.dat +++ b/tests/test_mg_tallies/inputs_true.dat @@ -1 +1 @@ -051fcc001b79dc016d74e339348e75d1dab0338f3246643fb0032a928dd3660574543e23a6f428ee3b1b174e7e5a9aa64b27a795fa42c80068d13e98cf42a294 \ No newline at end of file +255e71d921bb67f7f4832d1b217f4d19ea3c6bd96f551f1676e3735bd314986cc5f2be064e98c8f938a3f93c28b94487567d28829b4c0d66f8d2f8f5a776f302 \ 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 09a041c7d..67e6cf405 100644 --- a/tests/test_mg_tallies/results_true.dat +++ b/tests/test_mg_tallies/results_true.dat @@ -1,712 +1 @@ -k-combined: -1.034509E+00 4.099331E-02 -tally 1: -1.353282E+01 -3.743930E+01 -1.143045E+00 -2.712580E-01 -3.307076E+01 -2.236038E+02 -6.526994E-01 -8.855821E-02 -1.648619E+00 -5.666321E-01 -1.383226E+01 -3.869052E+01 -1.052120E+00 -2.328236E-01 -3.370167E+01 -2.297761E+02 -6.050050E-01 -7.697403E-02 -1.750404E+00 -6.331758E-01 -1.318250E+01 -3.553429E+01 -1.062624E+00 -2.357887E-01 -3.213491E+01 -2.111574E+02 -6.132682E-01 -7.853526E-02 -1.383452E+00 -4.189022E-01 -1.092857E+01 -2.455197E+01 -4.110603E-01 -3.568350E-02 -3.208428E+01 -2.114259E+02 -2.256563E-01 -1.081356E-02 -4.632141E-01 -4.677570E-02 -9.784679E+00 -1.972964E+01 -4.012515E-02 -6.039914E-04 -3.181098E+01 -2.085498E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -9.927108E+00 -2.035984E+01 -1.000276E-02 -1.000553E-04 -3.229710E+01 -2.155043E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.610209E+01 -5.213849E+01 -1.305253E-01 -4.741512E-03 -3.129504E+01 -1.971406E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.036344E+01 -1.862702E+02 -4.715504E-01 -4.701859E-02 -3.127921E+01 -1.975072E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.325556E+01 -2.242288E+02 -3.406537E-01 -3.172189E-02 -3.424625E+01 -2.377838E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.437896E+01 -2.376465E+02 -3.508672E-01 -2.662723E-02 -3.547702E+01 -2.530698E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -tally 2: -1.368605E+01 -3.822585E+01 -1.165647E+00 -2.774076E-01 -3.332128E+01 -2.265711E+02 -6.732988E-01 -9.255825E-02 -1.668893E+00 -5.686505E-01 -1.351185E+01 -3.714397E+01 -1.145268E+00 -2.669523E-01 -3.292797E+01 -2.205691E+02 -6.612158E-01 -8.898397E-02 -1.639208E+00 -5.468718E-01 -1.338220E+01 -3.637873E+01 -1.131564E+00 -2.601061E-01 -3.262172E+01 -2.161754E+02 -6.530550E-01 -8.663476E-02 -1.619062E+00 -5.325002E-01 -1.124444E+01 -2.583638E+01 -4.143035E-01 -3.514380E-02 -3.293951E+01 -2.216808E+02 -2.172466E-01 -9.667606E-03 -5.386005E-01 -5.942191E-02 -1.039401E+01 -2.195361E+01 -5.776981E-02 -6.785830E-04 -3.380760E+01 -2.322412E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -9.968429E+00 -2.018883E+01 -5.522413E-02 -6.196056E-04 -3.243154E+01 -2.136942E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.599575E+01 -5.164848E+01 -1.369508E-01 -3.787900E-03 -3.062851E+01 -1.892971E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.984125E+01 -1.813760E+02 -3.150772E-01 -2.022590E-02 -3.078896E+01 -1.929299E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.239082E+01 -2.130115E+02 -3.421610E-01 -2.377195E-02 -3.338365E+01 -2.262151E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.394890E+01 -2.331951E+02 -3.584238E-01 -2.599332E-02 -3.503323E+01 -2.483295E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -tally 3: -1.127805E+01 -2.608571E+01 -1.002813E+00 -2.123979E-01 -2.754396E+01 -1.556374E+02 -5.744190E-01 -6.983035E-02 -1.301487E+00 -3.559715E-01 -1.027524E+01 -2.176770E+01 -1.027808E+01 -2.177975E+01 -1.147696E+01 -2.681957E+01 -8.617077E-01 -1.528009E-01 -2.799053E+01 -1.596017E+02 -4.924622E-01 -4.996879E-02 -1.463919E+00 -4.452955E-01 -1.061525E+01 -2.304844E+01 -1.061818E+01 -2.306116E+01 -1.112664E+01 -2.517898E+01 -9.122203E-01 -1.733772E-01 -2.712336E+01 -1.496225E+02 -5.264663E-01 -5.774755E-02 -1.333478E+00 -3.684793E-01 -1.021442E+01 -2.118539E+01 -1.021724E+01 -2.119710E+01 -1.090672E+01 -2.450876E+01 -8.720475E-01 -1.544308E-01 -2.658725E+01 -1.456398E+02 -5.032815E-01 -5.143697E-02 -1.146804E+00 -2.835726E-01 -1.003467E+01 -2.079465E+01 -1.003744E+01 -2.080615E+01 -8.331989E+00 -1.409000E+01 -3.010595E-02 -5.041231E-04 -2.708797E+01 -1.489409E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -8.301883E+00 -1.399250E+01 -8.302183E+00 -1.399351E+01 -8.140468E+00 -1.380373E+01 -3.007957E-02 -5.030779E-04 -2.646953E+01 -1.459652E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -8.110389E+00 -1.372142E+01 -8.110683E+00 -1.372241E+01 -8.082005E+00 -1.362698E+01 -1.000276E-02 -1.000553E-04 -2.629420E+01 -1.442386E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -8.072002E+00 -1.358172E+01 -8.072302E+00 -1.358273E+01 -8.452493E+00 -1.439819E+01 -3.016800E-02 -3.033748E-04 -2.749955E+01 -1.524016E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -8.422325E+00 -1.429746E+01 -8.422638E+00 -1.429853E+01 -2.414436E+01 -1.174474E+02 -2.911770E-01 -2.007223E-02 -2.492486E+01 -1.250988E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.385318E+01 -1.146286E+02 -2.385318E+01 -1.146286E+02 -2.670358E+01 -1.446298E+02 -4.109267E-01 -3.665787E-02 -2.742207E+01 -1.524808E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.629265E+01 -1.401748E+02 -2.629265E+01 -1.401748E+02 -2.805989E+01 -1.590823E+02 -2.605721E-01 -1.547273E-02 -2.895612E+01 -1.694067E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.779932E+01 -1.561607E+02 -2.779932E+01 -1.561607E+02 -2.858483E+01 -1.648682E+02 -3.007528E-01 -2.029929E-02 -2.949783E+01 -1.755681E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.828408E+01 -1.615023E+02 -2.828408E+01 -1.615023E+02 -tally 4: -1.127805E+01 -2.608571E+01 -9.413263E-01 -1.814958E-01 -2.754396E+01 -1.556374E+02 -5.422850E-01 -6.023145E-02 -1.344903E+00 -3.704722E-01 -1.147696E+01 -2.681957E+01 -9.663242E-01 -1.895497E-01 -2.799053E+01 -1.596017E+02 -5.573458E-01 -6.303283E-02 -1.381910E+00 -3.875298E-01 -1.112664E+01 -2.517898E+01 -9.408395E-01 -1.800284E-01 -2.712336E+01 -1.496225E+02 -5.429832E-01 -5.996291E-02 -1.346171E+00 -3.685618E-01 -1.090672E+01 -2.450876E+01 -9.222434E-01 -1.752364E-01 -2.658725E+01 -1.456398E+02 -5.322509E-01 -5.836681E-02 -1.319563E+00 -3.587514E-01 -8.331989E+00 -1.409000E+01 -4.665612E-02 -4.414425E-04 -2.708797E+01 -1.489409E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -8.140468E+00 -1.380373E+01 -4.513252E-02 -4.265760E-04 -2.646953E+01 -1.459652E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -8.082005E+00 -1.362698E+01 -4.477352E-02 -4.182191E-04 -2.629420E+01 -1.442386E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -8.452493E+00 -1.439819E+01 -4.682599E-02 -4.418878E-04 -2.749955E+01 -1.524016E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.414436E+01 -1.174474E+02 -2.549248E-01 -1.309686E-02 -2.492486E+01 -1.250988E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.670358E+01 -1.446298E+02 -2.827393E-01 -1.621660E-02 -2.742207E+01 -1.524808E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.805989E+01 -1.590823E+02 -2.962491E-01 -1.773226E-02 -2.895612E+01 -1.694067E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.858483E+01 -1.648682E+02 -3.017914E-01 -1.837719E-02 -2.949783E+01 -1.755681E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -tally 5: -1.140031E+01 -2.654804E+01 -9.714892E-01 -1.928147E-01 -2.775330E+01 -1.573327E+02 -5.611798E-01 -6.433919E-02 -1.390960E+00 -3.952699E-01 -1.042894E+01 -2.221679E+01 -1.141545E+01 -2.652638E+01 -9.688838E-01 -1.912040E-01 -2.781363E+01 -1.574484E+02 -5.594851E-01 -6.375914E-02 -1.386962E+00 -3.918154E-01 -1.129668E-01 -2.597945E-03 -1.104472E+01 -2.480364E+01 -9.339121E-01 -1.773447E-01 -2.692364E+01 -1.473920E+02 -5.389851E-01 -5.906905E-02 -1.336259E+00 -3.630677E-01 -1.011089E+01 -2.078670E+01 -1.117137E+01 -2.545891E+01 -9.446221E-01 -1.820299E-01 -2.723240E+01 -1.512859E+02 -5.451662E-01 -6.062956E-02 -1.351583E+00 -3.726594E-01 -1.105108E-01 -2.491359E-03 -8.516856E+00 -1.480571E+01 -4.746789E-02 -4.599371E-04 -2.769452E+01 -1.565558E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -8.469171E+00 -1.464039E+01 -8.669841E+00 -1.526679E+01 -4.817729E-02 -4.716776E-04 -2.820058E+01 -1.615173E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.126905E-01 -2.579568E-03 -8.322112E+00 -1.408773E+01 -4.610369E-02 -4.323598E-04 -2.707537E+01 -1.491155E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -8.275818E+00 -1.393144E+01 -8.001626E+00 -1.291919E+01 -4.432823E-02 -3.964967E-04 -2.603269E+01 -1.367468E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.037888E-01 -2.173599E-03 -2.420071E+01 -1.187334E+02 -2.553808E-01 -1.322410E-02 -2.499803E+01 -1.266325E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.394540E+01 -1.162412E+02 -2.599102E+01 -1.379786E+02 -2.747004E-01 -1.541805E-02 -2.675330E+01 -1.460654E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.544592E-02 -4.872035E-05 -2.723238E+01 -1.502761E+02 -2.875125E-01 -1.675068E-02 -2.810218E+01 -1.600291E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.694487E+01 -1.471198E+02 -2.839730E+01 -1.630916E+02 -2.998114E-01 -1.817916E-02 -2.930431E+01 -1.736763E+02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.688140E-02 -5.763608E-05 -tally 6: -1.027524E+01 -2.176770E+01 -1.027808E+01 -2.177975E+01 -1.301487E+00 -3.559715E-01 -1.061525E+01 -2.304844E+01 -1.061818E+01 -2.306116E+01 -1.463919E+00 -4.452955E-01 -1.021442E+01 -2.118539E+01 -1.021724E+01 -2.119710E+01 -1.333478E+00 -3.684793E-01 -1.003467E+01 -2.079465E+01 -1.003744E+01 -2.080615E+01 -1.146804E+00 -2.835726E-01 -8.301883E+00 -1.399250E+01 -8.302183E+00 -1.399351E+01 -0.000000E+00 -0.000000E+00 -8.110389E+00 -1.372142E+01 -8.110683E+00 -1.372241E+01 -0.000000E+00 -0.000000E+00 -8.072002E+00 -1.358172E+01 -8.072302E+00 -1.358273E+01 -0.000000E+00 -0.000000E+00 -8.422325E+00 -1.429746E+01 -8.422638E+00 -1.429853E+01 -0.000000E+00 -0.000000E+00 -2.385318E+01 -1.146286E+02 -2.385318E+01 -1.146286E+02 -0.000000E+00 -0.000000E+00 -2.629265E+01 -1.401748E+02 -2.629265E+01 -1.401748E+02 -0.000000E+00 -0.000000E+00 -2.779932E+01 -1.561607E+02 -2.779932E+01 -1.561607E+02 -0.000000E+00 -0.000000E+00 -2.828408E+01 -1.615023E+02 -2.828408E+01 -1.615023E+02 -0.000000E+00 -0.000000E+00 +a78b7997b258f01764aebf601ae7107d7286d79269c1adcaa3c5b58d4f78f7b330cda152f415ad7c9b0622c3dc2b60284bfca74febfd35369c2772a87b9c4d44 \ 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 4e57120bd..b9bbcb554 100644 --- a/tests/test_mg_tallies/test_mg_tallies.py +++ b/tests/test_mg_tallies/test_mg_tallies.py @@ -3,14 +3,14 @@ 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=True) + self._input_set.build_default_materials_and_geometry(as_macro=False) self._input_set.build_default_settings() # Instantiate a tally mesh @@ -28,43 +28,55 @@ class MGTalliesTestHarness(PyAPITestHarness): mat_ids = [mat.id for mat in self._input_set.materials] mat_filter = openmc.MaterialFilter(mat_ids) + nuclides = [xs.name for xs in self._input_set.xs_data] + + scores= {False: ['total', 'absorption', 'flux', 'fission', 'nu-fission'], + True: ['total', 'absorption', 'fission', 'nu-fission']} + 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 - tallies.append(openmc.Tally()) - tallies[-1].filters = [mesh_filter] - tallies[-1].estimator = 'analog' - tallies[-1].scores = ['total', 'absorption', 'flux', - 'fission', 'nu-fission'] + 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 = [mesh_filter] - tallies[-1].estimator = 'tracklength' - tallies[-1].scores = ['total', 'absorption', 'flux', - 'fission', 'nu-fission'] + 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 = 'analog' - tallies[-1].scores = ['total', 'absorption', 'flux', - 'fission', 'nu-fission', 'scatter', - 'nu-scatter'] + 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 = 'collision' - tallies[-1].scores = ['total', 'absorption', 'flux', - 'fission', 'nu-fission'] + 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] - tallies[-1].estimator = 'tracklength' - tallies[-1].scores = ['total', 'absorption', 'flux', - 'fission', 'nu-fission', 'scatter'] - - tallies.append(openmc.Tally()) - tallies[-1].filters = [mat_filter, energy_filter, - energyout_filter] - tallies[-1].scores = ['scatter', 'nu-scatter', 'nu-fission'] + 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) From 6ae0b1b0e668d4c94e4605b3e29dbe8cfcd61c29 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 15 Oct 2016 16:23:10 -0400 Subject: [PATCH 39/42] Grr --- src/tally.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tally.F90 b/src/tally.F90 index e1c5769d1..978f26d7b 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -1867,7 +1867,7 @@ contains if (i_nuclide > 0) then atom_density = -ONE - ! Check to see if this nuclide was in the material of our collision. + ! 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) From fa6a3686605464238be29e6c90318f81af924946 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 15 Oct 2016 16:38:00 -0400 Subject: [PATCH 40/42] Updating example mgxs.h5 file --- examples/xml/pincell_multigroup/mgxs.h5 | Bin 16496 -> 61488 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/xml/pincell_multigroup/mgxs.h5 b/examples/xml/pincell_multigroup/mgxs.h5 index cbe338c1c7de692a9bed69901f1da186bc1d3348..fe93c44bfa6b3766155356e34bdcd31e9fdb6af0 100644 GIT binary patch literal 61488 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 JjV;W?p?}8JPhS84 From aaf9b401691e647c29c9c58a34046254a3e30e7c Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 15 Oct 2016 19:46:18 -0400 Subject: [PATCH 41/42] fixing the python2 test error --- tests/input_set.py | 7 ++++--- tests/test_mg_basic/inputs_true.dat | 2 +- tests/test_mg_basic/results_true.dat | 2 +- tests/test_mg_max_order/inputs_true.dat | 2 +- tests/test_mg_max_order/results_true.dat | 2 +- tests/test_mg_nuclide/inputs_true.dat | 2 +- tests/test_mg_nuclide/results_true.dat | 2 +- tests/test_mg_tallies/inputs_true.dat | 2 +- tests/test_mg_tallies/results_true.dat | 2 +- 9 files changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/input_set.py b/tests/input_set.py index e34927214..0d5a78bab 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): @@ -765,9 +766,9 @@ class MGInputSet(InputSet): 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 = 5. / float(len(mats)) + dz = round(5. / float(len(mats)), 4) for i in range(len(mats) - 1): - planes.append(openmc.ZPlane(z0=dz * (i + 1))) + planes.append(openmc.ZPlane(z0=dz * float(i + 1))) planes.append(openmc.ZPlane(z0=5.0, boundary_type='reflective')) # Define cells for each material diff --git a/tests/test_mg_basic/inputs_true.dat b/tests/test_mg_basic/inputs_true.dat index 31673c133..08917ab7d 100644 --- a/tests/test_mg_basic/inputs_true.dat +++ b/tests/test_mg_basic/inputs_true.dat @@ -1 +1 @@ -c657f05432d9668f56e671a463ba08aed47103a33072d3f893146ff24fce6711ec41ba49c7d14a70b076cccb9a526375a4d8c1241e64e8167b8e0e876ae6655c \ 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 a367c6026..01b792546 100644 --- a/tests/test_mg_basic/results_true.dat +++ b/tests/test_mg_basic/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.034509E+00 4.099331E-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 375a7fe21..3056e8cbd 100644 --- a/tests/test_mg_max_order/inputs_true.dat +++ b/tests/test_mg_max_order/inputs_true.dat @@ -1 +1 @@ -b4adeb6b98d1d6310484c6623dde61ccfb02e0b8b9422c60d94cb65e556f3e2744c94cb3661a94aa365964acb463a6bd93cddf2dd954bfc36e316335b4a058f3 \ 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 1fa95fb90..0e470e2cd 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.099449E+00 1.956787E-02 +1.098323E+00 1.979833E-02 diff --git a/tests/test_mg_nuclide/inputs_true.dat b/tests/test_mg_nuclide/inputs_true.dat index 5950ad3e4..57aa5d33f 100644 --- a/tests/test_mg_nuclide/inputs_true.dat +++ b/tests/test_mg_nuclide/inputs_true.dat @@ -1 +1 @@ -130e51d00cd4c00be14b4e722c285ef5725f7f7a25361f48524dc51bb70c0869149adb839199915fe6193273cb957414c073be2a9fda3ed03754967571b73f68 \ 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 a367c6026..01b792546 100644 --- a/tests/test_mg_nuclide/results_true.dat +++ b/tests/test_mg_nuclide/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.034509E+00 4.099331E-02 +1.160653E+00 6.227102E-02 diff --git a/tests/test_mg_tallies/inputs_true.dat b/tests/test_mg_tallies/inputs_true.dat index 4b1863929..6b0ff76b1 100644 --- a/tests/test_mg_tallies/inputs_true.dat +++ b/tests/test_mg_tallies/inputs_true.dat @@ -1 +1 @@ -255e71d921bb67f7f4832d1b217f4d19ea3c6bd96f551f1676e3735bd314986cc5f2be064e98c8f938a3f93c28b94487567d28829b4c0d66f8d2f8f5a776f302 \ 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 67e6cf405..b540d9a49 100644 --- a/tests/test_mg_tallies/results_true.dat +++ b/tests/test_mg_tallies/results_true.dat @@ -1 +1 @@ -a78b7997b258f01764aebf601ae7107d7286d79269c1adcaa3c5b58d4f78f7b330cda152f415ad7c9b0622c3dc2b60284bfca74febfd35369c2772a87b9c4d44 \ No newline at end of file +6ab4a178b642f886eea9fddbdf67a8d6d3e0d1968f06ee52d7fd5ecdc1b4a796398e9b3a8c15ac72fb1a011d13a5fcc59a868781d38fb11787e060bb2e602a7b \ No newline at end of file From 22df8cfe417d7cfe88361bd4cac75c315798f09e Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 18 Oct 2016 05:23:50 -0400 Subject: [PATCH 42/42] Incorporated @paulromano comments --- docs/source/io_formats/mgxs_library.rst | 2 +- openmc/mesh.py | 4 ++-- openmc/mgxs/library.py | 2 +- openmc/mgxs_library.py | 9 +++------ 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/docs/source/io_formats/mgxs_library.rst b/docs/source/io_formats/mgxs_library.rst index 2a1e63d43..4e5ea2196 100644 --- a/docs/source/io_formats/mgxs_library.rst +++ b/docs/source/io_formats/mgxs_library.rst @@ -9,7 +9,7 @@ nuclear data is available. In continuous-energy mode, the ``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, the multi-group meta-data and the -nuclear data itself is contained within an ``mgxs.h5``. This portion of +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. diff --git a/openmc/mesh.py b/openmc/mesh.py index 014cbc467..21144469f 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -286,8 +286,8 @@ class Mesh(object): openmc.XPlane(x0=self.upper_right[0], boundary_type=bc[1])] if len(self.dimension) == 1: - yplanes = [openmc.YPlane(y0=1000., boundary_type='reflective'), - openmc.YPlane(y0=1000., 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]), diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index c03aa7877..eb07e8097 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -1283,7 +1283,7 @@ class Library(object): ('nu-transport' not in self.mgxs_types))): error_flag = True warn('A "nu-transport" MGXS type is required since a "P0" ' - 'correction is applied, but a "nu-transport" MGXS == ' + 'correction is applied, but a "nu-transport" MGXS is ' 'not provided.') elif (((self.correction is None) and ('total' not in self.mgxs_types))): diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 35dff1223..b62c3ac83 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1135,19 +1135,16 @@ class XSdata(object): if self.fissionable is not None: grp.attrs['fissionable'] = self.fissionable if self.representation is not None: - grp.attrs['representation'] = np.array(self.representation, - dtype='S') + 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.array(self.scatter_format, - dtype='S') + grp.attrs['scatter_format'] = np.string_(self.scatter_format) if self.scatter_shape is not None: - grp.attrs['scatter_shape'] = np.array(self.scatter_shape, - dtype='S') + grp.attrs['scatter_shape'] = np.string_(self.scatter_shape) if self.order is not None: grp.attrs['order'] = self.order