From 89149ea7eb44b2f83204b1486ecf87aefc489077 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Thu, 13 Oct 2016 14:38:06 -0400 Subject: [PATCH 01/27] added treatment of delayed neutrons to the multi-group solver --- docs/source/io_formats/mgxs_library.rst | 12 +- docs/source/usersguide/input.rst | 12 +- .../python/pincell_multigroup/build-xml.py | 6 +- openmc/mgxs/library.py | 79 +- openmc/mgxs_library.py | 934 ++++++-- src/cmfd_input.F90 | 2 +- src/global.F90 | 5 +- src/hdf5_interface.F90 | 21 + src/input_xml.F90 | 58 +- src/mgxs_data.F90 | 88 +- src/mgxs_header.F90 | 1975 +++++++++++++---- src/physics_mg.F90 | 26 +- src/source.F90 | 6 +- src/tally.F90 | 596 ++++- src/tally_filter.F90 | 4 +- 15 files changed, 3019 insertions(+), 805 deletions(-) diff --git a/docs/source/io_formats/mgxs_library.rst b/docs/source/io_formats/mgxs_library.rst index 04474c01b5..a66764a837 100644 --- a/docs/source/io_formats/mgxs_library.rst +++ b/docs/source/io_formats/mgxs_library.rst @@ -15,8 +15,9 @@ to be used in the ``mgxs.h5`` file. 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. +energy groups, delayed groups, and the energy group structure, etc.) as +well as the actual cross section data itself for each of the necessary +nuclides or materials. .. _HDF5: http://www.hdfgroup.org/HDF5/ @@ -28,7 +29,8 @@ MGXS Library Specification **/** -:Attributes: - **groups** (*int*) -- Number of energy groups +:Attributes: - **energy_groups** (*int*) -- Number of energy groups + - **delayed_groups** (*int*) -- Number of delayed groups (optional) - **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. @@ -110,7 +112,7 @@ 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 + - **inverse-velocity** (*double[]*) -- Average inverse velocity for each of the groups in the library. This dataset is optional. **//K/scatter data/** @@ -159,4 +161,4 @@ Data specific to neutron scattering for the temperature K 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 + `g_out bounds`[1]. diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index 9e32118195..a7d38f01cb 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -1681,8 +1681,6 @@ The ```` element accepts the following sub-elements: - .. note:: This filter type is not used in the multi-group :ref:`energy_mode`. - :nuclides: If specified, the scores listed will be for particular nuclides, not the summation of reactions from all nuclides. The format for nuclides should be @@ -1863,12 +1861,10 @@ The ```` element accepts the following sub-elements: |Score | Description | +======================+===================================================+ |delayed-nu-fission |Total production of delayed neutrons due to | - | |fission. This score type is not used in the | - | |multi-group :ref:`energy_mode`. | + | |fission. | +----------------------+---------------------------------------------------+ |prompt-nu-fission |Total production of prompt neutrons due to | - | |fission. This score type is not used in the | - | |multi-group :ref:`energy_mode`. | + | |fission. | +----------------------+---------------------------------------------------+ |nu-fission |Total production of neutrons due to fission. | +----------------------+---------------------------------------------------+ @@ -1897,8 +1893,6 @@ The ```` element accepts the following sub-elements: +----------------------+---------------------------------------------------+ |inverse-velocity |The flux-weighted inverse velocity where the | | |velocity is in units of centimeters per second. | - | |This score type is not used in the | - | |multi-group :ref:`energy_mode`. | +----------------------+---------------------------------------------------+ |kappa-fission |The recoverable energy production rate due to | | |fission. The recoverable energy is defined as the | @@ -1934,8 +1928,6 @@ The ```` element accepts the following sub-elements: +----------------------+---------------------------------------------------+ |decay-rate |The delayed-nu-fission-weighted decay rate where | | |the decay rate is in units of inverse seconds. | - | |This score type is not used in the | - | |multi-group :ref:`energy_mode`. | +----------------------+---------------------------------------------------+ .. note:: diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index 216c565397..31a6c52f75 100644 --- a/examples/python/pincell_multigroup/build-xml.py +++ b/examples/python/pincell_multigroup/build-xml.py @@ -19,7 +19,7 @@ groups = openmc.mgxs.EnergyGroups(group_edges=[1E-11, 0.0635E-6, 10.0E-6, 1.0E-4, 1.0E-3, 0.5, 1.0, 20.0]) # Instantiate the 7-group (C5G7) cross section data -uo2_xsdata = openmc.XSdata('UO2', groups) +uo2_xsdata = openmc.XSdata('UO2', groups, delayed_groups=8) uo2_xsdata.order = 0 uo2_xsdata.set_total( [0.1779492, 0.3298048, 0.4803882, 0.5543674, 0.3118013, 0.3951678, @@ -42,6 +42,8 @@ uo2_xsdata.set_nu_fission([2.005998E-02, 2.027303E-03, 1.570599E-02, 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]) +uo2_xsdata.set_beta([2.13333e-4, 1.04514e-3, 6.03969e-4, 1.33963e-3, + 2.29386e-3, 7.05174e-4, 6.00381e-4, 2.07736e-4]) h2o_xsdata = openmc.XSdata('LWTR', groups) h2o_xsdata.order = 0 @@ -59,7 +61,7 @@ h2o_xsdata.set_scatter_matrix( [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 = openmc.MGXSLibrary(groups, delayed_groups=8) mg_cross_sections_file.add_xsdatas([uo2_xsdata, h2o_xsdata]) mg_cross_sections_file.export_to_hdf5() diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 02c63f50bb..e91f3a2452 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -898,6 +898,7 @@ class Library(object): if nuclide is not 'total': name += '_' + nuclide xsdata = openmc.XSdata(name, self.energy_groups) + xsdata.delayed_groups = self.num_delayed_groups if order is None: # Set the order to the Library's order (the defualt behavior) @@ -924,41 +925,79 @@ class Library(object): mymgxs = self.get_mgxs(domain, 'nu-transport') xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], subdomains=subdomain) + elif 'total' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'total') xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], subdomain=subdomain) + if 'absorption' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'absorption') xsdata.set_absorption_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], subdomain=subdomain) + if 'fission' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'fission') xsdata.set_fission_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], subdomain=subdomain) + if 'kappa-fission' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'kappa-fission') xsdata.set_kappa_fission_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], subdomain=subdomain) - # For chi and nu-fission we can either have only a nu-fission matrix - # provided, or vectors of chi and nu-fission provided + + if 'inverse-velocity' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'inverse-velocity') + xsdata.set_inverse_velocity_mgxs(mymgxs, xs_type=xs_type, + nuclide=[nuclide], + subdomain=subdomain) + if 'nu-fission matrix' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'nu-fission matrix') xsdata.set_nu_fission_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], subdomain=subdomain) - else: - if 'chi' in self.mgxs_types: - mymgxs = self.get_mgxs(domain, 'chi') - xsdata.set_chi_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain) - if 'nu-fission' in self.mgxs_types: - mymgxs = self.get_mgxs(domain, 'nu-fission') - xsdata.set_nu_fission_mgxs(mymgxs, xs_type=xs_type, - nuclide=[nuclide], - subdomain=subdomain) + + if 'chi' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'chi') + xsdata.set_chi_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], + subdomain=subdomain) + + if 'chi-prompt' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'chi-prompt') + xsdata.set_chi_prompt_mgxs(mymgxs, xs_type=xs_type, + nuclide=[nuclide], subdomain=subdomain) + + if 'chi-delayed' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'chi-delayed') + xsdata.set_chi_delayed_mgxs(mymgxs, xs_type=xs_type, + nuclide=[nuclide], subdomain=subdomain) + + if 'nu-fission' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'nu-fission') + xsdata.set_nu_fission_mgxs(mymgxs, xs_type=xs_type, + nuclide=[nuclide], + subdomain=subdomain) + + if 'prompt-nu-fission' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'prompt-nu-fission') + xsdata.set_prompt_nu_fission_mgxs(mymgxs, xs_type=xs_type, + nuclide=[nuclide], + subdomain=subdomain) + + if 'delayed-nu-fission' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'delayed-nu-fission') + xsdata.set_delayed_nu_fission_mgxs(mymgxs, xs_type=xs_type, + nuclide=[nuclide], + subdomain=subdomain) + + if 'beta' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'nu-fission') + xsdata.set_beta_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], + subdomain=subdomain) + # If multiplicity matrix is available, prefer that if 'multiplicity matrix' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'multiplicity matrix') @@ -966,6 +1005,7 @@ class Library(object): 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))): @@ -976,6 +1016,7 @@ class Library(object): nuclide=[nuclide], subdomain=subdomain) using_multiplicity = True + else: using_multiplicity = False @@ -991,14 +1032,13 @@ class Library(object): 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. + # 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: for i in range(len(xsdata.temperatures)): - xsdata._absorption[i] = \ - np.subtract(xsdata._total[i], np.sum( + xsdata._absorption[i] \ + = np.subtract(xsdata._total[i], np.sum( xsdata._scatter_matrix[i][0, :, :], axis=1)) return xsdata @@ -1051,7 +1091,8 @@ class Library(object): xs_type = 'macro' # Initialize file - mgxs_file = openmc.MGXSLibrary(self.energy_groups) + mgxs_file = openmc.MGXSLibrary(self.energy_groups, + delayed_groups=self.num_delayed_groups) if self.domain_type == 'mesh': # Create the xsdata objects and add to the mgxs_file diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index cba5c20a15..c661bb52fd 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -34,6 +34,8 @@ class XSdata(object): temperatures : numpy.ndarray Temperatures (in units of Kelvin) of the provided datasets. Defaults to a single temperature at 294K. + delayed_groups : int + Number of delayed groups Attributes ---------- @@ -47,6 +49,8 @@ class XSdata(object): to a single temperature at 294K. energy_groups : openmc.mgxs.EnergyGroups Energy group structure + delayed_groups : int + Num delayed groups fissionable : bool Whether or not this is a fissionable data set. scatter_format : {'legendre', 'histogram', or 'tabular'} @@ -64,20 +68,6 @@ class XSdata(object): num_polar : int Number of equal width angular bins that the polar angular domain is subdivided into. This only applies when ``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``. - matrix_shape : iterable of int - Dimensionality of matrix multi-group cross sections (e.g., the - fission matrix cross section). The return result depends on the - value of ``representation``. - pn_matrix_shape : iterable of int - Dimensionality of scattering matrix data (e.g., the - scattering matrix cross section). The return result depends on the - value of ``representation``. total : dict of numpy.ndarray Group-wise total cross section. absorption : dict of numpy.ndarray @@ -102,37 +92,37 @@ class XSdata(object): 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. + chi_prompt : dict of numpy.ndarray + Group-wise prompt fission spectra ordered by increasing group index + (i.e., fast to thermal). This attribute should be used if chi from + prompt and delayed neutrons is being set separately. + chi_delayed : dict of numpy.ndarray + Group-wise delayed fission spectra ordered by increasing group index + (i.e., fast to thermal). This attribute should be used if chi from + prompt and delayed neutrons is being set separately. 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. - 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 + prompt_nu_fission : dict of numpy.ndarray + Group-wise prompt fission production cross section vector. + delayed_nu_fission : dict of numpy.ndarray + Group-wise delayed fission production cross section vector. + beta : dict of numpy.ndarray + Delayed-group-wise delayed neutron fraction cross section vector. + decay_rate : dict of numpy.ndarray + Delayed-group-wise decay rate cross section vector. + inverse_velocity : dict of numpy.ndarray + Inverse of velocity, in units of sec/cm. """ def __init__(self, name, energy_groups, temperatures=[294.], - representation='isotropic'): + representation='isotropic', delayed_groups=0): + # Initialize class attributes self.name = name self.energy_groups = energy_groups + self.delayed_groups = delayed_groups self.temperatures = temperatures self.representation = representation self._awr = None @@ -141,16 +131,21 @@ class XSdata(object): self._order = None self._num_polar = None self._num_azimuthal = 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._prompt_nu_fission = len(temperatures) * [None] + self._delayed_nu_fission = len(temperatures) * [None] self._kappa_fission = len(temperatures) * [None] self._chi = len(temperatures) * [None] - self._inverse_velocities = len(temperatures) * [None] + self._chi_prompt = len(temperatures) * [None] + self._chi_delayed = len(temperatures) * [None] + self._beta = len(temperatures) * [None] + self._decay_rate = len(temperatures) * [None] + self._inverse_velocity = len(temperatures) * [None] @property def name(self): @@ -160,6 +155,10 @@ class XSdata(object): def energy_groups(self): return self._energy_groups + @property + def delayed_groups(self): + return self._delayed_groups + @property def representation(self): return self._representation @@ -192,10 +191,6 @@ class XSdata(object): def num_azimuthal(self): return self._num_azimuthal - @property - def use_chi(self): - return self._use_chi - @property def total(self): return self._total @@ -220,6 +215,14 @@ class XSdata(object): def nu_fission(self): return self._nu_fission + @property + def prompt_nu_fission(self): + return self._prompt_nu_fission + + @property + def delayed_nu_fission(self): + return self._delayed_nu_fission + @property def kappa_fission(self): return self._kappa_fission @@ -228,6 +231,14 @@ class XSdata(object): def chi(self): return self._chi + @property + def chi_prompt(self): + return self._chi_prompt + + @property + def chi_delayed(self): + return self._chi_delayed + @property def num_orders(self): if self._order is not None: @@ -236,34 +247,6 @@ class XSdata(object): else: return self._order - @property - def vector_shape(self): - if self.representation == 'isotropic': - return (self.energy_groups.num_groups,) - elif self.representation == 'angle': - return (self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups) - - @property - def matrix_shape(self): - if self.representation == 'isotropic': - return (self.energy_groups.num_groups, - self.energy_groups.num_groups) - 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 == 'isotropic': - return (self.num_orders, self.energy_groups.num_groups, - self.energy_groups.num_groups) - elif self.representation == 'angle': - return (self.num_polar, self.num_azimuthal, self.num_orders, - self.energy_groups.num_groups, - self.energy_groups.num_groups) - @name.setter def name(self, name): check_type('name for XSdata', name, basestring) @@ -271,6 +254,7 @@ class XSdata(object): @energy_groups.setter def energy_groups(self, energy_groups): + # Check validity of energy_groups check_type('energy_groups', energy_groups, openmc.mgxs.EnergyGroups) @@ -278,16 +262,28 @@ class XSdata(object): msg = 'Unable to assign an EnergyGroups object ' \ 'with uninitialized group edges' raise ValueError(msg) + self._energy_groups = energy_groups + @delayed_groups.setter + def delayed_groups(self, delayed_groups): + + # Check validity of delayed_groups + check_type('delayed_groups', delayed_groups, int) + check_greater_than('delayed_groups', delayed_groups, 0, equality=True) + + self._delayed_groups = delayed_groups + @representation.setter def representation(self, representation): + # Check it is of valid type. 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) @@ -300,8 +296,10 @@ 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) @@ -311,12 +309,14 @@ class XSdata(object): @scatter_format.setter def scatter_format(self, scatter_format): + # check to see it is of a valid type and value check_value('scatter_format', scatter_format, _SCATTER_TYPES) self._scatter_format = scatter_format @order.setter def order(self, order): + # Check type and value check_type('order', order, Integral) check_greater_than('order', order, 0, equality=True) @@ -324,6 +324,7 @@ class XSdata(object): @num_polar.setter def num_polar(self, num_polar): + # Make sure we have positive ints check_type('num_polar', num_polar, Integral) check_greater_than('num_polar', num_polar, 0) @@ -331,15 +332,11 @@ class XSdata(object): @num_azimuthal.setter def num_azimuthal(self, num_azimuthal): + check_type('num_azimuthal', num_azimuthal, Integral) check_greater_than('num_azimuthal', num_azimuthal, 0) self._num_azimuthal = num_azimuthal - @use_chi.setter - def use_chi(self, use_chi): - 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 @@ -351,6 +348,7 @@ class XSdata(object): Temperature (in units of Kelvin) of the provided dataset. """ + check_type('temperature', temperature, Real) temp_store = self.temperatures.tolist().append(temperature) @@ -362,9 +360,15 @@ class XSdata(object): self._multiplicity_matrix.append(None) self._fission.append(None) self._nu_fission.append(None) + self._prompt_nu_fission.append(None) + self._delayed_nu_fission.append(None) self._kappa_fission.append(None) self._chi.append(None) - self._inverse_velocities.append(None) + self._chi_prompt.append(None) + self._chi_delayed.append(None) + self._beta.append(None) + self._decay_rate.append(None) + self._inverse_velocity.append(None) def set_total(self, total, temperature=294.): """This method sets the cross section for this XSdata object at the @@ -383,10 +387,19 @@ class XSdata(object): openmc.mgxs_library.set_total_mgxs() """ + check_type('total', total, Iterable, expected_iter_type=Real) + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.energy_groups.num_groups,)] + else: + shapes = [(self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups)] + # 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_value('total shape', nptotal.shape, shapes) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -410,11 +423,19 @@ class XSdata(object): openmc.mgxs_library.set_absorption_mgxs() """ + check_type('absorption', absorption, Iterable, expected_iter_type=Real) + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.energy_groups.num_groups,)] + else: + shapes = [(self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups)] + # 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_value('absorption shape', npabsorption.shape, shapes) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -438,10 +459,19 @@ class XSdata(object): openmc.mgxs_library.set_fission_mgxs() """ + check_type('fission', fission, Iterable, expected_iter_type=Real) + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.energy_groups.num_groups,)] + else: + shapes = [(self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups)] + # 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_value('fission shape', npfission.shape, shapes) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -468,12 +498,20 @@ class XSdata(object): openmc.mgxs_library.set_kappa_fission_mgxs() """ + check_type('kappa_fission', kappa_fission, Iterable, expected_iter_type=Real) + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.energy_groups.num_groups,)] + else: + shapes = [(self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups)] + # 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]) + check_value('kappa fission shape', npkappa_fission.shape, shapes) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -500,27 +538,167 @@ class XSdata(object): 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' - raise ValueError(msg) - check_type('chi', chi, Iterable, expected_iter_type=Real) + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.energy_groups.num_groups,)] + else: + shapes = [(self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups)] + # Convert to a numpy array so we can easily get the shape for checking npchi = np.asarray(chi) - # Check the shape - if npchi.shape != self.vector_shape: - msg = 'Provided chi iterable does not have the expected shape.' - raise ValueError(msg) + check_value('chi shape', npchi.shape, shapes) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) i = self.temperatures.tolist().index(temperature) self._chi[i] = npchi - if self.use_chi is not None: - self.use_chi = True + def set_chi_prompt(self, chi_prompt, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + chi_prompt : np.ndarray + Prompt fission Spectrum + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 294K + + See also + -------- + openmc.mgxs_library.set_chi_prompt_mgxs() + + """ + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.energy_groups.num_groups,)] + else: + shapes = [(self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups)] + + # Convert to a numpy array so we can easily get the shape for checking + npchi_prompt = np.asarray(chi_prompt) + check_value('chi prompt shape', npchi_prompt.shape, shapes) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) + + i = self.temperatures.tolist().index(temperature) + self._chi_prompt[i] = npchi_prompt + + def set_chi_delayed(self, chi_delayed, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + chi_delayed : np.ndarray + Delayed fission Spectrum + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 294K + + See also + -------- + openmc.mgxs_library.set_chi_delayed_mgxs() + + """ + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.energy_groups.num_groups,), + (self.delayed_groups, self.energy_groups.num_groups)] + else: + shapes = [(self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups), + (self.delayed_groups, self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups)] + + # Convert to a numpy array so we can easily get the shape for checking + npchi_delayed = np.asarray(chi_delayed) + check_value('chi delayed shape', npchi_delayed.shape, shapes) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) + + i = self.temperatures.tolist().index(temperature) + self._chi_delayed[i] = npchi_delayed + + def set_beta(self, beta, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + beta : np.ndarray + Delayed fission spectrum + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 294K + + See also + -------- + openmc.mgxs_library.set_beta_mgxs() + + """ + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.delayed_groups,), + (self.delayed_groups, self.energy_groups.num_groups)] + else: + shapes = [(self.delayed_groups, self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups), + (self.delayed_groups, self.num_polar, self.num_azimuthal)] + + # Convert to a numpy array so we can easily get the shape for checking + npbeta = np.asarray(beta) + check_value('beta shape', npbeta.shape, shapes) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) + + i = self.temperatures.tolist().index(temperature) + self._beta[i] = npbeta + + def set_decay_rate(self, decay_rate, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + decay_rate : np.ndarray + Delayed neutron precursor decay rate + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 294K + + See also + -------- + openmc.mgxs_library.set_decay_rate_mgxs() + + """ + + check_type('decay_rate', decay_rate, Iterable, expected_iter_type=Real) + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.delayed_groups,), + (self.delayed_groups, self.energy_groups.num_groups)] + else: + shapes = [(self.delayed_groups, self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups), + (self.delayed_groups, self.num_polar, self.num_azimuthal)] + + # Convert to a numpy array so we can easily get the shape for checking + npdecay_rate = np.asarray(decay_rate) + check_value('decay rate shape', npdecay_rate.shape, shapes) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) + + i = self.temperatures.tolist().index(temperature) + self._decay_rate[i] = npdecay_rate def set_scatter_matrix(self, scatter, temperature=294.): """This method sets the cross section for this XSdata object at the @@ -539,11 +717,21 @@ class XSdata(object): openmc.mgxs_library.set_scatter_matrix_mgxs() """ + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.num_orders, self.energy_groups.num_groups, + self.energy_groups.num_groups)] + else: + shapes = [(self.num_polar, self.num_azimuthal, self.num_orders, + self.energy_groups.num_groups, + self.energy_groups.num_groups)] + # 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_value('scatter shape', npscatter.shape, shapes) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -567,12 +755,21 @@ class XSdata(object): openmc.mgxs_library.set_multiplicity_matrix_mgxs() """ + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.energy_groups.num_groups, + self.energy_groups.num_groups)] + else: + shapes = [(self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups, + self.energy_groups.num_groups)] + # Convert to a numpy array so we can easily get the shape for checking npmultiplicity = np.asarray(multiplicity) check_iterable_type('multiplicity', npmultiplicity, Real, max_depth=len(npmultiplicity.shape)) - check_value('multiplicity shape', npmultiplicity.shape, - [self.matrix_shape]) + check_value('multiplicity shape', npmultiplicity.shape, shapes) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -596,82 +793,153 @@ class XSdata(object): 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. - # nu_fission can be given as a vector or a matrix - # Vector is used when chi also exists. - # Matrix is used when chi does not exist. - # We have to check that the correct form is given, but only if - # chi already has been set. If not, we just check that this is OK - # and set the use_chi flag accordingly + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.energy_groups.num_groups,), + (self.energy_groups.num_groups, + self.energy_groups.num_groups)] + else: + shapes = [(self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups), + (self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups, + self.energy_groups.num_groups)] # Convert to a numpy array so we can easily get the shape for checking npnu_fission = np.asarray(nu_fission) - + check_value('nu_fission shape', npnu_fission.shape, shapes) 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: - check_value('nu_fission shape', npnu_fission.shape, - [self.vector_shape]) - else: - check_value('nu_fission shape', npnu_fission.shape, - [self.matrix_shape]) - else: - check_value('nu_fission shape', npnu_fission.shape, - [self.vector_shape, self.matrix_shape]) - # Find out if we have a nu-fission matrix or vector - # and set a flag to allow other methods to check this later. - if npnu_fission.shape == self.vector_shape: - self.use_chi = True - else: - self.use_chi = False - i = self.temperatures.tolist().index(temperature) self._nu_fission[i] = npnu_fission 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 + def set_prompt_nu_fission(self, prompt_nu_fission, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + prompt_nu_fission: np.ndarray + Prompt-nu-fission Cross Section + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 294K + + See also + -------- + openmc.mgxs_library.set_prompt_nu_fission_mgxs() + + """ + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.energy_groups.num_groups,)] + else: + shapes = [(self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups)] + + # Convert to a numpy array so we can easily get the shape for checking + npprompt_nu_fission = np.asarray(prompt_nu_fission) + check_value('prompt_nu_fission shape', npprompt_nu_fission.shape, shapes) + check_iterable_type('prompt_nu_fission', npprompt_nu_fission, Real, + max_depth=len(npprompt_nu_fission.shape)) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) + + i = self.temperatures.tolist().index(temperature) + self._prompt_nu_fission[i] = npprompt_nu_fission + if np.sum(npprompt_nu_fission) > 0.0: + self._fissionable = True + + def set_delayed_nu_fission(self, delayed_nu_fission, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + delayed_nu_fission: np.ndarray + Delayed-nu-fission Cross Section + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 294K + + See also + -------- + openmc.mgxs_library.set_delayed_nu_fission_mgxs() + + """ + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.delayed_groups, self.energy_groups.num_groups,)] + else: + shapes = [(self.delayed_groups, self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups)] + + # Convert to a numpy array so we can easily get the shape for checking + npdelayed_nu_fission = np.asarray(delayed_nu_fission) + check_value('delayed_nu_fission shape', npdelayed_nu_fission.shape, + shapes) + check_iterable_type('delayed_nu_fission', npdelayed_nu_fission, Real, + max_depth=len(npdelayed_nu_fission.shape)) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) + + i = self.temperatures.tolist().index(temperature) + self._delayed_nu_fission[i] = npdelayed_nu_fission + if np.sum(npdelayed_nu_fission) > 0.0: + self._fissionable = True + + def set_inverse_velocity(self, inv_vel, temperature=294.): + """This method sets the inverse velocity for this XSdata object at the provided temperature. Parameters ---------- inv_vel: np.ndarray - Inverse velocities in units of sec/cm. + Inverse velocity 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, + + check_type('inverse_velocity', inv_vel, Iterable, expected_iter_type=Real) + + # Get the accepted shapes for this xs + if self.representation is 'isotropic': + shapes = [(self.energy_groups.num_groups,)] + else: + shapes = [(self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups)] + # 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_value('inverse_velocity shape', npinv_vel.shape, shapes) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) i = self.temperatures.tolist().index(temperature) - self._inverse_velocities[i] = npinv_vel + self._inverse_velocity[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 - openmc.mgxs.TransportXS to be used to set the total cross section - for this XSdata object. + openmc.mgxs.TransportXS to be used to set the total cross section for + this XSdata object. Parameters ---------- total: openmc.mgxs.TotalXS or openmc.mgxs.TransportXS - MGXS Object containing the total or transport cross section - for the domain of interest. + MGXS Object containing the total, transport or nu-transport cross + section for the domain of interest. temperature : float Temperature (in units of Kelvin) of the provided dataset. Defaults to 294K @@ -850,14 +1118,117 @@ class XSdata(object): msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - if isinstance(nu_fission, openmc.mgxs.NuFissionMatrixXS): - self.use_chi = False - else: - self.use_chi = True - if np.sum(self._nu_fission) > 0.0: self._fissionable = True + def set_prompt_nu_fission_mgxs(self, prompt_nu_fission, temperature=294., + nuclide='total', xs_type='macro', + subdomain=None): + """This method allows for an openmc.mgxs.PromptNuFissionXS to be used to + set the prompt-nu-fission cross section for this XSdata object. + + Parameters + ---------- + prompt_nu_fission: openmc.mgxs.PromptNuFissionXS + MGXS Object containing the prompt-nu-fission cross section + for the domain of interest. + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 294K + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell (i.e., [i, j, k] index) to use. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + check_type('prompt_nu_fission', prompt_nu_fission, + (openmc.mgxs.PromptNuFissionXS,)) + check_value('energy_groups', prompt_nu_fission.energy_groups, + [self.energy_groups]) + check_value('domain_type', prompt_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._prompt_nu_fission[i] = prompt_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) + + if np.sum(self._prompt_nu_fission) > 0.0: + self._fissionable = True + + def set_delayed_nu_fission_mgxs(self, delayed_nu_fission, temperature=294., + nuclide='total', xs_type='macro', + subdomain=None): + """This method allows for an openmc.mgxs.DelayedNuFissionXS to be used + to set the delayed-nu-fission cross section for this XSdata object. + + Parameters + ---------- + delayed_nu_fission: openmc.mgxs.DelayedNuFissionXS + MGXS Object containing the delayed-nu-fission cross section + for the domain of interest. + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 294K + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell (i.e., [i, j, k] index) to use. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + check_type('delayed_nu_fission', delayed_nu_fission, + (openmc.mgxs.DelayedNuFissionXS,)) + check_value('energy_groups', delayed_nu_fission.energy_groups, + [self.energy_groups]) + check_value('delayed_groups', delayed_nu_fission.num_delayed_groups, + [self.delayed_groups]) + check_value('domain_type', delayed_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._delayed_nu_fission[i] = delayed_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) + + if np.sum(self._delayed_nu_fission) > 0.0: + self._fissionable = True + def set_kappa_fission_mgxs(self, k_fission, temperature=294., nuclide='total', xs_type='macro', subdomain=None): @@ -936,12 +1307,6 @@ class XSdata(object): """ - if self.use_chi is not None: - if not self.use_chi: - msg = 'Providing chi when nu_fission already provided as a ' \ - 'matrix!' - raise ValueError(msg) - check_type('chi', chi, openmc.mgxs.Chi) check_value('energy_groups', chi.energy_groups, [self.energy_groups]) check_value('domain_type', chi.domain_type, @@ -957,8 +1322,191 @@ class XSdata(object): msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - if self.use_chi is not None: - self.use_chi = True + def set_chi_prompt_mgxs(self, chi_prompt, temperature=294., nuclide='total', + xs_type='macro', subdomain=None): + """This method allows for an openmc.mgxs.ChiPrompt + to be used to set chi-prompt for this XSdata object. + + Parameters + ---------- + chi_prompt: openmc.mgxs.ChiPrompt + MGXS Object containing chi-prompt for the domain of interest. + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 294K + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell (i.e., [i, j, k] index) to use. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + check_type('chi_prompt', chi_prompt, openmc.mgxs.ChiPrompt) + check_value('energy_groups', chi_prompt.energy_groups, + [self.energy_groups]) + check_value('domain_type', chi_prompt.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_prompt[i] = chi_prompt.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_delayed_mgxs(self, chi_delayed, temperature=294., + nuclide='total', xs_type='macro', subdomain=None): + """This method allows for an openmc.mgxs.ChiDelayed + to be used to set chi-delayed for this XSdata object. + + Parameters + ---------- + chi_delayed: openmc.mgxs.ChiDelayed + MGXS Object containing chi-delayed for the domain of interest. + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 294K + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell (i.e., [i, j, k] index) to use. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + check_type('chi_delayed', chi_delayed, openmc.mgxs.ChiDelayed) + check_value('energy_groups', chi_delayed.energy_groups, + [self.energy_groups]) + check_value('delayed_groups', chi_delayed.num_delayed_groups, + [self.delayed_groups]) + check_value('domain_type', chi_delayed.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_delayed[i] = chi_delayed.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_beta_mgxs(self, beta, temperature=294., + nuclide='total', xs_type='macro', subdomain=None): + """This method allows for an openmc.mgxs.Beta + to be used to set beta for this XSdata object. + + Parameters + ---------- + beta : openmc.mgxs.Beta + MGXS Object containing beta for the domain of interest. + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 294K + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell (i.e., [i, j, k] index) to use. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + check_type('beta', beta, openmc.mgxs.Beta) + check_value('delayed_groups', beta.num_delayed_groups, + [self.delayed_groups]) + check_value('domain_type', beta.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._beta[i] = beta.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_decay_rate_mgxs(self, decay_rate, temperature=294., + nuclide='total', xs_type='macro', subdomain=None): + """This method allows for an openmc.mgxs.DecayRate + to be used to set decay rate for this XSdata object. + + Parameters + ---------- + decay_rate : openmc.mgxs.DecayRate + MGXS Object containing decay rate for the domain of interest. + temperature : float + Temperature (in units of Kelvin) of the provided dataset. Defaults + to 294K + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell (i.e., [i, j, k] index) to use. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + check_type('decay_rate', decay_rate, openmc.mgxs.DecayRate) + check_value('delayed_groups', decay_rate.num_delayed_groups, + [self.delayed_groups]) + check_value('domain_type', decay_rate.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._decay_rate[i] = decay_rate.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_scatter_matrix_mgxs(self, scatter, temperature=294., nuclide='total', xs_type='macro', @@ -1114,22 +1662,29 @@ class XSdata(object): np.nan_to_num(self._multiplicity_matrix[i]) def _get_xsdata_group(self, file): + 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.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_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 @@ -1141,27 +1696,63 @@ class XSdata(object): # Create the temperature datasets for i, temperature in enumerate(self.temperatures): + xs_grp = grp.create_group(str(int(np.round(temperature))) + "K") + if self._total[i] is None: raise ValueError('total data must be provided when writing ' 'the HDF5 library') + xs_grp.create_dataset("total", data=self._total[i]) + if self._absorption[i] is None: raise ValueError('absorption data must be provided when ' 'writing the HDF5 library') + xs_grp.create_dataset("absorption", data=self._absorption[i]) + if self.fissionable: if self._fission[i] is not None: xs_grp.create_dataset("fission", data=self._fission[i]) + if self._kappa_fission[i] is not None: xs_grp.create_dataset("kappa-fission", data=self._kappa_fission[i]) + if self._chi[i] is not None: xs_grp.create_dataset("chi", data=self._chi[i]) - if self._nu_fission[i] is None: - raise ValueError('nu-fission data must be provided when ' - 'writing the HDF5 library') - xs_grp.create_dataset("nu-fission", data=self._nu_fission[i]) + + if self._chi_prompt[i] is not None: + xs_grp.create_dataset("chi-prompt", + data=self._chi_prompt[i]) + + if self._chi_delayed[i] is not None: + xs_grp.create_dataset("chi-delayed", + data=self._chi_delayed[i]) + + if self._nu_fission[i] is None and \ + (self._delayed_nu_fission[i] is None or \ + self._prompt_nu_fission[i] is None): + raise ValueError('nu-fission or prompt-nu-fission and ' + 'delayed-nu-fission data must be provided ' + 'when writing the HDF5 library') + + if self._nu_fission[i] is not None: + xs_grp.create_dataset("nu-fission", data=self._nu_fission[i]) + + if self._prompt_nu_fission[i] is not None: + xs_grp.create_dataset("prompt-nu-fission", + data=self._prompt_nu_fission[i]) + + if self._delayed_nu_fission[i] is not None: + xs_grp.create_dataset("delayed-nu-fission", + data=self._delayed_nu_fission[i]) + + if self._beta[i] is not None: + xs_grp.create_dataset("beta", data=self._beta[i]) + + if self._decay_rate[i] is not None: + xs_grp.create_dataset("decay-rate", data=self._decay_rate[i]) if self._scatter_matrix[i] is None: raise ValueError('Scatter matrix must be provided when ' @@ -1170,11 +1761,14 @@ class XSdata(object): # Get the sparse scattering data to print to the library G = self.energy_groups.num_groups if self.representation == 'isotropic': + g_out_bounds = np.zeros((G, 2), dtype=np.int) + for g_in in range(G): nz = np.nonzero(self._scatter_matrix[i][0, g_in, :]) g_out_bounds[g_in, 0] = nz[0][0] g_out_bounds[g_in, 1] = nz[0][-1] + # Now create the flattened scatter matrix array matrix = self._scatter_matrix[i] flat_scatt = [] @@ -1183,12 +1777,15 @@ class XSdata(object): g_out_bounds[g_in, 1] + 1): for l in range(len(matrix[:, g_in, g_out])): flat_scatt.append(matrix[l, g_in, g_out]) + # And write it. scatt_grp = xs_grp.create_group('scatter data') scatt_grp.create_dataset("scatter matrix", data=np.array(flat_scatt)) + # Repeat for multiplicity if self._multiplicity_matrix[i] is not None: + # Now create the flattened scatter matrix array matrix = self._multiplicity_matrix[i][:, :] flat_mult = [] @@ -1196,6 +1793,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", data=np.array(flat_mult)) @@ -1209,6 +1807,7 @@ class XSdata(object): 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): @@ -1216,6 +1815,7 @@ class XSdata(object): nz = np.nonzero(matrix) g_out_bounds[p, a, g_in, 0] = nz[0][0] g_out_bounds[p, a, g_in, 1] = nz[0][-1] + # Now create the flattened scatter matrix array flat_scatt = [] for p in range(Np): @@ -1226,12 +1826,15 @@ class XSdata(object): g_out_bounds[p, a, g_in, 1] + 1): for l in range(len(matrix[:, g_in, g_out])): flat_scatt.append(matrix[l, g_in, g_out]) + # And write it. scatt_grp = xs_grp.create_group('scatter data') scatt_grp.create_dataset("scatter matrix", data=np.array(flat_scatt)) + # Repeat for multiplicity if self._multiplicity_matrix[i] is not None: + # Now create the flattened scatter matrix array flat_mult = [] for p in range(Np): @@ -1241,6 +1844,7 @@ 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)) @@ -1252,9 +1856,9 @@ class XSdata(object): 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]) + if self._inverse_velocity[i] is not None: + xs_grp.create_dataset("inverse-velocity", + data=self._inverse_velocity[i]) class MGXSLibrary(object): @@ -1266,23 +1870,32 @@ class MGXSLibrary(object): ---------- energy_groups : openmc.mgxs.EnergyGroups Energy group structure + delayed_groups : int + Num delayed groups Attributes ---------- energy_groups : openmc.mgxs.EnergyGroups Energy group structure. + delayed_groups : int + Num delayed groups xsdatas : Iterable of openmc.XSdata Iterable of multi-Group cross section data objects """ - def __init__(self, energy_groups): + def __init__(self, energy_groups, delayed_groups=0): self.energy_groups = energy_groups + self.delayed_groups = delayed_groups self._xsdatas = [] @property def energy_groups(self): return self._energy_groups + @property + def delayed_groups(self): + return self._delayed_groups + @property def temperatures(self): return self._temperatures @@ -1296,6 +1909,11 @@ class MGXSLibrary(object): check_type('energy groups', energy_groups, openmc.mgxs.EnergyGroups) self._energy_groups = energy_groups + @delayed_groups.setter + def delayed_groups(self, delayed_groups): + check_type('delayed groups', delayed_groups, int) + self._delayed_groups = delayed_groups + def add_xsdata(self, xsdata): """Add an XSdata entry to the file. @@ -1305,10 +1923,12 @@ class MGXSLibrary(object): MGXS information to add """ + if not isinstance(xsdata, XSdata): msg = 'Unable to add a non-XSdata "{0}" to the ' \ 'MGXSLibrary instance'.format(xsdata) raise ValueError(msg) + if xsdata.energy_groups != self._energy_groups: msg = 'Energy groups of XSdata do not match that of MGXSLibrary.' raise ValueError(msg) @@ -1324,6 +1944,7 @@ class MGXSLibrary(object): XSdatas to add """ + check_iterable_type('xsdatas', xsdatas, XSdata) for xsdata in xsdatas: @@ -1360,7 +1981,8 @@ class MGXSLibrary(object): # Create and write to the HDF5 file file = h5py.File(filename, "w") - file.attrs['groups'] = self.energy_groups.num_groups + file.attrs['energy_groups'] = self.energy_groups.num_groups + file.attrs['delayed_groups'] = self.delayed_groups file.attrs['group structure'] = self.energy_groups.group_edges for xsdata in self._xsdatas: diff --git a/src/cmfd_input.F90 b/src/cmfd_input.F90 index 327b55b42a..a60fc9a89a 100644 --- a/src/cmfd_input.F90 +++ b/src/cmfd_input.F90 @@ -107,7 +107,7 @@ contains if (.not. run_CE) then do i = 1, ng found = .false. - do g = 1, energy_groups + 1 + do g = 1, num_energy_groups + 1 if (cmfd % egrid(i) == energy_bins(g)) then found = .true. exit diff --git a/src/global.F90 b/src/global.F90 index 1e837b8c0f..48105bbf92 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -115,7 +115,10 @@ module global type(MgxsContainer), target, allocatable :: macro_xs(:) ! Number of energy groups - integer :: energy_groups + integer :: num_energy_groups + + ! Number of delayed groups + integer :: num_delayed_groups ! Energy group structure real(8), allocatable :: energy_bins(:) diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index 262bbc232c..da8ebe1206 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -99,6 +99,7 @@ module hdf5_interface public :: open_dataset public :: close_dataset public :: get_shape + public :: get_ndims public :: write_attribute_string public :: get_groups public :: get_datasets @@ -2601,6 +2602,26 @@ contains end if end subroutine get_shape + subroutine get_ndims(obj_id, ndims) + integer(HID_T), intent(in) :: obj_id + integer(HID_T), intent(out) :: ndims + + integer :: hdf5_err + integer :: type + integer(HID_T) :: space_id + + call h5iget_type_f(obj_id, type, hdf5_err) + if (type == H5I_DATASET_F) then + call h5dget_space_f(obj_id, space_id, hdf5_err) + call h5sget_simple_extent_ndims_f(space_id, ndims, hdf5_err) + call h5sclose_f(space_id, hdf5_err) + elseif (type == H5I_ATTR_F) then + call h5aget_space_f(obj_id, space_id, hdf5_err) + call h5sget_simple_extent_ndims_f(space_id, ndims, hdf5_err) + call h5sclose_f(space_id, hdf5_err) + end if + end subroutine get_ndims + function using_mpio_device(obj_id) result(mpio) integer(HID_T), intent(in) :: obj_id logical :: mpio diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 4702c3bcf1..536d94ad90 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -3060,8 +3060,8 @@ contains ! index is simply the group (after flipping for the different ! ordering of the library and tallying systems). if (.not. run_CE) then - if (n_words == energy_groups + 1) then - if (all(filt % bins == energy_bins(energy_groups + 1:1:-1))) & + if (n_words == num_energy_groups + 1) then + if (all(filt % bins == energy_bins(num_energy_groups + 1:1:-1))) & then filt % matches_transport_groups = .true. end if @@ -3086,8 +3086,8 @@ contains ! index is simply the group (after flipping for the different ! ordering of the library and tallying systems). if (.not. run_CE) then - if (n_words == energy_groups + 1) then - if (all(filt % bins == energy_bins(energy_groups + 1:1:-1))) & + if (n_words == num_energy_groups + 1) then + if (all(filt % bins == energy_bins(num_energy_groups + 1:1:-1))) & then filt % matches_transport_groups = .true. end if @@ -3101,14 +3101,6 @@ contains t % estimator = ESTIMATOR_ANALOG case ('delayedgroup') - ! Check to see if running in MG mode, because if so, the current - ! system isnt set up yet to support delayed group data and thus - ! these tallies - if (.not. run_CE) then - call fatal_error("delayedgroup filter on tally " & - // trim(to_str(t % id)) // " not yet supported& - & for multi-group mode.") - end if ! Allocate and declare the filter type allocate(DelayedGroupFilter::t % filters(j) % obj) @@ -3599,7 +3591,13 @@ contains end if case ('decay-rate') t % score_bins(j) = SCORE_DECAY_RATE - t % estimator = ESTIMATOR_ANALOG + + ! Set tally estimator to analog for CE mode + ! (MG mode has all data available without a collision being + ! necessary) + if (run_CE) then + t % estimator = ESTIMATOR_ANALOG + end if case ('delayed-nu-fission') t % score_bins(j) = SCORE_DELAYED_NU_FISSION if (t % find_filter(FILTER_ENERGYOUT) > 0) then @@ -3612,12 +3610,6 @@ contains ! Set tally estimator to analog t % estimator = ESTIMATOR_ANALOG end if - - ! Disallow for MG mode since data not present - if (.not. run_CE) then - call fatal_error("Cannot tally delayed nu-fission rate in & - &multi-group mode") - end if case ('kappa-fission') t % score_bins(j) = SCORE_KAPPA_FISSION case ('inverse-velocity') @@ -4654,15 +4646,25 @@ contains ! Open file for reading file_id = file_open(path_cross_sections, 'r', parallel=.true.) - if (check_attribute(file_id, "groups")) then - ! Get neutron group count - call read_attribute(energy_groups, file_id, "groups") + if (check_attribute(file_id, "energy_groups")) then + ! Get neutron energy group count + call read_attribute(num_energy_groups, file_id, "energy_groups") else - call fatal_error("'groups' attribute must exist!") + call fatal_error("'energy_groups' attribute must exist!") end if - allocate(rev_energy_bins(energy_groups + 1)) - allocate(energy_bins(energy_groups + 1)) + if (check_attribute(file_id, "delayed_groups")) then + ! Get neutron delayed group count + call read_attribute(num_delayed_groups, file_id, "delayed_groups") + else + num_delayed_groups = 0 + call write_message("WARNING: delayed_groups element not provided so & + &number of delayed groups set to 0") + end if + + allocate(rev_energy_bins(num_energy_groups + 1)) + allocate(energy_bins(num_energy_groups + 1)) + if (check_attribute(file_id, "group structure")) then ! Get neutron group structure call read_attribute(energy_bins, file_id, "group structure") @@ -4671,10 +4673,10 @@ contains end if ! First reverse the order of energy_groups - energy_bins = energy_bins(energy_groups + 1:1:-1) + energy_bins = energy_bins(num_energy_groups + 1:1:-1) - allocate(energy_bin_avg(energy_groups)) - do i = 1, energy_groups + allocate(energy_bin_avg(num_energy_groups)) + do i = 1, num_energy_groups energy_bin_avg(i) = HALF * (energy_bins(i) + energy_bins(i + 1)) end do diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 2fbfdfd420..f598958d43 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -21,26 +21,25 @@ contains !=============================================================================== subroutine read_mgxs() - integer :: i ! index in materials array - integer :: j ! index over nuclides in material - 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 + 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 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 - integer(HID_T) :: xsdata_group - logical :: file_exists - logical :: get_kfiss, get_fiss - integer :: l - type(DictCharInt) :: xsdata_dict + type(SetChar) :: already_read + integer(HID_T) :: file_id + integer(HID_T) :: xsdata_group + logical :: file_exists + type(DictCharInt) :: xsdata_dict type(VectorReal), allocatable :: temps(:) ! Check if MGXS Library exists inquire(FILE=path_cross_sections, EXIST=file_exists) if (.not. file_exists) then + ! Could not find MGXS Library file call fatal_error("Cross sections HDF5 file '" & &// trim(path_cross_sections) // "' does not exist!") @@ -60,23 +59,6 @@ contains allocate(micro_xs(n_nuclides_total)) !$omp end parallel - ! Find out if we need fission & kappa fission - ! (i.e., are there any SCORE_FISSION or SCORE_KAPPA_FISSION tallies?) - get_kfiss = .false. - get_fiss = .false. - do i = 1, n_tallies - do l = 1, tallies(i) % n_score_bins - if (tallies(i) % score_bins(l) == SCORE_KAPPA_FISSION) then - get_kfiss = .true. - end if - if (tallies(i) % score_bins(l) == SCORE_FISSION .or. & - tallies(i) % score_bins(l) == SCORE_NU_FISSION) then - get_fiss = .true. - end if - end do - if (get_kfiss .and. get_fiss) exit - end do - ! ========================================================================== ! READ ALL MGXS CROSS SECTION TABLES @@ -103,7 +85,9 @@ contains ! First find out the data representation if (check_attribute(xsdata_group, "representation")) 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 @@ -118,16 +102,19 @@ contains ! Now allocate accordingly select case(representation) + case(MGXS_ISOTROPIC) allocate(MgxsIso :: nuclides_MG(i_nuclide) % obj) + case(MGXS_ANGLE) allocate(MgxsAngle :: nuclides_MG(i_nuclide) % obj) + end select ! Now read in the data specific to the type we just declared call nuclides_MG(i_nuclide) % obj % from_hdf5(xsdata_group, & - energy_groups, temps(i_nuclide), temperature_method, & - temperature_tolerance, get_kfiss, get_fiss, max_order, & + num_energy_groups, num_delayed_groups, temps(i_nuclide), & + temperature_method, temperature_tolerance, max_order, & legendre_to_tabular, legendre_to_tabular_points) ! Add name to dictionary @@ -147,6 +134,7 @@ contains ! Loop around nuclides in material NUCLIDE_LOOP2: do j = 1, mat % n_nuclides + ! Is this fissionable? if (nuclides_MG(mat % nuclide(j)) % obj % fissionable) then mat % fissionable = .true. @@ -161,12 +149,12 @@ contains end subroutine read_mgxs !=============================================================================== -! CREATE_MACRO_XS generates the macroscopic x/s from the microscopic input data +! CREATE_MACRO_XS generates the macroscopic xs from the microscopic input data !=============================================================================== subroutine create_macro_xs() - integer :: i_mat ! index in materials array - type(Material), pointer :: mat ! current material + integer :: i_mat ! index in materials array + type(Material), pointer :: mat ! current material type(VectorReal), allocatable :: kTs(:) allocate(macro_xs(n_materials)) @@ -174,27 +162,32 @@ contains ! Get temperatures to read for each material call get_mat_kTs(kTs) + ! Force all nuclides in a material to be the same representation. + ! 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.allocate(macro_xs(n_materials)) do i_mat = 1, n_materials + + ! Get the material mat => materials(i_mat) - ! Check to see how our nuclides are represented - ! Force all to be the same type - ! Therefore type(nuclides(mat % nuclide(1)) % obj) dictates type(macroxs) + ! Get the scattering type for the first nuclide select type(nuc => nuclides_MG(mat % nuclide(1)) % obj) type is (MgxsIso) allocate(MgxsIso :: macro_xs(i_mat) % obj) type is (MgxsAngle) allocate(MgxsAngle :: macro_xs(i_mat) % obj) end select + ! 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) + num_energy_groups, num_delayed_groups, max_order, & + temperature_tolerance, temperature_method) end if end do + end subroutine create_macro_xs !=============================================================================== @@ -203,16 +196,17 @@ contains !=============================================================================== subroutine get_mat_kTs(kTs) - type(VectorReal), allocatable, intent(out) :: kTs(:) - integer :: i, j + type(VectorReal), allocatable, intent(out) :: kTs(:) + integer :: i, j ! Cell and material index integer :: i_material ! Index in materials array - real(8) :: kT ! temperature in MeV + 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 @@ -243,17 +237,18 @@ contains !=============================================================================== subroutine get_temperatures(temps) - type(VectorReal), allocatable, intent(out) :: temps(:) + type(VectorReal), allocatable, intent(out) :: temps(:) integer :: i, j, k integer :: i_nuclide ! index in nuclides array - integer :: i_material + integer :: i_material ! Index in materials array 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 @@ -268,6 +263,7 @@ contains 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))) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 193f337f13..a26453a8f6 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -26,11 +26,14 @@ module mgxs_header real(8), allocatable :: total(:) ! total cross section real(8), allocatable :: absorption(:) ! absorption cross section class(ScattData), allocatable :: scatter ! scattering info - real(8), allocatable :: nu_fission(:) ! fission production - real(8), allocatable :: k_fission(:) ! kappa-fission - real(8), allocatable :: fission(:) ! fission - real(8), allocatable :: chi(:, :) ! Fission Spectra - real(8), allocatable :: inv_vel(:) ! Inverse velocities + real(8), allocatable :: delayed_nu_fission(:,:) ! Delayed fission matrix (Gin x Dg) + real(8), allocatable :: prompt_nu_fission(:) ! Prompt fission vector (Gin) + real(8), allocatable :: kappa_fission(:) ! Kappa-fission + real(8), allocatable :: fission(:) ! Neutron production + real(8), allocatable :: decay_rate(:) ! Delayed neutron precursor decay rate + real(8), allocatable :: inverse_velocity(:) ! Inverse neutron velocity + real(8), allocatable :: chi_delayed(:, :, :) ! Delayed fission spectra + real(8), allocatable :: chi_prompt(:, :) ! Prompt fission spectra end type XsDataIso type :: XsDataAngle @@ -39,11 +42,14 @@ module mgxs_header real(8), allocatable :: total(:, :, :) ! total cross section real(8), allocatable :: absorption(:, :, :) ! absorption cross section type(ScattDataContainer), allocatable :: scatter(:, :) ! scattering info - real(8), allocatable :: nu_fission(:, :, :) ! fission production - real(8), allocatable :: k_fission(:, :, :) ! kappa-fission - real(8), allocatable :: fission(:, :, :) ! fission - real(8), allocatable :: chi(:, :, :, :) ! Fission Spectra - real(8), allocatable :: inv_vel(:, :, :) ! Inverse velocities + real(8), allocatable :: delayed_nu_fission(:, :, :, :) ! Delayed fission matrix (Gout x Gin) + real(8), allocatable :: prompt_nu_fission(:, :, :) ! Prompt fission matrix (Gout x Gin) + real(8), allocatable :: kappa_fission(:, :, :) ! Kappa-fission + real(8), allocatable :: fission(:, :, :) ! Neutron production + real(8), allocatable :: decay_rate(:, :, :) ! Delayed neutron precursor decay rate + real(8), allocatable :: inverse_velocity(:, :, :) ! Inverse neutron velocity + real(8), allocatable :: chi_delayed(:, :, :, :, :) ! Delayed fission spectra + real(8), allocatable :: chi_prompt(:, :, :, :) ! Prompt fission spectra end type XsDataAngle !=============================================================================== @@ -66,12 +72,17 @@ module mgxs_header procedure(mgxs_from_hdf5_), deferred :: from_hdf5 ! Load the data procedure(mgxs_combine_), deferred :: combine ! initializes object procedure(mgxs_get_xs_), deferred :: get_xs ! Get the requested xs + ! Sample the outgoing energy from a fission event procedure(mgxs_sample_fission_), deferred :: sample_fission_energy + ! Sample the outgoing energy and angle from a scatter event procedure(mgxs_sample_scatter_), deferred :: sample_scatter + ! Calculate the material specific MGXS data from the nuclides procedure(mgxs_calculate_xs_), deferred :: calculate_xs + + ! Find the temperature procedure :: find_temperature => mgxs_find_temperature end type Mgxs @@ -88,38 +99,38 @@ module mgxs_header !=============================================================================== abstract interface - subroutine mgxs_from_hdf5_(this, xs_id, groups, temperature, method, & - tolerance, get_kfiss, get_fiss, max_order, & - legendre_to_tabular, legendre_to_tabular_points) + subroutine mgxs_from_hdf5_(this, xs_id, energy_groups, delayed_groups, & + temperature, method, tolerance, max_order, legendre_to_tabular, & + legendre_to_tabular_points) import Mgxs, HID_T, VectorReal class(Mgxs), intent(inout) :: this ! Working Object integer(HID_T), intent(in) :: xs_id ! Library data - integer, intent(in) :: groups ! Number of Energy groups + integer, intent(in) :: energy_groups ! Number of energy groups + integer, intent(in) :: delayed_groups ! Number of delayed groups type(VectorReal), intent(in) :: temperature ! list of desired temperatures integer, intent(inout) :: method ! Type of temperature access real(8), intent(in) :: tolerance ! Tolerance on method - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Should we get fiss data? integer, intent(in) :: max_order ! Maximum requested order logical, intent(in) :: legendre_to_tabular ! Convert Legendres to Tabular? integer, intent(in) :: legendre_to_tabular_points ! Number of points to use ! in that conversion end subroutine mgxs_from_hdf5_ - subroutine mgxs_combine_(this, temps, mat, nuclides, groups, max_order, & - tolerance, method) + subroutine mgxs_combine_(this, temps, mat, nuclides, energy_groups, & + delayed_groups, max_order, tolerance, method) import Mgxs, Material, MgxsContainer, VectorReal class(Mgxs), intent(inout) :: this ! The Mgxs to initialize type(VectorReal), intent(in) :: temps ! Temperatures to obtain type(Material), pointer, intent(in) :: mat ! base material type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from - integer, intent(in) :: groups ! Number of E groups + integer, intent(in) :: energy_groups ! Number of energy groups + integer, intent(in) :: delayed_groups ! Number of delayed 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) + pure function mgxs_get_xs_(this, xstype, gin, gout, uvw, mu, dg) result(xs_val) import Mgxs class(Mgxs), intent(in) :: this character(*), intent(in) :: xstype ! Cross Section Type @@ -127,17 +138,19 @@ module mgxs_header integer, optional, intent(in) :: gout ! Outgoing Group real(8), optional, intent(in) :: uvw(3) ! Requested Angle real(8), optional, intent(in) :: mu ! Change in angle + integer, optional, intent(in) :: dg ! Delayed group real(8) :: xs_val ! Resultant xs end function mgxs_get_xs_ - function mgxs_sample_fission_(this, gin, uvw) result(gout) + subroutine mgxs_sample_fission_(this, gin, uvw, dg, gout) import Mgxs class(Mgxs), intent(in) :: this integer, intent(in) :: gin ! Incoming energy group real(8), intent(in) :: uvw(3) ! Particle Direction - integer :: gout ! Sampled outgoing group + integer, intent(out) :: dg ! Delayed group + integer, intent(out) :: gout ! Sampled outgoing group - end function mgxs_sample_fission_ + end subroutine mgxs_sample_fission_ subroutine mgxs_sample_scatter_(this, uvw, gin, gout, mu, wgt) import Mgxs @@ -393,29 +406,30 @@ 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, & - legendre_to_tabular, legendre_to_tabular_points) + subroutine mgxsiso_from_hdf5(this, xs_id, energy_groups, delayed_groups, & + temperature, method, tolerance, 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 + integer, intent(in) :: energy_groups ! Number of energy groups + integer, intent(in) :: delayed_groups ! Number of delayed groups type(VectorReal), intent(in) :: temperature ! list of desired temperatures integer, intent(inout) :: method ! Type of temperature access real(8), intent(in) :: tolerance ! Tolerance on method - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Should we get fiss data? integer, intent(in) :: max_order ! Maximum requested order logical, intent(in) :: legendre_to_tabular ! Convert Legendres to Tabular? integer, intent(in) :: legendre_to_tabular_points ! Number of points to use ! in that conversion character(MAX_LINE_LEN) :: temp_str - integer(HID_T) :: xsdata_grp, scatt_grp + integer(HID_T) :: xsdata, xsdata_grp, scatt_grp, ndims + integer(HSIZE_T) :: dims(2) real(8), allocatable :: temp_arr(:), temp_2d(:, :) + real(8), allocatable :: temp_beta(:, :) real(8) :: dmu, mu, norm integer :: order, order_dim, gin, gout, l, imu, length type(VectorInt) :: temps_to_read - integer :: t + integer :: t, dg type(Jagged2D), allocatable :: input_scatt(:), scatt_coeffs(:) type(Jagged1D), allocatable :: temp_mult(:) integer, allocatable :: gmin(:), gmax(:) @@ -427,99 +441,458 @@ module mgxs_header ! Load the more specific data do t = 1, temps_to_read % size() associate(xs => this % xs(t)) + ! Get temperature as a string temp_str = trim(to_str(temps_to_read % data(t))) // "K" xsdata_grp = open_group(xs_id, trim(temp_str)) + + ! Allocate data for all the cross sections + allocate(xs % total(energy_groups)) + allocate(xs % absorption(energy_groups)) + allocate(xs % delayed_nu_fission(energy_groups, delayed_groups)) + allocate(xs % prompt_nu_fission(energy_groups)) + allocate(xs % fission(energy_groups)) + allocate(xs % kappa_fission(energy_groups)) + allocate(xs % decay_rate(delayed_groups)) + allocate(xs % inverse_velocity(energy_groups)) + allocate(xs % chi_delayed(energy_groups, energy_groups, & + delayed_groups)) + allocate(xs % chi_prompt(energy_groups, energy_groups)) + + ! Set all fissionable terms to zero + xs % delayed_nu_fission = ZERO + xs % prompt_nu_fission = ZERO + xs % fission = ZERO + xs % kappa_fission = ZERO + xs % chi_delayed = ZERO + xs % chi_prompt = ZERO + xs % decay_rate = ZERO + 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) + + ! Allocate temporary array for beta + allocate(temp_beta(energy_groups, delayed_groups)) + + ! Set beta + if (check_dataset(xsdata_grp, "beta")) then + + ! Get the dimensions of the beta dataset + xsdata = open_dataset(xsdata_grp, "beta") + call get_ndims(xsdata, ndims) + + ! Beta is input as (delayed_groups) + if (ndims == 1) then + + ! Allocate temporary array for beta + allocate(temp_arr(delayed_groups)) + + ! Read beta + call read_dataset(temp_arr, xsdata_grp, "beta") + + do dg = 1, delayed_groups + do gin = 1, energy_groups + temp_beta(gin, dg) = temp_arr(dg) + end do end do - ! Normalize chi so its CDF goes to 1 - xs % chi(:, gin) = xs % chi(:, gin) / sum(xs % chi(:, gin)) - end do - deallocate(temp_arr) - ! Get nu_fission (as a vector) - if (check_dataset(xsdata_grp, "nu-fission")) then - call read_dataset(xs % nu_fission, xsdata_grp, "nu-fission") + ! Deallocate temporary beta array + deallocate(temp_arr) + + ! Beta is input as (delayed_groups, energy_groups) + else if (ndims == 2) then + + ! Allocate temporary array for beta + allocate(temp_arr(delayed_groups * energy_groups)) + + ! Read beta + call read_dataset(temp_arr, xsdata_grp, "beta") + + ! Reshape array and set to dedicated beta array + temp_beta = reshape(temp_arr, (/energy_groups, delayed_groups/)) + + ! Deallocate temporary beta array + deallocate(temp_arr) + else - call fatal_error("If fissionable, must provide nu-fission!") + call fatal_error("beta must be provided as a 1D or 2D array") end if - 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 - - ! Now pull out information needed for chi - xs % chi(:, :) = temp_2d - ! Normalize chi so its CDF goes to 1 - do gin = 1, groups - xs % chi(:, gin) = xs % chi(:, gin) / sum(xs % chi(:, gin)) - end do - deallocate(temp_2d) + temp_beta = ZERO 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_dataset(xsdata_grp, "fission")) then - allocate(xs % fission(groups)) - call read_dataset(xs % fission, xsdata_grp, "fission") + ! If chi provided, set chi_prompt and chi_delayed + if (check_dataset(xsdata_grp, "chi")) then + + ! Allocate temporary array for chi + allocate(temp_arr(energy_groups)) + + ! Read chi + call read_dataset(temp_arr, xsdata_grp, "chi") + + do gin = 1, energy_groups + do gout = 1, energy_groups + xs % chi_prompt(gout, gin) = temp_arr(gout) + end do + + ! Normalize chi_prompt so its CDF goes to 1 + if (sum(xs % chi_prompt(:, gin)) == ZERO) then + call fatal_error("Encountered chi for a group that sums to & + &zero") + else + xs % chi_prompt(:, gin) = xs % chi_prompt(:, gin) / & + sum(xs % chi_prompt(:, gin)) + end if + end do + + ! Set chi_delayed to chi_prompt + do dg = 1, delayed_groups + xs % chi_delayed(:, :, dg) = xs % chi_prompt(:, :) + end do + + ! Deallocate temporary chi array + deallocate(temp_arr) + end if + + ! If nu-fission provided, set prompt_nu_fission and + ! delayed_nu_fission. If nu-fission is a matrix, set chi_prompt and + ! chi_delayed. + if (check_dataset(xsdata_grp, "nu-fission")) then + + ! Get the dimensions of the nu-fission dataset + xsdata = open_dataset(xsdata_grp, "nu-fission") + call get_ndims(xsdata, ndims) + + ! If nu-fission is a vector + if (ndims == 1) then + + ! Get nu_fission + call read_dataset(xs % prompt_nu_fission, xsdata_grp, & + "nu-fission") + + ! Set delayed_nu_fission and correct prompt_nu_fission with + ! beta + do gin = 1, energy_groups + do dg = 1, delayed_groups + + ! Set delayed_nu_fission using delayed neutron fraction + xs % delayed_nu_fission(gin, dg) = temp_beta(gin, dg) * & + xs % prompt_nu_fission(gin) + end do + + ! Correct prompt_nu_fission using delayed neutron fraction + xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(gin, :))) * & + xs % prompt_nu_fission(gin) + end do + + ! If nu-fission is a matrix, set prompt_nu_fission, + ! delayed_nu_fission, chi_prompt, and chi_delayed. + else if (ndims == 2) then + + ! chi is embedded in nu_fission -> extract chi + allocate(temp_arr(energy_groups * energy_groups)) + call read_dataset(temp_arr, xsdata_grp, "nu-fission") + allocate(temp_2d(energy_groups, energy_groups)) + temp_2d = reshape(temp_arr, (/energy_groups, energy_groups/)) + + ! Deallocate temporary 1D array for nu_fission matrix + deallocate(temp_arr) + + ! Set the vector nu-fission from the matrix nu-fission + do gin = 1, energy_groups + xs % prompt_nu_fission(gin) = sum(temp_2d(:, gin)) + end do + + ! Set delayed_nu_fission and correct prompt_nu_fission with + ! beta + do gin = 1, energy_groups + do dg = 1, delayed_groups + + ! Set delayed_nu_fission using delayed neutron fraction + xs % delayed_nu_fission(gin, dg) = temp_beta(gin, dg) * & + xs % prompt_nu_fission(gin) + end do + + ! Correct prompt_nu_fission using delayed neutron fraction + xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(gin, :))) * & + xs % prompt_nu_fission(gin) + end do + + ! Now pull out information needed for chi + xs % chi_prompt(:, :) = temp_2d + + ! Deallocate temporary 2D array for nu_fission matrix + deallocate(temp_2d) + + ! Normalize chi so its CDF goes to 1 + do gin = 1, energy_groups + if (sum(xs % chi_prompt(:, gin)) == ZERO) then + call fatal_error("Encountered chi for a group that sums to & + &zero") + else + xs % chi_prompt(:, gin) = xs % chi_prompt(:, gin) / & + sum(xs % chi_prompt(:, gin)) + end if + end do + + ! Set chi_delayed to chi_prompt + do dg = 1, delayed_groups + xs % chi_delayed(:, :, dg) = xs % chi_prompt(:, :) + end do else - call fatal_error("Fission data missing, required due to fission& - & tallies in tallies.xml file!") + call fatal_error("nu-fission must be provided as a 1D or 2D & + &array") end if end if - if (get_kfiss) then - if (check_dataset(xsdata_grp, "kappa-fission")) then - allocate(xs % k_fission(groups)) - call read_dataset(xs % k_fission, xsdata_grp, "kappa-fission") + + ! If chi_prompt provided, set chi_prompt + if (check_dataset(xsdata_grp, "chi-prompt")) then + + ! Allocate temporary array for chi_prompt + allocate(temp_arr(energy_groups)) + + ! Get array with chi_prompt + call read_dataset(temp_arr, xsdata_grp, "chi-prompt") + + do gin = 1, energy_groups + do gout = 1, energy_groups + xs % chi_prompt(gout, gin) = temp_arr(gout) + end do + + ! Normalize chi so its CDF goes to 1 + if (sum(xs % chi_prompt(:, gin)) == ZERO) then + call fatal_error("Encountered chi prompt for a group that & + &sums to zero") + else + xs % chi_prompt(:, gin) = xs % chi_prompt(:, gin) / & + sum(xs % chi_prompt(:, gin)) + end if + end do + + ! Deallocate temporary array for chi_prompt + deallocate(temp_arr) + end if + + ! If chi_delayed provided, set chi_delayed + if (check_dataset(xsdata_grp, "chi-delayed")) then + + ! Get the dimensions of the nu-fission dataset + xsdata = open_dataset(xsdata_grp, "chi-delayed") + call get_ndims(xsdata, ndims) + + ! If chi-delayed is a vector + if (ndims == 1) then + + ! Allocate temporary array for chi_delayed + allocate(temp_arr(energy_groups)) + + ! Get chi-delayed + call read_dataset(temp_arr, xsdata_grp, "chi-delayed") + + do dg = 1, delayed_groups + do gin = 1, energy_groups + do gout = 1, energy_groups + xs % chi_delayed(gout, gin, dg) = temp_arr(gout) + end do + + ! Normalize chi so its CDF goes to 1 + if (sum(xs % chi_delayed(:, gin, dg)) == ZERO) then + call fatal_error("Encountered chi delayed for a group & + &that sums to zero") + else + xs % chi_delayed(:, gin, dg) = & + xs % chi_delayed(:, gin, dg) / & + sum(xs % chi_delayed(:, gin, dg)) + end if + end do + end do + + ! Deallocate temporary array for chi_delayed + deallocate(temp_arr) + + else if (ndims == 2) then + + ! Allocate temporary array for chi_delayed + allocate(temp_arr(delayed_groups * energy_groups)) + + ! Get chi-delayed + call read_dataset(temp_arr, xsdata_grp, "chi-delayed") + allocate(temp_2d(energy_groups, delayed_groups)) + temp_2d = reshape(temp_arr, (/energy_groups, delayed_groups/)) + + do dg = 1, delayed_groups + do gin = 1, energy_groups + do gout = 1, energy_groups + xs % chi_delayed(gout, gin, dg) = temp_2d(gout, dg) + end do + + ! Normalize chi so its CDF goes to 1 + if (sum(xs % chi_delayed(:, gin, dg)) == ZERO) then + call fatal_error("Encountered chi delayed for a group & + &that sums to zero") + else + xs % chi_delayed(:, gin, dg) = & + xs % chi_delayed(:, gin, dg) / & + sum(xs % chi_delayed(:, gin, dg)) + end if + end do + end do + + ! Deallocate temporary arrays for chi_delayed + deallocate(temp_arr) + deallocate(temp_2d) + else - call fatal_error("kappa-fission data missing, required due to & - &kappa-fission tallies in tallies.xml file!") + call fatal_error("chi-delayed must be provided as a 1D or 2D & + &array") end if end if + + ! If prompt-nu-fission present, set prompt_nu_fission + if (check_dataset(xsdata_grp, "prompt-nu-fission")) then + + ! Set prompt_nu_fission + call read_dataset(xs % prompt_nu_fission, xsdata_grp, & + "prompt-nu-fission") + end if + + ! If delayed-nu-fission provided, set delayed_nu_fission. If + ! delayed-nu-fission is a matrix, set chi_delayed. + if (check_dataset(xsdata_grp, "delayed-nu-fission")) then + + ! Get the dimensions of the delayed-nu-fission dataset + xsdata = open_dataset(xsdata_grp, "delayed-nu-fission") + call get_ndims(xsdata, ndims) + + ! If delayed-nu-fission is a vector + if (ndims == 1) then + + ! If beta is zeros, raise error + if (temp_beta(1,1) == ZERO) then + call fatal_error("cannot set delayed-nu-fission with a 1D & + &array if beta not provided") + end if + + ! Allocate temporary array for delayed_nu_fission + allocate(temp_arr(energy_groups)) + + ! Get delayed_nu_fission + call read_dataset(temp_arr, xsdata_grp, "delayed-nu-fission") + + do gin = 1, energy_groups + do dg = 1, delayed_groups + + ! Set delayed_nu_fission using delayed neutron fraction + xs % delayed_nu_fission(gin, dg) = temp_beta(gin, dg) * & + temp_arr(gin) + end do + end do + + ! Deallocate temporary delayed_nu_fission array + deallocate(temp_arr) + + ! If delayed-nu-fission is a (delayed_group, energy_group) + ! matrix, set delayed_nu_fission separately for each delayed + ! group. + else if (ndims == 2) then + + ! Get the shape of delayed-nu-fission + call get_shape(xsdata, dims) + + ! Issue error if 1st dimension not correct + if (dims(1) /= energy_groups) then + call fatal_error("The delayed-nu-fission matrix was input & + &with a 1st dimension not equal to the number of & + &energy groups.") + end if + + ! Issue error if 2nd dimension not correct + if (dims(2) /= delayed_groups) then + call fatal_error("The delayed-nu-fission matrix was input & + &with a 2nd dimension not equal to the number of & + &delayed groups.") + end if + + ! Issue warning if delayed_groups == energy_groups + if (delayed_groups == energy_groups) then + call warning("delayed-nu-fission was input as a dimension & + &2 matrix with the same number of delayed groups and & + &groups. It is important to know that OpenMC assumes & + &the dimensions in the matrix are (energy_groups, & + &delayed_groups). Currently, delayed-nu-fission cannot & + &be set as a group by group matrix.") + end if + + ! Get delayed_nu_fission + allocate(temp_arr(delayed_groups * energy_groups)) + call read_dataset(temp_arr, xsdata_grp, "delayed-nu-fission") + xs % delayed_nu_fission = reshape(temp_arr, (/energy_groups, & + delayed_groups/)) + + ! Deallocate temporary array for delayed_nu_fission matrix + deallocate(temp_arr) + + else + call fatal_error("delayed-nu-fission must be provided as a & + &1D or 2D array") + end if + end if + + ! Deallocate temporary beta array + deallocate(temp_beta) + + ! chi_prompt, chi_delayed, prompt_nu_fission, and delayed_nu_fission + ! have been set; Now we will check for the rest of the XS that are + ! unique to fissionable isotopes + + ! Get fission xs + if (check_dataset(xsdata_grp, "fission")) then + call read_dataset(xs % fission, xsdata_grp, "fission") + end if + + ! Get kappa_fission xs + if (check_dataset(xsdata_grp, "kappa_fission")) then + call read_dataset(xs % kappa_fission, xsdata_grp, "kappa_fission") + end if + + ! Get decay rate xs + if (check_dataset(xsdata_grp, "decay_rate")) then + call read_dataset(xs % decay_rate, xsdata_grp, "decay_rate") + end if end if + ! All the XS unique to fissionable isotopes have been set; Now set all + ! the generation XS + 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!") end if + ! Get inverse velocity + if (check_dataset(xsdata_grp, "inverse_velocity")) then + call read_dataset(xs % inverse_velocity, xsdata_grp, & + "inverse_velocity") + else + xs % inverse_velocity = ZERO + 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(scatt_grp, "g_min")) then - allocate(gmin(groups)) + allocate(gmin(energy_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(scatt_grp, "g_max")) then - allocate(gmax(groups)) + allocate(gmax(energy_groups)) call read_dataset(gmax, scatt_grp, "g_max") else call fatal_error("'g_max' for the scatter matrix must be provided") @@ -528,11 +901,14 @@ module mgxs_header ! Now use this information to find the length of a container array ! to hold the flattened data length = 0 - do gin = 1, groups + + do gin = 1, energy_groups length = length + order_dim * (gmax(gin) - gmin(gin) + 1) 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") @@ -544,11 +920,12 @@ module mgxs_header 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)) + ! Convert temp_arr to a jagged array ((gin) % data(l, gout)) for + ! passing to ScattData + allocate(input_scatt(energy_groups)) + index = 1 - do gin = 1, groups + do gin = 1, energy_groups allocate(input_scatt(gin) % data(order_dim, gmin(gin):gmax(gin))) do gout = gmin(gin), gmax(gin) do l = 1, order_dim @@ -557,21 +934,28 @@ module mgxs_header end do end do end do + deallocate(temp_arr) ! Finally convert the legendre to tabular if needed - allocate(scatt_coeffs(groups)) + allocate(scatt_coeffs(energy_groups)) + if (this % scatter_format == ANGLE_LEGENDRE .and. & legendre_to_tabular) then + this % scatter_format = ANGLE_TABULAR order_dim = legendre_to_tabular_points order = order_dim dmu = TWO / real(order - 1, 8) - do gin = 1, groups + + do gin = 1, energy_groups allocate(scatt_coeffs(gin) % data(order_dim, gmin(gin):gmax(gin))) do gout = gmin(gin), gmax(gin) + norm = ZERO + do imu = 1, order_dim + if (imu == 1) then mu = -ONE else if (imu == order_dim) then @@ -579,11 +963,14 @@ module mgxs_header 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 * & @@ -591,8 +978,10 @@ module mgxs_header 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 + + ! Now that we have the integral, lets ensure that the + ! distribution is normalized such that it preserves the original + ! scattering xs if (norm > ZERO) then scatt_coeffs(gin) % data(:, gout) = & scatt_coeffs(gin) % data(:, gout) * & @@ -601,33 +990,41 @@ module mgxs_header end do ! gout end do ! gin else + ! Sticking with current representation - do gin = 1, groups + do gin = 1, energy_groups allocate(scatt_coeffs(gin) % data(order_dim, gmin(gin):gmax(gin))) scatt_coeffs(gin) % data(:, :) = & input_scatt(gin) % data(1:order_dim, :) end do end if + deallocate(input_scatt) ! Now get the multiplication matrix if (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 + + do gin = 1, energy_groups length = length + (gmax(gin) - gmin(gin) + 1) end do + ! Allocate flattened array allocate(temp_arr(length)) call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") - ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing - ! to ScattData - allocate(temp_mult(groups)) + ! Convert temp_arr to a jagged array ((gin) % data(gout)) for + ! passing to ScattData + allocate(temp_mult(energy_groups)) + index = 1 - do gin = 1, groups + do gin = 1, energy_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 @@ -635,9 +1032,11 @@ module mgxs_header end do deallocate(temp_arr) else + ! Default to multiplicities of 1.0 - allocate(temp_mult(groups)) - do gin = 1, groups + allocate(temp_mult(energy_groups)) + + do gin = 1, energy_groups allocate(temp_mult(gin) % data(gmin(gin):gmax(gin))) temp_mult(gin) % data = ONE end do @@ -658,12 +1057,11 @@ module mgxs_header ! 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 + do gin = 1, energy_groups if (xs % absorption(gin) == ZERO) xs % absorption(gin) = 1E-10_8 end do ! Get, or infer, total xs data. - allocate(xs % total(groups)) if (check_dataset(xsdata_grp, "total")) then call read_dataset(xs % total, xsdata_grp, "total") else @@ -672,16 +1070,10 @@ module mgxs_header ! Check sigT to ensure it is not 0 since it is ! often divided by in the tally routines - do gin = 1, groups + do gin = 1, energy_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) @@ -690,28 +1082,29 @@ module mgxs_header end do ! Temperatures end subroutine mgxsiso_from_hdf5 - subroutine mgxsang_from_hdf5(this, xs_id, groups, temperature, method, & - tolerance, get_kfiss, get_fiss, max_order, & - legendre_to_tabular, legendre_to_tabular_points) + subroutine mgxsang_from_hdf5(this, xs_id, energy_groups, delayed_groups, & + temperature, method, tolerance, 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 + integer, intent(in) :: energy_groups ! Number of energy groups + integer, intent(in) :: delayed_groups ! Number of energy groups type(VectorReal), intent(in) :: temperature ! list of desired temperatures integer, intent(inout) :: method ! Type of temperature access real(8), intent(in) :: tolerance ! Tolerance on method - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Should we get fiss data? integer, intent(in) :: max_order ! Maximum requested order logical, intent(in) :: legendre_to_tabular ! Convert Legendres to Tabular? integer, intent(in) :: legendre_to_tabular_points ! Number of points to use ! in that conversion character(MAX_LINE_LEN) :: temp_str - integer(HID_T) :: xsdata_grp, scatt_grp + integer(HID_T) :: xsdata, xsdata_grp, scatt_grp, ndims + integer(HSIZE_T) :: dims(4) integer, allocatable :: int_arr(:) - real(8), allocatable :: temp_arr(:), temp_4d(:, :, :, :) + real(8), allocatable :: temp_1d(:), temp_2d(:, :), temp_3d(:, :, :) + real(8), allocatable :: temp_4d(:, :, :, :), temp_beta(:, :, :, :) real(8) :: dmu, mu, norm - integer :: order, order_dim, gin, gout, l, imu + integer :: order, order_dim, gin, gout, l, imu, dg type(VectorInt) :: temps_to_read integer :: t, length, ipol, iazi type(Jagged2D), allocatable :: input_scatt(:, :, :), scatt_coeffs(:, :, :) @@ -725,154 +1118,509 @@ module mgxs_header ! Load the more specific data do t = 1, temps_to_read % size() associate(xs => this % xs(t)) + ! Get temperature as a string temp_str = trim(to_str(temps_to_read % data(t))) // "K" xsdata_grp = open_group(xs_id, trim(temp_str)) + + ! Load the more specific data + allocate(xs % prompt_nu_fission(energy_groups, this % n_azi, & + this % n_pol)) + allocate(xs % delayed_nu_fission(energy_groups, delayed_groups, & + this % n_azi, this % n_pol)) + allocate(xs % chi_prompt(energy_groups, energy_groups, this % n_azi, & + this % n_pol)) + allocate(xs % chi_delayed(energy_groups, energy_groups, & + delayed_groups, this % n_azi, this % n_pol)) + allocate(xs % total(energy_groups, this % n_azi, this % n_pol)) + allocate(xs % absorption(energy_groups, this % n_azi, this % n_pol)) + allocate(xs % fission(energy_groups, this % n_azi, this % n_pol)) + allocate(xs % kappa_fission(energy_groups, this % n_azi, & + this % n_pol)) + allocate(xs % decay_rate(delayed_groups, this % n_azi, this % n_pol)) + allocate(xs % inverse_velocity(energy_groups, this % n_azi, & + this % n_pol)) + + ! Set all fissionable terms to zero + xs % delayed_nu_fission = ZERO + xs % prompt_nu_fission = ZERO + xs % fission = ZERO + xs % kappa_fission = ZERO + xs % chi_delayed = ZERO + xs % chi_prompt = ZERO + xs % decay_rate = ZERO + 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 - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call read_dataset(temp_arr, xsdata_grp, "chi") - ! Initialize counter for temp_arr - l = 0 - gin = 1 - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gout = 1, groups - l = l + 1 - xs % chi(gout, gin, iazi, ipol) = temp_arr(l) - end do - ! Normalize chi so its CDF goes to 1 - xs % chi(:, gin, iazi, ipol) = & - xs % chi(:, gin, iazi, ipol) / & - sum(xs % chi(:, gin, iazi, ipol)) - end do - end do - ! Now set all the other gin values - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gin = 2, groups - xs % chi(:, gin, iazi, ipol) = & - xs % chi(:, 1, iazi, ipol) + ! Allocate temporary array for beta + allocate(temp_beta(energy_groups, delayed_groups, this % n_azi, & + this % n_pol)) + + ! Set beta + if (check_dataset(xsdata_grp, "beta")) then + + ! Get the dimensions of the beta dataset + xsdata = open_dataset(xsdata_grp, "beta") + call get_ndims(xsdata, ndims) + + ! Beta is input as (delayed_groups, n_azi, n_pol) + if (ndims == 3) then + + ! Allocate temporary arrays for beta + allocate(temp_1d(delayed_groups * this % n_azi * this % n_pol)) + allocate(temp_3d(delayed_groups, this % n_azi, this % n_pol)) + + ! Read beta + call read_dataset(temp_1d, xsdata_grp, "beta") + temp_3d = reshape(temp_1d, (/delayed_groups, this % n_azi, & + this % n_pol/)) + + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do dg = 1, delayed_groups + do gin = 1, energy_groups + temp_beta(gin, dg, iazi, ipol) = temp_3d(dg, iazi, ipol) + end do + end do end do end do - end do - deallocate(temp_arr) - ! Get nu_fission (as a vector) - if (check_dataset(xsdata_grp, "nu-fission")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call read_dataset(temp_arr, xsdata_grp, "nu-fission") - xs % nu_fission = reshape(temp_arr, (/groups, this % n_azi, & - this % n_pol/)) - deallocate(temp_arr) + ! Deallocate temporary beta arrays + deallocate(temp_1d) + deallocate(temp_3d) + + ! Beta is input as (delayed_groups, energy_groups, n_azi, n_pol) + else if (ndims == 4) then + + ! Allocate temporary array for beta + allocate(temp_1d(delayed_groups * energy_groups * this % n_azi & + * this % n_pol)) + + ! Read beta + call read_dataset(temp_1d, xsdata_grp, "beta") + + ! Reshape array and set to dedicated beta array + temp_beta = reshape(temp_1d, (/energy_groups, & + delayed_groups, this % n_azi, this % n_pol/)) + + ! Deallocate temporary beta array + deallocate(temp_1d) + else - call fatal_error("If fissionable, must provide nu-fission!") + call fatal_error("beta must be provided as a 3D or 4D array") end if - 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_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, & + temp_beta = ZERO + end if + + ! If chi provided, set chi_prompt and chi_delayed + if (check_dataset(xsdata_grp, "chi")) then + + ! Allocate temporary array for chi + allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) + allocate(temp_3d(energy_groups, this % n_azi, this % n_pol)) + + ! Read chi + call read_dataset(temp_1d, xsdata_grp, "chi") + temp_3d = reshape(temp_1d, (/energy_groups, this % n_azi, & + this % n_pol/)) + + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, energy_groups + do gout = 1, energy_groups + xs % chi_prompt(gout, gin, iazi, ipol) = & + temp_3d(gout, iazi, ipol) + end do + + ! Normalize chi_prompt so its CDF goes to 1 + if (sum(xs % chi_prompt(:, gin, iazi, ipol)) == ZERO) then + call fatal_error("Encountered chi for a group that sums& + & to zero") + else + xs % chi_prompt(:, gin, iazi, ipol) = & + xs % chi_prompt(:, gin, iazi, ipol) / & + sum(xs % chi_prompt(:, gin, iazi, ipol)) + end if + end do + end do + end do + + ! Set chi_delayed to chi_prompt + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do dg = 1, delayed_groups + xs % chi_delayed(:, :, dg, iazi, ipol) = & + xs % chi_prompt(:, :, iazi, ipol) + end do + end do + end do + + ! Deallocate temporary chi arrays + deallocate(temp_1d) + deallocate(temp_3d) + end if + + ! If chi_prompt provided, set chi_prompt + if (check_dataset(xsdata_grp, "chi-prompt")) then + + ! Allocate temporary array for chi_prompt + allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) + allocate(temp_3d(energy_groups, this % n_azi, this % n_pol)) + + ! Get array with chi_prompt + call read_dataset(temp_1d, xsdata_grp, "chi-prompt") + temp_3d = reshape(temp_1d, (/energy_groups, this % n_azi, & + this % n_pol/)) + + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, energy_groups + do gout = 1, energy_groups + xs % chi_prompt(gout, gin, iazi, ipol) = & + temp_3d(gout, iazi, ipol) + end do + + ! Normalize chi so its CDF goes to 1 + if (sum(xs % chi_prompt(:, gin, iazi, ipol)) == ZERO) then + call fatal_error("Encountered chi prompt for a group that& + & sums to zero") + else + xs % chi_prompt(:, gin, iazi, ipol) = & + xs % chi_prompt(:, gin, iazi, ipol) / & + sum(xs % chi_prompt(:, gin, iazi, ipol)) + end if + end do + end do + end do + + ! Deallocate temporary arrays for chi_prompt + deallocate(temp_1d) + deallocate(temp_3d) + end if + + ! If chi_delayed provided, set chi_delayed + if (check_dataset(xsdata_grp, "chi-delayed")) then + + ! Get the dimensions of the nu-fission dataset + xsdata = open_dataset(xsdata_grp, "chi-delayed") + call get_ndims(xsdata, ndims) + + ! If chi-delayed is a vector + if (ndims == 1) then + + ! Allocate temporary array for chi_prompt + allocate(temp_1d(delayed_groups * this % n_azi * this % n_pol)) + allocate(temp_3d(delayed_groups, this % n_azi, this % n_pol)) + + ! Get array with chi_prompt + call read_dataset(temp_1d, xsdata_grp, "chi-delayed") + temp_3d = reshape(temp_1d, (/delayed_groups, this % n_azi, & + this % n_pol/)) + + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do dg = 1, delayed_groups + do gin = 1, energy_groups + do gout = 1, energy_groups + xs % chi_delayed(gout, gin, dg, iazi, ipol) = & + temp_3d(gout, iazi, ipol) + end do + + ! Normalize chi so its CDF goes to 1 + if (sum(xs % chi_delayed(:, gin, dg, iazi, ipol)) & + == ZERO) then + call fatal_error("Encountered chi delayed for a group& + & that sums to zero") + else + xs % chi_delayed(:, gin, dg, iazi, ipol) = & + xs % chi_delayed(:, gin, dg, iazi, ipol) / & + sum(xs % chi_delayed(:, gin, dg, iazi, ipol)) + end if + end do + end do + end do + end do + + ! Deallocate temporary arrays for chi_delayed + deallocate(temp_1d) + deallocate(temp_3d) + + else if (ndims == 2) then + + ! Allocate temporary array for chi_delayed + allocate(temp_1d(delayed_groups * energy_groups * this % n_azi & + * this % n_pol)) + allocate(temp_4d(energy_groups, delayed_groups, this % n_azi, & + this % n_pol)) + + ! Get chi-delayed + call read_dataset(temp_1d, xsdata_grp, "chi-delayed") + temp_4d = reshape(temp_1d, (/energy_groups, delayed_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)) + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do dg = 1, delayed_groups + do gin = 1, energy_groups + do gout = 1, energy_groups + xs % chi_delayed(gout, gin, dg, iazi, ipol) = & + temp_4d(gout, dg, iazi, ipol) + end do + + ! Normalize chi so its CDF goes to 1 + if (sum(xs % chi_delayed(:, gin, dg, iazi, ipol)) & + == ZERO) then + call fatal_error("Encountered chi delayed for a group& + & that sums to zero") + else + xs % chi_delayed(:, gin, dg, iazi, ipol) = & + xs % chi_delayed(:, gin, dg, iazi, ipol) / & + sum(xs % chi_delayed(:, gin, dg, iazi, ipol)) + end if + end do + end do 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)) + ! Deallocate temporary arrays for chi_delayed + deallocate(temp_1d) + deallocate(temp_4d) + + else + call fatal_error("chi-delayed must be provided as a 3D or 4D & + &array") + end if + end if + + ! If prompt-nu-fission present, set prompt_nu_fission + if (check_dataset(xsdata_grp, "prompt-nu-fission")) then + + ! Allocate temporary array for prompt-nu-fission + allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) + + ! Read prompt-nu-fission + call read_dataset(temp_1d, xsdata_grp, "prompt-nu-fission") + xs % prompt_nu_fission = reshape(temp_1d, (/energy_groups, & + this % n_azi, this % n_pol/)) + + ! Deallocate temporary array for prompt_nu_fission + deallocate(temp_1d) + end if + + ! If delayed-nu-fission provided, set delayed_nu_fission. If + ! delayed-nu-fission is a matrix, set chi_delayed. + if (check_dataset(xsdata_grp, "delayed-nu-fission")) then + + ! Get the dimensions of the delayed-nu-fission dataset + xsdata = open_dataset(xsdata_grp, "delayed-nu-fission") + call get_ndims(xsdata, ndims) + + ! If delayed-nu-fission is a vector + if (ndims == 3) then + + ! If beta is zeros, raise error + if (temp_beta(1,1,1,1) == ZERO) then + call fatal_error("cannot set delayed-nu-fission with a 1D & + &array if beta not provided") + end if + + ! Allocate temporary arrays for delayed_nu_fission + allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) + allocate(temp_3d(energy_groups, this % n_azi, this % n_pol)) + + ! Get delayed_nu_fission + call read_dataset(temp_1d, xsdata_grp, "delayed-nu-fission") + temp_3d = reshape(temp_1d, (/energy_groups, this % n_azi, & + this % n_pol/)) + + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, energy_groups + do dg = 1, delayed_groups + + ! Set delayed_nu_fission using delayed neutron fraction + xs % delayed_nu_fission(gin, dg, iazi, ipol) = & + temp_beta(gin, dg, iazi, ipol) * & + temp_3d(gin, iazi, ipol) + end do + end do end do end do - end do - deallocate(temp_4d) + + ! Deallocate temporary delayed_nu_fission arrays + deallocate(temp_1d) + deallocate(temp_3d) + + ! If delayed-nu-fission is a (delayed_group, energy_group) + ! matrix, set delayed_nu_fission separately for each delayed + ! group. + else if (ndims == 4) then + + ! Get the shape of delayed-nu-fission + call get_shape(xsdata, dims) + + ! Issue error if 1st dimension not correct + if (dims(1) /= energy_groups) then + call fatal_error("The delayed-nu-fission matrix was input & + &with a 1st dimension not equal to the number of & + &energy groups.") + end if + + ! Issue error if 2nd dimension not correct + if (dims(2) /= delayed_groups) then + call fatal_error("The delayed-nu-fission matrix was input & + &with a 2nd dimension not equal to the number of & + &delayed groups.") + end if + + ! Issue warning if delayed_groups == energy_groups + if (delayed_groups == energy_groups) then + call warning("delayed-nu-fission was input as a dimension & + &4 matrix with the same number of delayed groups and & + &groups. It is important to know that OpenMC assumes & + &the dimensions in the matrix are (energy_groups, & + &delayed_groups, n_azi, n_pol). Currently, & + &delayed-nu-fission cannot be set as a group by group & + &matrix.") + end if + + ! Get delayed_nu_fission + allocate(temp_1d(delayed_groups * energy_groups * this % n_azi & + * this % n_pol)) + call read_dataset(temp_1d, xsdata_grp, "delayed-nu-fission") + xs % delayed_nu_fission = reshape(temp_1d, (/energy_groups, & + delayed_groups, this % n_azi, this % n_pol /)) + + ! Deallocate temporary array for delayed_nu_fission matrix + deallocate(temp_1d) + + else + call fatal_error("delayed-nu-fission must be provided as a & + &1D or 2D array") + end if 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_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)) - xs % fission = reshape(temp_arr, (/groups, this % n_azi, & - this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("Fission data missing, required due to fission& - & tallies in tallies.xml file!") - end if + ! Deallocate temporary beta array + deallocate(temp_beta) + + ! chi_prompt, chi_delayed, prompt_nu_fission, and delayed_nu_fission + ! have been set; Now we will check for the rest of the XS that are + ! unique to fissionable isotopes + + ! Set fission xs + if (check_dataset(xsdata_grp, "fission")) then + + ! Allocate temporary array for fission + allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) + + ! Get fission array + call read_dataset(temp_1d, xsdata_grp, "fission") + xs % fission(:, :, :) = reshape(temp_1d, (/energy_groups, & + this % n_azi, this % n_pol/)) + + ! Deallocate temporary array for fission + deallocate(temp_1d) 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)) - xs % k_fission = reshape(temp_arr, (/groups, this % n_azi, & - this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("kappa_fission data missing, required due to & - &kappa-fission tallies in tallies.xml file!") - end if + + ! Set kappa_fission xs + if (check_dataset(xsdata_grp, "kappa-fission")) then + + ! Allocate temporary array for kappa_fission + allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) + + ! Get kappa_fission array + call read_dataset(temp_1d, xsdata_grp, "kappa-fission") + xs % kappa_fission(:, :, :) = reshape(temp_1d, (/energy_groups, & + this % n_azi, this % n_pol/)) + + ! Deallocate temporary array for kappa_fission + deallocate(temp_1d) + end if + + ! Set decay rate + if (check_dataset(xsdata_grp, "decay-rate")) then + + ! Allocate temporary array for decay_rate + allocate(temp_1d(this % n_azi * this % n_pol * delayed_groups)) + + ! Get decay_rate array + call read_dataset(temp_1d, xsdata_grp, "decay-rate") + xs % decay_rate(:, :, :) = reshape(temp_1d, (/delayed_groups, & + this % n_azi, this % n_pol/)) + + ! Deallocate temporary array for decay_rate + deallocate(temp_1d) end if end if + ! All the XS unique to fissionable isotopes have been set; Now set all + ! the generation XS + 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)) - xs % absorption = reshape(temp_arr, (/groups, this % n_azi, & - this % n_pol/)) - deallocate(temp_arr) + + ! Allocate temporary array for absorption xs + allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) + + ! Read in absorption xs + call read_dataset(temp_1d, xsdata_grp, "absorption") + + xs % absorption = reshape(temp_1d, (/energy_groups, this % n_azi, & + this % n_pol/)) + + ! Deallocate temporary array for absorption xs + deallocate(temp_1d) else call fatal_error("Must provide absorption!") end if + if (check_dataset(xsdata_grp, "inverse_velocity")) then + + ! Allocate temporary array for inverse velocity + allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) + + ! Read in inverse velocity + call read_dataset(temp_1d, xsdata_grp, "inverse_velocity") + + allocate(xs % inverse_velocity(energy_groups, this % n_azi, & + this % n_pol)) + xs % inverse_velocity = reshape(temp_1d, (/energy_groups, & + this % n_azi, this % n_pol/)) + + ! Deallocate temporary array for inverse velocity + deallocate(temp_1d) + 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(scatt_grp, "g_min")) then - allocate(int_arr(groups * this % n_azi * this % n_pol)) + + allocate(int_arr(energy_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/)) + allocate(gmin(energy_groups, this % n_azi, this % n_pol)) + gmin = reshape(int_arr, (/energy_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(int_arr(groups * this % n_azi * this % n_pol)) + + allocate(int_arr(energy_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/)) + allocate(gmax(energy_groups, this % n_azi, this % n_pol)) + gmax = reshape(int_arr, (/energy_groups, this % n_azi, & + this % n_pol/)) + deallocate(int_arr) else call fatal_error("'g_max' for the scatter matrix must be provided") @@ -883,17 +1631,19 @@ module mgxs_header length = 0 do ipol = 1, this % n_pol do iazi = 1, this % n_azi - do gin = 1, groups + do gin = 1, energy_groups length = length + order_dim * (gmax(gin, iazi, ipol) - & - gmin(gin, iazi, ipol) + 1) + gmin(gin, iazi, ipol) + 1) end do end do end do + ! Allocate flattened array - allocate(temp_arr(length)) + allocate(temp_1d(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") + call read_dataset(temp_1d, scatt_grp, "scatter matrix") ! Compare the number of orders given with the maximum order of the ! problem. Strip off the superfluous orders if needed. @@ -902,41 +1652,47 @@ module mgxs_header order_dim = order + 1 end if - ! Convert temp_arr to a jagged array ((gin) % data(l, gout)) for passing + ! Convert temp_1d to a jagged array ((gin) % data(l, gout)) for passing ! to ScattData - allocate(input_scatt(groups, this % n_azi, this % n_pol)) + allocate(input_scatt(energy_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 + do gin = 1, energy_groups allocate(input_scatt(gin, iazi, ipol) % data(order_dim, & gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) do gout = gmin(gin, iazi, ipol), gmax(gin, iazi, ipol) do l = 1, order_dim input_scatt(gin, iazi, ipol) % data(l, gout) = & - temp_arr(index) + temp_1d(index) index = index + 1 end do ! gout end do ! order end do ! gin end do ! iazi end do ! ipol - deallocate(temp_arr) + + deallocate(temp_1d) ! Finally convert the legendre to tabular if needed - allocate(scatt_coeffs(groups, this % n_azi, this % n_pol)) + allocate(scatt_coeffs(energy_groups, this % n_azi, this % n_pol)) + if (this % scatter_format == ANGLE_LEGENDRE .and. & legendre_to_tabular) then + this % scatter_format = ANGLE_TABULAR order_dim = legendre_to_tabular_points order = order_dim dmu = TWO / real(order - 1, 8) + do ipol = 1, this % n_pol do iazi = 1, this % n_azi - do gin = 1, groups + do gin = 1, energy_groups allocate(scatt_coeffs(gin, iazi, ipol) % data(& order_dim, & gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) + do gout = gmin(gin, iazi, ipol), gmax(gin, iazi, ipol) norm = ZERO do imu = 1, order_dim @@ -947,12 +1703,15 @@ module mgxs_header 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 * & @@ -960,6 +1719,7 @@ module mgxs_header 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 @@ -976,7 +1736,7 @@ module mgxs_header ! Sticking with current representation, carry forward do ipol = 1, this % n_pol do iazi = 1, this % n_azi - do gin = 1, groups + do gin = 1, energy_groups allocate(scatt_coeffs(gin, iazi, ipol) % data(order_dim, & gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) scatt_coeffs(gin, iazi, ipol) % data(:, :) = & @@ -985,46 +1745,54 @@ module mgxs_header end do end do end if + deallocate(input_scatt) ! Now get the multiplication matrix 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 + do gin = 1, energy_groups length = length + (gmax(gin, iazi, ipol) - gmin(gin, iazi, ipol) + 1) end do end do end do + ! Allocate flattened array - allocate(temp_arr(length)) - call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") - ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing + allocate(temp_1d(length)) + call read_dataset(temp_1d, scatt_grp, "multiplicity matrix") + + ! Convert temp_1d to a jagged array ((gin) % data(gout)) for passing ! to ScattData - allocate(temp_mult(groups, this % n_azi, this % n_pol)) + allocate(temp_mult(energy_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 + do gin = 1, energy_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) + temp_mult(gin, iazi, ipol) % data(gout) = temp_1d(index) index = index + 1 end do end do end do end do - deallocate(temp_arr) + deallocate(temp_1d) else - allocate(temp_mult(groups, this % n_azi, this % n_pol)) + + allocate(temp_mult(energy_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 + do gin = 1, energy_groups allocate(temp_mult(gin, iazi, ipol) % data( & gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) temp_mult(gin, iazi, ipol) % data = ONE @@ -1035,8 +1803,10 @@ module mgxs_header ! Allocate and initialize our ScattData Object. allocate(xs % scatter(this % n_azi, this % n_pol)) + do ipol = 1, this % n_pol do iazi = 1, this % n_azi + ! Allocate and initialize our ScattData Object. if (this % scatter_format == ANGLE_HISTOGRAM) then allocate(ScattDataHistogram :: xs % scatter(iazi, ipol) % obj) @@ -1058,7 +1828,7 @@ module mgxs_header ! (This may happen with Helium data) do ipol = 1, this % n_pol do iazi = 1, this % n_azi - do gin = 1, groups + do gin = 1, energy_groups if (xs % absorption(gin, iazi, ipol) == ZERO) then xs % absorption(gin, iazi, ipol) = 1E-10_8 end if @@ -1066,13 +1836,14 @@ module mgxs_header end do end do - allocate(xs % total(groups, this % n_azi, this % n_pol)) if (check_dataset(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, & + + allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) + call read_dataset(temp_1d, xsdata_grp, "total") + xs % total = reshape(temp_1d, (/energy_groups, this % n_azi, & this % n_pol/)) - deallocate(temp_arr) + + deallocate(temp_1d) else do ipol = 1, this % n_pol do iazi = 1, this % n_azi @@ -1086,7 +1857,7 @@ module mgxs_header ! the tally routines do ipol = 1, this % n_pol do iazi = 1, this % n_azi - do gin = 1, groups + do gin = 1, energy_groups if (xs % total(gin, iazi, ipol) == ZERO) then xs % total(gin, iazi, ipol) = 1E-10_8 end if @@ -1094,20 +1865,11 @@ 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) deallocate(scatt_coeffs, temp_mult) + end associate ! xs end do ! Temperatures end subroutine mgxsang_from_hdf5 @@ -1134,6 +1896,7 @@ module mgxs_header else this % name = trim(mat % name) end if + this % fissionable = mat % fissionable ! The following info we should initialize, but we dont need it nor @@ -1141,6 +1904,7 @@ module mgxs_header this % awr = -ONE allocate(this % kTs(temps % size())) + do t = 1, temps % size() this % kTs(t) = temps % data(t) end do @@ -1156,12 +1920,14 @@ module mgxs_header ! Determine the scattering type of our data and ensure all scattering orders ! are the same. scatter_format = nuclides(mat % nuclide(1)) % obj % scatter_format + select type(nuc => nuclides(mat % nuclide(1)) % obj) type is (MgxsIso) order = size(nuc % 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 (scatter_format == ANGLE_HISTOGRAM) then ! Check all scattering data to ensure it is the same size @@ -1177,8 +1943,10 @@ module mgxs_header & same length!") end select end do + ! Ok, got our order, store the dimensionality order_dim = order + else if (scatter_format == ANGLE_TABULAR) then ! Check all scattering data to ensure it is the same size do i = 2, mat % n_nuclides @@ -1193,11 +1961,15 @@ module mgxs_header & same length!") end select end do + ! Ok, got our order, store the dimensionality order_dim = order + else if (scatter_format == ANGLE_LEGENDRE) then + ! Need to determine the maximum scattering order of all data in this material mat_max_order = 0 + do i = 1, mat % n_nuclides select type(nuc => nuclides(mat % nuclide(i)) % obj) type is (MgxsIso) @@ -1217,19 +1989,21 @@ module mgxs_header ! 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 end if end subroutine mgxs_combine - subroutine mgxsiso_combine(this, temps, mat, nuclides, groups, max_order, & - tolerance, method) - class(MgxsIso), intent(inout) :: this ! The Mgxs to initialize + subroutine mgxsiso_combine(this, temps, mat, nuclides, energy_groups, & + delayed_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 + type(Material), pointer, intent(in) :: mat ! base material + type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from + integer, intent(in) :: energy_groups ! Number of energy groups + integer, intent(in) :: delayed_groups ! Number of delayed 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 @@ -1237,6 +2011,7 @@ module mgxs_header integer :: i ! loop index over nuclides integer :: t ! Index in to temps integer :: gin, gout ! group indices + integer :: dg ! delayed group index real(8) :: atom_density ! atom density of a nuclide real(8) :: norm, nuscatt integer :: order_dim, nuc_order_dim @@ -1257,31 +2032,54 @@ 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(groups)) + allocate(this % xs(t) % total(energy_groups)) this % xs(t) % total(:) = ZERO - allocate(this % xs(t) % absorption(groups)) + + allocate(this % xs(t) % absorption(energy_groups)) this % xs(t) % absorption(:) = ZERO - allocate(this % xs(t) % fission(groups)) + + allocate(this % xs(t) % fission(energy_groups)) this % xs(t) % fission(:) = ZERO - allocate(this % xs(t) % k_fission(groups)) - this % xs(t) % k_fission(:) = ZERO - allocate(this % xs(t) % nu_fission(groups)) - this % xs(t) % nu_fission(:) = ZERO - allocate(this % xs(t) % chi(groups,groups)) - this % xs(t) % chi(:, :) = ZERO - allocate(this % xs(t) % inv_vel(groups)) - this % xs(t) % inv_vel(:) = ZERO - allocate(temp_mult(groups,groups)) + + allocate(this % xs(t) % kappa_fission(energy_groups)) + this % xs(t) % kappa_fission(:) = ZERO + + allocate(this % xs(t) % prompt_nu_fission(energy_groups)) + this % xs(t) % prompt_nu_fission(:) = ZERO + + allocate(this % xs(t) % delayed_nu_fission(energy_groups, & + delayed_groups)) + this % xs(t) % delayed_nu_fission(:, :) = ZERO + + allocate(this % xs(t) % chi_prompt(energy_groups, energy_groups)) + this % xs(t) % chi_prompt(:, :) = ZERO + + allocate(this % xs(t) % chi_delayed(energy_groups, energy_groups, & + delayed_groups)) + this % xs(t) % chi_delayed(:, :, :) = ZERO + + allocate(this % xs(t) % inverse_velocity(energy_groups)) + this % xs(t) % inverse_velocity(:) = ZERO + + allocate(this % xs(t) % decay_rate(delayed_groups)) + this % xs(t) % decay_rate(:) = ZERO + + allocate(temp_mult(energy_groups, energy_groups)) temp_mult(:, :) = ZERO - allocate(mult_num(groups,groups)) + + allocate(mult_num(energy_groups, energy_groups)) mult_num(:, :) = ZERO - allocate(mult_denom(groups,groups)) + + allocate(mult_denom(energy_groups, energy_groups)) mult_denom(:, :) = ZERO - allocate(scatt_coeffs(order_dim,groups,groups)) + + allocate(scatt_coeffs(order_dim, energy_groups, energy_groups)) scatt_coeffs(:, :, :) = ZERO this % scatter_format = scatter_format + if (scatter_format == ANGLE_LEGENDRE) then allocate(ScattDataLegendre :: this % xs(t) % scatter) else if (scatter_format == ANGLE_TABULAR) then @@ -1293,16 +2091,20 @@ 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 + + ! Copy atom density of nuclide in material atom_density = mat % atom_density(i) select case (method) case (TEMPERATURE_NEAREST) + ! Determine actual temperatures to read temp_desired = temps % data(i) allocate(nuc_ts(1)) + nuc_ts(1) = minloc(abs(nuc % kTs - temp_desired), dim=1) temp_actual = nuc % kTs(nuc_ts(1)) + if (abs(temp_actual - temp_desired) >= K_BOLTZMANN * tolerance) then call fatal_error("MGXS library does not contain cross sections & &for " // trim(this % name) // " at or near " // & @@ -1310,11 +2112,13 @@ module mgxs_header 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 @@ -1331,7 +2135,9 @@ module mgxs_header select type(nuc) type is (MgxsIso) do j = 1, size(nuc_ts) + nuc_t = nuc_ts(j) + if (size(nuc_ts) == 1) then interp = ONE else if (j == 1) then @@ -1345,25 +2151,38 @@ module mgxs_header ! 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 + + this % xs(t) % decay_rate = this % xs(t) % decay_rate + & + atom_density * nuc % xs(nuc_t) % decay_rate * interp + + this % xs(t) % inverse_velocity = & + this % xs(t) % inverse_velocity + & + atom_density * nuc % xs(nuc_t) % inverse_velocity * interp + if (nuc % fissionable) then - this % xs(t) % chi = this % xs(t) % chi + & - atom_density * nuc % xs(nuc_t) % chi * interp - this % xs(t) % nu_fission = this % xs(t) % nu_fission + & - atom_density * nuc % xs(nuc_t) % nu_fission * interp - if (allocated(nuc % xs(nuc_t) % fission)) then - this % xs(t) % fission = this % xs(t) % fission + & - atom_density * nuc % xs(nuc_t) % fission * interp - end if - if (allocated(nuc % xs(nuc_t) % k_fission)) then - this % xs(t) % k_fission = this % xs(t) % k_fission + & - atom_density * nuc % xs(nuc_t) % k_fission * interp - end if - end if - if (allocated(nuc % xs(nuc_t) % inv_vel)) then - this % xs(t) % inv_vel = this % xs(t) % inv_vel + & - atom_density * nuc % xs(nuc_t) % inv_vel * interp + + this % xs(t) % chi_prompt = this % xs(t) % chi_prompt + & + atom_density * nuc % xs(nuc_t) % chi_prompt * interp + + this % xs(t) % chi_delayed = this % xs(t) % chi_delayed + & + atom_density * nuc % xs(nuc_t) % chi_delayed * interp + + this % xs(t) % prompt_nu_fission = this % xs(t) % & + prompt_nu_fission + atom_density * nuc % xs(nuc_t) % & + prompt_nu_fission * interp + + this % xs(t) % delayed_nu_fission = this % xs(t) % & + delayed_nu_fission + atom_density * nuc % xs(nuc_t) % & + delayed_nu_fission * interp + + this % xs(t) % fission = this % xs(t) % fission + & + atom_density * nuc % xs(nuc_t) % fission * interp + + this % xs(t) % kappa_fission = this % xs(t) % kappa_fission +& + atom_density * nuc % xs(nuc_t) % kappa_fission * interp end if ! We will next gather the multiplicity and scattering matrices. @@ -1383,12 +2202,15 @@ module mgxs_header ! 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 gin = 1, energy_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) * & @@ -1404,9 +2226,11 @@ module mgxs_header ! 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 gin = 1, energy_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) = & @@ -1422,8 +2246,8 @@ module mgxs_header end select ! Obtain temp_mult - do gin = 1, groups - do gout = 1, groups + do gin = 1, energy_groups + do gout = 1, energy_groups if (mult_denom(gout, gin) > ZERO) then temp_mult(gout, gin) = mult_num(gout, gin) / mult_denom(gout, gin) else @@ -1442,12 +2266,23 @@ module mgxs_header ! Now normalize chi if (mat % fissionable) then - do gin = 1, groups - norm = sum(this % xs(t) % chi(:, gin)) + do gin = 1, energy_groups + norm = sum(this % xs(t) % chi_prompt(:, gin)) if (norm > ZERO) then - this % xs(t) % chi(:, gin) = this % xs(t) % chi(:, gin) / norm + this % xs(t) % chi_prompt(:, gin) = & + this % xs(t) % chi_prompt(:, gin) / norm end if end do + + do dg = 1, delayed_groups + do gin = 1, energy_groups + norm = sum(this % xs(t) % chi_delayed(:, gin, dg)) + if (norm > ZERO) then + this % xs(t) % chi_delayed(:, gin, dg) = & + this % xs(t) % chi_delayed(:, gin, dg) / norm + end if + end do + end do end if ! Deallocate temporaries @@ -1459,13 +2294,14 @@ module mgxs_header end subroutine mgxsiso_combine - subroutine mgxsang_combine(this, temps, mat, nuclides, groups, max_order, & - tolerance, method) + subroutine mgxsang_combine(this, temps, mat, nuclides, energy_groups, & + delayed_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) :: energy_groups ! Number of energy groups + integer, intent(in) :: delayed_groups ! Number of delayed 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 @@ -1473,6 +2309,7 @@ module mgxs_header integer :: i ! loop index over nuclides integer :: t ! temperature loop index integer :: gin, gout ! group indices + integer :: dg ! delayed group index real(8) :: atom_density ! atom density of a nuclide integer :: ipol, iazi, n_pol, n_azi real(8) :: norm, nuscatt @@ -1490,20 +2327,24 @@ module mgxs_header ! Set the meta-data call mgxs_combine(this, temps, mat, nuclides, max_order, scatter_format, & - order_dim) + 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 n_pol = -1 n_azi = -1 + do i = 1, mat % n_nuclides select type(nuc => nuclides(mat % nuclide(i)) % obj) type is (MgxsAngle) + if (n_pol == -1) then n_pol = nuc % n_pol n_azi = nuc % n_azi + allocate(this % polar(n_pol)) this % polar(:) = nuc % polar(:) + allocate(this % azimuthal(n_azi)) this % azimuthal(:) = nuc % azimuthal(:) else @@ -1516,31 +2357,55 @@ 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(groups, n_azi, n_pol)) + allocate(this % xs(t) % total(energy_groups, n_azi, n_pol)) this % xs(t) % total = ZERO - allocate(this % xs(t) % absorption(groups, n_azi, n_pol)) + + allocate(this % xs(t) % absorption(energy_groups, n_azi, n_pol)) this % xs(t) % absorption = ZERO - allocate(this % xs(t) % fission(groups, n_azi, n_pol)) + + allocate(this % xs(t) % fission(energy_groups, n_azi, n_pol)) this % xs(t) % fission = ZERO - allocate(this % xs(t) % k_fission(groups, n_azi, n_pol)) - this % xs(t) % k_fission = ZERO - allocate(this % xs(t) % nu_fission(groups, n_azi, n_pol)) - this % xs(t) % nu_fission = ZERO - allocate(this % xs(t) % chi(groups, groups, n_azi, n_pol)) - this % xs(t) % chi = ZERO - allocate(this % xs(t) % inv_vel(groups, n_azi, n_pol)) - this % xs(t) % inv_vel = ZERO - allocate(temp_mult(groups, groups, n_azi, n_pol)) + + allocate(this % xs(t) % decay_rate(delayed_groups, n_azi, n_pol)) + this % xs(t) % decay_rate = ZERO + + allocate(this % xs(t) % inverse_velocity(energy_groups, n_azi, n_pol)) + this % xs(t) % inverse_velocity = ZERO + + allocate(this % xs(t) % kappa_fission(energy_groups, n_azi, n_pol)) + this % xs(t) % kappa_fission = ZERO + + allocate(this % xs(t) % prompt_nu_fission(energy_groups, n_azi, n_pol)) + this % xs(t) % prompt_nu_fission = ZERO + + allocate(this % xs(t) % delayed_nu_fission(energy_groups, & + delayed_groups, n_azi, n_pol)) + this % xs(t) % delayed_nu_fission = ZERO + + allocate(this % xs(t) % chi_prompt(energy_groups, energy_groups, & + n_azi, n_pol)) + this % xs(t) % chi_prompt = ZERO + + allocate(this % xs(t) % chi_delayed(energy_groups, energy_groups, & + delayed_groups, n_azi, n_pol)) + this % xs(t) % chi_delayed = ZERO + + allocate(temp_mult(energy_groups, energy_groups, n_azi, n_pol)) temp_mult = ZERO - allocate(mult_num(groups, groups, n_azi, n_pol)) + + allocate(mult_num(energy_groups, energy_groups, n_azi, n_pol)) mult_num = ZERO - allocate(mult_denom(groups, groups, n_azi, n_pol)) + + allocate(mult_denom(energy_groups, energy_groups, n_azi, n_pol)) mult_denom = ZERO - allocate(scatt_coeffs(order_dim, groups, groups, n_azi, n_pol)) + + allocate(scatt_coeffs(order_dim, energy_groups, energy_groups, n_azi, n_pol)) scatt_coeffs = ZERO allocate(this % xs(t) % scatter(n_azi, n_pol)) + do ipol = 1, n_pol do iazi = 1, n_azi if (scatter_format == ANGLE_LEGENDRE) then @@ -1562,11 +2427,14 @@ module mgxs_header select case (method) case (TEMPERATURE_NEAREST) + ! Determine actual temperatures to read temp_desired = temps % data(i) allocate(nuc_ts(1)) + nuc_ts(1) = minloc(abs(nuc % kTs - temp_desired), dim=1) temp_actual = nuc % kTs(nuc_ts(1)) + if (abs(temp_actual - temp_desired) >= K_BOLTZMANN * tolerance) then call fatal_error("MGXS library does not contain cross sections & &for " // trim(this % name) // " at or near " // & @@ -1574,11 +2442,13 @@ module mgxs_header 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 @@ -1598,7 +2468,9 @@ module mgxs_header select type(nuc) type is (MgxsAngle) do j = 1, size(nuc_ts) + nuc_t = nuc_ts(j) + if (size(nuc_ts) == 1) then interp = ONE else if (j == 1) then @@ -1607,30 +2479,44 @@ module mgxs_header else interp = ONE - interp end if + ! Perform our operations which depend upon the type ! Add contributions to total, absorption, and fission data ! (if necessary) this % xs(t) % total = this % xs(t) % total + & atom_density * nuc % xs(nuc_t) % total * interp + this % xs(t) % absorption = this % xs(t) % absorption + & atom_density * nuc % xs(nuc_t) % absorption * interp - if (allocated(nuc % xs(nuc_t) % inv_vel)) then - this % xs(t) % inv_vel = this % xs(t) % inv_vel + & - atom_density * nuc % xs(nuc_t) % inv_vel * interp - end if + + this % xs(t) % decay_rate = this % xs(t) % decay_rate + & + atom_density * nuc % xs(nuc_t) % decay_rate * interp + + this % xs(t) % inverse_velocity = & + this % xs(t) % inverse_velocity + & + atom_density * nuc % xs(nuc_t) % inverse_velocity * 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 + + this % xs(t) % chi_prompt = this % xs(t) % chi_prompt + & + atom_density * nuc % xs(nuc_t) % chi_prompt * interp + + this % xs(t) % chi_delayed = this % xs(t) % chi_delayed + & + atom_density * nuc % xs(nuc_t) % chi_delayed * interp + + this % xs(t) % prompt_nu_fission = & + this % xs(t) % prompt_nu_fission + atom_density * & + nuc % xs(nuc_t) % prompt_nu_fission * interp + + this % xs(t) % delayed_nu_fission = & + this % xs(t) % delayed_nu_fission + atom_density * & + nuc % xs(nuc_t) % delayed_nu_fission * interp + + this % xs(t) % fission = this % xs(t) % fission + & + atom_density * nuc % xs(nuc_t) % fission * interp + + this % xs(t) % kappa_fission = this % xs(t) % kappa_fission & + + atom_density * nuc % xs(nuc_t) % kappa_fission * interp end if ! We will next gather the multiplicity and scattering matrices. @@ -1652,14 +2538,17 @@ module mgxs_header ! scatter % scattxs do ipol = 1, n_pol do iazi = 1, n_azi - do gin = 1, groups + do gin = 1, energy_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 * & @@ -1679,9 +2568,11 @@ module mgxs_header 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 gin = 1, energy_groups do gout = & nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % gmin(gin), & nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % gmax(gin) @@ -1703,8 +2594,8 @@ module mgxs_header do ipol = 1, n_pol do iazi = 1, n_azi ! Obtain temp_mult - do gin = 1, groups - do gout = 1, groups + do gin = 1, energy_groups + do gout = 1, energy_groups if (mult_denom(gout, gin, iazi, ipol) > ZERO) then temp_mult(gout, gin, iazi, ipol) = & mult_num(gout, gin, iazi, ipol) / & @@ -1732,15 +2623,31 @@ module mgxs_header if (mat % fissionable) then do ipol = 1, n_pol do iazi = 1, n_azi - do gin = 1, groups - norm = sum(this % xs(t) % chi(:, gin, iazi, ipol)) + do gin = 1, energy_groups + norm = sum(this % xs(t) % chi_prompt(:, gin, iazi, ipol)) if (norm > ZERO) then - this % xs(t) % chi(:, gin, iazi, ipol) = & - this % xs(t) % chi(:, gin, iazi, ipol) / norm + this % xs(t) % chi_prompt(:, gin, iazi, ipol) = & + this % xs(t) % chi_prompt(:, gin, iazi, ipol) / norm end if end do end do end do + + do dg = 1, delayed_groups + do ipol = 1, n_pol + do iazi = 1, n_azi + do gin = 1, energy_groups + norm = sum(this % xs(t) % chi_prompt(:, gin, iazi, ipol)) + if (norm > ZERO) then + this % xs(t) % chi_delayed(:, gin, dg, iazi, ipol) = & + this % xs(t) % chi_delayed(:, gin, dg, iazi, ipol)& + / norm + end if + end do + end do + end do + end do + end if ! Deallocate temporaries @@ -1755,44 +2662,110 @@ module mgxs_header ! MGXS*_GET_XS returns the requested data cross section data !=============================================================================== - pure function mgxsiso_get_xs(this, xstype, gin, gout, uvw, mu) result(xs) + pure function mgxsiso_get_xs(this, xstype, gin, gout, uvw, mu, dg) result(xs) class(MgxsIso), intent(in) :: this ! The Xs to get data from character(*) , intent(in) :: xstype ! Type of xs requested integer, intent(in) :: gin ! Incoming Energy group integer, optional, intent(in) :: gout ! Outgoing Energy group real(8), optional, intent(in) :: uvw(3) ! Requested Angle real(8), optional, intent(in) :: mu ! Change in angle + integer, optional, intent(in) :: dg ! Delayed group real(8) :: xs ! Requested x/s integer :: t ! temperature index t = this % index_temp select case(xstype) + case('total') xs = this % xs(t) % total(gin) + case('absorption') xs = this % xs(t) % absorption(gin) + case('fission') - if (allocated(this % xs(t) % fission)) then - xs = this % xs(t) % fission(gin) - else - xs = ZERO - end if + xs = this % xs(t) % fission(gin) + case('kappa_fission') - if (allocated(this % xs(t) % k_fission)) then - xs = this % xs(t) % k_fission(gin) + xs = this % xs(t) % kappa_fission(gin) + + case('inverse_velocity') + xs = this % xs(t) % inverse_velocity(gin) + + case('decay_rate') + if (present(dg)) then + xs = this % xs(t) % decay_rate(dg) + else + xs = this % xs(t) % decay_rate(1) + end if + + case('prompt_nu_fission') + xs = this % xs(t) % prompt_nu_fission(gin) + + case('delayed_nu_fission') + if (present(dg)) then + xs = this % xs(t) % delayed_nu_fission(gin, dg) + else + xs = sum(this % xs(t) % delayed_nu_fission(gin, :)) + end if + + case('nu_fission') + xs = this % xs(t) % prompt_nu_fission(gin) + & + sum(this % xs(t) % delayed_nu_fission(gin, :)) + + case('nu') + if (this % xs(t) % fission(gin) > ZERO) then + xs = (sum(this % xs(t) % delayed_nu_fission(gin, :)) + & + this % xs(t) % prompt_nu_fission(gin)) / & + this % xs(t) % fission(gin) else xs = ZERO end if - case('nu_fission') - xs = this % xs(t) % nu_fission(gin) - case('chi') + + case('nu_prompt') + if (this % xs(t) % fission(gin) > ZERO) then + xs = this % xs(t) % prompt_nu_fission(gin) / & + this % xs(t) % fission(gin) + else + xs = ZERO + end if + + case('nu_delayed') + if (this % xs(t) % fission(gin) > ZERO) then + if (present(dg)) then + xs = this % xs(t) % delayed_nu_fission(gin, dg) & + / this % xs(t) % fission(gin) + else + xs = sum(this % xs(t) % delayed_nu_fission(gin, :)) & + / this % xs(t) % fission(gin) + end if + else + xs = ZERO + end if + + case('chi_prompt') if (present(gout)) then - xs = this % xs(t) % chi(gout,gin) + xs = this % xs(t) % chi_prompt(gout,gin) else ! Not sure youd want a 1 or a 0, but here you go! - xs = sum(this % xs(t) % chi(:, gin)) + xs = sum(this % xs(t) % chi_prompt(:, gin)) end if + + case('chi_delayed') + if (present(gout)) then + if (present(dg)) then + xs = this % xs(t) % chi_delayed(gout, gin, dg) + else + xs = this % xs(t) % chi_delayed(gout, gin, 1) + end if + else + if (present(dg)) then + xs = sum(this % xs(t) % chi_delayed(:, gin, dg)) + else + xs = sum(this % xs(t) % chi_delayed(:, gin, 1)) + end if + end if + case('scatter') if (present(gout)) then if (gout < this % xs(t) % scatter % gmin(gin) .or. & @@ -1805,6 +2778,7 @@ module mgxs_header 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. & @@ -1820,6 +2794,7 @@ module mgxs_header (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. & @@ -1840,20 +2815,21 @@ 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 + end function mgxsiso_get_xs - pure function mgxsang_get_xs(this, xstype, gin, gout, uvw, mu) result(xs) + pure function mgxsang_get_xs(this, xstype, gin, gout, uvw, mu, dg) 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 + integer, optional, intent(in) :: dg ! Delayed group real(8) :: xs ! Requested x/s integer :: iazi, ipol, t @@ -1861,33 +2837,100 @@ module mgxs_header t = this % index_temp if (present(uvw)) then + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + select case(xstype) + case('total') xs = this % xs(t) % total(gin, iazi, ipol) + case('absorption') xs = this % xs(t) % absorption(gin, iazi, ipol) + case('fission') - if (allocated(this % xs(t) % fission)) then - xs = this % xs(t) % fission(gin, iazi, ipol) - else - xs = ZERO - end if + xs = this % xs(t) % fission(gin, iazi, ipol) + case('kappa_fission') - if (allocated(this % xs(t) % k_fission)) then - xs = this % xs(t) % k_fission(gin, iazi, ipol) + xs = this % xs(t) % kappa_fission(gin, iazi, ipol) + + case('prompt_nu_fission') + xs = this % xs(t) % prompt_nu_fission(gin, iazi, ipol) + + case('delayed_nu_fission') + if (present(dg)) then + xs = this % xs(t) % delayed_nu_fission(gin, dg, iazi, ipol) + else + xs = sum(this % xs(t) % delayed_nu_fission(gin, :, iazi, ipol)) + end if + + case('nu_fission') + xs = this % xs(t) % prompt_nu_fission(gin, iazi, ipol) + & + sum(this % xs(t) % delayed_nu_fission(gin, :, iazi, ipol)) + + case('nu') + if (this % xs(t) % fission(gin, iazi, ipol) > ZERO) then + xs = (sum(this % xs(t) % delayed_nu_fission(gin, :, iazi, ipol)) + & + this % xs(t) % prompt_nu_fission(gin, iazi, ipol)) / & + this % xs(t) % fission(gin, iazi, ipol) else xs = ZERO end if - case('nu_fission') - xs = this % xs(t) % nu_fission(gin, iazi, ipol) - case('chi') + + case('nu_prompt') + if (this % xs(t) % fission(gin, iazi, ipol) > ZERO) then + xs = this % xs(t) % prompt_nu_fission(gin, iazi, ipol) / & + this % xs(t) % fission(gin, iazi, ipol) + else + xs = ZERO + end if + + case('nu_delayed') + if (this % xs(t) % fission(gin, iazi, ipol) > ZERO) then + if (present(dg)) then + xs = this % xs(t) % delayed_nu_fission(gin, dg, iazi, ipol) / & + this % xs(t) % fission(gin, iazi, ipol) + else + xs = sum(this % xs(t) % delayed_nu_fission(gin, :, iazi, ipol)) & + / this % xs(t) % fission(gin, iazi, ipol) + end if + else + xs = ZERO + end if + + case('chi_prompt') if (present(gout)) then - xs = this % xs(t) % chi(gout, gin, iazi, ipol) + xs = this % xs(t) % chi_prompt(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)) + xs = sum(this % xs(t) % chi_prompt(:, gin, iazi, ipol)) end if + + case('chi_delayed') + if (present(gout)) then + if (present(dg)) then + xs = this % xs(t) % chi_delayed(gout, gin, dg, iazi, ipol) + else + xs = this % xs(t) % chi_delayed(gout, gin, 1, iazi, ipol) + end if + else + if (present(dg)) then + xs = sum(this % xs(t) % chi_delayed(:, gin, dg, iazi, ipol)) + else + xs = sum(this % xs(t) % chi_delayed(:, gin, 1, iazi, ipol)) + end if + end if + + case('decay_rate') + if (present(dg)) then + xs = this % xs(t) % decay_rate(iazi, ipol, dg) + else + xs = this % xs(t) % decay_rate(iazi, ipol, 1) + end if + + case('inverse_velocity') + xs = this % xs(t) % inverse_velocity(gin, iazi, ipol) + case('scatter') if (present(gout)) then if (gout < this % xs(t) % scatter(iazi, ipol) % obj % gmin(gin) .or. & @@ -1900,6 +2943,7 @@ module mgxs_header 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. & @@ -1915,6 +2959,7 @@ module mgxs_header (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. & @@ -1936,60 +2981,150 @@ 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 + else xs = ZERO end if + end function mgxsang_get_xs !=============================================================================== ! MGXS*_SAMPLE_FISSION_ENERGY samples the outgoing energy from a fission event !=============================================================================== - function mgxsiso_sample_fission_energy(this, gin, uvw) result(gout) - class(MgxsIso), intent(in) :: this ! Data to work with - integer, intent(in) :: gin ! Incoming energy group - real(8), intent(in) :: uvw(3) ! Particle Direction - integer :: gout ! Sampled outgoing group - real(8) :: xi ! Our random number - real(8) :: prob ! Running probability + subroutine mgxsiso_sample_fission_energy(this, gin, uvw, dg, gout) - xi = prn() - gout = 1 - prob = this % xs(this % index_temp) % chi(gout,gin) + 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, intent(out) :: dg ! Delayed group + integer, intent(out) :: gout ! Sampled outgoing group + real(8) :: xi_pd ! Our random number for prompt/delayed + real(8) :: xi_gout ! Our random number for gout + real(8) :: prob_pd ! Running probability for prompt/delayed + real(8) :: prob_gout ! Running probability for gout - do while (prob < xi) - gout = gout + 1 - prob = prob + this % xs(this % index_temp) % chi(gout,gin) - end do + ! Get nu and nu_prompt + real(8) :: nu, nu_prompt + nu = this % get_xs('nu', gin) + nu_prompt = this % get_xs('nu_prompt', gin) - end function mgxsiso_sample_fission_energy + ! Sample random numbers + xi_pd = prn() + xi_gout = prn() - function mgxsang_sample_fission_energy(this, gin, uvw) result(gout) + ! Neutron is born prompt + if (xi_pd < nu_prompt / nu) then + + ! set the delayed group for the particle born from fission to 0 + dg = 0 + + gout = 1 + prob_gout = this % xs(this % index_temp) % chi_prompt(gout, gin) + + do while (prob_gout < xi_gout) + gout = gout + 1 + prob_gout = prob_gout + & + this % xs(this % index_temp) % chi_prompt(gout, gin) + end do + + ! Neutron is born delayed + else + + ! Get the delayed group + dg = 0 + prob_pd = nu_prompt / nu + + do while (xi_pd >= prob_pd) + dg = dg + 1 + prob_pd = prob_pd + & + this % get_xs('nu_delayed', gin, dg=dg) & + / nu + end do + + ! Adjust dg in case of round off error + dg = min(dg, num_delayed_groups) + + ! Get the outgoing group + gout = 1 + prob_gout = this % xs(this % index_temp) % chi_delayed(gout, gin, dg) + + do while (prob_gout < xi_gout) + gout = gout + 1 + prob_gout = prob_gout + & + this % xs(this % index_temp) % chi_delayed(gout, gin, dg) + end do + end if + + end subroutine mgxsiso_sample_fission_energy + + subroutine mgxsang_sample_fission_energy(this, gin, uvw, dg, 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 ! Angle indices + real(8), intent(in) :: uvw(3) ! Direction vector + integer, intent(out) :: dg ! Delayed group + integer, intent(out) :: gout ! Sampled outgoing group + real(8) :: xi_pd ! Our random number for prompt/delayed + real(8) :: xi_gout ! Our random number for gout + real(8) :: prob_pd ! Running probability for prompt/delayed + real(8) :: prob_gout ! Running probability for gout + real(8) :: nu, nu_prompt - call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + ! Get nu and nu_prompt + nu = this % get_xs('nu', gin, uvw=uvw) + nu_prompt = this % get_xs('nu_prompt', gin, uvw=uvw) - xi = prn() - gout = 1 - prob = this % xs(this % index_temp) % chi(gout, gin, iazi, ipol) + ! Sample random numbers + xi_pd = prn() + xi_gout = prn() - do while (prob < xi) - gout = gout + 1 - prob = prob + this % xs(this % index_temp) % chi(gout, gin, iazi, ipol) - end do + ! Neutron is born prompt + if (xi_pd < nu_prompt / nu) then - end function mgxsang_sample_fission_energy + ! set the delayed group for the particle born from fission to 0 + dg = 0 + + gout = 1 + prob_gout = this % get_xs('chi_prompt', gin, gout, uvw=uvw) + + do while (prob_gout < xi_gout) + gout = gout + 1 + prob_gout = prob_gout + & + this % get_xs('chi_prompt', gin, gout, uvw=uvw) + end do + + ! Neutron is born delayed + else + + ! Get the delayed group + dg = 0 + prob_pd = nu_prompt / nu + + do while (xi_pd < prob_pd) + dg = dg + 1 + prob_pd = prob_pd + & + this % get_xs('nu_delayed', gin, uvw=uvw, dg=dg) / nu + end do + + ! Adjust dg in case of round off error + dg = min(dg, num_delayed_groups) + + ! Get the outgoing group + gout = 1 + prob_gout = this % get_xs('chi_delayed', gin, gout, uvw=uvw, dg=dg) + + do while (prob_gout < xi_gout) + gout = gout + 1 + prob_gout = this % get_xs('chi_delayed', gin, gout, uvw=uvw, dg=dg) + end do + end if + + end subroutine mgxsang_sample_fission_energy !=============================================================================== ! MGXS*_SAMPLE_SCATTER Selects outgoing energy and angle after a scatter event @@ -2038,7 +3173,9 @@ module mgxs_header 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) + xs % nu_fission = & + this % xs(this % index_temp) % prompt_nu_fission(gin) + & + sum(this % xs(this % index_temp) % delayed_nu_fission(gin, :)) end subroutine mgxsiso_calculate_xs @@ -2060,7 +3197,9 @@ module mgxs_header xs % fission = this % xs(this % index_temp) % & fission(gin, iazi, ipol) xs % nu_fission = this % xs(this % index_temp) % & - nu_fission(gin, iazi, ipol) + prompt_nu_fission(gin, iazi, ipol) + & + sum(this % xs(this % index_temp) % & + delayed_nu_fission(gin, iazi, ipol, :)) end subroutine mgxsang_calculate_xs diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index c60fc6e2e1..776c7905aa 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -171,7 +171,10 @@ contains type(Bank), intent(inout) :: bank_array(:) integer(8), intent(inout) :: size_bank + integer :: nu_d(MAX_DELAYED_GROUPS) ! number of delayed neutrons born integer :: i ! loop index + integer :: dg ! delayed group + integer :: gout ! group out integer :: nu ! actual number of neutrons produced integer :: ijk(3) ! indices in ufs mesh real(8) :: nu_t ! total nu @@ -190,8 +193,10 @@ contains ! the expected number of fission sites produced if (ufs) then + ! Determine indices on ufs mesh for current location call get_mesh_indices(ufs_mesh, p % coord(1) % xyz, ijk, in_mesh) + if (.not. in_mesh) then call write_particle_restart(p) call fatal_error("Source site outside UFS mesh!") @@ -209,6 +214,7 @@ contains ! Determine expected number of neutrons produced nu_t = p % wgt / keff * weight * & material_xs % nu_fission / material_xs % total + ! Sample number of neutrons produced if (prn() > nu_t - int(nu_t)) then nu = int(nu_t) @@ -234,6 +240,10 @@ contains ! Bank source neutrons if (nu == 0 .or. size_bank == size(bank_array)) return + ! Initialize counter of delayed neutrons encountered for each delayed group + ! to zero. + nu_d(:) = 0 + p % fission = .true. ! Fission neutrons will be banked do i = int(size_bank,4) + 1, int(min(size_bank + nu, int(size(bank_array),8)),4) ! Bank source neutrons by copying particle data @@ -254,8 +264,19 @@ contains ! Sample secondary energy distribution for fission reaction and set energy ! in fission bank - bank_array(i) % E = & - real(xs % sample_fission_energy(p % g, bank_array(i) % uvw), 8) + call xs % sample_fission_energy(p % g, bank_array(i) % uvw, dg, gout) + + bank_array(i) % E = real(gout, 8) + bank_array(i) % delayed_group = dg + + ! Set delayed group on particle too + p % delayed_group = dg + + ! Increment the number of neutrons born delayed + if (p % delayed_group > 0) then + nu_d(p % delayed_group) = nu_d(p % delayed_group) + 1 + end if + end do ! increment number of bank sites @@ -264,6 +285,7 @@ contains ! Store total weight banked for analog fission tallies p % n_bank = nu p % wgt_bank = nu/weight + p % n_delayed_bank(:) = nu_d(:) end subroutine create_fission_sites diff --git a/src/source.F90 b/src/source.F90 index 9aeccde156..cc85bf6eca 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -199,10 +199,10 @@ contains if (.not. run_CE) then if (site % E <= energy_bins(1)) then site % E = real(1, 8) - else if (site % E > energy_bins(energy_groups + 1)) then - site % E = real(energy_groups, 8) + else if (site % E > energy_bins(num_energy_groups + 1)) then + site % E = real(num_energy_groups, 8) else - site % E = real(binary_search(energy_bins, energy_groups + 1, & + site % E = real(binary_search(energy_bins, num_energy_groups + 1, & site % E), 8) end if end if diff --git a/src/tally.F90 b/src/tally.F90 index 24c1b94950..c5a1b83522 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -164,6 +164,7 @@ contains case (SCORE_INVERSE_VELOCITY) + ! make sure the correct energy is used if (t % estimator == ESTIMATOR_TRACKLENGTH) then E = p % E @@ -382,7 +383,7 @@ contains ! neutrons were emitted with different energies, multiple ! outgoing energy bins may have been scored to. The following ! logic treats this special case and results to multiple bins - call score_fission_eout_ce(p, t, score_index, score_bin) + call score_fission_eout(p, t, score_index, score_bin) cycle SCORE_LOOP end if end if @@ -432,7 +433,7 @@ contains ! neutrons were emitted with different energies, multiple ! outgoing energy bins may have been scored to. The following ! logic treats this special case and results to multiple bins - call score_fission_eout_ce(p, t, score_index, score_bin) + call score_fission_eout(p, t, score_index, score_bin) cycle SCORE_LOOP end if end if @@ -504,7 +505,7 @@ contains ! neutrons were emitted with different energies, multiple ! outgoing energy bins may have been scored to. The following ! logic treats this special case and results to multiple bins - call score_fission_eout_ce(p, t, score_index, score_bin) + call score_fission_eout(p, t, score_index, score_bin) cycle SCORE_LOOP end if end if @@ -512,7 +513,8 @@ contains ! No fission events occur if survival biasing is on -- need to ! calculate fraction of absorptions that would have resulted in ! delayed-nu-fission - if (micro_xs(p % event_nuclide) % absorption > ZERO) then + if (micro_xs(p % event_nuclide) % absorption > ZERO .and. & + nuclides(p % event_nuclide) % fissionable) then ! Check if the delayed group filter is present if (dg_filter > 0) then @@ -572,7 +574,9 @@ contains d = filt % groups(d_bin) ! Compute the score and tally to bin - score = keff * p % wgt_bank / p % n_bank * p % n_delayed_bank(d) + score = keff * p % wgt_bank / p % n_bank * & + p % n_delayed_bank(d) + call score_fission_delayed_dg(t, d_bin, score, score_index) end do cycle SCORE_LOOP @@ -1106,6 +1110,11 @@ contains integer :: q ! loop index for scoring bins integer :: score_bin ! scoring bin, e.g. SCORE_FLUX integer :: score_index ! scoring bin index + integer :: d ! delayed neutron index + integer :: g ! delayed neutron index + integer :: k ! loop index for bank sites + integer :: d_bin ! delayed group bin index + integer :: dg_filter ! index of delayed group filter real(8) :: score ! analog tally score real(8) :: p_uvw(3) ! Particle's current uvw integer :: p_g ! Particle group to use for getting info @@ -1117,7 +1126,9 @@ contains ! this only depends on if we if (t % estimator == ESTIMATOR_ANALOG .or. & t % estimator == ESTIMATOR_COLLISION) then + if (survival_biasing) then + ! Then we either are alive and had a scatter (and so g changed), ! or are dead and g did not change if (p % alive) then @@ -1128,16 +1139,19 @@ contains p_g = p % g end if else if (p % event == EVENT_SCATTER) then + ! Then the energy group has been changed by the scattering routine ! meaning gin is now in p % last_g p_uvw = p % last_uvw p_g = p % last_g else + ! No scatter, no change in g. p_uvw = p % coord(p % n_coord) % uvw p_g = p % g end if else + ! No actual collision so g has not changed. p_uvw = p % coord(p % n_coord) % uvw p_g = p % g @@ -1146,6 +1160,7 @@ contains ! To significantly reduce de-referencing, point matxs to the ! macroscopic Mgxs for the material of interest matxs => macro_xs(p % material) % obj + ! Do same for nucxs, point it to the microscopic nuclide data of interest if (i_nuclide > 0) then nucxs => nuclides_MG(i_nuclide) % obj @@ -1172,6 +1187,7 @@ contains ! All events score to a flux bin. We actually use a collision ! estimator in place of an analog one since there is no way to count ! 'events' exactly for the flux + if (survival_biasing) then ! We need to account for the fact that some weight was already ! absorbed @@ -1199,6 +1215,7 @@ contains else score = p % last_wgt end if + if (i_nuclide > 0) then score = score * atom_density * & nucxs % get_xs('total', p_g, UVW=p_uvw) / & @@ -1228,20 +1245,21 @@ contains else score = p % last_wgt end if + 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 + score = score * nucxs % get_xs('inverse_velocity', p_g, UVW=p_uvw) & + / nucxs % get_xs('total', p_g, UVW=p_uvw) * flux else - score = matxs % get_xs('inv_vel', p_g, UVW=p_uvw) * flux + score = score * matxs % get_xs('inverse_velocity', p_g, UVW=p_uvw) & + / matxs % get_xs('total', p_g, UVW=p_uvw) * flux end if else - ! For inverse velocity, we need no cross section + if (i_nuclide > 0) then - score = score * nucxs % get_xs('inv_vel', p_g, UVW=p_uvw) * & - atom_density * flux + score = flux * nucxs % get_xs('inverse_velocity', p_g, UVW=p_uvw) else - score = flux * matxs % get_xs('inv_vel', p_g, UVW=p_uvw) + score = flux * matxs % get_xs('inverse_velocity', p_g, UVW=p_uvw) end if end if @@ -1358,6 +1376,14 @@ contains case (SCORE_FISSION) + + ! make sure the correct energy is used + if (t % estimator == ESTIMATOR_TRACKLENGTH) then + p_g = p % g + else + p_g = p % last_g + end if + if (t % estimator == ESTIMATOR_ANALOG) then if (survival_biasing) then ! No fission events occur if survival biasing is on -- need to @@ -1386,13 +1412,20 @@ contains score = nucxs % get_xs('fission', p_g, UVW=p_uvw) * & atom_density * flux else - score = flux * material_xs % fission - + score = matxs % get_xs('fission', p_g, UVW=p_uvw) * flux end if end if case (SCORE_NU_FISSION) + + ! make sure the correct energy is used + if (t % estimator == ESTIMATOR_TRACKLENGTH) then + p_g = p % g + else + p_g = p % last_g + end if + if (t % estimator == ESTIMATOR_ANALOG) then if (survival_biasing .or. p % fission) then if (t % find_filter(FILTER_ENERGYOUT) > 0) then @@ -1401,8 +1434,7 @@ contains ! neutrons were emitted with different energies, multiple ! outgoing energy bins may have been scored to. The following ! logic treats this special case and results to multiple bins - call score_fission_eout_mg(p, t, score_index, i_nuclide, & - atom_density) + call score_fission_eout(p, t, score_index, score_bin) cycle SCORE_LOOP end if end if @@ -1441,12 +1473,418 @@ contains score = nucxs % get_xs('nu_fission', p_g, UVW=p_uvw) * & atom_density * flux else - score = material_xs % nu_fission * flux + score = matxs % get_xs('nu_fission', p_g, UVW=p_uvw) * flux + end if + end if + + + case (SCORE_PROMPT_NU_FISSION) + + ! make sure the correct energy is used + if (t % estimator == ESTIMATOR_TRACKLENGTH) then + p_g = p % g + else + p_g = p % last_g + end if + + if (t % estimator == ESTIMATOR_ANALOG) then + if (survival_biasing .or. p % fission) then + if (t % find_filter(FILTER_ENERGYOUT) > 0) then + ! Normally, we only need to make contributions to one scoring + ! bin. However, in the case of fission, since multiple fission + ! neutrons were emitted with different energies, multiple + ! outgoing energy bins may have been scored to. The following + ! logic treats this special case and results to multiple bins + call score_fission_eout(p, t, score_index, score_bin) + cycle SCORE_LOOP + end if + end if + if (survival_biasing) then + ! No fission events occur if survival biasing is on -- need to + ! calculate fraction of absorptions that would have resulted in + ! nu-fission + score = p % absorb_wgt * flux + if (i_nuclide > 0) then + score = score * atom_density * & + nucxs % get_xs('prompt_nu_fission', p_g, UVW=p_uvw) / & + matxs % get_xs('absorption', p_g, UVW=p_uvw) + else + score = score * & + matxs % get_xs('prompt_nu_fission', p_g, UVW=p_uvw) / & + matxs % get_xs('absorption', p_g, UVW=p_uvw) + end if + else + ! Skip any non-fission events + if (.not. p % fission) cycle SCORE_LOOP + ! If there is no outgoing energy filter, than we only need to + ! score to one bin. For the score to be 'analog', we need to + ! score the number of particles that were banked in the fission + ! bank. Since this was weighted by 1/keff, we multiply by keff + ! to get the proper score. + score = keff * p % wgt_bank * (ONE - sum(p % n_delayed_bank) & + / real(p % n_bank, 8)) + if (i_nuclide > 0) then + score = score * atom_density * & + nucxs % get_xs('fission', p_g, UVW=p_uvw) / & + matxs % get_xs('fission', p_g, UVW=p_uvw) + end if + end if + + else + if (i_nuclide > 0) then + score = nucxs % get_xs('prompt_nu_fission', p_g, UVW=p_uvw) * & + atom_density * flux + else + score = matxs % get_xs('prompt_nu_fission', p_g, UVW=p_uvw) * flux + end if + end if + + + case (SCORE_DELAYED_NU_FISSION) + + ! make sure the correct energy is used + if (t % estimator == ESTIMATOR_TRACKLENGTH) then + p_g = p % g + else + p_g = p % last_g + end if + + ! Set the delayedgroup filter index and the number of delayed group bins + dg_filter = t % find_filter(FILTER_DELAYEDGROUP) + + if (t % estimator == ESTIMATOR_ANALOG) then + if (survival_biasing .or. p % fission) then + if (t % find_filter(FILTER_ENERGYOUT) > 0) then + ! Normally, we only need to make contributions to one scoring + ! bin. However, in the case of fission, since multiple fission + ! neutrons were emitted with different energies, multiple + ! outgoing energy bins may have been scored to. The following + ! logic treats this special case and results to multiple bins + call score_fission_eout(p, t, score_index, score_bin) + cycle SCORE_LOOP + end if + end if + if (survival_biasing) then + ! No fission events occur if survival biasing is on -- need to + ! calculate fraction of absorptions that would have resulted in + ! nu-fission + if (matxs % get_xs('absorption', p_g, UVW=p_uvw) > ZERO) then + + if (dg_filter > 0) then + select type(filt => t % filters(dg_filter) % obj) + type is (DelayedGroupFilter) + + ! Loop over all delayed group bins and tally to them + ! individually + do d_bin = 1, filt % n_bins + + ! Get the delayed group for this bin + d = filt % groups(d_bin) + + score = p % absorb_wgt * flux + if (i_nuclide > 0) then + score = score * nucxs % get_xs('delayed_nu_fission', & + p_g, UVW=p_uvw, dg=d) / & + nucxs % get_xs('absorption', p_g, UVW=p_uvw) + else + score = score * matxs % get_xs('delayed_nu_fission', & + p_g, UVW=p_uvw, dg=d) / & + matxs % get_xs('absorption', p_g, UVW=p_uvw) + end if + + call score_fission_delayed_dg(t, d_bin, score, score_index) + end do + cycle SCORE_LOOP + end select + else + score = p % absorb_wgt * flux + if (i_nuclide > 0) then + score = score * nucxs % get_xs('delayed_nu_fission', p_g, & + UVW=p_uvw) / nucxs % get_xs('absorption', p_g, UVW=p_uvw) + else + score = score * matxs % get_xs('delayed_nu_fission', p_g, & + UVW=p_uvw) / matxs % get_xs('absorption', p_g, UVW=p_uvw) + end if + end if + end if + else + ! Skip any non-fission events + if (.not. p % fission) cycle SCORE_LOOP + ! If there is no outgoing energy filter, than we only need to + ! score to one bin. For the score to be 'analog', we need to + ! score the number of particles that were banked in the fission + ! bank. Since this was weighted by 1/keff, we multiply by keff + ! to get the proper score. + + ! Check if the delayed group filter is present + if (dg_filter > 0) then + select type(filt => t % filters(dg_filter) % obj) + type is (DelayedGroupFilter) + + ! Loop over all delayed group bins and tally to them + ! individually + do d_bin = 1, filt % n_bins + + ! Get the delayed group for this bin + d = filt % groups(d_bin) + + score = keff * p % wgt_bank / p % n_bank * & + p % n_delayed_bank(d) + + if (i_nuclide > 0) then + score = score * atom_density * & + nucxs % get_xs('fission', p_g, UVW=p_uvw) / & + matxs % get_xs('fission', p_g, UVW=p_uvw) + end if + + call score_fission_delayed_dg(t, d_bin, score, score_index) + end do + cycle SCORE_LOOP + end select + else + score = keff * p % wgt_bank / p % n_bank * sum(p % n_delayed_bank) + if (i_nuclide > 0) then + score = score * atom_density * & + nucxs % get_xs('fission', p_g, UVW=p_uvw) / & + matxs % get_xs('fission', p_g, UVW=p_uvw) + end if + end if + end if + else + + ! Check if the delayed group filter is present + if (dg_filter > 0) then + select type(filt => t % filters(dg_filter) % obj) + type is (DelayedGroupFilter) + + ! Loop over all delayed group bins and tally to them + ! individually + do d_bin = 1, filt % n_bins + + ! Get the delayed group for this bin + d = filt % groups(d_bin) + + if (i_nuclide > 0) then + score = nucxs % get_xs('delayed_nu_fission', p_g, & + UVW=p_uvw, dg=d) * atom_density * flux + else + score = matxs % get_xs('delayed_nu_fission', p_g, & + UVW=p_uvw, dg=d) * flux + end if + + call score_fission_delayed_dg(t, d_bin, score, score_index) + end do + cycle SCORE_LOOP + end select + else + if (i_nuclide > 0) then + score = nucxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw) & + * atom_density * flux + else + score = matxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw) & + * flux + end if + end if + end if + + case (SCORE_DECAY_RATE) + + ! make sure the correct energy is used + if (t % estimator == ESTIMATOR_TRACKLENGTH) then + p_g = p % g + else + p_g = p % last_g + end if + + ! Set the delayedgroup filter index and the number of delayed group bins + dg_filter = t % find_filter(FILTER_DELAYEDGROUP) + + if (t % estimator == ESTIMATOR_ANALOG) then + if (survival_biasing) then + ! No fission events occur if survival biasing is on -- need to + ! calculate fraction of absorptions that would have resulted in + ! nu-fission + if (matxs % get_xs('absorption', p_g, UVW=p_uvw) > ZERO) then + + if (dg_filter > 0) then + select type(filt => t % filters(dg_filter) % obj) + type is (DelayedGroupFilter) + + ! Loop over all delayed group bins and tally to them + ! individually + do d_bin = 1, filt % n_bins + + ! Get the delayed group for this bin + d = filt % groups(d_bin) + + score = p % absorb_wgt * flux + if (i_nuclide > 0) then + score = score * nucxs % get_xs('decay_rate', p_g, & + UVW=p_uvw, dg=d) * & + nucxs % get_xs('delayed_nu_fission', p_g, & + UVW=p_uvw, dg=d) / nucxs % get_xs('absorption', & + p_g, UVW=p_uvw) + else + score = score * matxs % get_xs('decay_rate', p_g, & + UVW=p_uvw, dg=d) * & + matxs % get_xs('delayed_nu_fission', p_g, & + UVW=p_uvw, dg=d) / matxs % get_xs('absorption', & + p_g, UVW=p_uvw) + end if + + call score_fission_delayed_dg(t, d_bin, score, score_index) + end do + cycle SCORE_LOOP + end select + else + + score = ZERO + + ! If the delayed group filter is not present, compute the score + ! by accumulating the absorbed weight times the decay rate times + ! the fraction of the delayed-nu-fission xs to the absorption xs + ! for all delayed groups. + do d = 1, num_delayed_groups + if (i_nuclide > 0) then + score = score + p % absorb_wgt * & + nucxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=d) * & + nucxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw, & + dg=d) / nucxs % get_xs('absorption', p_g, UVW=p_uvw) + else + score = score + p % absorb_wgt * & + matxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=d) * & + matxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw, & + dg=d) / matxs % get_xs('absorption', p_g, UVW=p_uvw) + end if + end do + end if + end if + else + ! Skip any non-fission events + if (.not. p % fission) cycle SCORE_LOOP + ! If there is no outgoing energy filter, than we only need to + ! score to one bin. For the score to be 'analog', we need to + ! score the number of particles that were banked in the fission + ! bank. Since this was weighted by 1/keff, we multiply by keff + ! to get the proper score. + + score = ZERO + + ! loop over number of particles banked + do k = 1, p % n_bank + + ! get the delayed group + g = fission_bank(n_bank - p % n_bank + k) % delayed_group + + ! Case for tallying delayed emissions + if (g /= 0) then + + ! determine score based on bank site weight and keff. + if (i_nuclide > 0) then + score = score + keff * atom_density * & + fission_bank(n_bank - p % n_bank + k) % wgt * & + nucxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=g) * & + nucxs % get_xs('fission', p_g, UVW=p_uvw) / & + matxs % get_xs('fission', p_g, UVW=p_uvw) + else + score = score + keff * & + fission_bank(n_bank - p % n_bank + k) % wgt * & + matxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=g) + end if + + ! if the delayed group filter is present, tally to corresponding + ! delayed group bin if it exists + if (dg_filter > 0) then + + ! declare the delayed group filter type + select type(filt => t % filters(dg_filter) % obj) + type is (DelayedGroupFilter) + + ! loop over delayed group bins until the corresponding bin + ! is found + do d_bin = 1, filt % n_bins + d = filt % groups(d_bin) + + ! check whether the delayed group of the particle is equal + ! to the delayed group of this bin + if (d == g) then + call score_fission_delayed_dg(t, d_bin, score, & + score_index) + end if + end do + end select + + ! Reset the score to zero + score = ZERO + end if + end if + end do + + ! If the delayed group filter is present, cycle because the + ! score_fission_delayed_dg(...) has already tallied the score + if (dg_filter > 0) then + cycle SCORE_LOOP + end if + end if + else + + ! Check if the delayed group filter is present + if (dg_filter > 0) then + select type(filt => t % filters(dg_filter) % obj) + type is (DelayedGroupFilter) + + ! Loop over all delayed group bins and tally to them + ! individually + do d_bin = 1, filt % n_bins + + ! Get the delayed group for this bin + d = filt % groups(d_bin) + + if (i_nuclide > 0) then + score = nucxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=d) * & + nucxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw, & + dg=d) * atom_density * flux + else + score = matxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=d) * & + matxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw, & + dg=d) * flux + end if + + call score_fission_delayed_dg(t, d_bin, score, score_index) + end do + cycle SCORE_LOOP + end select + else + score = ZERO + + ! If the delayed group filter is not present, compute the score + ! by accumulating the absorbed weight times the decay rate times + ! the fraction of the delayed-nu-fission xs to the absorption xs + ! for all delayed groups. + do d = 1, num_delayed_groups + if (i_nuclide > 0) then + score = score + atom_density * flux * & + nucxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=d) * & + nucxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw, dg=d) + else + score = score + flux * & + matxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=d) * & + matxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw, dg=d) + end if + end do end if end if case (SCORE_KAPPA_FISSION) + + ! make sure the correct energy is used + if (t % estimator == ESTIMATOR_TRACKLENGTH) then + p_g = p % g + else + p_g = p % last_g + end if + if (t % estimator == ESTIMATOR_ANALOG) then if (survival_biasing) then ! No fission events occur if survival biasing is on -- need to @@ -1472,10 +1910,10 @@ contains end if else if (i_nuclide > 0) then - score = flux * atom_density * & - nucxs % get_xs('kappa_fission', p_g, UVW=p_uvw) + score = nucxs % get_xs('kappa_fission', p_g, UVW=p_uvw) * & + atom_density * flux else - score = flux * matxs % get_xs('kappa_fission', p_g, UVW=p_uvw) + score = matxs % get_xs('kappa_fission', p_g, UVW=p_uvw) * flux end if end if @@ -1931,7 +2369,7 @@ contains ! neutrons produced with different energies. !=============================================================================== - subroutine score_fission_eout_ce(p, t, i_score, score_bin) + subroutine score_fission_eout(p, t, i_score, score_bin) type(Particle), intent(in) :: p type(TallyObject), intent(inout) :: t @@ -1950,6 +2388,7 @@ contains real(8) :: filter_weight ! combined weight of all filters real(8) :: score ! actual score real(8) :: E_out ! energy of fission bank site + integer :: g_out ! energy group of fission bank site ! save original outgoing energy bin and score index i = t % find_filter(FILTER_ENERGYOUT) @@ -1976,14 +2415,31 @@ contains ! determine score based on bank site weight and keff score = keff * fission_bank(n_bank - p % n_bank + k) % wgt - ! determine outgoing energy from fission bank - E_out = fission_bank(n_bank - p % n_bank + k) % E + if (.not. run_CE .and. eo_filt % matches_transport_groups) then - ! check if outgoing energy is within specified range on filter - if (E_out < eo_filt % bins(1) .or. E_out > eo_filt % bins(n)) cycle + ! determine outgoing energy from fission bank + g_out = int(fission_bank(n_bank - p % n_bank + k) % E) - ! change outgoing energy bin - Matching_bins(i) = binary_search(eo_filt % bins, n, E_out) + ! change outgoing energy bin + matching_bins(i) = g_out + + else + + ! determine outgoing energy from fission bank + if (run_CE) then + E_out = fission_bank(n_bank - p % n_bank + k) % E + else + E_out = energy_bin_avg(int(fission_bank(n_bank - p % n_bank + k) & + % E)) + end if + + ! check if outgoing energy is within specified range on filter + if (E_out < eo_filt % bins(1) .or. E_out > eo_filt % bins(n)) cycle + + ! change outgoing energy bin + matching_bins(i) = binary_search(eo_filt % bins, n, E_out) + + end if ! Case for tallying prompt neutrons if (score_bin == SCORE_NU_FISSION .or. & @@ -2046,91 +2502,7 @@ contains ! reset outgoing energy bin and score index matching_bins(i) = bin_energyout - end subroutine score_fission_eout_ce - - subroutine score_fission_eout_mg(p, t, i_score, i_nuclide, atom_density) - type(Particle), intent(in) :: p - type(TallyObject), intent(inout) :: t - integer, intent(in) :: i_score ! index for score - integer, intent(in) :: i_nuclide ! index for nuclide - real(8), intent(in) :: atom_density - - integer :: i ! index of outgoing energy filter - integer :: n ! number of energies on filter - integer :: k ! loop index for bank sites - integer :: bin_energyout ! original outgoing energy bin - integer :: i_filter ! index for matching filter bin combination - real(8) :: filter_weight ! combined weight of all filters - real(8) :: score ! actual score - integer :: gout ! energy group of fission bank site - integer :: gin ! energy group of incident particle - real(8) :: E_out - - ! save original outgoing energy bin and score index - i = t % find_filter(FILTER_ENERGYOUT) - bin_energyout = matching_bins(i) - - ! Declare the filter type - select type(filt => t % filters(i) % obj) - type is (EnergyoutFilter) - - ! Get number of energies on filter - n = size(filt % bins) - - ! Since the creation of fission sites is weighted such that it is - ! expected to create n_particles sites, we need to multiply the - ! score by keff to get the true nu-fission rate. Otherwise, the sum - ! of all nu-fission rates would be ~1.0. - - ! loop over number of particles banked - do k = 1, p % n_bank - ! determine score based on bank site weight and keff - score = keff * fission_bank(n_bank - p % n_bank + k) % wgt - if (i_nuclide > 0) then - if (survival_biasing) then - gin = p % g - else - gin = p % last_g - end if - score = score * atom_density * & - nuclides_MG(i_nuclide) % obj % get_xs('fission', gin, & - UVW=p % last_uvw) / & - macro_xs(p % material) % obj % get_xs('fission', gin, & - UVW=p % last_uvw) - end if - - if (filt % matches_transport_groups) then - ! determine outgoing energy from fission bank - gout = int(fission_bank(n_bank - p % n_bank + k) % E) - - ! change outgoing energy bin - matching_bins(i) = gout - else - ! determine outgoing energy from fission bank - E_out = energy_bin_avg(int(fission_bank(n_bank - p % n_bank + k) % E)) - - ! check if outgoing energy is within specified range on filter - if (E_out < filt % bins(1) .or. E_out > filt % bins(n)) cycle - - ! change outgoing energy bin - matching_bins(i) = binary_search(filt % bins, n, E_out) - end if - - ! determine scoring index and weight for this filter combination - i_filter = sum((matching_bins(1:size(t%filters)) - 1) * t % stride) + 1 - filter_weight = product(filter_weights(:size(t % filters))) - - ! Add score to tally -!$omp atomic - t % results(i_score, i_filter) % value = & - t % results(i_score, i_filter) % value + score * filter_weight - end do - - ! reset outgoing energy bin and score index - matching_bins(i) = bin_energyout - end select - - end subroutine score_fission_eout_mg + end subroutine score_fission_eout !=============================================================================== ! SCORE_FISSION_DELAYED_DG helper function used to increment the tally when a diff --git a/src/tally_filter.F90 b/src/tally_filter.F90 index 4dd9bf129d..37265cc5ff 100644 --- a/src/tally_filter.F90 +++ b/src/tally_filter.F90 @@ -890,7 +890,7 @@ contains ! Tallies are ordered in increasing groups, group indices ! however are the opposite, so switch - next_bin = energy_groups - next_bin + 1 + next_bin = num_energy_groups - next_bin + 1 else ! Make sure the correct energy is used. @@ -959,7 +959,7 @@ contains ! Tallies are ordered in increasing groups, group indices ! however are the opposite, so switch - next_bin = energy_groups - next_bin + 1 + next_bin = num_energy_groups - next_bin + 1 else ! Check if energy of the particle is within energy bins. From 480d2ca6e578616793ffe5d592f40cbd36c7a2fc Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Thu, 13 Oct 2016 16:54:47 -0400 Subject: [PATCH 02/27] fixed issue in mgxs_header.F90 where nu cannot be calculated if a fission xs has not been given --- .../python/pincell_multigroup/build-xml.py | 6 +- examples/xml/pincell_multigroup/geometry.xml | 22 ++- examples/xml/pincell_multigroup/materials.xml | 58 ++------ examples/xml/pincell_multigroup/mgxs.h5 | Bin 16496 -> 16744 bytes examples/xml/pincell_multigroup/settings.xml | 50 ++----- examples/xml/pincell_multigroup/tallies.xml | 2 +- src/mgxs_header.F90 | 135 +++++------------- .../results_true.dat | 2 +- .../test_mgxs_library_ce_to_mg.py | 3 +- 9 files changed, 74 insertions(+), 204 deletions(-) diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index 31a6c52f75..216c565397 100644 --- a/examples/python/pincell_multigroup/build-xml.py +++ b/examples/python/pincell_multigroup/build-xml.py @@ -19,7 +19,7 @@ groups = openmc.mgxs.EnergyGroups(group_edges=[1E-11, 0.0635E-6, 10.0E-6, 1.0E-4, 1.0E-3, 0.5, 1.0, 20.0]) # Instantiate the 7-group (C5G7) cross section data -uo2_xsdata = openmc.XSdata('UO2', groups, delayed_groups=8) +uo2_xsdata = openmc.XSdata('UO2', groups) uo2_xsdata.order = 0 uo2_xsdata.set_total( [0.1779492, 0.3298048, 0.4803882, 0.5543674, 0.3118013, 0.3951678, @@ -42,8 +42,6 @@ uo2_xsdata.set_nu_fission([2.005998E-02, 2.027303E-03, 1.570599E-02, 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]) -uo2_xsdata.set_beta([2.13333e-4, 1.04514e-3, 6.03969e-4, 1.33963e-3, - 2.29386e-3, 7.05174e-4, 6.00381e-4, 2.07736e-4]) h2o_xsdata = openmc.XSdata('LWTR', groups) h2o_xsdata.order = 0 @@ -61,7 +59,7 @@ h2o_xsdata.set_scatter_matrix( [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, delayed_groups=8) +mg_cross_sections_file = openmc.MGXSLibrary(groups) mg_cross_sections_file.add_xsdatas([uo2_xsdata, h2o_xsdata]) mg_cross_sections_file.export_to_hdf5() diff --git a/examples/xml/pincell_multigroup/geometry.xml b/examples/xml/pincell_multigroup/geometry.xml index 94c70cb340..7f2fb36e82 100644 --- a/examples/xml/pincell_multigroup/geometry.xml +++ b/examples/xml/pincell_multigroup/geometry.xml @@ -1,16 +1,10 @@ + - - - - - - - - - - - - - - + + + + + + + diff --git a/examples/xml/pincell_multigroup/materials.xml b/examples/xml/pincell_multigroup/materials.xml index f75d7ef6f4..9b9ce21805 100644 --- a/examples/xml/pincell_multigroup/materials.xml +++ b/examples/xml/pincell_multigroup/materials.xml @@ -1,51 +1,11 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + diff --git a/examples/xml/pincell_multigroup/mgxs.h5 b/examples/xml/pincell_multigroup/mgxs.h5 index cbe338c1c7de692a9bed69901f1da186bc1d3348..debdf0257b3a70162986d343d179c444d985fccd 100644 GIT binary patch delta 1317 zcmZuwO-vI(6yBXSWp`<5AqHwoV3AUgf)td3mAC~BG)4^^jD(m#kxDfRl^+9*A=GHV z14-*UNc5r{v=9$$HYR!_XtcotjVF%vLP*r4df}{{7DMIjlpaGgRYVynh6;`aCq`!nM<>Ro z!;=(T);WM{;Ed$2k>KsXY;a@{{5qay;HK^~9fD?@CnN>*Wr$9~tYN$>aa=AT*Co4@ z8fRPz&L}_B5UGk6;YZe@8Yc{KaUXac%V>bq%=FM~idD{KAj;O#8`3IUhLFVwn}uVY zjM|`<%dN(}Hsy|1Goj|t&Si5-ca42Cy#XIgRR!Ch4z6N4adAnSDdK4%=52g|WUCgQc!MoMC*ONc^gqlSY zD3_Hyn6$G5A|^kw7Q;uA#-ErtXT4_4dR(rAOlYS~8aRmwg*`CQnnZkYR@XsK9Py`R z!?ZE=Zf`!*el?!y$Y+}LkZBT&^ygBU?NMTTE_X?;O`XjuxZHsiOtP_JCEMO1_4<8( VtLGOq^)elrdNU>eQ*ZrW^bfgsQp*4U delta 1109 zcmZ8fJ#5oJ6ux^Y>Ddiw=#W}fQm#K~LR*ng)DTn(hJ}$bQ56Z91)&TjY$=n4glGjr z+_waYp=_uNwY*drXxIW%Vd|I(Rq8-kP&TlA=Q!b_=-qes{N4B7_fB8Zj!A1dsOZ*w ziJv2s5Tdz%ZzbHHw|K-4q)TvK%hIU5UxRpo47sP243ijP1ZxqFm57Rs$YbHuX$;KBI~TE&t0ROIigwv&(B)ZvM} zsMXZ5nM}~9&iCX!s)pS7O_`%L=e{-!V+TS2S(EW(1~-N#)w--$r&ykzR8JPgb@wth zid8V<_%_YG*YGIwIu?}%5OR{T>`5%7813TY)J2s`*3-0iZl)M8?(UX!d9F=~O;DFE zu`wgggZj-0%ictuF2iB?^r!S0bOs>J;hVJI1#~Z|(L=wc-l-wCS3lGzG#+b?8X>qd4Eh2R|nfvl6ZZ2 zuuW_K&2MO%922M|Fcudj<(EFdVZpYG6f4u38glyWX%{^WXcQS#m$6)IK|QSGD6@m@ zYYcKF&rB{vkka)*m4?LT%Am^QWznxP9EX&iL*WO$1hy(1+FQZh8!gK4;i~ZVC}V+f YD==g2X1^KTm3}ii7Y5A8jrGBuf6M0rmH+?% diff --git a/examples/xml/pincell_multigroup/settings.xml b/examples/xml/pincell_multigroup/settings.xml index ab716d9e47..6b9080b5a5 100644 --- a/examples/xml/pincell_multigroup/settings.xml +++ b/examples/xml/pincell_multigroup/settings.xml @@ -1,39 +1,15 @@ - + - - multi-group - - - - 100 - 10 - 1000 - - - - - - - -0.63 -0.63 -1E50 - 0.63 0.63 1E50 - - - - - - true - true - - - false - - ./mgxs.h5 - + + 1000 + 100 + 10 + + + + -0.63 -0.63 -1 0.63 0.63 1 + + + ./mgxs.h5 + multi-group diff --git a/examples/xml/pincell_multigroup/tallies.xml b/examples/xml/pincell_multigroup/tallies.xml index df65b461db..0b8b8ef923 100644 --- a/examples/xml/pincell_multigroup/tallies.xml +++ b/examples/xml/pincell_multigroup/tallies.xml @@ -1,4 +1,4 @@ - + 100 100 1 diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index a26453a8f6..7c57846499 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -426,7 +426,7 @@ module mgxs_header integer(HSIZE_T) :: dims(2) real(8), allocatable :: temp_arr(:), temp_2d(:, :) real(8), allocatable :: temp_beta(:, :) - real(8) :: dmu, mu, norm + real(8) :: dmu, mu, norm, chi_sum integer :: order, order_dim, gin, gout, l, imu, length type(VectorInt) :: temps_to_read integer :: t, dg @@ -535,12 +535,12 @@ module mgxs_header end do ! Normalize chi_prompt so its CDF goes to 1 - if (sum(xs % chi_prompt(:, gin)) == ZERO) then + chi_sum =sum(xs % chi_prompt(:, gin)) + if (chi_sum == ZERO) then call fatal_error("Encountered chi for a group that sums to & &zero") else - xs % chi_prompt(:, gin) = xs % chi_prompt(:, gin) / & - sum(xs % chi_prompt(:, gin)) + xs % chi_prompt(:, gin) = xs % chi_prompt(:, gin) / chi_sum end if end do @@ -625,12 +625,12 @@ module mgxs_header ! Normalize chi so its CDF goes to 1 do gin = 1, energy_groups - if (sum(xs % chi_prompt(:, gin)) == ZERO) then + chi_sum = sum(xs % chi_prompt(:, gin)) + if (chi_sum == ZERO) then call fatal_error("Encountered chi for a group that sums to & &zero") else - xs % chi_prompt(:, gin) = xs % chi_prompt(:, gin) / & - sum(xs % chi_prompt(:, gin)) + xs % chi_prompt(:, gin) = xs % chi_prompt(:, gin) / chi_sum end if end do @@ -642,6 +642,11 @@ module mgxs_header call fatal_error("nu-fission must be provided as a 1D or 2D & &array") end if + + print *, xs % prompt_nu_fission + print *, xs % delayed_nu_fission + print *, xs % chi_prompt + print *, xs % chi_delayed end if ! If chi_prompt provided, set chi_prompt @@ -659,12 +664,12 @@ module mgxs_header end do ! Normalize chi so its CDF goes to 1 - if (sum(xs % chi_prompt(:, gin)) == ZERO) then + chi_sum = sum(xs % chi_prompt(:, gin)) + if (chi_sum == ZERO) then call fatal_error("Encountered chi prompt for a group that & &sums to zero") else - xs % chi_prompt(:, gin) = xs % chi_prompt(:, gin) / & - sum(xs % chi_prompt(:, gin)) + xs % chi_prompt(:, gin) = xs % chi_prompt(:, gin) / chi_sum end if end do @@ -695,13 +700,13 @@ module mgxs_header end do ! Normalize chi so its CDF goes to 1 - if (sum(xs % chi_delayed(:, gin, dg)) == ZERO) then + chi_sum = sum(xs % chi_delayed(:, gin, dg)) + if (chi_sum == ZERO) then call fatal_error("Encountered chi delayed for a group & &that sums to zero") else xs % chi_delayed(:, gin, dg) = & - xs % chi_delayed(:, gin, dg) / & - sum(xs % chi_delayed(:, gin, dg)) + xs % chi_delayed(:, gin, dg) / chi_sum end if end do end do @@ -726,13 +731,13 @@ module mgxs_header end do ! Normalize chi so its CDF goes to 1 - if (sum(xs % chi_delayed(:, gin, dg)) == ZERO) then + chi_sum = sum(xs % chi_delayed(:, gin, dg)) + if (chi_sum == ZERO) then call fatal_error("Encountered chi delayed for a group & &that sums to zero") else xs % chi_delayed(:, gin, dg) = & - xs % chi_delayed(:, gin, dg) / & - sum(xs % chi_delayed(:, gin, dg)) + xs % chi_delayed(:, gin, dg) / chi_sum end if end do end do @@ -1101,7 +1106,7 @@ module mgxs_header integer(HID_T) :: xsdata, xsdata_grp, scatt_grp, ndims integer(HSIZE_T) :: dims(4) integer, allocatable :: int_arr(:) - real(8), allocatable :: temp_1d(:), temp_2d(:, :), temp_3d(:, :, :) + real(8), allocatable :: temp_1d(:), temp_3d(:, :, :) real(8), allocatable :: temp_4d(:, :, :, :), temp_beta(:, :, :, :) real(8) :: dmu, mu, norm integer :: order, order_dim, gin, gout, l, imu, dg @@ -2713,36 +2718,6 @@ module mgxs_header xs = this % xs(t) % prompt_nu_fission(gin) + & sum(this % xs(t) % delayed_nu_fission(gin, :)) - case('nu') - if (this % xs(t) % fission(gin) > ZERO) then - xs = (sum(this % xs(t) % delayed_nu_fission(gin, :)) + & - this % xs(t) % prompt_nu_fission(gin)) / & - this % xs(t) % fission(gin) - else - xs = ZERO - end if - - case('nu_prompt') - if (this % xs(t) % fission(gin) > ZERO) then - xs = this % xs(t) % prompt_nu_fission(gin) / & - this % xs(t) % fission(gin) - else - xs = ZERO - end if - - case('nu_delayed') - if (this % xs(t) % fission(gin) > ZERO) then - if (present(dg)) then - xs = this % xs(t) % delayed_nu_fission(gin, dg) & - / this % xs(t) % fission(gin) - else - xs = sum(this % xs(t) % delayed_nu_fission(gin, :)) & - / this % xs(t) % fission(gin) - end if - else - xs = ZERO - end if - case('chi_prompt') if (present(gout)) then xs = this % xs(t) % chi_prompt(gout,gin) @@ -2868,36 +2843,6 @@ module mgxs_header xs = this % xs(t) % prompt_nu_fission(gin, iazi, ipol) + & sum(this % xs(t) % delayed_nu_fission(gin, :, iazi, ipol)) - case('nu') - if (this % xs(t) % fission(gin, iazi, ipol) > ZERO) then - xs = (sum(this % xs(t) % delayed_nu_fission(gin, :, iazi, ipol)) + & - this % xs(t) % prompt_nu_fission(gin, iazi, ipol)) / & - this % xs(t) % fission(gin, iazi, ipol) - else - xs = ZERO - end if - - case('nu_prompt') - if (this % xs(t) % fission(gin, iazi, ipol) > ZERO) then - xs = this % xs(t) % prompt_nu_fission(gin, iazi, ipol) / & - this % xs(t) % fission(gin, iazi, ipol) - else - xs = ZERO - end if - - case('nu_delayed') - if (this % xs(t) % fission(gin, iazi, ipol) > ZERO) then - if (present(dg)) then - xs = this % xs(t) % delayed_nu_fission(gin, dg, iazi, ipol) / & - this % xs(t) % fission(gin, iazi, ipol) - else - xs = sum(this % xs(t) % delayed_nu_fission(gin, :, iazi, ipol)) & - / this % xs(t) % fission(gin, iazi, ipol) - end if - else - xs = ZERO - end if - case('chi_prompt') if (present(gout)) then xs = this % xs(t) % chi_prompt(gout, gin, iazi, ipol) @@ -3006,20 +2951,20 @@ module mgxs_header integer, intent(out) :: gout ! Sampled outgoing group real(8) :: xi_pd ! Our random number for prompt/delayed real(8) :: xi_gout ! Our random number for gout - real(8) :: prob_pd ! Running probability for prompt/delayed real(8) :: prob_gout ! Running probability for gout ! Get nu and nu_prompt - real(8) :: nu, nu_prompt - nu = this % get_xs('nu', gin) - nu_prompt = this % get_xs('nu_prompt', gin) + real(8) :: prob_prompt + + prob_prompt = this % get_xs('prompt_nu_fission', gin) / & + this % get_xs('nu_fission', gin) ! Sample random numbers xi_pd = prn() xi_gout = prn() ! Neutron is born prompt - if (xi_pd < nu_prompt / nu) then + if (xi_pd <= prob_prompt) then ! set the delayed group for the particle born from fission to 0 dg = 0 @@ -3038,13 +2983,12 @@ module mgxs_header ! Get the delayed group dg = 0 - prob_pd = nu_prompt / nu - do while (xi_pd >= prob_pd) + do while (xi_pd >= prob_prompt) dg = dg + 1 - prob_pd = prob_pd + & - this % get_xs('nu_delayed', gin, dg=dg) & - / nu + prob_prompt = prob_prompt + & + this % get_xs('delayed_nu_fision', gin, dg=dg) & + / this % get_xs('nu_fission', gin) end do ! Adjust dg in case of round off error @@ -3071,20 +3015,19 @@ module mgxs_header integer, intent(out) :: gout ! Sampled outgoing group real(8) :: xi_pd ! Our random number for prompt/delayed real(8) :: xi_gout ! Our random number for gout - real(8) :: prob_pd ! Running probability for prompt/delayed real(8) :: prob_gout ! Running probability for gout - real(8) :: nu, nu_prompt + real(8) :: prob_prompt ! Get nu and nu_prompt - nu = this % get_xs('nu', gin, uvw=uvw) - nu_prompt = this % get_xs('nu_prompt', gin, uvw=uvw) + prob_prompt = this % get_xs('prompt_nu_fission', gin, uvw=uvw) / & + this % get_xs('nu_fission', gin, uvw=uvw) ! Sample random numbers xi_pd = prn() xi_gout = prn() ! Neutron is born prompt - if (xi_pd < nu_prompt / nu) then + if (xi_pd <= prob_prompt) then ! set the delayed group for the particle born from fission to 0 dg = 0 @@ -3103,12 +3046,12 @@ module mgxs_header ! Get the delayed group dg = 0 - prob_pd = nu_prompt / nu - do while (xi_pd < prob_pd) + do while (xi_pd < prob_prompt) dg = dg + 1 - prob_pd = prob_pd + & - this % get_xs('nu_delayed', gin, uvw=uvw, dg=dg) / nu + prob_prompt = prob_prompt + & + this % get_xs('delayed_nu_fission', gin, uvw=uvw, dg=dg) / & + this % get_xs('nu_fission', gin, uvw=uvw) end do ! Adjust dg in case of round off error 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 0b73724c9c..27db7f3f66 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.140724E+00 2.952379E-02 +1.133362E+00 1.746521E-02 diff --git a/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py b/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py index eee528e88e..74a424597c 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 @@ -20,8 +20,7 @@ class MGXSTestHarness(PyAPITestHarness): super(MGXSTestHarness, self)._build_inputs() # Initialize a two-group structure - energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625e-6, - 20.]) + energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625e-6, 20.]) # Initialize MGXS Library for a few cross section types self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) From 01c28052da5703aef176a4af864981351640e531 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Thu, 13 Oct 2016 17:11:50 -0400 Subject: [PATCH 03/27] updated test mg hdf5 file and failing tests --- src/mgxs_header.F90 | 2 +- tests/1d_mgxs.h5 | Bin 123864 -> 124016 bytes tests/test_mg_basic/results_true.dat | 2 +- tests/test_mg_max_order/results_true.dat | 2 +- tests/test_mg_nuclide/results_true.dat | 2 +- tests/test_mg_tallies/results_true.dat | 1306 +++++++++++----------- 6 files changed, 657 insertions(+), 657 deletions(-) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 7c57846499..5acdd64ebf 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -3142,7 +3142,7 @@ module mgxs_header xs % nu_fission = this % xs(this % index_temp) % & prompt_nu_fission(gin, iazi, ipol) + & sum(this % xs(this % index_temp) % & - delayed_nu_fission(gin, iazi, ipol, :)) + delayed_nu_fission(gin, :, iazi, ipol)) end subroutine mgxsang_calculate_xs diff --git a/tests/1d_mgxs.h5 b/tests/1d_mgxs.h5 index 65dcf36cf7ee6c22d854c4fbcf2160e63209280f..0119cd6d6adbcc2bf8e8736149938016ad2ed903 100644 GIT binary patch delta 85 zcmca{oc+TI_6ZtH1y3ewSxioH65m)E&MYXvAiw|uHy$&B=^4!rnYTY=X8eAC@&s2d l5k3YU1`dYQywsxf%J}r6{L+GAhRJ@+O3Vxl0TT~~0syzi8pr?u delta 40 ycmV+@0N4NU$OqWR2aqTN*yE8ZH~|H*V{HQi000n?!4;D*TN#4^1h)YM0oUI?V-5rW diff --git a/tests/test_mg_basic/results_true.dat b/tests/test_mg_basic/results_true.dat index 7cdda73b5d..571ccd6c2a 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.091835E+00 2.710745E-03 diff --git a/tests/test_mg_max_order/results_true.dat b/tests/test_mg_max_order/results_true.dat index 4db04e0897..7eb19c6c5a 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.066827E+00 2.533280E-02 diff --git a/tests/test_mg_nuclide/results_true.dat b/tests/test_mg_nuclide/results_true.dat index 7cdda73b5d..571ccd6c2a 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.091835E+00 2.710745E-03 diff --git a/tests/test_mg_tallies/results_true.dat b/tests/test_mg_tallies/results_true.dat index cb0498e511..89bc8bb91b 100644 --- a/tests/test_mg_tallies/results_true.dat +++ b/tests/test_mg_tallies/results_true.dat @@ -1,86 +1,86 @@ k-combined: -1.047136E+00 2.765964E-02 +1.091835E+00 2.710745E-03 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 +2.285316E+00 +1.101573E+00 +6.659973E-02 +9.094515E-04 +3.358002E+00 +2.327388E+00 +2.827777E-02 +1.662805E-04 +7.010661E-02 +1.022043E-03 +2.063821E+00 +9.042696E-01 +6.666307E-02 +9.208182E-04 +3.231731E+00 +2.187032E+00 +2.995736E-02 +1.847975E-04 +7.427068E-02 +1.135857E-03 +2.086322E+00 +8.970572E-01 +6.132378E-02 +7.702047E-04 +3.146080E+00 +2.035674E+00 +2.623893E-02 +1.420401E-04 +6.505189E-02 +8.730491E-04 +2.524366E+00 +1.329552E+00 +7.498352E-02 +1.132501E-03 +3.755775E+00 +2.891945E+00 +3.220368E-02 +2.089579E-04 +7.983977E-02 +1.284359E-03 +2.738986E+00 +1.533886E+00 +8.724759E-02 +1.561113E-03 +4.160515E+00 +3.545983E+00 +3.877084E-02 +3.094340E-04 +9.612117E-02 +1.901935E-03 +2.831125E+00 +1.623396E+00 +8.180217E-02 +1.363527E-03 +4.224769E+00 +3.602597E+00 +3.472263E-02 +2.494520E-04 +8.608478E-02 +1.533256E-03 +3.057419E+00 +1.915745E+00 +9.211311E-02 +1.726036E-03 +4.531753E+00 +4.181041E+00 +3.979766E-02 +3.227473E-04 +9.866688E-02 +1.983765E-03 +3.480936E+00 +2.540229E+00 +9.732605E-02 +2.014693E-03 +5.098077E+00 +5.454306E+00 +4.045679E-02 +3.560751E-04 +1.003010E-01 +2.188614E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -171,86 +171,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.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 +2.306652E+00 +1.096454E+00 +7.276779E-02 +1.108917E-03 +3.496473E+00 +2.513899E+00 +3.220790E-02 +2.243239E-04 +7.985025E-02 +1.378806E-03 +2.176409E+00 +9.684410E-01 +6.403617E-02 +8.625208E-04 +3.190516E+00 +2.077859E+00 +2.730895E-02 +1.642621E-04 +6.770470E-02 +1.009636E-03 +2.197130E+00 +9.819204E-01 +6.040879E-02 +7.544380E-04 +3.241373E+00 +2.141423E+00 +2.493183E-02 +1.311958E-04 +6.181133E-02 +8.063946E-04 +2.393048E+00 +1.171566E+00 +6.498294E-02 +8.947303E-04 +3.396864E+00 +2.367501E+00 +2.642090E-02 +1.580118E-04 +6.550305E-02 +9.712191E-04 +2.847922E+00 +1.657158E+00 +8.448507E-02 +1.438618E-03 +4.101609E+00 +3.400223E+00 +3.605495E-02 +2.657310E-04 +8.938789E-02 +1.633315E-03 +2.465716E+00 +1.254241E+00 +9.114707E-02 +1.699186E-03 +3.990102E+00 +3.257986E+00 +4.324307E-02 +3.870739E-04 +1.072088E-01 +2.379149E-03 +2.876619E+00 +1.694743E+00 +8.490588E-02 +1.460065E-03 +4.306090E+00 +3.770279E+00 +3.637566E-02 +2.686961E-04 +9.018301E-02 +1.651540E-03 +3.120676E+00 +2.040388E+00 +9.374630E-02 +1.838062E-03 +4.566041E+00 +4.338530E+00 +4.035292E-02 +3.439650E-04 +1.000435E-01 +2.114180E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -341,86 +341,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.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 +2.738229E+00 +1.533281E+00 +8.920521E-02 +1.618464E-03 +4.145383E+00 +3.466069E+00 +4.001789E-02 +3.332346E-04 +9.921286E-02 +2.048225E-03 +2.510750E+00 +1.291568E+00 +7.210702E-02 +1.075681E-03 +3.692580E+00 +2.798640E+00 +3.039981E-02 +1.930259E-04 +7.536759E-02 +1.186433E-03 +2.663343E+00 +1.446047E+00 +7.518114E-02 +1.144886E-03 +3.833104E+00 +2.987849E+00 +3.131945E-02 +1.987570E-04 +7.764759E-02 +1.221659E-03 +2.354708E+00 +1.181690E+00 +6.441840E-02 +8.629146E-04 +3.449134E+00 +2.503760E+00 +2.649790E-02 +1.458544E-04 +6.569393E-02 +8.964938E-04 +2.725032E+00 +1.539242E+00 +8.428396E-02 +1.439775E-03 +4.082279E+00 +3.415921E+00 +3.691684E-02 +2.761522E-04 +9.152470E-02 +1.697368E-03 +2.742259E+00 +1.507303E+00 +9.352321E-02 +1.756792E-03 +4.341383E+00 +3.776509E+00 +4.299801E-02 +3.721411E-04 +1.066012E-01 +2.287364E-03 +2.758328E+00 +1.567995E+00 +8.729189E-02 +1.582523E-03 +4.155658E+00 +3.551008E+00 +3.862915E-02 +3.125373E-04 +9.576989E-02 +1.921009E-03 +2.695304E+00 +1.591733E+00 +8.663333E-02 +1.670218E-03 +4.115542E+00 +3.716056E+00 +3.866770E-02 +3.407809E-04 +9.586546E-02 +2.094609E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -511,86 +511,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.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 +2.956860E+00 +1.872138E+00 +8.141436E-02 +1.355209E-03 +4.181302E+00 +3.632020E+00 +3.335279E-02 +2.324624E-04 +8.268866E-02 +1.428829E-03 +2.728975E+00 +1.529805E+00 +7.967207E-02 +1.290786E-03 +4.026605E+00 +3.295403E+00 +3.388731E-02 +2.387035E-04 +8.401385E-02 +1.467190E-03 +2.669199E+00 +1.464819E+00 +8.465445E-02 +1.461478E-03 +4.019722E+00 +3.287556E+00 +3.751790E-02 +2.891213E-04 +9.301485E-02 +1.777083E-03 +2.631443E+00 +1.470512E+00 +8.148599E-02 +1.360154E-03 +4.008888E+00 +3.332058E+00 +3.580301E-02 +2.600385E-04 +8.876327E-02 +1.598326E-03 +2.574029E+00 +1.376461E+00 +8.293561E-02 +1.395379E-03 +3.968622E+00 +3.209609E+00 +3.714994E-02 +2.860300E-04 +9.210262E-02 +1.758082E-03 +2.806197E+00 +1.619124E+00 +8.856837E-02 +1.579348E-03 +4.245051E+00 +3.651342E+00 +3.919197E-02 +3.103521E-04 +9.716524E-02 +1.907578E-03 +2.714275E+00 +1.569268E+00 +8.742660E-02 +1.566177E-03 +4.142304E+00 +3.570080E+00 +3.907342E-02 +3.130266E-04 +9.687132E-02 +1.924017E-03 +2.787773E+00 +1.747984E+00 +8.870710E-02 +1.637685E-03 +4.260751E+00 +3.907149E+00 +3.945308E-02 +3.189321E-04 +9.781259E-02 +1.960315E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -681,86 +681,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.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 +2.318477E+00 +1.094935E+00 +6.361208E-02 +8.495096E-04 +3.327542E+00 +2.275954E+00 +2.610300E-02 +1.479888E-04 +6.471490E-02 +9.096126E-04 +2.527779E+00 +1.283713E+00 +8.065932E-02 +1.310121E-03 +3.868442E+00 +3.001729E+00 +3.590329E-02 +2.621011E-04 +8.901191E-02 +1.611004E-03 +2.930403E+00 +1.742366E+00 +8.637033E-02 +1.498228E-03 +4.309597E+00 +3.742298E+00 +3.689461E-02 +2.751390E-04 +9.146960E-02 +1.691141E-03 +2.672087E+00 +1.514743E+00 +8.348892E-02 +1.426887E-03 +4.084409E+00 +3.472246E+00 +3.685052E-02 +2.754247E-04 +9.136028E-02 +1.692897E-03 +3.028585E+00 +1.980992E+00 +9.493567E-02 +1.835319E-03 +4.598943E+00 +4.418843E+00 +4.191487E-02 +3.600577E-04 +1.039159E-01 +2.213094E-03 +2.899624E+00 +1.743612E+00 +8.682218E-02 +1.533415E-03 +4.351883E+00 +3.877967E+00 +3.749851E-02 +2.847704E-04 +9.296680E-02 +1.750341E-03 +2.726144E+00 +1.551860E+00 +8.139408E-02 +1.361697E-03 +4.087576E+00 +3.460075E+00 +3.510993E-02 +2.530784E-04 +8.704500E-02 +1.555546E-03 +2.683816E+00 +1.494662E+00 +7.499045E-02 +1.158079E-03 +3.903804E+00 +3.169221E+00 +3.113122E-02 +1.996036E-04 +7.718092E-02 +1.226863E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -851,86 +851,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.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 +2.555507E+00 +1.312958E+00 +7.812870E-02 +1.249917E-03 +3.851310E+00 +3.003452E+00 +3.407125E-02 +2.419178E-04 +8.446988E-02 +1.486947E-03 +2.861514E+00 +1.673522E+00 +8.255707E-02 +1.456184E-03 +4.150036E+00 +3.550595E+00 +3.479322E-02 +2.715473E-04 +8.625980E-02 +1.669065E-03 +3.034899E+00 +1.867035E+00 +8.864020E-02 +1.579275E-03 +4.525059E+00 +4.139892E+00 +3.777795E-02 +2.879498E-04 +9.365959E-02 +1.769883E-03 +2.894954E+00 +1.707984E+00 +8.118137E-02 +1.328540E-03 +4.162382E+00 +3.508790E+00 +3.367485E-02 +2.285599E-04 +8.348713E-02 +1.404843E-03 +3.105518E+00 +1.983253E+00 +9.193688E-02 +1.728073E-03 +4.586812E+00 +4.301208E+00 +3.938176E-02 +3.201474E-04 +9.763577E-02 +1.967785E-03 +3.230900E+00 +2.172193E+00 +9.652802E-02 +1.921544E-03 +4.820349E+00 +4.800592E+00 +4.157146E-02 +3.620584E-04 +1.030645E-01 +2.225391E-03 +3.022632E+00 +1.928131E+00 +8.052749E-02 +1.336450E-03 +4.351296E+00 +3.937284E+00 +3.248944E-02 +2.201600E-04 +8.054825E-02 +1.353213E-03 +2.963848E+00 +1.888793E+00 +7.561691E-02 +1.171119E-03 +4.111126E+00 +3.512823E+00 +2.951728E-02 +1.819387E-04 +7.317963E-02 +1.118286E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -1021,86 +1021,86 @@ tally 1: 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 +2.781010E+00 +1.630536E+00 +8.470226E-02 +1.463340E-03 +4.203914E+00 +3.669913E+00 +3.688480E-02 +2.768423E-04 +9.144528E-02 +1.701611E-03 +3.010930E+00 +1.861129E+00 +8.189326E-02 +1.395901E-03 +4.327707E+00 +3.862532E+00 +3.342757E-02 +2.352194E-04 +8.287407E-02 +1.445775E-03 +2.859838E+00 +1.733557E+00 +7.949062E-02 +1.305315E-03 +4.120074E+00 +3.531936E+00 +3.281638E-02 +2.253353E-04 +8.135879E-02 +1.385023E-03 +3.274289E+00 +2.303643E+00 +9.332701E-02 +1.798878E-03 +4.786796E+00 +4.819112E+00 +3.916394E-02 +3.222382E-04 +9.709574E-02 +1.980636E-03 +2.759328E+00 +1.580882E+00 +9.004840E-02 +1.668745E-03 +4.191387E+00 +3.621622E+00 +4.045290E-02 +3.368932E-04 +1.002914E-01 +2.070713E-03 +2.984716E+00 +1.923142E+00 +8.511031E-02 +1.484773E-03 +4.406789E+00 +4.076262E+00 +3.576644E-02 +2.604056E-04 +8.867263E-02 +1.600582E-03 +3.186003E+00 +2.068943E+00 +9.154230E-02 +1.730292E-03 +4.638429E+00 +4.403404E+00 +3.853991E-02 +3.119206E-04 +9.554864E-02 +1.917219E-03 +2.681828E+00 +1.458603E+00 +8.088140E-02 +1.321169E-03 +4.008235E+00 +3.236545E+00 +3.502783E-02 +2.504996E-04 +8.684145E-02 +1.539695E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -1191,86 +1191,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.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 +2.638841E+00 +1.519548E+00 +6.861172E-02 +9.797618E-04 +3.768518E+00 +3.016030E+00 +2.726695E-02 +1.518527E-04 +6.760057E-02 +9.333621E-04 +2.632274E+00 +1.403795E+00 +7.627151E-02 +1.185466E-03 +3.895015E+00 +3.065040E+00 +3.234595E-02 +2.142801E-04 +8.019249E-02 +1.317072E-03 +2.977161E+00 +1.841128E+00 +8.486243E-02 +1.521976E-03 +4.385376E+00 +3.996789E+00 +3.565106E-02 +2.762516E-04 +8.838657E-02 +1.697979E-03 +2.821184E+00 +1.758711E+00 +9.228589E-02 +1.823903E-03 +4.398002E+00 +4.172387E+00 +4.165874E-02 +3.718428E-04 +1.032809E-01 +2.285530E-03 +2.732368E+00 +1.579739E+00 +8.774594E-02 +1.648818E-03 +4.190617E+00 +3.720228E+00 +3.921586E-02 +3.357760E-04 +9.722447E-02 +2.063846E-03 +3.155807E+00 +2.031570E+00 +8.820313E-02 +1.586850E-03 +4.562308E+00 +4.224783E+00 +3.658589E-02 +2.767670E-04 +9.070421E-02 +1.701147E-03 +3.340158E+00 +2.263933E+00 +7.925393E-02 +1.269551E-03 +4.491834E+00 +4.077177E+00 +2.930432E-02 +1.760158E-04 +7.265165E-02 +1.081880E-03 +2.788760E+00 +1.635894E+00 +7.851904E-02 +1.285342E-03 +4.005348E+00 +3.359993E+00 +3.265021E-02 +2.226228E-04 +8.094683E-02 +1.368351E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -2892,15 +2892,15 @@ tally 1: 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 +4.194996E+01 +3.529246E+02 +4.196155E+01 +3.531197E+02 +6.665335E+00 +8.998861E+00 +6.665580E+00 +8.999524E+00 +1.218023E+02 +3.020889E+03 +1.218023E+02 +3.020889E+03 From 7d0170d255b2d8606c939f5af982d7ab443e4eb6 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Thu, 13 Oct 2016 17:53:53 -0400 Subject: [PATCH 04/27] removed unnecessary print statements --- src/mgxs_header.F90 | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 5acdd64ebf..784a22930f 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -642,11 +642,6 @@ module mgxs_header call fatal_error("nu-fission must be provided as a 1D or 2D & &array") end if - - print *, xs % prompt_nu_fission - print *, xs % delayed_nu_fission - print *, xs % chi_prompt - print *, xs % chi_delayed end if ! If chi_prompt provided, set chi_prompt From a73ff74bb5ed3053ee4b6bca5d84a2a085e30e6c Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Fri, 14 Oct 2016 14:26:33 -0400 Subject: [PATCH 05/27] changed underscores to hyphens --- examples/xml/pincell_multigroup/mgxs.h5 | Bin 16744 -> 16568 bytes openmc/mgxs_library.py | 6 +- src/mgxs_data.F90 | 1 + src/mgxs_header.F90 | 235 ++++++++++++------------ src/tally.F90 | 84 ++++----- 5 files changed, 163 insertions(+), 163 deletions(-) diff --git a/examples/xml/pincell_multigroup/mgxs.h5 b/examples/xml/pincell_multigroup/mgxs.h5 index debdf0257b3a70162986d343d179c444d985fccd..4916f9915c62a087bee867618d73e47328fb6dd4 100644 GIT binary patch delta 823 zcmZ9JJ#5oZ5XbXgqGDTVF&RSICc#Pb;eJH13=Kih5;3(C=>k<5(ufaL8L9{}m@P0= z9y-*z#X<}jBc_-qp(vBbs#Dn5nyHGIVChgXVD~-8gty%NPw(!2y8rki>VH5dGVWKb zm7^fEd5-jhT5!I(5V(GbhQQV`O%BNRjSGZoMB)F0Lg%w+mnd^RL?p2@W7rj9N6lcQ z$C|1vN*UM-C56!{)fEJdbW)HCOcr5K(m-8IU(W+OdxU1-d~q3+xCUHYjCc@wigt9D z;4J>kuw{@E#}uNM2qT)=NiQ4TVHx~NnZm!#d=8JYWRQ;H*y$33WZ~V*daL#NZ4Jhm zEyLzOTPV+awO934-TmhA>>Ji|P_hj?x(T1Nl81kS%CM8mV>xeFNr7X7hZ)1VaDY`9 zTE|M}~iVOW>Yo87}dLW>833#?a_t95Wg%=yCi9@*i*g=A3j>G1rlkwhNDx|)-jc_^QZ*=WxPHFuw DD&fVq delta 888 zcmY+CL2S}c7{_@J;#z_mGlsDNTOmNlfUKg!2+R&=lo^eBPzmuc(3!8PzU5f{#6;nwI0;crpt?54KbDlYzn#v@1IUd|dW-?RvnVZQ>60Ekn5U@D*7+}&h zhdN;0;(=MKvG~Odly$}tBkXC1QmCpW(l0xqY`qGMZC)`V*bGRiR{GVdHb5#6Yzwfh zH9{;Hrn(ftF$i0F6@Xt%Nxx6GO1trxTUxT4uzAf%ILM;9fbH-!G@R!!V}yu{QH>N( z2{v6U&a*|aUr&)koU16-Wz+y9SPoZ=FmEF#1ok)Nf@BT?`y5ib9^`|pZWwXmk_ls@ z4|3jHbTdKN^nONu;OHXlSJWHBP^DQZ>hFd3ZOn1xTq$>~H zaSAghyMMO`iKhf oK4NdigyUnoG)6atVvrmipw*c)Byn^C;h94%19C=KXzTO;0rMUG!T extract chi + ! chi is embedded in nu-fission -> extract chi allocate(temp_arr(energy_groups * energy_groups)) call read_dataset(temp_arr, xsdata_grp, "nu-fission") allocate(temp_2d(energy_groups, energy_groups)) temp_2d = reshape(temp_arr, (/energy_groups, energy_groups/)) - ! Deallocate temporary 1D array for nu_fission matrix + ! Deallocate temporary 1D array for nu-fission matrix deallocate(temp_arr) ! Set the vector nu-fission from the matrix nu-fission @@ -602,17 +603,17 @@ module mgxs_header xs % prompt_nu_fission(gin) = sum(temp_2d(:, gin)) end do - ! Set delayed_nu_fission and correct prompt_nu_fission with + ! Set delayed-nu-fission and correct prompt-nu-fission with ! beta do gin = 1, energy_groups do dg = 1, delayed_groups - ! Set delayed_nu_fission using delayed neutron fraction + ! Set delayed-nu-fission using delayed neutron fraction xs % delayed_nu_fission(gin, dg) = temp_beta(gin, dg) * & xs % prompt_nu_fission(gin) end do - ! Correct prompt_nu_fission using delayed neutron fraction + ! Correct prompt-nu-fission using delayed neutron fraction xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(gin, :))) * & xs % prompt_nu_fission(gin) end do @@ -620,7 +621,7 @@ module mgxs_header ! Now pull out information needed for chi xs % chi_prompt(:, :) = temp_2d - ! Deallocate temporary 2D array for nu_fission matrix + ! Deallocate temporary 2D array for nu-fission matrix deallocate(temp_2d) ! Normalize chi so its CDF goes to 1 @@ -634,7 +635,7 @@ module mgxs_header end if end do - ! Set chi_delayed to chi_prompt + ! Set chi-delayed to chi-prompt do dg = 1, delayed_groups xs % chi_delayed(:, :, dg) = xs % chi_prompt(:, :) end do @@ -644,13 +645,13 @@ module mgxs_header end if end if - ! If chi_prompt provided, set chi_prompt + ! If chi-prompt provided, set chi-prompt if (object_exists(xsdata_grp, "chi-prompt")) then - ! Allocate temporary array for chi_prompt + ! Allocate temporary array for chi-prompt allocate(temp_arr(energy_groups)) - ! Get array with chi_prompt + ! Get array with chi-prompt call read_dataset(temp_arr, xsdata_grp, "chi-prompt") do gin = 1, energy_groups @@ -668,21 +669,21 @@ module mgxs_header end if end do - ! Deallocate temporary array for chi_prompt + ! Deallocate temporary array for chi-prompt deallocate(temp_arr) end if - ! If chi_delayed provided, set chi_delayed + ! If chi-delayed provided, set chi-delayed if (object_exists(xsdata_grp, "chi-delayed")) then - ! Get the dimensions of the nu-fission dataset + ! Get the dimensions of the chi-delayed dataset xsdata = open_dataset(xsdata_grp, "chi-delayed") call get_ndims(xsdata, ndims) ! If chi-delayed is a vector if (ndims == 1) then - ! Allocate temporary array for chi_delayed + ! Allocate temporary array for chi-delayed allocate(temp_arr(energy_groups)) ! Get chi-delayed @@ -706,12 +707,12 @@ module mgxs_header end do end do - ! Deallocate temporary array for chi_delayed + ! Deallocate temporary array for chi-delayed deallocate(temp_arr) else if (ndims == 2) then - ! Allocate temporary array for chi_delayed + ! Allocate temporary array for chi-delayed allocate(temp_arr(delayed_groups * energy_groups)) ! Get chi-delayed @@ -737,7 +738,7 @@ module mgxs_header end do end do - ! Deallocate temporary arrays for chi_delayed + ! Deallocate temporary arrays for chi-delayed deallocate(temp_arr) deallocate(temp_2d) @@ -747,16 +748,16 @@ module mgxs_header end if end if - ! If prompt-nu-fission present, set prompt_nu_fission + ! If prompt-nu-fission present, set prompt-nu-fission if (object_exists(xsdata_grp, "prompt-nu-fission")) then - ! Set prompt_nu_fission + ! Set prompt-nu-fission call read_dataset(xs % prompt_nu_fission, xsdata_grp, & "prompt-nu-fission") end if - ! If delayed-nu-fission provided, set delayed_nu_fission. If - ! delayed-nu-fission is a matrix, set chi_delayed. + ! If delayed-nu-fission provided, set delayed-nu-fission. If + ! delayed-nu-fission is a matrix, set chi-delayed. if (object_exists(xsdata_grp, "delayed-nu-fission")) then ! Get the dimensions of the delayed-nu-fission dataset @@ -772,26 +773,26 @@ module mgxs_header &array if beta not provided") end if - ! Allocate temporary array for delayed_nu_fission + ! Allocate temporary array for delayed-nu-fission allocate(temp_arr(energy_groups)) - ! Get delayed_nu_fission + ! Get delayed-nu-fission call read_dataset(temp_arr, xsdata_grp, "delayed-nu-fission") do gin = 1, energy_groups do dg = 1, delayed_groups - ! Set delayed_nu_fission using delayed neutron fraction + ! Set delayed-nu-fission using delayed neutron fraction xs % delayed_nu_fission(gin, dg) = temp_beta(gin, dg) * & temp_arr(gin) end do end do - ! Deallocate temporary delayed_nu_fission array + ! Deallocate temporary delayed-nu-fission array deallocate(temp_arr) ! If delayed-nu-fission is a (delayed_group, energy_group) - ! matrix, set delayed_nu_fission separately for each delayed + ! matrix, set delayed-nu-fission separately for each delayed ! group. else if (ndims == 2) then @@ -822,13 +823,13 @@ module mgxs_header &be set as a group by group matrix.") end if - ! Get delayed_nu_fission + ! Get delayed-nu-fission allocate(temp_arr(delayed_groups * energy_groups)) call read_dataset(temp_arr, xsdata_grp, "delayed-nu-fission") xs % delayed_nu_fission = reshape(temp_arr, (/energy_groups, & delayed_groups/)) - ! Deallocate temporary array for delayed_nu_fission matrix + ! Deallocate temporary array for delayed-nu-fission matrix deallocate(temp_arr) else @@ -840,7 +841,7 @@ module mgxs_header ! Deallocate temporary beta array deallocate(temp_beta) - ! chi_prompt, chi_delayed, prompt_nu_fission, and delayed_nu_fission + ! chi-prompt, chi-delayed, prompt-nu-fission, and delayed-nu-fission ! have been set; Now we will check for the rest of the XS that are ! unique to fissionable isotopes @@ -849,14 +850,14 @@ module mgxs_header call read_dataset(xs % fission, xsdata_grp, "fission") end if - ! Get kappa_fission xs - if (object_exists(xsdata_grp, "kappa_fission")) then - call read_dataset(xs % kappa_fission, xsdata_grp, "kappa_fission") + ! Get kappa-fission xs + if (object_exists(xsdata_grp, "kappa-fission")) then + call read_dataset(xs % kappa_fission, xsdata_grp, "kappa-fission") end if ! Get decay rate xs - if (object_exists(xsdata_grp, "decay_rate")) then - call read_dataset(xs % decay_rate, xsdata_grp, "decay_rate") + if (object_exists(xsdata_grp, "decay rate")) then + call read_dataset(xs % decay_rate, xsdata_grp, "decay rate") end if end if @@ -870,11 +871,9 @@ module mgxs_header end if ! Get inverse velocity - if (object_exists(xsdata_grp, "inverse_velocity")) then + if (object_exists(xsdata_grp, "inverse-velocity")) then call read_dataset(xs % inverse_velocity, xsdata_grp, & - "inverse_velocity") - else - xs % inverse_velocity = ZERO + "inverse-velocity") end if ! Get scattering data @@ -1080,6 +1079,7 @@ module mgxs_header deallocate(scatt_coeffs, temp_mult) end associate ! xs end do ! Temperatures + end subroutine mgxsiso_from_hdf5 subroutine mgxsang_from_hdf5(this, xs_id, energy_groups, delayed_groups, & @@ -1213,7 +1213,7 @@ module mgxs_header temp_beta = ZERO end if - ! If chi provided, set chi_prompt and chi_delayed + ! If chi provided, set chi-prompt and chi-delayed if (object_exists(xsdata_grp, "chi")) then ! Allocate temporary array for chi @@ -1233,7 +1233,7 @@ module mgxs_header temp_3d(gout, iazi, ipol) end do - ! Normalize chi_prompt so its CDF goes to 1 + ! Normalize chi-prompt so its CDF goes to 1 if (sum(xs % chi_prompt(:, gin, iazi, ipol)) == ZERO) then call fatal_error("Encountered chi for a group that sums& & to zero") @@ -1246,7 +1246,7 @@ module mgxs_header end do end do - ! Set chi_delayed to chi_prompt + ! Set chi-delayed to chi-prompt do ipol = 1, this % n_pol do iazi = 1, this % n_azi do dg = 1, delayed_groups @@ -1261,14 +1261,14 @@ module mgxs_header deallocate(temp_3d) end if - ! If chi_prompt provided, set chi_prompt + ! If chi-prompt provided, set chi-prompt if (object_exists(xsdata_grp, "chi-prompt")) then - ! Allocate temporary array for chi_prompt + ! Allocate temporary array for chi-prompt allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) allocate(temp_3d(energy_groups, this % n_azi, this % n_pol)) - ! Get array with chi_prompt + ! Get array with chi-prompt call read_dataset(temp_1d, xsdata_grp, "chi-prompt") temp_3d = reshape(temp_1d, (/energy_groups, this % n_azi, & this % n_pol/)) @@ -1294,26 +1294,26 @@ module mgxs_header end do end do - ! Deallocate temporary arrays for chi_prompt + ! Deallocate temporary arrays for chi-prompt deallocate(temp_1d) deallocate(temp_3d) end if - ! If chi_delayed provided, set chi_delayed + ! If chi-delayed provided, set chi-delayed if (object_exists(xsdata_grp, "chi-delayed")) then - ! Get the dimensions of the nu-fission dataset + ! Get the dimensions of the chi-delayed dataset xsdata = open_dataset(xsdata_grp, "chi-delayed") call get_ndims(xsdata, ndims) ! If chi-delayed is a vector if (ndims == 1) then - ! Allocate temporary array for chi_prompt + ! Allocate temporary array for chi-prompt allocate(temp_1d(delayed_groups * this % n_azi * this % n_pol)) allocate(temp_3d(delayed_groups, this % n_azi, this % n_pol)) - ! Get array with chi_prompt + ! Get array with chi-prompt call read_dataset(temp_1d, xsdata_grp, "chi-delayed") temp_3d = reshape(temp_1d, (/delayed_groups, this % n_azi, & this % n_pol/)) @@ -1342,13 +1342,13 @@ module mgxs_header end do end do - ! Deallocate temporary arrays for chi_delayed + ! Deallocate temporary arrays for chi-delayed deallocate(temp_1d) deallocate(temp_3d) else if (ndims == 2) then - ! Allocate temporary array for chi_delayed + ! Allocate temporary array for chi-delayed allocate(temp_1d(delayed_groups * energy_groups * this % n_azi & * this % n_pol)) allocate(temp_4d(energy_groups, delayed_groups, this % n_azi, & @@ -1383,7 +1383,7 @@ module mgxs_header end do end do - ! Deallocate temporary arrays for chi_delayed + ! Deallocate temporary arrays for chi-delayed deallocate(temp_1d) deallocate(temp_4d) @@ -1393,7 +1393,7 @@ module mgxs_header end if end if - ! If prompt-nu-fission present, set prompt_nu_fission + ! If prompt-nu-fission present, set prompt-nu-fission if (object_exists(xsdata_grp, "prompt-nu-fission")) then ! Allocate temporary array for prompt-nu-fission @@ -1404,12 +1404,12 @@ module mgxs_header xs % prompt_nu_fission = reshape(temp_1d, (/energy_groups, & this % n_azi, this % n_pol/)) - ! Deallocate temporary array for prompt_nu_fission + ! Deallocate temporary array for prompt-nu-fission deallocate(temp_1d) end if - ! If delayed-nu-fission provided, set delayed_nu_fission. If - ! delayed-nu-fission is a matrix, set chi_delayed. + ! If delayed-nu-fission provided, set delayed-nu-fission. If + ! delayed-nu-fission is a matrix, set chi-delayed. if (object_exists(xsdata_grp, "delayed-nu-fission")) then ! Get the dimensions of the delayed-nu-fission dataset @@ -1425,11 +1425,11 @@ module mgxs_header &array if beta not provided") end if - ! Allocate temporary arrays for delayed_nu_fission + ! Allocate temporary arrays for delayed-nu-fission allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) allocate(temp_3d(energy_groups, this % n_azi, this % n_pol)) - ! Get delayed_nu_fission + ! Get delayed-nu-fission call read_dataset(temp_1d, xsdata_grp, "delayed-nu-fission") temp_3d = reshape(temp_1d, (/energy_groups, this % n_azi, & this % n_pol/)) @@ -1439,7 +1439,7 @@ module mgxs_header do gin = 1, energy_groups do dg = 1, delayed_groups - ! Set delayed_nu_fission using delayed neutron fraction + ! Set delayed-nu-fission using delayed neutron fraction xs % delayed_nu_fission(gin, dg, iazi, ipol) = & temp_beta(gin, dg, iazi, ipol) * & temp_3d(gin, iazi, ipol) @@ -1448,12 +1448,12 @@ module mgxs_header end do end do - ! Deallocate temporary delayed_nu_fission arrays + ! Deallocate temporary delayed-nu-fission arrays deallocate(temp_1d) deallocate(temp_3d) ! If delayed-nu-fission is a (delayed_group, energy_group) - ! matrix, set delayed_nu_fission separately for each delayed + ! matrix, set delayed-nu-fission separately for each delayed ! group. else if (ndims == 4) then @@ -1485,14 +1485,14 @@ module mgxs_header &matrix.") end if - ! Get delayed_nu_fission + ! Get delayed-nu-fission allocate(temp_1d(delayed_groups * energy_groups * this % n_azi & * this % n_pol)) call read_dataset(temp_1d, xsdata_grp, "delayed-nu-fission") xs % delayed_nu_fission = reshape(temp_1d, (/energy_groups, & delayed_groups, this % n_azi, this % n_pol /)) - ! Deallocate temporary array for delayed_nu_fission matrix + ! Deallocate temporary array for delayed-nu-fission matrix deallocate(temp_1d) else @@ -1504,7 +1504,7 @@ module mgxs_header ! Deallocate temporary beta array deallocate(temp_beta) - ! chi_prompt, chi_delayed, prompt_nu_fission, and delayed_nu_fission + ! chi-prompt, chi-delayed, prompt-nu-fission, and delayed-nu-fission ! have been set; Now we will check for the rest of the XS that are ! unique to fissionable isotopes @@ -1523,33 +1523,33 @@ module mgxs_header deallocate(temp_1d) end if - ! Set kappa_fission xs + ! Set kappa-fission xs if (object_exists(xsdata_grp, "kappa-fission")) then - ! Allocate temporary array for kappa_fission + ! Allocate temporary array for kappa-fission allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) - ! Get kappa_fission array + ! Get kappa-fission array call read_dataset(temp_1d, xsdata_grp, "kappa-fission") xs % kappa_fission(:, :, :) = reshape(temp_1d, (/energy_groups, & this % n_azi, this % n_pol/)) - ! Deallocate temporary array for kappa_fission + ! Deallocate temporary array for kappa-fission deallocate(temp_1d) end if ! Set decay rate - if (object_exists(xsdata_grp, "decay-rate")) then + if (object_exists(xsdata_grp, "decay rate")) then - ! Allocate temporary array for decay_rate + ! Allocate temporary array for decay rate allocate(temp_1d(this % n_azi * this % n_pol * delayed_groups)) - ! Get decay_rate array - call read_dataset(temp_1d, xsdata_grp, "decay-rate") + ! Get decay rate array + call read_dataset(temp_1d, xsdata_grp, "decay rate") xs % decay_rate(:, :, :) = reshape(temp_1d, (/delayed_groups, & this % n_azi, this % n_pol/)) - ! Deallocate temporary array for decay_rate + ! Deallocate temporary array for decay rate deallocate(temp_1d) end if end if @@ -1574,16 +1574,14 @@ module mgxs_header call fatal_error("Must provide absorption!") end if - if (object_exists(xsdata_grp, "inverse_velocity")) then + if (object_exists(xsdata_grp, "inverse-velocity")) then ! Allocate temporary array for inverse velocity allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) ! Read in inverse velocity - call read_dataset(temp_1d, xsdata_grp, "inverse_velocity") + call read_dataset(temp_1d, xsdata_grp, "inverse-velocity") - allocate(xs % inverse_velocity(energy_groups, this % n_azi, & - this % n_pol)) xs % inverse_velocity = reshape(temp_1d, (/energy_groups, & this % n_azi, this % n_pol/)) @@ -2517,6 +2515,7 @@ module mgxs_header this % xs(t) % kappa_fission = this % xs(t) % kappa_fission & + atom_density * nuc % xs(nuc_t) % kappa_fission * interp + end if ! We will next gather the multiplicity and scattering matrices. @@ -2686,34 +2685,34 @@ module mgxs_header case('fission') xs = this % xs(t) % fission(gin) - case('kappa_fission') + case('kappa-fission') xs = this % xs(t) % kappa_fission(gin) - case('inverse_velocity') + case('inverse-velocity') xs = this % xs(t) % inverse_velocity(gin) - case('decay_rate') + case('decay rate') if (present(dg)) then xs = this % xs(t) % decay_rate(dg) else xs = this % xs(t) % decay_rate(1) end if - case('prompt_nu_fission') + case('prompt-nu-fission') xs = this % xs(t) % prompt_nu_fission(gin) - case('delayed_nu_fission') + case('delayed-nu-fission') if (present(dg)) then xs = this % xs(t) % delayed_nu_fission(gin, dg) else xs = sum(this % xs(t) % delayed_nu_fission(gin, :)) end if - case('nu_fission') + case('nu-fission') xs = this % xs(t) % prompt_nu_fission(gin) + & sum(this % xs(t) % delayed_nu_fission(gin, :)) - case('chi_prompt') + case('chi-prompt') if (present(gout)) then xs = this % xs(t) % chi_prompt(gout,gin) else @@ -2721,7 +2720,7 @@ module mgxs_header xs = sum(this % xs(t) % chi_prompt(:, gin)) end if - case('chi_delayed') + case('chi-delayed') if (present(gout)) then if (present(dg)) then xs = this % xs(t) % chi_delayed(gout, gin, dg) @@ -2821,24 +2820,24 @@ module mgxs_header case('fission') xs = this % xs(t) % fission(gin, iazi, ipol) - case('kappa_fission') + case('kappa-fission') xs = this % xs(t) % kappa_fission(gin, iazi, ipol) - case('prompt_nu_fission') + case('prompt-nu-fission') xs = this % xs(t) % prompt_nu_fission(gin, iazi, ipol) - case('delayed_nu_fission') + case('delayed-nu-fission') if (present(dg)) then xs = this % xs(t) % delayed_nu_fission(gin, dg, iazi, ipol) else xs = sum(this % xs(t) % delayed_nu_fission(gin, :, iazi, ipol)) end if - case('nu_fission') + case('nu-fission') xs = this % xs(t) % prompt_nu_fission(gin, iazi, ipol) + & sum(this % xs(t) % delayed_nu_fission(gin, :, iazi, ipol)) - case('chi_prompt') + case('chi-prompt') if (present(gout)) then xs = this % xs(t) % chi_prompt(gout, gin, iazi, ipol) else @@ -2846,7 +2845,7 @@ module mgxs_header xs = sum(this % xs(t) % chi_prompt(:, gin, iazi, ipol)) end if - case('chi_delayed') + case('chi-delayed') if (present(gout)) then if (present(dg)) then xs = this % xs(t) % chi_delayed(gout, gin, dg, iazi, ipol) @@ -2861,14 +2860,14 @@ module mgxs_header end if end if - case('decay_rate') + case('decay rate') if (present(dg)) then xs = this % xs(t) % decay_rate(iazi, ipol, dg) else xs = this % xs(t) % decay_rate(iazi, ipol, 1) end if - case('inverse_velocity') + case('inverse-velocity') xs = this % xs(t) % inverse_velocity(gin, iazi, ipol) case('scatter') @@ -2951,8 +2950,8 @@ module mgxs_header ! Get nu and nu_prompt real(8) :: prob_prompt - prob_prompt = this % get_xs('prompt_nu_fission', gin) / & - this % get_xs('nu_fission', gin) + prob_prompt = this % get_xs('prompt-nu-fission', gin) / & + this % get_xs('nu-fission', gin) ! Sample random numbers xi_pd = prn() @@ -2983,7 +2982,7 @@ module mgxs_header dg = dg + 1 prob_prompt = prob_prompt + & this % get_xs('delayed_nu_fision', gin, dg=dg) & - / this % get_xs('nu_fission', gin) + / this % get_xs('nu-fission', gin) end do ! Adjust dg in case of round off error @@ -3014,8 +3013,8 @@ module mgxs_header real(8) :: prob_prompt ! Get nu and nu_prompt - prob_prompt = this % get_xs('prompt_nu_fission', gin, uvw=uvw) / & - this % get_xs('nu_fission', gin, uvw=uvw) + prob_prompt = this % get_xs('prompt-nu-fission', gin, uvw=uvw) / & + this % get_xs('nu-fission', gin, uvw=uvw) ! Sample random numbers xi_pd = prn() @@ -3028,12 +3027,12 @@ module mgxs_header dg = 0 gout = 1 - prob_gout = this % get_xs('chi_prompt', gin, gout, uvw=uvw) + prob_gout = this % get_xs('chi-prompt', gin, gout, uvw=uvw) do while (prob_gout < xi_gout) gout = gout + 1 prob_gout = prob_gout + & - this % get_xs('chi_prompt', gin, gout, uvw=uvw) + this % get_xs('chi-prompt', gin, gout, uvw=uvw) end do ! Neutron is born delayed @@ -3045,8 +3044,8 @@ module mgxs_header do while (xi_pd < prob_prompt) dg = dg + 1 prob_prompt = prob_prompt + & - this % get_xs('delayed_nu_fission', gin, uvw=uvw, dg=dg) / & - this % get_xs('nu_fission', gin, uvw=uvw) + this % get_xs('delayed-nu-fission', gin, uvw=uvw, dg=dg) / & + this % get_xs('nu-fission', gin, uvw=uvw) end do ! Adjust dg in case of round off error @@ -3054,11 +3053,11 @@ module mgxs_header ! Get the outgoing group gout = 1 - prob_gout = this % get_xs('chi_delayed', gin, gout, uvw=uvw, dg=dg) + prob_gout = this % get_xs('chi-delayed', gin, gout, uvw=uvw, dg=dg) do while (prob_gout < xi_gout) gout = gout + 1 - prob_gout = this % get_xs('chi_delayed', gin, gout, uvw=uvw, dg=dg) + prob_gout = this % get_xs('chi-delayed', gin, gout, uvw=uvw, dg=dg) end do end if diff --git a/src/tally.F90 b/src/tally.F90 index c5a1b83522..865da6058f 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -1247,19 +1247,19 @@ contains end if if (i_nuclide > 0) then - score = score * nucxs % get_xs('inverse_velocity', p_g, UVW=p_uvw) & + score = score * nucxs % get_xs('inverse-velocity', p_g, UVW=p_uvw) & / nucxs % get_xs('total', p_g, UVW=p_uvw) * flux else - score = score * matxs % get_xs('inverse_velocity', p_g, UVW=p_uvw) & + score = score * matxs % get_xs('inverse-velocity', p_g, UVW=p_uvw) & / matxs % get_xs('total', p_g, UVW=p_uvw) * flux end if else if (i_nuclide > 0) then - score = flux * nucxs % get_xs('inverse_velocity', p_g, UVW=p_uvw) + score = flux * nucxs % get_xs('inverse-velocity', p_g, UVW=p_uvw) else - score = flux * matxs % get_xs('inverse_velocity', p_g, UVW=p_uvw) + score = flux * matxs % get_xs('inverse-velocity', p_g, UVW=p_uvw) end if end if @@ -1445,11 +1445,11 @@ contains score = p % absorb_wgt * flux if (i_nuclide > 0) then score = score * atom_density * & - nucxs % get_xs('nu_fission', p_g, UVW=p_uvw) / & + nucxs % get_xs('nu-fission', p_g, UVW=p_uvw) / & matxs % get_xs('absorption', p_g, UVW=p_uvw) else score = score * & - matxs % get_xs('nu_fission', p_g, UVW=p_uvw) / & + matxs % get_xs('nu-fission', p_g, UVW=p_uvw) / & matxs % get_xs('absorption', p_g, UVW=p_uvw) end if else @@ -1470,10 +1470,10 @@ contains else if (i_nuclide > 0) then - score = nucxs % get_xs('nu_fission', p_g, UVW=p_uvw) * & + score = nucxs % get_xs('nu-fission', p_g, UVW=p_uvw) * & atom_density * flux else - score = matxs % get_xs('nu_fission', p_g, UVW=p_uvw) * flux + score = matxs % get_xs('nu-fission', p_g, UVW=p_uvw) * flux end if end if @@ -1506,11 +1506,11 @@ contains score = p % absorb_wgt * flux if (i_nuclide > 0) then score = score * atom_density * & - nucxs % get_xs('prompt_nu_fission', p_g, UVW=p_uvw) / & + nucxs % get_xs('prompt-nu-fission', p_g, UVW=p_uvw) / & matxs % get_xs('absorption', p_g, UVW=p_uvw) else score = score * & - matxs % get_xs('prompt_nu_fission', p_g, UVW=p_uvw) / & + matxs % get_xs('prompt-nu-fission', p_g, UVW=p_uvw) / & matxs % get_xs('absorption', p_g, UVW=p_uvw) end if else @@ -1532,10 +1532,10 @@ contains else if (i_nuclide > 0) then - score = nucxs % get_xs('prompt_nu_fission', p_g, UVW=p_uvw) * & + score = nucxs % get_xs('prompt-nu-fission', p_g, UVW=p_uvw) * & atom_density * flux else - score = matxs % get_xs('prompt_nu_fission', p_g, UVW=p_uvw) * flux + score = matxs % get_xs('prompt-nu-fission', p_g, UVW=p_uvw) * flux end if end if @@ -1583,11 +1583,11 @@ contains score = p % absorb_wgt * flux if (i_nuclide > 0) then - score = score * nucxs % get_xs('delayed_nu_fission', & + score = score * nucxs % get_xs('delayed-nu-fission', & p_g, UVW=p_uvw, dg=d) / & nucxs % get_xs('absorption', p_g, UVW=p_uvw) else - score = score * matxs % get_xs('delayed_nu_fission', & + score = score * matxs % get_xs('delayed-nu-fission', & p_g, UVW=p_uvw, dg=d) / & matxs % get_xs('absorption', p_g, UVW=p_uvw) end if @@ -1599,10 +1599,10 @@ contains else score = p % absorb_wgt * flux if (i_nuclide > 0) then - score = score * nucxs % get_xs('delayed_nu_fission', p_g, & + score = score * nucxs % get_xs('delayed-nu-fission', p_g, & UVW=p_uvw) / nucxs % get_xs('absorption', p_g, UVW=p_uvw) else - score = score * matxs % get_xs('delayed_nu_fission', p_g, & + score = score * matxs % get_xs('delayed-nu-fission', p_g, & UVW=p_uvw) / matxs % get_xs('absorption', p_g, UVW=p_uvw) end if end if @@ -1665,10 +1665,10 @@ contains d = filt % groups(d_bin) if (i_nuclide > 0) then - score = nucxs % get_xs('delayed_nu_fission', p_g, & + score = nucxs % get_xs('delayed-nu-fission', p_g, & UVW=p_uvw, dg=d) * atom_density * flux else - score = matxs % get_xs('delayed_nu_fission', p_g, & + score = matxs % get_xs('delayed-nu-fission', p_g, & UVW=p_uvw, dg=d) * flux end if @@ -1678,10 +1678,10 @@ contains end select else if (i_nuclide > 0) then - score = nucxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw) & + score = nucxs % get_xs('delayed-nu-fission', p_g, UVW=p_uvw) & * atom_density * flux else - score = matxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw) & + score = matxs % get_xs('delayed-nu-fission', p_g, UVW=p_uvw) & * flux end if end if @@ -1719,15 +1719,15 @@ contains score = p % absorb_wgt * flux if (i_nuclide > 0) then - score = score * nucxs % get_xs('decay_rate', p_g, & + score = score * nucxs % get_xs('decay rate', p_g, & UVW=p_uvw, dg=d) * & - nucxs % get_xs('delayed_nu_fission', p_g, & + nucxs % get_xs('delayed-nu-fission', p_g, & UVW=p_uvw, dg=d) / nucxs % get_xs('absorption', & p_g, UVW=p_uvw) else - score = score * matxs % get_xs('decay_rate', p_g, & + score = score * matxs % get_xs('decay rate', p_g, & UVW=p_uvw, dg=d) * & - matxs % get_xs('delayed_nu_fission', p_g, & + matxs % get_xs('delayed-nu-fission', p_g, & UVW=p_uvw, dg=d) / matxs % get_xs('absorption', & p_g, UVW=p_uvw) end if @@ -1747,13 +1747,13 @@ contains do d = 1, num_delayed_groups if (i_nuclide > 0) then score = score + p % absorb_wgt * & - nucxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=d) * & - nucxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw, & + nucxs % get_xs('decay rate', p_g, UVW=p_uvw, dg=d) * & + nucxs % get_xs('delayed-nu-fission', p_g, UVW=p_uvw, & dg=d) / nucxs % get_xs('absorption', p_g, UVW=p_uvw) else score = score + p % absorb_wgt * & - matxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=d) * & - matxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw, & + matxs % get_xs('decay rate', p_g, UVW=p_uvw, dg=d) * & + matxs % get_xs('delayed-nu-fission', p_g, UVW=p_uvw, & dg=d) / matxs % get_xs('absorption', p_g, UVW=p_uvw) end if end do @@ -1783,13 +1783,13 @@ contains if (i_nuclide > 0) then score = score + keff * atom_density * & fission_bank(n_bank - p % n_bank + k) % wgt * & - nucxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=g) * & + nucxs % get_xs('decay rate', p_g, UVW=p_uvw, dg=g) * & nucxs % get_xs('fission', p_g, UVW=p_uvw) / & matxs % get_xs('fission', p_g, UVW=p_uvw) else score = score + keff * & fission_bank(n_bank - p % n_bank + k) % wgt * & - matxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=g) + matxs % get_xs('decay rate', p_g, UVW=p_uvw, dg=g) end if ! if the delayed group filter is present, tally to corresponding @@ -1841,12 +1841,12 @@ contains d = filt % groups(d_bin) if (i_nuclide > 0) then - score = nucxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=d) * & - nucxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw, & + score = nucxs % get_xs('decay rate', p_g, UVW=p_uvw, dg=d) * & + nucxs % get_xs('delayed-nu-fission', p_g, UVW=p_uvw, & dg=d) * atom_density * flux else - score = matxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=d) * & - matxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw, & + score = matxs % get_xs('decay rate', p_g, UVW=p_uvw, dg=d) * & + matxs % get_xs('delayed-nu-fission', p_g, UVW=p_uvw, & dg=d) * flux end if @@ -1864,12 +1864,12 @@ contains do d = 1, num_delayed_groups if (i_nuclide > 0) then score = score + atom_density * flux * & - nucxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=d) * & - nucxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw, dg=d) + nucxs % get_xs('decay rate', p_g, UVW=p_uvw, dg=d) * & + nucxs % get_xs('delayed-nu-fission', p_g, UVW=p_uvw, dg=d) else score = score + flux * & - matxs % get_xs('decay_rate', p_g, UVW=p_uvw, dg=d) * & - matxs % get_xs('delayed_nu_fission', p_g, UVW=p_uvw, dg=d) + matxs % get_xs('decay rate', p_g, UVW=p_uvw, dg=d) * & + matxs % get_xs('delayed-nu-fission', p_g, UVW=p_uvw, dg=d) end if end do end if @@ -1901,19 +1901,19 @@ contains end if if (i_nuclide > 0) then score = score * atom_density * & - nucxs % get_xs('kappa_fission', p_g, UVW=p_uvw) / & + nucxs % get_xs('kappa-fission', p_g, UVW=p_uvw) / & matxs % get_xs('absorption', p_g, UVW=p_uvw) else score = score * & - matxs % get_xs('kappa_fission', p_g, UVW=p_uvw) / & + matxs % get_xs('kappa-fission', p_g, UVW=p_uvw) / & matxs % get_xs('absorption', p_g, UVW=p_uvw) end if else if (i_nuclide > 0) then - score = nucxs % get_xs('kappa_fission', p_g, UVW=p_uvw) * & + score = nucxs % get_xs('kappa-fission', p_g, UVW=p_uvw) * & atom_density * flux else - score = matxs % get_xs('kappa_fission', p_g, UVW=p_uvw) * flux + score = matxs % get_xs('kappa-fission', p_g, UVW=p_uvw) * flux end if end if From 7b814b32e27fede86f57b55655a6690654a182b1 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Fri, 14 Oct 2016 15:20:22 -0400 Subject: [PATCH 06/27] fixed issue with initializing mgxs inverse-velocity --- src/mgxs_header.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 0b02960add..da83cf6530 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -1149,6 +1149,7 @@ module mgxs_header xs % chi_delayed = ZERO xs % chi_prompt = ZERO xs % decay_rate = ZERO + xs % inverse_velocity = ZERO if (this % fissionable) then @@ -2653,6 +2654,7 @@ module mgxs_header deallocate(scatt_coeffs, temp_mult, mult_num, mult_denom) end associate ! nuc end do NUC_LOOP + end do TEMP_LOOP end subroutine mgxsang_combine From 93d100ec255290c926523dd2d95642bb5485d628 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Sat, 15 Oct 2016 10:29:00 -0400 Subject: [PATCH 07/27] fixed typo in reading in multiplicity matrix --- src/mgxs_header.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index da83cf6530..208ec528e2 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -1013,7 +1013,7 @@ module mgxs_header ! 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 From 6234ef5693fd2bca98eff2546f54d4225b931054 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Tue, 18 Oct 2016 08:03:26 -0400 Subject: [PATCH 08/27] updated setup.py to version in develop --- setup.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/setup.py b/setup.py index 9dceb1cbf7..da98506d3b 100755 --- a/setup.py +++ b/setup.py @@ -61,9 +61,5 @@ if have_cython: 'ext_modules': cythonize('openmc/data/reconstruct.pyx'), 'include_dirs': [np.get_include()] }) - import numpy as np - kwargs.update({ - 'include_dirs': [np.get_include()] - }) setup(**kwargs) From f7c3f80504553bf5a0ce563d4fd3e5a74a1bc440 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Tue, 18 Oct 2016 08:11:19 -0400 Subject: [PATCH 09/27] updated results to mg tests --- tests/test_mg_basic/results_true.dat | 2 +- tests/test_mg_max_order/results_true.dat | 2 +- tests/test_mg_nuclide/results_true.dat | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_mg_basic/results_true.dat b/tests/test_mg_basic/results_true.dat index 01b7925469..5178ade21d 100644 --- a/tests/test_mg_basic/results_true.dat +++ b/tests/test_mg_basic/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.160653E+00 6.227102E-02 +5.788739E-01 1.945182E-02 diff --git a/tests/test_mg_max_order/results_true.dat b/tests/test_mg_max_order/results_true.dat index 0e470e2cdb..2189587d4f 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.098323E+00 1.979833E-02 +1.077247E+00 2.412834E-02 diff --git a/tests/test_mg_nuclide/results_true.dat b/tests/test_mg_nuclide/results_true.dat index 01b7925469..5178ade21d 100644 --- a/tests/test_mg_nuclide/results_true.dat +++ b/tests/test_mg_nuclide/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.160653E+00 6.227102E-02 +5.788739E-01 1.945182E-02 From 857593ad4760e98c02d6dbd2a522f3448b4ce06c Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Tue, 18 Oct 2016 23:11:17 -0400 Subject: [PATCH 10/27] addressed most of comments from @nelsonag --- openmc/mgxs_library.py | 137 +++++++++++++++++++------------------ scripts/openmc-update-mgxs | 10 +-- src/input_xml.F90 | 2 - src/tally.F90 | 4 +- 4 files changed, 76 insertions(+), 77 deletions(-) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 4a6b75c8ec..d4acd94697 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -35,7 +35,7 @@ class XSdata(object): temperatures : Iterable of float Temperatures (in units of Kelvin) of the provided datasets. Defaults to a single temperature at 294K. - delayed_groups : int + num_delayed_groups : int Number of delayed groups Attributes @@ -50,7 +50,7 @@ class XSdata(object): to a single temperature at 294K. energy_groups : openmc.mgxs.EnergyGroups Energy group structure - delayed_groups : int + num_delayed_groups : int Num delayed groups fissionable : bool Whether or not this is a fissionable data set. @@ -71,7 +71,8 @@ class XSdata(object): 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". total : dict of numpy.ndarray Group-wise total cross section. absorption : dict of numpy.ndarray @@ -95,7 +96,7 @@ 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. chi_prompt : dict of numpy.ndarray Group-wise prompt fission spectra ordered by increasing group index (i.e., fast to thermal). This attribute should be used if chi from @@ -121,12 +122,12 @@ class XSdata(object): """ def __init__(self, name, energy_groups, temperatures=[294.], - representation='isotropic', delayed_groups=0): + representation='isotropic', num_delayed_groups=0): # Initialize class attributes self.name = name self.energy_groups = energy_groups - self.delayed_groups = delayed_groups + self.num_delayed_groups = num_delayed_groups self.temperatures = temperatures self.representation = representation self._atomic_weight_ratio = None @@ -161,8 +162,8 @@ class XSdata(object): return self._energy_groups @property - def delayed_groups(self): - return self._delayed_groups + def num_delayed_groups(self): + return self._num_delayed_groups @property def representation(self): @@ -274,14 +275,15 @@ class XSdata(object): self._energy_groups = energy_groups - @delayed_groups.setter - def delayed_groups(self, delayed_groups): + @num_delayed_groups.setter + def num_delayed_groups(self, num_delayed_groups): - # Check validity of delayed_groups - check_type('delayed_groups', delayed_groups, int) - check_greater_than('delayed_groups', delayed_groups, 0, equality=True) + # Check validity of num_delayed_groups + check_type('num_delayed_groups', num_delayed_groups, int) + check_greater_than('delayed_groups', num_delayed_groups, 0, + equality=True) - self._delayed_groups = delayed_groups + self._num_delayed_groups = num_delayed_groups @representation.setter def representation(self, representation): @@ -612,12 +614,12 @@ class XSdata(object): # Get the accepted shapes for this xs if self.representation is 'isotropic': shapes = [(self.energy_groups.num_groups,), - (self.delayed_groups, self.energy_groups.num_groups)] + (self.num_delayed_groups, self.energy_groups.num_groups)] else: shapes = [(self.num_polar, self.num_azimuthal, self.energy_groups.num_groups), - (self.delayed_groups, self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups)] + (self.num_delayed_groups, self.num_polar, + self.num_azimuthal, self.energy_groups.num_groups)] # Convert to a numpy array so we can easily get the shape for checking chi_delayed = np.asarray(chi_delayed) @@ -648,12 +650,13 @@ class XSdata(object): # Get the accepted shapes for this xs if self.representation is 'isotropic': - shapes = [(self.delayed_groups,), - (self.delayed_groups, self.energy_groups.num_groups)] + shapes = [(self.num_delayed_groups,), + (self.num_delayed_groups, self.energy_groups.num_groups)] else: - shapes = [(self.delayed_groups, self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups), - (self.delayed_groups, self.num_polar, self.num_azimuthal)] + shapes = [(self.num_delayed_groups, self.num_polar, + self.num_azimuthal, self.energy_groups.num_groups), + (self.num_delayed_groups, self.num_polar, + self.num_azimuthal)] # Convert to a numpy array so we can easily get the shape for checking beta = np.asarray(beta) @@ -686,12 +689,13 @@ class XSdata(object): # Get the accepted shapes for this xs if self.representation is 'isotropic': - shapes = [(self.delayed_groups,), - (self.delayed_groups, self.energy_groups.num_groups)] + shapes = [(self.num_delayed_groups,), + (self.num_delayed_groups, self.energy_groups.num_groups)] else: - shapes = [(self.delayed_groups, self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups), - (self.delayed_groups, self.num_polar, self.num_azimuthal)] + shapes = [(self.num_delayed_groups, self.num_polar, + self.num_azimuthal, self.energy_groups.num_groups), + (self.num_delayed_groups, self.num_polar, + self.num_azimuthal)] # Convert to a numpy array so we can easily get the shape for checking decay_rate = np.asarray(decay_rate) @@ -879,10 +883,10 @@ class XSdata(object): # Get the accepted shapes for this xs if self.representation is 'isotropic': - shapes = [(self.delayed_groups, self.energy_groups.num_groups,)] + shapes = [(self.num_delayed_groups, self.energy_groups.num_groups,)] else: - shapes = [(self.delayed_groups, self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups)] + shapes = [(self.num_delayed_groups, self.num_polar, + self.num_azimuthal, self.energy_groups.num_groups)] # Convert to a numpy array so we can easily get the shape for checking delayed_nu_fission = np.asarray(delayed_nu_fission) @@ -965,8 +969,7 @@ class XSdata(object): check_type('total', total, (openmc.mgxs.TotalXS, openmc.mgxs.TransportXS)) check_value('energy_groups', total.energy_groups, [self.energy_groups]) - check_value('domain_type', total.domain_type, - ['universe', 'cell', 'material', 'mesh']) + check_value('domain_type', total.domain_type, openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1012,7 +1015,7 @@ class XSdata(object): check_value('energy_groups', absorption.energy_groups, [self.energy_groups]) check_value('domain_type', absorption.domain_type, - ['universe', 'cell', 'material', 'mesh']) + openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1059,7 +1062,7 @@ class XSdata(object): check_value('energy_groups', fission.energy_groups, [self.energy_groups]) check_value('domain_type', fission.domain_type, - ['universe', 'cell', 'material', 'mesh']) + openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1107,7 +1110,7 @@ class XSdata(object): check_value('energy_groups', nu_fission.energy_groups, [self.energy_groups]) check_value('domain_type', nu_fission.domain_type, - ['universe', 'cell', 'material', 'mesh']) + openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1159,7 +1162,7 @@ class XSdata(object): check_value('energy_groups', prompt_nu_fission.energy_groups, [self.energy_groups]) check_value('domain_type', prompt_nu_fission.domain_type, - ['universe', 'cell', 'material', 'mesh']) + openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1211,10 +1214,10 @@ class XSdata(object): (openmc.mgxs.DelayedNuFissionXS,)) check_value('energy_groups', delayed_nu_fission.energy_groups, [self.energy_groups]) - check_value('delayed_groups', delayed_nu_fission.num_delayed_groups, - [self.delayed_groups]) + check_value('num_delayed_groups', delayed_nu_fission.num_delayed_groups, + [self.num_delayed_groups]) check_value('domain_type', delayed_nu_fission.domain_type, - ['universe', 'cell', 'material', 'mesh']) + openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1267,7 +1270,7 @@ class XSdata(object): check_value('energy_groups', k_fission.energy_groups, [self.energy_groups]) check_value('domain_type', k_fission.domain_type, - ['universe', 'cell', 'material', 'mesh']) + openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1311,8 +1314,7 @@ class XSdata(object): check_type('chi', chi, openmc.mgxs.Chi) check_value('energy_groups', chi.energy_groups, [self.energy_groups]) - check_value('domain_type', chi.domain_type, - ['universe', 'cell', 'material', 'mesh']) + check_value('domain_type', chi.domain_type, openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1357,7 +1359,7 @@ class XSdata(object): check_value('energy_groups', chi_prompt.energy_groups, [self.energy_groups]) check_value('domain_type', chi_prompt.domain_type, - ['universe', 'cell', 'material', 'mesh']) + openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1402,10 +1404,10 @@ class XSdata(object): check_type('chi_delayed', chi_delayed, openmc.mgxs.ChiDelayed) check_value('energy_groups', chi_delayed.energy_groups, [self.energy_groups]) - check_value('delayed_groups', chi_delayed.num_delayed_groups, - [self.delayed_groups]) + check_value('num_delayed_groups', chi_delayed.num_delayed_groups, + [self.num_delayed_groups]) check_value('domain_type', chi_delayed.domain_type, - ['universe', 'cell', 'material', 'mesh']) + openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1448,10 +1450,9 @@ class XSdata(object): """ check_type('beta', beta, openmc.mgxs.Beta) - check_value('delayed_groups', beta.num_delayed_groups, - [self.delayed_groups]) - check_value('domain_type', beta.domain_type, - ['universe', 'cell', 'material', 'mesh']) + check_value('num_delayed_groups', beta.num_delayed_groups, + [self.num_delayed_groups]) + check_value('domain_type', beta.domain_type, openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1494,10 +1495,10 @@ class XSdata(object): """ check_type('decay_rate', decay_rate, openmc.mgxs.DecayRate) - check_value('delayed_groups', decay_rate.num_delayed_groups, - [self.delayed_groups]) + check_value('num_delayed_groups', decay_rate.num_delayed_groups, + [self.num_delayed_groups]) check_value('domain_type', decay_rate.domain_type, - ['universe', 'cell', 'material', 'mesh']) + openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1547,7 +1548,7 @@ class XSdata(object): check_value('energy_groups', scatter.energy_groups, [self.energy_groups]) check_value('domain_type', scatter.domain_type, - ['universe', 'cell', 'material', 'mesh']) + openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1629,7 +1630,7 @@ class XSdata(object): check_value('energy_groups', nuscatter.energy_groups, [self.energy_groups]) check_value('domain_type', nuscatter.domain_type, - ['universe', 'cell', 'material', 'mesh']) + openmc.mgxs.DOMAIN_TYPES) check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) @@ -1643,8 +1644,7 @@ class XSdata(object): check_value('energy_groups', scatter.energy_groups, [self.energy_groups]) check_value('domain_type', scatter.domain_type, - ['universe', 'cell', 'material', 'mesh']) - + openmc.mgxs.DOMAIN_TYPES) i = np.where(self.temperatures == temperature)[0][0] if self.representation == 'isotropic': nuscatt = nuscatter.get_xs(nuclides=nuclide, @@ -1876,22 +1876,22 @@ class MGXSLibrary(object): ---------- energy_groups : openmc.mgxs.EnergyGroups Energy group structure - delayed_groups : int + num_delayed_groups : int Num delayed groups Attributes ---------- energy_groups : openmc.mgxs.EnergyGroups Energy group structure. - delayed_groups : int + num_delayed_groups : int Num delayed groups xsdatas : Iterable of openmc.XSdata Iterable of multi-Group cross section data objects """ - def __init__(self, energy_groups, delayed_groups=0): + def __init__(self, energy_groups, num_delayed_groups=0): self.energy_groups = energy_groups - self.delayed_groups = delayed_groups + self.num_delayed_groups = num_delayed_groups self._xsdatas = [] @property @@ -1899,8 +1899,8 @@ class MGXSLibrary(object): return self._energy_groups @property - def delayed_groups(self): - return self._delayed_groups + def num_delayed_groups(self): + return self._num_delayed_groups @property def temperatures(self): @@ -1915,10 +1915,11 @@ class MGXSLibrary(object): check_type('energy groups', energy_groups, openmc.mgxs.EnergyGroups) self._energy_groups = energy_groups - @delayed_groups.setter - def delayed_groups(self, delayed_groups): - check_type('delayed groups', delayed_groups, int) - self._delayed_groups = delayed_groups + @num_delayed_groups.setter + def num_delayed_groups(self, num_delayed_groups): + check_type('num_delayed_groups', num_delayed_groups, int) + check_greater_than('delayed_groups', delayed_groups, 0, equality=True) + self._num_delayed_groups = num_delayed_groups def add_xsdata(self, xsdata): """Add an XSdata entry to the file. @@ -1988,7 +1989,7 @@ class MGXSLibrary(object): # Create and write to the HDF5 file file = h5py.File(filename, "w") file.attrs['energy_groups'] = self.energy_groups.num_groups - file.attrs['delayed_groups'] = self.delayed_groups + file.attrs['delayed_groups'] = self.num_delayed_groups file.attrs['group structure'] = self.energy_groups.group_edges for xsdata in self._xsdatas: diff --git a/scripts/openmc-update-mgxs b/scripts/openmc-update-mgxs index 658be9fef7..cad48d0e31 100755 --- a/scripts/openmc-update-mgxs +++ b/scripts/openmc-update-mgxs @@ -85,13 +85,13 @@ if __name__ == '__main__': temp = np.array(temp.split()) group_structure = temp.astype(np.float) energy_groups = openmc.mgxs.EnergyGroups(group_structure) - temp = tree.find('inverse_velocities') + temp = tree.find('inverse-velocity') if temp is not None: temp = temp.text.strip() temp = np.array(temp.split()) - inverse_velocities = temp.astype(np.float) + inverse_velocity = temp.astype(np.float) else: - inverse_velocities = None + inverse_velocity = None xsd = [] names = [] @@ -166,8 +166,8 @@ if __name__ == '__main__': 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) + if inverse_velocity is not None: + xsd[i].set_inverse_velocity(inverse_velocity, temperature) temp = get_data(xsdata_elem, 'absorption') temp = np.array(temp.split()) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index f6d8e9b9aa..324fce0c7d 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -4665,8 +4665,6 @@ contains call read_attribute(num_delayed_groups, file_id, "delayed_groups") else num_delayed_groups = 0 - call write_message("WARNING: delayed_groups element not provided so & - &number of delayed groups set to 0") end if allocate(rev_energy_bins(num_energy_groups + 1)) diff --git a/src/tally.F90 b/src/tally.F90 index 0cdd259a4b..b151e35ddf 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -1250,10 +1250,10 @@ contains if (i_nuclide > 0) then score = score * nucxs % get_xs('inverse-velocity', p_g, UVW=p_uvw) & - / nucxs % get_xs('total', p_g, UVW=p_uvw) * flux + / matxs % get_xs('absorption', p_g, UVW=p_uvw) * flux else score = score * matxs % get_xs('inverse-velocity', p_g, UVW=p_uvw) & - / matxs % get_xs('total', p_g, UVW=p_uvw) * flux + / matxs % get_xs('absorption', p_g, UVW=p_uvw) * flux end if else From 9dad1d1c77b10f338eb962b45db7ad5c78106534 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Tue, 18 Oct 2016 23:33:47 -0400 Subject: [PATCH 11/27] fixed typo in mgxs_library.py and added comment to python doc string noting beta is not importance-weighted --- openmc/mgxs/mdgxs.py | 5 +++++ openmc/mgxs_library.py | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/openmc/mgxs/mdgxs.py b/openmc/mgxs/mdgxs.py index 2c616b3682..aab5d855be 100644 --- a/openmc/mgxs/mdgxs.py +++ b/openmc/mgxs/mdgxs.py @@ -1468,6 +1468,11 @@ class Beta(MDGXS): \beta_{d,g} &= \frac{\langle \nu^d \sigma_f \phi \rangle} {\langle \nu \sigma_f \phi \rangle} + NOTE: The Beta MGXS is the delayed neutron fraction computed directly from + the nuclear data. Often the delayed neutron fraction is + "importance-weighted" by the adjoint flux and called "beta-effective". It + is important to make clear that this Beta is not importance-weighted. + Parameters ---------- domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index d4acd94697..9718f8e2a5 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1918,7 +1918,8 @@ class MGXSLibrary(object): @num_delayed_groups.setter def num_delayed_groups(self, num_delayed_groups): check_type('num_delayed_groups', num_delayed_groups, int) - check_greater_than('delayed_groups', delayed_groups, 0, equality=True) + check_greater_than('delayed_groups', num_delayed_groups, 0, + equality=True) self._num_delayed_groups = num_delayed_groups def add_xsdata(self, xsdata): From 0f45127eb560cff6bfb36655115507e4a29bfd7f Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Wed, 19 Oct 2016 10:45:57 -0400 Subject: [PATCH 12/27] added xs_shapes dict for containing all possible shapes of mgxs --- openmc/mgxs/library.py | 52 ++++------ openmc/mgxs/mdgxs.py | 2 +- openmc/mgxs_library.py | 216 +++++++++++++++++++++-------------------- 3 files changed, 135 insertions(+), 135 deletions(-) diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index e7c0be07b1..14f6ece3ce 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -66,8 +66,8 @@ class Library(object): The highest legendre moment in the scattering matrices (default is 0) energy_groups : openmc.mgxs.EnergyGroups Energy group structure for energy condensation - delayed_groups : list of int - Delayed groups to filter out the xs + num_delayed_groups : int + Number of delayed groups estimator : str or None The tally estimator used to compute multi-group cross sections. If None, the default for each MGXS type is used. @@ -102,7 +102,7 @@ class Library(object): self._domain_type = None self._domains = 'all' self._energy_groups = None - self._delayed_groups = None + self._num_delayed_groups = 0 self._correction = 'P0' self._legendre_order = 0 self._tally_trigger = None @@ -135,7 +135,7 @@ class Library(object): clone._correction = self.correction clone._legendre_order = self.legendre_order clone._energy_groups = copy.deepcopy(self.energy_groups, memo) - clone._delayed_groups = copy.deepcopy(self.delayed_groups, memo) + clone._num_delayed_groups = self.num_delayed_groups clone._tally_trigger = copy.deepcopy(self.tally_trigger, memo) clone._all_mgxs = copy.deepcopy(self.all_mgxs) clone._sp_filename = self._sp_filename @@ -205,8 +205,8 @@ class Library(object): return self._energy_groups @property - def delayed_groups(self): - return self._delayed_groups + def num_delayed_groups(self): + return self._num_delayed_groups @property def correction(self): @@ -228,13 +228,6 @@ class Library(object): def num_groups(self): return self.energy_groups.num_groups - @property - def num_delayed_groups(self): - if self.delayed_groups == None: - return 0 - else: - return len(self.delayed_groups) - @property def all_mgxs(self): return self._all_mgxs @@ -334,22 +327,14 @@ class Library(object): cv.check_type('energy groups', energy_groups, openmc.mgxs.EnergyGroups) self._energy_groups = energy_groups - @delayed_groups.setter - def delayed_groups(self, delayed_groups): + @num_delayed_groups.setter + def num_delayed_groups(self, num_delayed_groups): - if delayed_groups != None: - - cv.check_type('delayed groups', delayed_groups, list, int) - cv.check_greater_than('num delayed groups', len(delayed_groups), 0) - - # Check that the groups are within [1, MAX_DELAYED_GROUPS] - for group in delayed_groups: - cv.check_greater_than('delayed group', group, 0) - cv.check_less_than('delayed group', group, - openmc.mgxs.MAX_DELAYED_GROUPS, - equality=True) - - self._delayed_groups = delayed_groups + cv.check_less_than('num delayed groups', num_delayed_groups, + MAX_DELAYED_GROUPS, equality=True) + cv.check_greater_than('num delayed groups', num_delayed_groups, 0, + equality=True) + self._num_delayed_groups = num_delayed_groups @correction.setter def correction(self, correction): @@ -434,7 +419,11 @@ class Library(object): mgxs.estimator = self.estimator if mgxs_type in openmc.mgxs.MDGXS_TYPES: - mgxs.delayed_groups = self.delayed_groups + if self.num_delayed_groups == 0: + mgxs.delayed_groups = None + else: + delayed_groups = list(range(1,self.num_delayed_groups)) + mgxs.delayed_groups = delayed_groups # If a tally trigger was specified, add it to the MGXS if self.tally_trigger is not None: @@ -899,7 +888,7 @@ class Library(object): if nuclide != 'total': name += '_' + nuclide xsdata = openmc.XSdata(name, self.energy_groups) - xsdata.delayed_groups = self.num_delayed_groups + xsdata.num_delayed_groups = self.num_delayed_groups if order is None: # Set the order to the Library's order (the defualt behavior) @@ -1096,7 +1085,8 @@ class Library(object): # Initialize file mgxs_file = openmc.MGXSLibrary(self.energy_groups, - delayed_groups=self.num_delayed_groups) + num_delayed_groups=\ + self.num_delayed_groups) if self.domain_type == 'mesh': # Create the xsdata objects and add to the mgxs_file diff --git a/openmc/mgxs/mdgxs.py b/openmc/mgxs/mdgxs.py index aab5d855be..4f1213c4ee 100644 --- a/openmc/mgxs/mdgxs.py +++ b/openmc/mgxs/mdgxs.py @@ -188,7 +188,7 @@ class MDGXS(MGXS): cv.check_less_than('delayed group', group, MAX_DELAYED_GROUPS, equality=True) - self._delayed_groups = delayed_groups + self._delayed_groups = delayed_groups @property def filters(self): diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 9718f8e2a5..f6b92b4175 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_iterable_type + check_iterable_type, check_less_than if sys.version_info[0] >= 3: basestring = str @@ -16,7 +16,8 @@ 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']"] +_XS_SHAPES = ["[Order][G][G']", "[G]", "[G']", "[G][G']", "[DG]", "[DG][G]", + "[DG][G']"] class XSdata(object): @@ -56,8 +57,6 @@ 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 @@ -118,6 +117,38 @@ class XSdata(object): Delayed-group-wise decay rate cross section vector. inverse_velocity : dict of numpy.ndarray Inverse of velocity, in units of sec/cm. + xs_shapes : dict of iterable of int + Dictionary with keys of _XS_SHAPES and iterable of int values with the + corresponding shapes where "Order" corresponds to the pn scattering + order, "G" corresponds to incoming energy group, "G'" corresponds to + outgoing energy group, and "DG" corresponds to delayed group. + + Notes + ----- + The parameters containing cross section data have dimensionalities which + depend upon the value of :attr:`XSdata.representation` as well as the + number of Legendre or other angular dimensions as described by + :attr:`XSdata.order`. The :attr:`XSdata.xs_shapes` are provided to obtain + the dimensionality of the data for each temperature. + + The following are cross sections which should use each of the properties. + Note that some cross sections can be input in more than one shape so they + are listed multiple times: + + [Order][G][G']: scatter_matrix + + [G]: total, absorption, fission, kappa_fission, nu_fission, + prompt_nu_fission, inverse_velocity + + [G']: chi, chi_prompt, chi_delayed + + [G][G']: multiplicity_matrix, nu_fission + + [DG]: beta, decay_rate + + [DG][G]: delayed_nu_fission, beta, decay_rate + + [DG][G']: chi_delayed, """ @@ -133,7 +164,6 @@ 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 @@ -152,6 +182,7 @@ class XSdata(object): self._beta = len(temperatures) * [None] self._decay_rate = len(temperatures) * [None] self._inverse_velocity = len(temperatures) * [None] + self._xs_shapes = None @property def name(self): @@ -185,10 +216,6 @@ 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 @@ -257,6 +284,53 @@ class XSdata(object): else: return self._order + @property + def xs_shapes(self): + + if self._xs_shapes is None: + + self._xs_shapes = {} + + if self.representation == 'isotropic': + self._xs_shapes["[G]"] = (self.energy_groups.num_groups,) + self._xs_shapes["[G']"] = (self.energy_groups.num_groups,) + self._xs_shapes["[G][G']"] = (self.energy_groups.num_groups, + self.energy_groups.num_groups) + self._xs_shapes["[DG]"] = (self.num_delayed_groups,) + self._xs_shapes["[DG][G]"] = (self.num_delayed_groups, + self.energy_groups.num_groups) + self._xs_shapes["[DG][G']"] = (self.num_delayed_groups, + self.energy_groups.num_groups) + self._xs_shapes["[Order][G][G']"] \ + = (self.num_orders, self.energy_groups.num_groups, + self.energy_groups.num_groups) + + elif self.representation == 'angle': + self._xs_shapes["[G]"] = (self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups) + self._xs_shapes["[G']"] = (self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups) + self._xs_shapes["[G][G']"] = (self.num_polar, + self.num_azimuthal, + self.energy_groups.num_groups, + self.energy_groups.num_groups) + self._xs_shapes["[DG]"] = (self.num_polar, self.num_azimuthal, + self.num_delayed_groups) + self._xs_shapes["[DG][G]"] = (self.num_polar, + self.num_azimuthal, + self.num_delayed_groups, + self.energy_groups.num_groups) + self._xs_shapes["[DG][G']"] = (self.num_polar, + self.num_azimuthal, + self.num_delayed_groups, + self.energy_groups.num_groups) + self._xs_shapes["[Order][G][G']"] \ + = (self.num_polar, self.num_azimuthal, self.num_orders, + self.energy_groups.num_groups, + self.energy_groups.num_groups) + + return self._xs_shapes + @name.setter def name(self, name): check_type('name for XSdata', name, basestring) @@ -280,9 +354,10 @@ class XSdata(object): # Check validity of num_delayed_groups check_type('num_delayed_groups', num_delayed_groups, int) - check_greater_than('delayed_groups', num_delayed_groups, 0, + check_less_than('num_delayed_groups', num_delayed_groups, + openmc.mgxs.MAX_DELAYED_GROUPS, equality=True) + check_greater_than('num_delayed_groups', num_delayed_groups, 0, equality=True) - self._num_delayed_groups = num_delayed_groups @representation.setter @@ -294,6 +369,7 @@ class XSdata(object): @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) @@ -301,8 +377,8 @@ class XSdata(object): @temperatures.setter def temperatures(self, temperatures): - check_iterable_type('temperatures', temperatures, Real) + check_iterable_type('temperatures', temperatures, Real) self._temperatures = np.array(temperatures) @scatter_format.setter @@ -312,12 +388,6 @@ 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): @@ -395,11 +465,7 @@ class XSdata(object): check_type('total', total, Iterable, expected_iter_type=Real) # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.energy_groups.num_groups,)] - else: - shapes = [(self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups)] + shapes = [self.xs_shapes["[G]"]] # Convert to a numpy array so we can easily get the shape for checking total = np.asarray(total) @@ -431,11 +497,7 @@ class XSdata(object): check_type('absorption', absorption, Iterable, expected_iter_type=Real) # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.energy_groups.num_groups,)] - else: - shapes = [(self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups)] + shapes = [self.xs_shapes["[G]"]] # Convert to a numpy array so we can easily get the shape for checking absorption = np.asarray(absorption) @@ -467,11 +529,7 @@ class XSdata(object): check_type('fission', fission, Iterable, expected_iter_type=Real) # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.energy_groups.num_groups,)] - else: - shapes = [(self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups)] + shapes = [self.xs_shapes["[G]"]] # Convert to a numpy array so we can easily get the shape for checking fission = np.asarray(fission) @@ -507,11 +565,7 @@ class XSdata(object): expected_iter_type=Real) # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.energy_groups.num_groups,)] - else: - shapes = [(self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups)] + shapes = [self.xs_shapes["[G]"]] # Convert to a numpy array so we can easily get the shape for checking kappa_fission = np.asarray(kappa_fission) @@ -544,11 +598,7 @@ class XSdata(object): """ # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.energy_groups.num_groups,)] - else: - shapes = [(self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups)] + shapes = [self.xs_shapes["[G']"]] # Convert to a numpy array so we can easily get the shape for checking chi = np.asarray(chi) @@ -578,11 +628,7 @@ class XSdata(object): """ # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.energy_groups.num_groups,)] - else: - shapes = [(self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups)] + shapes = [self.xs_shapes["[G']"]] # Convert to a numpy array so we can easily get the shape for checking chi_prompt = np.asarray(chi_prompt) @@ -611,6 +657,9 @@ class XSdata(object): """ + # Get the accepted shapes for this xs + shapes = [self.xs_shapes["[G']"], self.xs_shapes["[DG][G']"]] + # Get the accepted shapes for this xs if self.representation is 'isotropic': shapes = [(self.energy_groups.num_groups,), @@ -649,14 +698,7 @@ class XSdata(object): """ # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.num_delayed_groups,), - (self.num_delayed_groups, self.energy_groups.num_groups)] - else: - shapes = [(self.num_delayed_groups, self.num_polar, - self.num_azimuthal, self.energy_groups.num_groups), - (self.num_delayed_groups, self.num_polar, - self.num_azimuthal)] + shapes = [self.xs_shapes["[DG]"], self.xs_shapes["[DG][G]"]] # Convert to a numpy array so we can easily get the shape for checking beta = np.asarray(beta) @@ -688,14 +730,7 @@ class XSdata(object): check_type('decay_rate', decay_rate, Iterable, expected_iter_type=Real) # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.num_delayed_groups,), - (self.num_delayed_groups, self.energy_groups.num_groups)] - else: - shapes = [(self.num_delayed_groups, self.num_polar, - self.num_azimuthal, self.energy_groups.num_groups), - (self.num_delayed_groups, self.num_polar, - self.num_azimuthal)] + shapes = [self.xs_shapes["[DG]"], self.xs_shapes["[DG][G]"]] # Convert to a numpy array so we can easily get the shape for checking decay_rate = np.asarray(decay_rate) @@ -725,13 +760,7 @@ class XSdata(object): """ # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.num_orders, self.energy_groups.num_groups, - self.energy_groups.num_groups)] - else: - shapes = [(self.num_polar, self.num_azimuthal, self.num_orders, - self.energy_groups.num_groups, - self.energy_groups.num_groups)] + shapes = [self.xs_shapes["[Order][G][G']"]] # Convert to a numpy array so we can easily get the shape for checking scatter = np.asarray(scatter) @@ -763,13 +792,7 @@ class XSdata(object): """ # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.energy_groups.num_groups, - self.energy_groups.num_groups)] - else: - shapes = [(self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups, - self.energy_groups.num_groups)] + shapes = [self.xs_shapes["[G][G']"]] # Convert to a numpy array so we can easily get the shape for checking multiplicity = np.asarray(multiplicity) @@ -801,16 +824,7 @@ class XSdata(object): """ # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.energy_groups.num_groups,), - (self.energy_groups.num_groups, - self.energy_groups.num_groups)] - else: - shapes = [(self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups), - (self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups, - self.energy_groups.num_groups)] + shapes = [self.xs_shapes["[G]"], self.xs_shapes["[G][G']"]] # Convert to a numpy array so we can easily get the shape for checking nu_fission = np.asarray(nu_fission) @@ -843,12 +857,8 @@ class XSdata(object): """ - # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.energy_groups.num_groups,)] - else: - shapes = [(self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups)] + # Get the accepted shapes for this xs + shapes = [self.xs_shapes["[G]"]] # Convert to a numpy array so we can easily get the shape for checking prompt_nu_fission = np.asarray(prompt_nu_fission) @@ -881,7 +891,10 @@ class XSdata(object): """ - # Get the accepted shapes for this xs + # Get the accepted shapes for this xs + shapes = [self.xs_shapes["[DG][G]"]] + + # Get the accepted shapes for this xs if self.representation is 'isotropic': shapes = [(self.num_delayed_groups, self.energy_groups.num_groups,)] else: @@ -920,11 +933,7 @@ class XSdata(object): expected_iter_type=Real) # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.energy_groups.num_groups,)] - else: - shapes = [(self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups)] + shapes = [self.xs_shapes["[G]"]] # Convert to a numpy array so we can easily get the shape for checking inv_vel = np.asarray(inv_vel) @@ -1687,10 +1696,9 @@ class XSdata(object): if self.num_polar is not None: grp.attrs['num-polar'] = self.num_polar + grp.attrs['scatter_shape'] = np.string_("[Order][G][G']") if self.scatter_format is not None: grp.attrs['scatter_format'] = np.string_(self.scatter_format) - if self.scatter_shape is not None: - grp.attrs['scatter_shape'] = np.string_(self.scatter_shape) if self.order is not None: grp.attrs['order'] = self.order @@ -1918,8 +1926,10 @@ class MGXSLibrary(object): @num_delayed_groups.setter def num_delayed_groups(self, num_delayed_groups): check_type('num_delayed_groups', num_delayed_groups, int) - check_greater_than('delayed_groups', num_delayed_groups, 0, + check_greater_than('num_delayed_groups', num_delayed_groups, 0, equality=True) + check_less_than('num_delayed_groups', num_delayed_groups, + openmc.mgxs.MAX_DELAYED_GROUPS, equality=True) self._num_delayed_groups = num_delayed_groups def add_xsdata(self, xsdata): From e28f71a27e3002af6d57eb9b77a4b98ed92eb274 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Wed, 19 Oct 2016 10:54:48 -0400 Subject: [PATCH 13/27] modified python doc string in mgxs_library.py --- openmc/mgxs_library.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index f6b92b4175..38c61ff56e 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -114,7 +114,7 @@ class XSdata(object): beta : dict of numpy.ndarray Delayed-group-wise delayed neutron fraction cross section vector. decay_rate : dict of numpy.ndarray - Delayed-group-wise decay rate cross section vector. + Delayed-group-wise decay rate vector. inverse_velocity : dict of numpy.ndarray Inverse of velocity, in units of sec/cm. xs_shapes : dict of iterable of int @@ -148,7 +148,7 @@ class XSdata(object): [DG][G]: delayed_nu_fission, beta, decay_rate - [DG][G']: chi_delayed, + [DG][G']: chi_delayed """ From 5f750f3976ec4d11aa7c512318f0cffdfedad294 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Wed, 19 Oct 2016 11:58:32 -0400 Subject: [PATCH 14/27] updated setting of delayed groups in mgxs tests --- openmc/mgxs/library.py | 5 +++-- .../test_mgxs_library_condense/test_mgxs_library_condense.py | 5 +---- .../test_mgxs_library_distribcell.py | 5 +---- tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py | 5 +---- tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py | 5 +---- .../test_mgxs_library_no_nuclides.py | 5 +---- 6 files changed, 8 insertions(+), 22 deletions(-) diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 14f6ece3ce..7344445567 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -331,7 +331,7 @@ class Library(object): def num_delayed_groups(self, num_delayed_groups): cv.check_less_than('num delayed groups', num_delayed_groups, - MAX_DELAYED_GROUPS, equality=True) + openmc.mgxs.MAX_DELAYED_GROUPS, equality=True) cv.check_greater_than('num delayed groups', num_delayed_groups, 0, equality=True) self._num_delayed_groups = num_delayed_groups @@ -422,7 +422,8 @@ class Library(object): if self.num_delayed_groups == 0: mgxs.delayed_groups = None else: - delayed_groups = list(range(1,self.num_delayed_groups)) + delayed_groups \ + = list(range(1,self.num_delayed_groups+1)) mgxs.delayed_groups = delayed_groups # If a tally trigger was specified, add it to the MGXS diff --git a/tests/test_mgxs_library_condense/test_mgxs_library_condense.py b/tests/test_mgxs_library_condense/test_mgxs_library_condense.py index d3f2bc08e8..19c6ffda90 100644 --- a/tests/test_mgxs_library_condense/test_mgxs_library_condense.py +++ b/tests/test_mgxs_library_condense/test_mgxs_library_condense.py @@ -23,9 +23,6 @@ class MGXSTestHarness(PyAPITestHarness): energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625e-6, 20.]) - # Initialize a six-delayed-group structure - delayed_groups = list(range(1,7)) - # Initialize MGXS Library for a few cross section types self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) self.mgxs_lib.by_nuclide = False @@ -34,7 +31,7 @@ class MGXSTestHarness(PyAPITestHarness): self.mgxs_lib.mgxs_types = openmc.mgxs.MGXS_TYPES + \ openmc.mgxs.MDGXS_TYPES self.mgxs_lib.energy_groups = energy_groups - self.mgxs_lib.delayed_groups = delayed_groups + self.mgxs_lib.num_delayed_groups = 6 self.mgxs_lib.legendre_order = 3 self.mgxs_lib.domain_type = 'material' self.mgxs_lib.build_library() diff --git a/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py b/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py index 940985d916..5c402749ab 100644 --- a/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py +++ b/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py @@ -22,9 +22,6 @@ class MGXSTestHarness(PyAPITestHarness): # Initialize a one-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 20.]) - # Initialize a six-delayed-group structure - delayed_groups = list(range(1,7)) - # Initialize MGXS Library for a few cross section types # for one material-filled cell in the geometry self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) @@ -34,7 +31,7 @@ class MGXSTestHarness(PyAPITestHarness): self.mgxs_lib.mgxs_types = openmc.mgxs.MGXS_TYPES + \ openmc.mgxs.MDGXS_TYPES self.mgxs_lib.energy_groups = energy_groups - self.mgxs_lib.delayed_groups = delayed_groups + self.mgxs_lib.num_delayed_groups = 6 self.mgxs_lib.legendre_order = 3 self.mgxs_lib.domain_type = 'distribcell' cells = self.mgxs_lib.openmc_geometry.get_all_material_cells() diff --git a/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py b/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py index b4d7e5dbbe..959f9e70a8 100644 --- a/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py +++ b/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py @@ -24,9 +24,6 @@ class MGXSTestHarness(PyAPITestHarness): energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625e-6, 20.]) - # Initialize a six-delayed-group structure - delayed_groups = list(range(1,7)) - # Initialize MGXS Library for a few cross section types self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) self.mgxs_lib.by_nuclide = False @@ -35,7 +32,7 @@ class MGXSTestHarness(PyAPITestHarness): self.mgxs_lib.mgxs_types = openmc.mgxs.MGXS_TYPES + \ openmc.mgxs.MDGXS_TYPES self.mgxs_lib.energy_groups = energy_groups - self.mgxs_lib.delayed_groups = delayed_groups + self.mgxs_lib.num_delayed_groups = 6 self.mgxs_lib.legendre_order = 3 self.mgxs_lib.domain_type = 'material' self.mgxs_lib.build_library() diff --git a/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py b/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py index 1f31bd5660..3a42ccd34e 100644 --- a/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py +++ b/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py @@ -18,9 +18,6 @@ class MGXSTestHarness(PyAPITestHarness): # Initialize a one-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 20.]) - # Initialize a six-delayed-group structure - delayed_groups = list(range(1,7)) - # Initialize MGXS Library for a few cross section types # for one material-filled cell in the geometry self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) @@ -30,7 +27,7 @@ class MGXSTestHarness(PyAPITestHarness): self.mgxs_lib.mgxs_types = openmc.mgxs.MGXS_TYPES + \ openmc.mgxs.MDGXS_TYPES self.mgxs_lib.energy_groups = energy_groups - self.mgxs_lib.delayed_groups = delayed_groups + self.mgxs_lib.num_delayed_groups = 6 self.mgxs_lib.legendre_order = 3 self.mgxs_lib.domain_type = 'mesh' diff --git a/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py b/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py index edd41f1c56..a8eea412be 100644 --- a/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py +++ b/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py @@ -23,9 +23,6 @@ class MGXSTestHarness(PyAPITestHarness): energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625e-6, 20.]) - # Initialize a six-delayed-group structure - delayed_groups = list(range(1,7)) - # Initialize MGXS Library for a few cross section types self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) self.mgxs_lib.by_nuclide = False @@ -34,7 +31,7 @@ class MGXSTestHarness(PyAPITestHarness): self.mgxs_lib.mgxs_types = openmc.mgxs.MGXS_TYPES + \ openmc.mgxs.MDGXS_TYPES self.mgxs_lib.energy_groups = energy_groups - self.mgxs_lib.delayed_groups = delayed_groups + self.mgxs_lib.num_delayed_groups = 6 self.mgxs_lib.legendre_order = 3 self.mgxs_lib.domain_type = 'material' self.mgxs_lib.build_library() From 3b40554673bf25e0cfaaefaf817028bd626cdf1b Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Sun, 23 Oct 2016 15:57:28 -0400 Subject: [PATCH 15/27] removed unnecessary code in mgxs_library.py --- openmc/mgxs_library.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 3da26f0305..8199a27515 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -659,16 +659,6 @@ class XSdata(object): # Get the accepted shapes for this xs shapes = [self.xs_shapes["[G']"], self.xs_shapes["[DG][G']"]] - # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.energy_groups.num_groups,), - (self.num_delayed_groups, self.energy_groups.num_groups)] - else: - shapes = [(self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups), - (self.num_delayed_groups, self.num_polar, - self.num_azimuthal, self.energy_groups.num_groups)] - # Convert to a numpy array so we can easily get the shape for checking chi_delayed = np.asarray(chi_delayed) check_value('chi delayed shape', chi_delayed.shape, shapes) @@ -893,13 +883,6 @@ class XSdata(object): # Get the accepted shapes for this xs shapes = [self.xs_shapes["[DG][G]"]] - # Get the accepted shapes for this xs - if self.representation is 'isotropic': - shapes = [(self.num_delayed_groups, self.energy_groups.num_groups,)] - else: - shapes = [(self.num_delayed_groups, self.num_polar, - self.num_azimuthal, self.energy_groups.num_groups)] - # Convert to a numpy array so we can easily get the shape for checking delayed_nu_fission = np.asarray(delayed_nu_fission) check_value('delayed_nu_fission shape', delayed_nu_fission.shape, From edbb25f5569b2e683c5895d5e565ea4c7da1396e Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Mon, 24 Oct 2016 09:59:41 -0400 Subject: [PATCH 16/27] shortened setting of xs shapes --- openmc/mgxs_library.py | 54 +++++++++++++----------------------------- 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 8199a27515..cb4483464a 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -289,44 +289,24 @@ class XSdata(object): if self._xs_shapes is None: self._xs_shapes = {} - - if self.representation == 'isotropic': - self._xs_shapes["[G]"] = (self.energy_groups.num_groups,) - self._xs_shapes["[G']"] = (self.energy_groups.num_groups,) - self._xs_shapes["[G][G']"] = (self.energy_groups.num_groups, - self.energy_groups.num_groups) - self._xs_shapes["[DG]"] = (self.num_delayed_groups,) - self._xs_shapes["[DG][G]"] = (self.num_delayed_groups, - self.energy_groups.num_groups) - self._xs_shapes["[DG][G']"] = (self.num_delayed_groups, - self.energy_groups.num_groups) - self._xs_shapes["[Order][G][G']"] \ - = (self.num_orders, self.energy_groups.num_groups, - self.energy_groups.num_groups) - - elif self.representation == 'angle': - self._xs_shapes["[G]"] = (self.num_polar, self.num_azimuthal, - self.energy_groups.num_groups) - self._xs_shapes["[G']"] = (self.num_polar, self.num_azimuthal, + self._xs_shapes["[G]"] = (self.energy_groups.num_groups,) + self._xs_shapes["[G']"] = (self.energy_groups.num_groups,) + self._xs_shapes["[G][G']"] = (self.energy_groups.num_groups, + self.energy_groups.num_groups) + self._xs_shapes["[DG]"] = (self.num_delayed_groups,) + self._xs_shapes["[DG][G]"] = (self.num_delayed_groups, + self.energy_groups.num_groups) + self._xs_shapes["[DG][G']"] = (self.num_delayed_groups, self.energy_groups.num_groups) - self._xs_shapes["[G][G']"] = (self.num_polar, - self.num_azimuthal, - self.energy_groups.num_groups, - self.energy_groups.num_groups) - self._xs_shapes["[DG]"] = (self.num_polar, self.num_azimuthal, - self.num_delayed_groups) - self._xs_shapes["[DG][G]"] = (self.num_polar, - self.num_azimuthal, - self.num_delayed_groups, - self.energy_groups.num_groups) - self._xs_shapes["[DG][G']"] = (self.num_polar, - self.num_azimuthal, - self.num_delayed_groups, - self.energy_groups.num_groups) - self._xs_shapes["[Order][G][G']"] \ - = (self.num_polar, self.num_azimuthal, self.num_orders, - self.energy_groups.num_groups, - self.energy_groups.num_groups) + self._xs_shapes["[Order][G][G']"] \ + = (self.num_orders, self.energy_groups.num_groups, + self.energy_groups.num_groups) + + # If representation is by angle prepend num polar and num azim + if self.representation == 'angle': + for key,shapes in self._xs_shapes.items(): + self._xs_shapes[key] \ + = (self.num_polar, self.num_azimuthal) + shapes return self._xs_shapes From 65cf4305999f66e58eca1c6ef36c075ad5079804 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Mon, 24 Oct 2016 10:08:19 -0400 Subject: [PATCH 17/27] fixed some errors in tally.F90 --- src/tally.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tally.F90 b/src/tally.F90 index b151e35ddf..cc21c67c13 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -1587,7 +1587,7 @@ contains if (i_nuclide > 0) then score = score * nucxs % get_xs('delayed-nu-fission', & p_g, UVW=p_uvw, dg=d) / & - nucxs % get_xs('absorption', p_g, UVW=p_uvw) + matxs % get_xs('absorption', p_g, UVW=p_uvw) else score = score * matxs % get_xs('delayed-nu-fission', & p_g, UVW=p_uvw, dg=d) / & @@ -1602,7 +1602,7 @@ contains score = p % absorb_wgt * flux if (i_nuclide > 0) then score = score * nucxs % get_xs('delayed-nu-fission', p_g, & - UVW=p_uvw) / nucxs % get_xs('absorption', p_g, UVW=p_uvw) + UVW=p_uvw) / matxs % get_xs('absorption', p_g, UVW=p_uvw) else score = score * matxs % get_xs('delayed-nu-fission', p_g, & UVW=p_uvw) / matxs % get_xs('absorption', p_g, UVW=p_uvw) @@ -1724,7 +1724,7 @@ contains score = score * nucxs % get_xs('decay rate', p_g, & UVW=p_uvw, dg=d) * & nucxs % get_xs('delayed-nu-fission', p_g, & - UVW=p_uvw, dg=d) / nucxs % get_xs('absorption', & + UVW=p_uvw, dg=d) / matxs % get_xs('absorption', & p_g, UVW=p_uvw) else score = score * matxs % get_xs('decay rate', p_g, & @@ -1751,7 +1751,7 @@ contains score = score + p % absorb_wgt * & nucxs % get_xs('decay rate', p_g, UVW=p_uvw, dg=d) * & nucxs % get_xs('delayed-nu-fission', p_g, UVW=p_uvw, & - dg=d) / nucxs % get_xs('absorption', p_g, UVW=p_uvw) + dg=d) / matxs % get_xs('absorption', p_g, UVW=p_uvw) else score = score + p % absorb_wgt * & matxs % get_xs('decay rate', p_g, UVW=p_uvw, dg=d) * & From c7016ba1f20c7befbf1d5c32c44e0e2cac4111ea Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Mon, 31 Oct 2016 12:12:04 -0400 Subject: [PATCH 18/27] fixed errors with ordering delayed groups and energy groups in mgxs_header.F90 --- src/mgxs_header.F90 | 245 ++++++++++++++++++++------------------- tests/testing_harness.py | 3 +- 2 files changed, 125 insertions(+), 123 deletions(-) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index bd574e1a22..28931dbd5d 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -418,8 +418,8 @@ module mgxs_header 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) :: energy_groups ! Number of energy groups - integer, intent(in) :: delayed_groups ! Number of delayed groups + integer, intent(in) :: energy_groups ! Number of energy groups + integer, intent(in) :: delayed_groups ! Number of delayed groups type(VectorReal), intent(in) :: temperature ! list of desired temperatures integer, intent(inout) :: method ! Type of temperature access real(8), intent(in) :: tolerance ! Tolerance on method @@ -456,14 +456,14 @@ module mgxs_header ! Allocate data for all the cross sections allocate(xs % total(energy_groups)) allocate(xs % absorption(energy_groups)) - allocate(xs % delayed_nu_fission(energy_groups, delayed_groups)) + allocate(xs % delayed_nu_fission(delayed_groups, energy_groups)) allocate(xs % prompt_nu_fission(energy_groups)) allocate(xs % fission(energy_groups)) allocate(xs % kappa_fission(energy_groups)) allocate(xs % decay_rate(delayed_groups)) allocate(xs % inverse_velocity(energy_groups)) - allocate(xs % chi_delayed(energy_groups, energy_groups, & - delayed_groups)) + allocate(xs % chi_delayed(delayed_groups, energy_groups, & + energy_groups)) allocate(xs % chi_prompt(energy_groups, energy_groups)) ! Set all fissionable terms to zero @@ -479,7 +479,7 @@ module mgxs_header if (this % fissionable) then ! Allocate temporary array for beta - allocate(temp_beta(energy_groups, delayed_groups)) + allocate(temp_beta(delayed_groups, energy_groups)) ! Set beta if (object_exists(xsdata_grp, "beta")) then @@ -499,7 +499,7 @@ module mgxs_header do dg = 1, delayed_groups do gin = 1, energy_groups - temp_beta(gin, dg) = temp_arr(dg) + temp_beta(dg, gin) = temp_arr(dg) end do end do @@ -516,7 +516,7 @@ module mgxs_header call read_dataset(temp_arr, xsdata_grp, "beta") ! Reshape array and set to dedicated beta array - temp_beta = reshape(temp_arr, (/energy_groups, delayed_groups/)) + temp_beta = reshape(temp_arr, (/delayed_groups, energy_groups/)) ! Deallocate temporary beta array deallocate(temp_arr) @@ -554,7 +554,7 @@ module mgxs_header ! Set chi-delayed to chi-prompt do dg = 1, delayed_groups - xs % chi_delayed(:, :, dg) = xs % chi_prompt(:, :) + xs % chi_delayed(dg, :, :) = xs % chi_prompt(:, :) end do ! Deallocate temporary chi array @@ -583,12 +583,12 @@ module mgxs_header do dg = 1, delayed_groups ! Set delayed-nu-fission using delayed neutron fraction - xs % delayed_nu_fission(gin, dg) = temp_beta(gin, dg) * & + xs % delayed_nu_fission(dg, gin) = temp_beta(dg, gin) * & xs % prompt_nu_fission(gin) end do ! Correct prompt-nu-fission using delayed neutron fraction - xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(gin, :))) * & + xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(:, gin))) * & xs % prompt_nu_fission(gin) end do @@ -616,12 +616,12 @@ module mgxs_header do dg = 1, delayed_groups ! Set delayed-nu-fission using delayed neutron fraction - xs % delayed_nu_fission(gin, dg) = temp_beta(gin, dg) * & + xs % delayed_nu_fission(dg, gin) = temp_beta(dg, gin) * & xs % prompt_nu_fission(gin) end do ! Correct prompt-nu-fission using delayed neutron fraction - xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(gin, :))) * & + xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(:, gin))) * & xs % prompt_nu_fission(gin) end do @@ -644,7 +644,7 @@ module mgxs_header ! Set chi-delayed to chi-prompt do dg = 1, delayed_groups - xs % chi_delayed(:, :, dg) = xs % chi_prompt(:, :) + xs % chi_delayed(dg, :, :) = xs % chi_prompt(:, :) end do else call fatal_error("nu-fission must be provided as a 1D or 2D & @@ -699,17 +699,17 @@ module mgxs_header do dg = 1, delayed_groups do gin = 1, energy_groups do gout = 1, energy_groups - xs % chi_delayed(gout, gin, dg) = temp_arr(gout) + xs % chi_delayed(dg, gout, gin) = temp_arr(gout) end do ! Normalize chi so its CDF goes to 1 - chi_sum = sum(xs % chi_delayed(:, gin, dg)) + chi_sum = sum(xs % chi_delayed(dg, :, gin)) if (chi_sum == ZERO) then call fatal_error("Encountered chi delayed for a group & &that sums to zero") else - xs % chi_delayed(:, gin, dg) = & - xs % chi_delayed(:, gin, dg) / chi_sum + xs % chi_delayed(dg, :, gin) = & + xs % chi_delayed(dg, :, gin) / chi_sum end if end do end do @@ -724,23 +724,23 @@ module mgxs_header ! Get chi-delayed call read_dataset(temp_arr, xsdata_grp, "chi-delayed") - allocate(temp_2d(energy_groups, delayed_groups)) - temp_2d = reshape(temp_arr, (/energy_groups, delayed_groups/)) + allocate(temp_2d(delayed_groups, energy_groups)) + temp_2d = reshape(temp_arr, (/delayed_groups, energy_groups/)) do dg = 1, delayed_groups do gin = 1, energy_groups do gout = 1, energy_groups - xs % chi_delayed(gout, gin, dg) = temp_2d(gout, dg) + xs % chi_delayed(dg, gout, gin) = temp_2d(dg, gout) end do ! Normalize chi so its CDF goes to 1 - chi_sum = sum(xs % chi_delayed(:, gin, dg)) + chi_sum = sum(xs % chi_delayed(dg, :, gin)) if (chi_sum == ZERO) then call fatal_error("Encountered chi delayed for a group & &that sums to zero") else - xs % chi_delayed(:, gin, dg) = & - xs % chi_delayed(:, gin, dg) / chi_sum + xs % chi_delayed(dg, :, gin) = & + xs % chi_delayed(dg, :, gin) / chi_sum end if end do end do @@ -790,7 +790,7 @@ module mgxs_header do dg = 1, delayed_groups ! Set delayed-nu-fission using delayed neutron fraction - xs % delayed_nu_fission(gin, dg) = temp_beta(gin, dg) * & + xs % delayed_nu_fission(dg, gin) = temp_beta(dg, gin) * & temp_arr(gin) end do end do @@ -807,17 +807,17 @@ module mgxs_header call get_shape(xsdata, dims) ! Issue error if 1st dimension not correct - if (dims(1) /= energy_groups) then + if (dims(1) /= delayed_groups) then call fatal_error("The delayed-nu-fission matrix was input & &with a 1st dimension not equal to the number of & - &energy groups.") + &delayed groups.") end if ! Issue error if 2nd dimension not correct - if (dims(2) /= delayed_groups) then + if (dims(2) /= energy_groups) then call fatal_error("The delayed-nu-fission matrix was input & &with a 2nd dimension not equal to the number of & - &delayed groups.") + &energy groups.") end if ! Issue warning if delayed_groups == energy_groups @@ -825,16 +825,16 @@ module mgxs_header call warning("delayed-nu-fission was input as a dimension & &2 matrix with the same number of delayed groups and & &groups. It is important to know that OpenMC assumes & - &the dimensions in the matrix are (energy_groups, & - &delayed_groups). Currently, delayed-nu-fission cannot & + &the dimensions in the matrix are (delayed_groups, & + &energy_groups). Currently, delayed-nu-fission cannot & &be set as a group by group matrix.") end if ! Get delayed-nu-fission allocate(temp_arr(delayed_groups * energy_groups)) call read_dataset(temp_arr, xsdata_grp, "delayed-nu-fission") - xs % delayed_nu_fission = reshape(temp_arr, (/energy_groups, & - delayed_groups/)) + xs % delayed_nu_fission = reshape(temp_arr, (/delayed_groups, & + energy_groups/)) ! Deallocate temporary array for delayed-nu-fission matrix deallocate(temp_arr) @@ -1094,8 +1094,8 @@ module mgxs_header 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) :: energy_groups ! Number of energy groups - integer, intent(in) :: delayed_groups ! Number of energy groups + integer, intent(in) :: energy_groups ! Number of energy groups + integer, intent(in) :: delayed_groups ! Number of energy groups type(VectorReal), intent(in) :: temperature ! list of desired temperatures integer, intent(inout) :: method ! Type of temperature access real(8), intent(in) :: tolerance ! Tolerance on method @@ -1110,7 +1110,7 @@ module mgxs_header integer, allocatable :: int_arr(:) real(8), allocatable :: temp_1d(:), temp_3d(:, :, :) real(8), allocatable :: temp_4d(:, :, :, :), temp_beta(:, :, :, :) - real(8) :: dmu, mu, norm + real(8) :: dmu, mu, norm, chi_sum integer :: order, order_dim, gin, gout, l, imu, dg type(VectorInt) :: temps_to_read integer :: t, length, ipol, iazi @@ -1133,12 +1133,12 @@ module mgxs_header ! Load the more specific data allocate(xs % prompt_nu_fission(energy_groups, this % n_azi, & this % n_pol)) - allocate(xs % delayed_nu_fission(energy_groups, delayed_groups, & + allocate(xs % delayed_nu_fission(delayed_groups, energy_groups, & this % n_azi, this % n_pol)) allocate(xs % chi_prompt(energy_groups, energy_groups, this % n_azi, & this % n_pol)) - allocate(xs % chi_delayed(energy_groups, energy_groups, & - delayed_groups, this % n_azi, this % n_pol)) + allocate(xs % chi_delayed(delayed_groups, energy_groups, & + energy_groups, this % n_azi, this % n_pol)) allocate(xs % total(energy_groups, this % n_azi, this % n_pol)) allocate(xs % absorption(energy_groups, this % n_azi, this % n_pol)) allocate(xs % fission(energy_groups, this % n_azi, this % n_pol)) @@ -1161,7 +1161,7 @@ module mgxs_header if (this % fissionable) then ! Allocate temporary array for beta - allocate(temp_beta(energy_groups, delayed_groups, this % n_azi, & + allocate(temp_beta(delayed_groups, energy_groups, this % n_azi, & this % n_pol)) ! Set beta @@ -1187,7 +1187,7 @@ module mgxs_header do iazi = 1, this % n_azi do dg = 1, delayed_groups do gin = 1, energy_groups - temp_beta(gin, dg, iazi, ipol) = temp_3d(dg, iazi, ipol) + temp_beta(dg, gin, iazi, ipol) = temp_3d(dg, iazi, ipol) end do end do end do @@ -1208,8 +1208,8 @@ module mgxs_header call read_dataset(temp_1d, xsdata_grp, "beta") ! Reshape array and set to dedicated beta array - temp_beta = reshape(temp_1d, (/energy_groups, & - delayed_groups, this % n_azi, this % n_pol/)) + temp_beta = reshape(temp_1d, (/delayed_groups, & + energy_groups, this % n_azi, this % n_pol/)) ! Deallocate temporary beta array deallocate(temp_1d) @@ -1242,13 +1242,13 @@ module mgxs_header end do ! Normalize chi-prompt so its CDF goes to 1 - if (sum(xs % chi_prompt(:, gin, iazi, ipol)) == ZERO) then + chi_sum = sum(xs % chi_prompt(:, gin, iazi, ipol)) + if (chi_sum == ZERO) then call fatal_error("Encountered chi for a group that sums& & to zero") else xs % chi_prompt(:, gin, iazi, ipol) = & - xs % chi_prompt(:, gin, iazi, ipol) / & - sum(xs % chi_prompt(:, gin, iazi, ipol)) + xs % chi_prompt(:, gin, iazi, ipol) / chi_sum end if end do end do @@ -1258,7 +1258,7 @@ module mgxs_header do ipol = 1, this % n_pol do iazi = 1, this % n_azi do dg = 1, delayed_groups - xs % chi_delayed(:, :, dg, iazi, ipol) = & + xs % chi_delayed(dg, :, :, iazi, ipol) = & xs % chi_prompt(:, :, iazi, ipol) end do end do @@ -1290,13 +1290,13 @@ module mgxs_header end do ! Normalize chi so its CDF goes to 1 - if (sum(xs % chi_prompt(:, gin, iazi, ipol)) == ZERO) then + chi_sum = sum(xs % chi_prompt(:, gin, iazi, ipol)) + if (chi_sum == ZERO) then call fatal_error("Encountered chi prompt for a group that& & sums to zero") else xs % chi_prompt(:, gin, iazi, ipol) = & - xs % chi_prompt(:, gin, iazi, ipol) / & - sum(xs % chi_prompt(:, gin, iazi, ipol)) + xs % chi_prompt(:, gin, iazi, ipol) / chi_sum end if end do end do @@ -1314,16 +1314,16 @@ module mgxs_header xsdata = open_dataset(xsdata_grp, "chi-delayed") call get_ndims(xsdata, ndims) - ! If chi-delayed is a vector - if (ndims == 1) then + ! chi-delayed is input as (energy_groups, n_azi, n_pol) + if (ndims == 3) then ! Allocate temporary array for chi-prompt - allocate(temp_1d(delayed_groups * this % n_azi * this % n_pol)) - allocate(temp_3d(delayed_groups, this % n_azi, this % n_pol)) + allocate(temp_1d(energy_groups * this % n_azi * this % n_pol)) + allocate(temp_3d(energy_groups, this % n_azi, this % n_pol)) ! Get array with chi-prompt call read_dataset(temp_1d, xsdata_grp, "chi-delayed") - temp_3d = reshape(temp_1d, (/delayed_groups, this % n_azi, & + temp_3d = reshape(temp_1d, (/energy_groups, this % n_azi, & this % n_pol/)) do ipol = 1, this % n_pol @@ -1331,19 +1331,19 @@ module mgxs_header do dg = 1, delayed_groups do gin = 1, energy_groups do gout = 1, energy_groups - xs % chi_delayed(gout, gin, dg, iazi, ipol) = & + xs % chi_delayed(dg, gout, gin, iazi, ipol) = & temp_3d(gout, iazi, ipol) end do ! Normalize chi so its CDF goes to 1 - if (sum(xs % chi_delayed(:, gin, dg, iazi, ipol)) & - == ZERO) then + chi_sum = sum(xs % chi_delayed(dg, :, gin, iazi, ipol)) + if (chi_sum == ZERO) then call fatal_error("Encountered chi delayed for a group& & that sums to zero") else - xs % chi_delayed(:, gin, dg, iazi, ipol) = & - xs % chi_delayed(:, gin, dg, iazi, ipol) / & - sum(xs % chi_delayed(:, gin, dg, iazi, ipol)) + xs % chi_delayed(dg, :, gin, iazi, ipol) = & + xs % chi_delayed(dg, :, gin, iazi, ipol) / & + chi_sum end if end do end do @@ -1354,17 +1354,19 @@ module mgxs_header deallocate(temp_1d) deallocate(temp_3d) - else if (ndims == 2) then + ! chi-delayed is input as (delayed_groups, energy_groups, n_azi, + ! n_pol) + else if (ndims == 4) then ! Allocate temporary array for chi-delayed allocate(temp_1d(delayed_groups * energy_groups * this % n_azi & * this % n_pol)) - allocate(temp_4d(energy_groups, delayed_groups, this % n_azi, & + allocate(temp_4d(delayed_groups, energy_groups, this % n_azi, & this % n_pol)) ! Get chi-delayed call read_dataset(temp_1d, xsdata_grp, "chi-delayed") - temp_4d = reshape(temp_1d, (/energy_groups, delayed_groups, & + temp_4d = reshape(temp_1d, (/delayed_groups, energy_groups, & this % n_azi, this % n_pol/)) do ipol = 1, this % n_pol @@ -1372,19 +1374,19 @@ module mgxs_header do dg = 1, delayed_groups do gin = 1, energy_groups do gout = 1, energy_groups - xs % chi_delayed(gout, gin, dg, iazi, ipol) = & - temp_4d(gout, dg, iazi, ipol) + xs % chi_delayed(dg, gout, gin, iazi, ipol) = & + temp_4d(dg, gout, iazi, ipol) end do ! Normalize chi so its CDF goes to 1 - if (sum(xs % chi_delayed(:, gin, dg, iazi, ipol)) & - == ZERO) then + chi_sum = sum(xs % chi_delayed(dg, :, gin, iazi, ipol)) + if (chi_sum == ZERO) then call fatal_error("Encountered chi delayed for a group& & that sums to zero") else - xs % chi_delayed(:, gin, dg, iazi, ipol) = & - xs % chi_delayed(:, gin, dg, iazi, ipol) / & - sum(xs % chi_delayed(:, gin, dg, iazi, ipol)) + xs % chi_delayed(dg, :, gin, iazi, ipol) = & + xs % chi_delayed(dg, :, gin, iazi, ipol) / & + chi_sum end if end do end do @@ -1424,7 +1426,7 @@ module mgxs_header xsdata = open_dataset(xsdata_grp, "delayed-nu-fission") call get_ndims(xsdata, ndims) - ! If delayed-nu-fission is a vector + ! delayed-nu-fission is input as (energy_groups, n_azi, n_pol) if (ndims == 3) then ! If beta is zeros, raise error @@ -1448,8 +1450,8 @@ module mgxs_header do dg = 1, delayed_groups ! Set delayed-nu-fission using delayed neutron fraction - xs % delayed_nu_fission(gin, dg, iazi, ipol) = & - temp_beta(gin, dg, iazi, ipol) * & + xs % delayed_nu_fission(dg, gin, iazi, ipol) = & + temp_beta(dg, gin, iazi, ipol) * & temp_3d(gin, iazi, ipol) end do end do @@ -1460,26 +1462,26 @@ module mgxs_header deallocate(temp_1d) deallocate(temp_3d) - ! If delayed-nu-fission is a (delayed_group, energy_group) - ! matrix, set delayed-nu-fission separately for each delayed - ! group. + ! If delayed-nu-fission is a (delayed_group, energy_group, + ! n_azi, n_pol) matrix, set delayed-nu-fission separately for + ! each delayed group. else if (ndims == 4) then ! Get the shape of delayed-nu-fission call get_shape(xsdata, dims) ! Issue error if 1st dimension not correct - if (dims(1) /= energy_groups) then + if (dims(1) /= delayed_groups) then call fatal_error("The delayed-nu-fission matrix was input & &with a 1st dimension not equal to the number of & - &energy groups.") + &delayed groups.") end if ! Issue error if 2nd dimension not correct - if (dims(2) /= delayed_groups) then + if (dims(2) /= energy_groups) then call fatal_error("The delayed-nu-fission matrix was input & &with a 2nd dimension not equal to the number of & - &delayed groups.") + &energy groups.") end if ! Issue warning if delayed_groups == energy_groups @@ -1487,8 +1489,8 @@ module mgxs_header call warning("delayed-nu-fission was input as a dimension & &4 matrix with the same number of delayed groups and & &groups. It is important to know that OpenMC assumes & - &the dimensions in the matrix are (energy_groups, & - &delayed_groups, n_azi, n_pol). Currently, & + &the dimensions in the matrix are (delayed_groups, & + &energy_groups, n_azi, n_pol). Currently, & &delayed-nu-fission cannot be set as a group by group & &matrix.") end if @@ -1497,8 +1499,8 @@ module mgxs_header allocate(temp_1d(delayed_groups * energy_groups * this % n_azi & * this % n_pol)) call read_dataset(temp_1d, xsdata_grp, "delayed-nu-fission") - xs % delayed_nu_fission = reshape(temp_1d, (/energy_groups, & - delayed_groups, this % n_azi, this % n_pol /)) + xs % delayed_nu_fission = reshape(temp_1d, (/delayed_groups, & + energy_groups, this % n_azi, this % n_pol /)) ! Deallocate temporary array for delayed-nu-fission matrix deallocate(temp_1d) @@ -2055,15 +2057,15 @@ module mgxs_header allocate(this % xs(t) % prompt_nu_fission(energy_groups)) this % xs(t) % prompt_nu_fission(:) = ZERO - allocate(this % xs(t) % delayed_nu_fission(energy_groups, & - delayed_groups)) + allocate(this % xs(t) % delayed_nu_fission(delayed_groups, & + energy_groups)) this % xs(t) % delayed_nu_fission(:, :) = ZERO allocate(this % xs(t) % chi_prompt(energy_groups, energy_groups)) this % xs(t) % chi_prompt(:, :) = ZERO - allocate(this % xs(t) % chi_delayed(energy_groups, energy_groups, & - delayed_groups)) + allocate(this % xs(t) % chi_delayed(delayed_groups, energy_groups, & + energy_groups)) this % xs(t) % chi_delayed(:, :, :) = ZERO allocate(this % xs(t) % inverse_velocity(energy_groups)) @@ -2282,10 +2284,10 @@ module mgxs_header do dg = 1, delayed_groups do gin = 1, energy_groups - norm = sum(this % xs(t) % chi_delayed(:, gin, dg)) + norm = sum(this % xs(t) % chi_delayed(dg, :, gin)) if (norm > ZERO) then - this % xs(t) % chi_delayed(:, gin, dg) = & - this % xs(t) % chi_delayed(:, gin, dg) / norm + this % xs(t) % chi_delayed(dg, :, gin) = & + this % xs(t) % chi_delayed(dg, :, gin) / norm end if end do end do @@ -2386,16 +2388,16 @@ module mgxs_header allocate(this % xs(t) % prompt_nu_fission(energy_groups, n_azi, n_pol)) this % xs(t) % prompt_nu_fission = ZERO - allocate(this % xs(t) % delayed_nu_fission(energy_groups, & - delayed_groups, n_azi, n_pol)) + allocate(this % xs(t) % delayed_nu_fission(delayed_groups, & + energy_groups, n_azi, n_pol)) this % xs(t) % delayed_nu_fission = ZERO allocate(this % xs(t) % chi_prompt(energy_groups, energy_groups, & n_azi, n_pol)) this % xs(t) % chi_prompt = ZERO - allocate(this % xs(t) % chi_delayed(energy_groups, energy_groups, & - delayed_groups, n_azi, n_pol)) + allocate(this % xs(t) % chi_delayed(delayed_groups, energy_groups, & + energy_groups, n_azi, n_pol)) this % xs(t) % chi_delayed = ZERO allocate(temp_mult(energy_groups, energy_groups, n_azi, n_pol)) @@ -2644,10 +2646,10 @@ module mgxs_header do ipol = 1, n_pol do iazi = 1, n_azi do gin = 1, energy_groups - norm = sum(this % xs(t) % chi_prompt(:, gin, iazi, ipol)) + norm = sum(this % xs(t) % chi_delayed(dg, :, gin, iazi, ipol)) if (norm > ZERO) then - this % xs(t) % chi_delayed(:, gin, dg, iazi, ipol) = & - this % xs(t) % chi_delayed(:, gin, dg, iazi, ipol)& + this % xs(t) % chi_delayed(dg, :, gin, iazi, ipol) = & + this % xs(t) % chi_delayed(dg, :, gin, iazi, ipol)& / norm end if end do @@ -2712,14 +2714,14 @@ module mgxs_header case('delayed-nu-fission') if (present(dg)) then - xs = this % xs(t) % delayed_nu_fission(gin, dg) + xs = this % xs(t) % delayed_nu_fission(dg, gin) else - xs = sum(this % xs(t) % delayed_nu_fission(gin, :)) + xs = sum(this % xs(t) % delayed_nu_fission(:, gin)) end if case('nu-fission') xs = this % xs(t) % prompt_nu_fission(gin) + & - sum(this % xs(t) % delayed_nu_fission(gin, :)) + sum(this % xs(t) % delayed_nu_fission(:, gin)) case('chi-prompt') if (present(gout)) then @@ -2732,15 +2734,15 @@ module mgxs_header case('chi-delayed') if (present(gout)) then if (present(dg)) then - xs = this % xs(t) % chi_delayed(gout, gin, dg) + xs = this % xs(t) % chi_delayed(dg, gout, gin) else - xs = this % xs(t) % chi_delayed(gout, gin, 1) + xs = this % xs(t) % chi_delayed(1, gout, gin) end if else if (present(dg)) then - xs = sum(this % xs(t) % chi_delayed(:, gin, dg)) + xs = sum(this % xs(t) % chi_delayed(dg, :, gin)) else - xs = sum(this % xs(t) % chi_delayed(:, gin, 1)) + xs = sum(this % xs(t) % chi_delayed(dg, :, gin)) end if end if @@ -2837,14 +2839,14 @@ module mgxs_header case('delayed-nu-fission') if (present(dg)) then - xs = this % xs(t) % delayed_nu_fission(gin, dg, iazi, ipol) + xs = this % xs(t) % delayed_nu_fission(dg, gin, iazi, ipol) else - xs = sum(this % xs(t) % delayed_nu_fission(gin, :, iazi, ipol)) + xs = sum(this % xs(t) % delayed_nu_fission(:, gin, iazi, ipol)) end if case('nu-fission') xs = this % xs(t) % prompt_nu_fission(gin, iazi, ipol) + & - sum(this % xs(t) % delayed_nu_fission(gin, :, iazi, ipol)) + sum(this % xs(t) % delayed_nu_fission(:, gin, iazi, ipol)) case('chi-prompt') if (present(gout)) then @@ -2857,15 +2859,15 @@ module mgxs_header case('chi-delayed') if (present(gout)) then if (present(dg)) then - xs = this % xs(t) % chi_delayed(gout, gin, dg, iazi, ipol) + xs = this % xs(t) % chi_delayed(dg, gout, gin, iazi, ipol) else - xs = this % xs(t) % chi_delayed(gout, gin, 1, iazi, ipol) + xs = this % xs(t) % chi_delayed(1, gout, gin, iazi, ipol) end if else if (present(dg)) then - xs = sum(this % xs(t) % chi_delayed(:, gin, dg, iazi, ipol)) + xs = sum(this % xs(t) % chi_delayed(dg, :, gin, iazi, ipol)) else - xs = sum(this % xs(t) % chi_delayed(:, gin, 1, iazi, ipol)) + xs = sum(this % xs(t) % chi_delayed(1, :, gin, iazi, ipol)) end if end if @@ -2973,12 +2975,11 @@ module mgxs_header dg = 0 gout = 1 - prob_gout = this % xs(this % index_temp) % chi_prompt(gout, gin) + prob_gout = this % get_xs('chi-prompt', gin, gout) do while (prob_gout < xi_gout) gout = gout + 1 - prob_gout = prob_gout + & - this % xs(this % index_temp) % chi_prompt(gout, gin) + prob_gout = prob_gout + this % get_xs('chi-prompt', gin, gout) end do ! Neutron is born delayed @@ -2999,12 +3000,11 @@ module mgxs_header ! Get the outgoing group gout = 1 - prob_gout = this % xs(this % index_temp) % chi_delayed(gout, gin, dg) + prob_gout = this % get_xs('chi-delayed', gin, gout, dg=dg) do while (prob_gout < xi_gout) gout = gout + 1 - prob_gout = prob_gout + & - this % xs(this % index_temp) % chi_delayed(gout, gin, dg) + prob_gout = prob_gout + this % get_xs('chi-delayed', gin, gout, dg=dg) end do end if @@ -3066,7 +3066,8 @@ module mgxs_header do while (prob_gout < xi_gout) gout = gout + 1 - prob_gout = this % get_xs('chi-delayed', gin, gout, uvw=uvw, dg=dg) + prob_gout = prob_gout + & + this % get_xs('chi-delayed', gin, gout, uvw=uvw, dg=dg) end do end if @@ -3121,7 +3122,7 @@ module mgxs_header xs % fission = this % xs(this % index_temp) % fission(gin) xs % nu_fission = & this % xs(this % index_temp) % prompt_nu_fission(gin) + & - sum(this % xs(this % index_temp) % delayed_nu_fission(gin, :)) + sum(this % xs(this % index_temp) % delayed_nu_fission(:, gin)) end subroutine mgxsiso_calculate_xs @@ -3145,7 +3146,7 @@ module mgxs_header xs % nu_fission = this % xs(this % index_temp) % & prompt_nu_fission(gin, iazi, ipol) + & sum(this % xs(this % index_temp) % & - delayed_nu_fission(gin, :, iazi, ipol)) + delayed_nu_fission(:, gin, iazi, ipol)) end subroutine mgxsang_calculate_xs diff --git a/tests/testing_harness.py b/tests/testing_harness.py index 150d124c8c..a9cffd8582 100644 --- a/tests/testing_harness.py +++ b/tests/testing_harness.py @@ -291,7 +291,8 @@ class PyAPITestHarness(TestHarness): self._write_results(results) self._overwrite_results() finally: - self._cleanup() + a = 1 + #self._cleanup() def _build_inputs(self): """Write input XML files.""" From ccab350cd67a970e24466c532cddc229599b0293 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Wed, 2 Nov 2016 13:09:19 -0400 Subject: [PATCH 19/27] fixed error in mgxs_header.F90 with nu-fission not being read in for angle dependent xs --- src/mgxs_header.F90 | 133 ++++++++++++++++++++++++++- tests/test_mg_basic/results_true.dat | 2 +- 2 files changed, 130 insertions(+), 5 deletions(-) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 28931dbd5d..711f49a29f 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -588,8 +588,10 @@ module mgxs_header end do ! Correct prompt-nu-fission using delayed neutron fraction - xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(:, gin))) * & - xs % prompt_nu_fission(gin) + if (delayed_groups > 0) then + xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(:, gin))) * & + xs % prompt_nu_fission(gin) + end if end do ! If nu-fission is a matrix, set prompt-nu-fission, @@ -621,8 +623,10 @@ module mgxs_header end do ! Correct prompt-nu-fission using delayed neutron fraction - xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(:, gin))) * & - xs % prompt_nu_fission(gin) + if (delayed_groups > 0) then + xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(:, gin))) * & + xs % prompt_nu_fission(gin) + end if end do ! Now pull out information needed for chi @@ -1269,6 +1273,127 @@ module mgxs_header deallocate(temp_3d) end if + ! If nu-fission provided, set prompt-nu_-ission and + ! delayed-nu-fission. If nu fission is a matrix, set chi-prompt and + ! chi-delayed. + if (object_exists(xsdata_grp, "nu-fission")) then + + ! Get the dimensions of the nu-fission dataset + xsdata = open_dataset(xsdata_grp, "nu-fission") + call get_ndims(xsdata, ndims) + + ! If nu-fission is a 3D array + if (ndims == 3) then + + ! Get nu-fission + call read_dataset(xs % prompt_nu_fission, xsdata_grp, & + "nu-fission") + + ! Set delayed-nu-fission and correct prompt-nu-fission with + ! beta + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, energy_groups + do dg = 1, delayed_groups + + ! Set delayed-nu-fission using delayed neutron fraction + xs % delayed_nu_fission(dg, gin, iazi, ipol) = & + temp_beta(dg, gin, iazi, ipol) * & + xs % prompt_nu_fission(gin, iazi, ipol) + end do + + ! Correct prompt-nu-fission using delayed neutron fraction + if (delayed_groups > 0) then + xs % prompt_nu_fission(gin, iazi, ipol) = & + (1 - sum(temp_beta(:, gin, iazi, ipol))) * & + xs % prompt_nu_fission(gin, iazi, ipol) + end if + end do + end do + end do + + ! If nu-fission is a matrix, set prompt-nu-fission, + ! delayed-nu-fission, chi-prompt, and chi-delayed. + else if (ndims == 4) then + + ! chi is embedded in nu-fission -> extract chi + allocate(temp_1d(energy_groups * energy_groups * & + this % n_azi * this % n_pol)) + call read_dataset(temp_1d, xsdata_grp, "nu-fission") + allocate(temp_4d(energy_groups, energy_groups, this % n_azi, & + this % n_pol)) + temp_4d = reshape(temp_1d, (/energy_groups, energy_groups, & + this % n_azi, this % n_pol /)) + + ! Deallocate temporary 1D array for nu-fission matrix + deallocate(temp_1d) + + ! 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, energy_groups + xs % prompt_nu_fission(gin, iazi, ipol) = & + sum(temp_4d(:, gin, iazi, ipol)) + end do + end do + end do + + ! Set delayed-nu-fission and correct prompt-nu-fission with + ! beta + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, energy_groups + do dg = 1, delayed_groups + + ! Set delayed-nu-fission using delayed neutron fraction + xs % delayed_nu_fission(dg, gin, iazi, ipol) = & + temp_beta(dg, gin, iazi, ipol) * & + xs % prompt_nu_fission(gin, iazi, ipol) + end do + + ! Correct prompt-nu-fission using delayed neutron fraction + if (delayed_groups > 0) then + xs % prompt_nu_fission(gin, iazi, ipol) = & + (1 - sum(temp_beta(:, gin, iazi, ipol))) * & + xs % prompt_nu_fission(gin, iazi, ipol) + end if + end do + end do + end do + + ! Now pull out information needed for chi + xs % chi_prompt(:, :, :, :) = temp_4d + + ! Deallocate temporary 4D array for nu-fission matrix + deallocate(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, energy_groups + chi_sum = sum(xs % chi_prompt(:, gin, iazi, ipol)) + if (chi_sum == ZERO) then + call fatal_error("Encountered chi for a group that & + &sums to zero") + else + xs % chi_prompt(:, gin, iazi, ipol) = & + xs % chi_prompt(:, gin, iazi, ipol) / chi_sum + end if + end do + + ! Set chi-delayed to chi-prompt + do dg = 1, delayed_groups + xs % chi_delayed(dg, :, :, iazi, ipol) = & + xs % chi_prompt(:, :, iazi, ipol) + end do + end do + end do + else + call fatal_error("nu-fission must be provided as a 3D or & + &4D array") + end if + end if + ! If chi-prompt provided, set chi-prompt if (object_exists(xsdata_grp, "chi-prompt")) then diff --git a/tests/test_mg_basic/results_true.dat b/tests/test_mg_basic/results_true.dat index 5178ade21d..656c39347d 100644 --- a/tests/test_mg_basic/results_true.dat +++ b/tests/test_mg_basic/results_true.dat @@ -1,2 +1,2 @@ k-combined: -5.788739E-01 1.945182E-02 +1.086853E+00 2.677280E-02 From e14cc02386fb717ae7da048f5af6c4b95a9ba20b Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Wed, 2 Nov 2016 13:38:23 -0400 Subject: [PATCH 20/27] updated mg tallies and mg nuclide tests --- tests/test_mg_nuclide/results_true.dat | 2 +- tests/test_mg_tallies/results_true.dat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_mg_nuclide/results_true.dat b/tests/test_mg_nuclide/results_true.dat index 5178ade21d..656c39347d 100644 --- a/tests/test_mg_nuclide/results_true.dat +++ b/tests/test_mg_nuclide/results_true.dat @@ -1,2 +1,2 @@ k-combined: -5.788739E-01 1.945182E-02 +1.086853E+00 2.677280E-02 diff --git a/tests/test_mg_tallies/results_true.dat b/tests/test_mg_tallies/results_true.dat index 236e79c510..bc6ee3d924 100644 --- a/tests/test_mg_tallies/results_true.dat +++ b/tests/test_mg_tallies/results_true.dat @@ -1 +1 @@ -fa242fd21d5c78ea02759fb3bbcfedc8d9ad52bd2b28dafbfd9f968c3c24fa9e8f0e40046366ff08dd7dcb138c50cb59bd79d12fc606194c7d00d1853874221b \ No newline at end of file +1edf0c3e5557b2f480bca714e85f4503ae25ee055fb6b9a6ebdfa917200f0a20bd31925ef66f859ff3cf3476f7a899b802bab7431f706a08f5f2a7cfa35130c1 \ No newline at end of file From fa87d320346f7a9413fb8cfd900c2edfff44c641 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Wed, 2 Nov 2016 13:40:16 -0400 Subject: [PATCH 21/27] removed comment in testing harness --- tests/testing_harness.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/testing_harness.py b/tests/testing_harness.py index a9cffd8582..150d124c8c 100644 --- a/tests/testing_harness.py +++ b/tests/testing_harness.py @@ -291,8 +291,7 @@ class PyAPITestHarness(TestHarness): self._write_results(results) self._overwrite_results() finally: - a = 1 - #self._cleanup() + self._cleanup() def _build_inputs(self): """Write input XML files.""" From 5736a104e22b87437a1a1f517b27dbc8620f77dd Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Thu, 3 Nov 2016 15:59:12 -0400 Subject: [PATCH 22/27] fixed a few errors in setting mgxs --- openmc/mgxs_library.py | 48 +++++++++++++++--------------------------- src/mgxs_header.F90 | 12 +++++------ 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index cb4483464a..adfabe022f 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -15,8 +15,8 @@ from openmc.checkvalue import check_type, check_value, check_greater_than, \ # Supported incoming particle MGXS angular treatment representations _REPRESENTATIONS = ['isotropic', 'angle'] _SCATTER_TYPES = ['tabular', 'legendre', 'histogram'] -_XS_SHAPES = ["[Order][G][G']", "[G]", "[G']", "[G][G']", "[DG]", "[DG][G]", - "[DG][G']"] +_XS_SHAPES = ["[Order][G][G']", "[G]", "[G']", "[G][G']", "[DG]", "[G][DG]", + "[G'][DG]"] class XSdata(object): @@ -145,9 +145,9 @@ class XSdata(object): [DG]: beta, decay_rate - [DG][G]: delayed_nu_fission, beta, decay_rate + [G][DG]: delayed_nu_fission, beta, decay_rate - [DG][G']: chi_delayed + [G'][DG]: chi_delayed """ @@ -294,10 +294,10 @@ class XSdata(object): self._xs_shapes["[G][G']"] = (self.energy_groups.num_groups, self.energy_groups.num_groups) self._xs_shapes["[DG]"] = (self.num_delayed_groups,) - self._xs_shapes["[DG][G]"] = (self.num_delayed_groups, - self.energy_groups.num_groups) - self._xs_shapes["[DG][G']"] = (self.num_delayed_groups, - self.energy_groups.num_groups) + self._xs_shapes["[G][DG]"] = (self.energy_groups.num_groups, + self.num_delayed_groups) + self._xs_shapes["[G'][DG]"] = (self.energy_groups.num_groups, + self.num_delayed_groups) self._xs_shapes["[Order][G][G']"] \ = (self.num_orders, self.energy_groups.num_groups, self.energy_groups.num_groups) @@ -441,8 +441,6 @@ class XSdata(object): """ - check_type('total', total, Iterable, expected_iter_type=Real) - # Get the accepted shapes for this xs shapes = [self.xs_shapes["[G]"]] @@ -473,8 +471,6 @@ class XSdata(object): """ - check_type('absorption', absorption, Iterable, expected_iter_type=Real) - # Get the accepted shapes for this xs shapes = [self.xs_shapes["[G]"]] @@ -505,8 +501,6 @@ class XSdata(object): """ - check_type('fission', fission, Iterable, expected_iter_type=Real) - # Get the accepted shapes for this xs shapes = [self.xs_shapes["[G]"]] @@ -540,9 +534,6 @@ class XSdata(object): """ - check_type('kappa_fission', kappa_fission, Iterable, - expected_iter_type=Real) - # Get the accepted shapes for this xs shapes = [self.xs_shapes["[G]"]] @@ -637,7 +628,7 @@ class XSdata(object): """ # Get the accepted shapes for this xs - shapes = [self.xs_shapes["[G']"], self.xs_shapes["[DG][G']"]] + shapes = [self.xs_shapes["[G']"], self.xs_shapes["[G'][DG]"]] # Convert to a numpy array so we can easily get the shape for checking chi_delayed = np.asarray(chi_delayed) @@ -667,7 +658,7 @@ class XSdata(object): """ # Get the accepted shapes for this xs - shapes = [self.xs_shapes["[DG]"], self.xs_shapes["[DG][G]"]] + shapes = [self.xs_shapes["[DG]"], self.xs_shapes["[G][DG]"]] # Convert to a numpy array so we can easily get the shape for checking beta = np.asarray(beta) @@ -696,10 +687,8 @@ class XSdata(object): """ - check_type('decay_rate', decay_rate, Iterable, expected_iter_type=Real) - # Get the accepted shapes for this xs - shapes = [self.xs_shapes["[DG]"], self.xs_shapes["[DG][G]"]] + shapes = [self.xs_shapes["[DG]"], self.xs_shapes["[G][DG]"]] # Convert to a numpy array so we can easily get the shape for checking decay_rate = np.asarray(decay_rate) @@ -861,7 +850,7 @@ class XSdata(object): """ # Get the accepted shapes for this xs - shapes = [self.xs_shapes["[DG][G]"]] + shapes = [self.xs_shapes["[G][DG]"]] # Convert to a numpy array so we can easily get the shape for checking delayed_nu_fission = np.asarray(delayed_nu_fission) @@ -891,9 +880,6 @@ class XSdata(object): """ - check_type('inverse_velocity', inv_vel, Iterable, - expected_iter_type=Real) - # Get the accepted shapes for this xs shapes = [self.xs_shapes["[G]"]] @@ -1653,10 +1639,10 @@ class XSdata(object): 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 + 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 grp.attrs['scatter_shape'] = np.string_("[Order][G][G']") if self.scatter_format is not None: @@ -1821,9 +1807,9 @@ 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", - data=np.array(flat_mult)) + # And write it. + scatt_grp.create_dataset("multiplicity_matrix", + data=np.array(flat_mult)) # 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 711f49a29f..ff235e14a6 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -26,7 +26,7 @@ module mgxs_header real(8), allocatable :: total(:) ! total cross section real(8), allocatable :: absorption(:) ! absorption cross section class(ScattData), allocatable :: scatter ! scattering info - real(8), allocatable :: delayed_nu_fission(:,:) ! Delayed fission matrix (Gin x Dg) + real(8), allocatable :: delayed_nu_fission(:,:) ! Delayed fission matrix (Dg x Gin) real(8), allocatable :: prompt_nu_fission(:) ! Prompt fission vector (Gin) real(8), allocatable :: kappa_fission(:) ! Kappa fission real(8), allocatable :: fission(:) ! Neutron production @@ -589,8 +589,8 @@ module mgxs_header ! Correct prompt-nu-fission using delayed neutron fraction if (delayed_groups > 0) then - xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(:, gin))) * & - xs % prompt_nu_fission(gin) + xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(:, gin))) & + * xs % prompt_nu_fission(gin) end if end do @@ -624,8 +624,8 @@ module mgxs_header ! Correct prompt-nu-fission using delayed neutron fraction if (delayed_groups > 0) then - xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(:, gin))) * & - xs % prompt_nu_fission(gin) + xs % prompt_nu_fission(gin) = (1 - sum(temp_beta(:, gin))) & + * xs % prompt_nu_fission(gin) end if end do @@ -3116,7 +3116,7 @@ module mgxs_header do while (xi_pd >= prob_prompt) dg = dg + 1 prob_prompt = prob_prompt + & - this % get_xs('delayed_nu_fision', gin, dg=dg) & + this % get_xs('delayed-nu-fission', gin, dg=dg) & / this % get_xs('nu-fission', gin) end do From ba07380fabe4fb832aa9251ba584560c0ee9bf4c Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 3 Nov 2016 16:05:37 -0400 Subject: [PATCH 23/27] Specify the default source energy distribution --- docs/source/usersguide/input.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index 74de4caa41..203b56dccc 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -528,6 +528,8 @@ attributes/sub-elements: sub-elements/attributes are those of a univariate probability distribution (see the description in :ref:`univariate`). + *Default*: Watt spectrum with :math:`a` = 0.988 MeV and :math:`b` = 2.249 MeV + :write_initial: An element specifying whether to write out the initial source bank used at the beginning of the first batch. The output file is named From 7880d4f2461a945a99ffd4fb5a88a92191a06f5c Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 3 Nov 2016 16:12:20 -0400 Subject: [PATCH 24/27] Allow a plotting calculation without BCs --- src/input_xml.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 2cefd76f67..e254831f50 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -1636,8 +1636,10 @@ contains ! Check to make sure a boundary condition was applied to at least one ! surface - if (.not. boundary_exists) then - call fatal_error("No boundary conditions were applied to any surfaces!") + if (run_mode /= MODE_PLOTTING) then + if (.not. boundary_exists) then + call fatal_error("No boundary conditions were applied to any surfaces!") + end if end if ! Determine opposite side for periodic boundaries From f28fdff7216f92e1a0fc0fbc9dfbfb649aae7d6a Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 3 Nov 2016 16:58:21 -0400 Subject: [PATCH 25/27] Fix units on #750 --- docs/source/usersguide/input.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index 203b56dccc..2e5a80cd37 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -528,7 +528,8 @@ attributes/sub-elements: sub-elements/attributes are those of a univariate probability distribution (see the description in :ref:`univariate`). - *Default*: Watt spectrum with :math:`a` = 0.988 MeV and :math:`b` = 2.249 MeV + *Default*: Watt spectrum with :math:`a` = 0.988 MeV and :math:`b` = + 2.249 MeV :sup:`-1` :write_initial: An element specifying whether to write out the initial source bank used at From cc9bcc577cf9cd686b2a8d9e0e4cb11f5ff0b6d3 Mon Sep 17 00:00:00 2001 From: samuel shaner Date: Sat, 5 Nov 2016 16:40:22 +0000 Subject: [PATCH 26/27] added num_delayed_groups attribute to mgxs object --- src/mgxs_header.F90 | 22 ++++++++++++++++++---- tests/1d_mgxs.h5 | Bin 124720 -> 128136 bytes 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 7c149d5e1a..fc5e8cb3e1 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -64,6 +64,7 @@ module mgxs_header ! Fission information logical :: fissionable ! mgxs object is fissionable? integer :: scatter_format ! either legendre, histogram, or tabular. + integer :: num_delayed_groups ! Num delayed groups ! Caching information integer :: index_temp ! temperature index for nuclide @@ -445,6 +446,9 @@ module mgxs_header call mgxs_from_hdf5(this, xs_id, temperature, method, tolerance, & temps_to_read, order_dim) + ! Set the number of delayed groups + this % num_delayed_groups = delayed_groups + ! Load the more specific data do t = 1, temps_to_read % size() associate(xs => this % xs(t)) @@ -1126,6 +1130,9 @@ module mgxs_header call mgxs_from_hdf5(this, xs_id, temperature, method, tolerance, & temps_to_read, order_dim) + ! Set the number of delayed groups + this % num_delayed_groups = delayed_groups + ! Load the more specific data do t = 1, temps_to_read % size() associate(xs => this % xs(t)) @@ -1556,7 +1563,7 @@ module mgxs_header ! If beta is zeros, raise error if (temp_beta(1,1,1,1) == ZERO) then - call fatal_error("cannot set delayed-nu-fission with a 1D & + call fatal_error("cannot set delayed-nu-fission with a 3D & &array if beta not provided") end if @@ -2030,6 +2037,7 @@ module mgxs_header this % name = trim(mat % name) end if + ! Set whether this material is fissionable this % fissionable = mat % fissionable ! The following info we should initialize, but we dont need it nor @@ -2163,6 +2171,9 @@ module mgxs_header call mgxs_combine(this, temps, mat, nuclides, max_order, scatter_format, & order_dim) + ! Set the number of delayed groups + this % num_delayed_groups = delayed_groups + ! Create the Xs Data for each temperature TEMP_LOOP: do t = 1, temps % size() @@ -2462,6 +2473,9 @@ module mgxs_header call mgxs_combine(this, temps, mat, nuclides, max_order, scatter_format, & order_dim) + ! Set the number of delayed groups + this % num_delayed_groups = delayed_groups + ! Get the number of each polar and azi angles and make sure all the ! NuclideAngle types have the same number of these angles n_pol = -1 @@ -3121,7 +3135,7 @@ module mgxs_header end do ! Adjust dg in case of round off error - dg = min(dg, num_delayed_groups) + dg = min(dg, this % num_delayed_groups) ! Get the outgoing group gout = 1 @@ -3175,7 +3189,7 @@ module mgxs_header ! Get the delayed group dg = 0 - do while (xi_pd < prob_prompt) + do while (xi_pd >= prob_prompt) dg = dg + 1 prob_prompt = prob_prompt + & this % get_xs('delayed-nu-fission', gin, uvw=uvw, dg=dg) / & @@ -3183,7 +3197,7 @@ module mgxs_header end do ! Adjust dg in case of round off error - dg = min(dg, num_delayed_groups) + dg = min(dg, this % num_delayed_groups) ! Get the outgoing group gout = 1 diff --git a/tests/1d_mgxs.h5 b/tests/1d_mgxs.h5 index 5989962ce035ce67a0d1a2fe430b84adee2f2844..e3b85c24163fe4020435db5c5d674575f2b65be0 100644 GIT binary patch delta 1879 zcmc&#Sx}Q#7|kE-5D*lpLRcb+h^7<>OIQU@K$gg&h)Pj#NdXlkg2n|!j4fE%T$0}w zMUg!bTp$ElT|mXEh~k1!1+CZtK@ns`D`Hy|Y#%z)m(H|z=H5Hsde1oz-z~YJn$)ej zpG{4AB{6j%JKS^>u_bzhrSc2?c!E$Rgi4W!Fcq z)><0rZx}=N&xlk8Fj}c(WKFCJzmFgrMMf&^uNh=%vVK-L=n;J#`40#qXb*S!~PZ^#^NN)iai2>sjQs- zGfC`J9;zH+K_hjm|6<|a{Q++}Pn}RB*H?QH{v^wgL)KRFNz2X@Wk=2B2@e1E^#pc9 z1-pUhH<+YF8D+?SHHwf&J~mvhVmTtqdwnC7t8W;jcqTcM{SiGu9nJZ~g*wLRPdk0V zM8b{MH)?B<4>a{ugWocOD3mplI^hUwZ5n^H(Ku4SYAQh`t*VShPKlbeL;Q|riHPKceP$uFGQg|O&M40)DdjOR_2$!9Ow;X7sUw;mlbl$hwH zy(^JH<*g*QNFYPv(7g-wg9WJDEG6fM6hQW5FiI%PN5Lug1B+VnurRhPJ@tJqZlxr3 zuo$^8b3EKqp`sxz)>VO)r*X+rntyz3Y#o^3ISRWE`IzedGu)5#4priu<1ZFpO{+rCmrqI;{osN&LErw2Ko?wf)~(g-cgEalP2GFK zoUub|x7_&XENrjqoibGFggHu2O?$Z`Zjp}#xqBRtb?C*fack{yKTyqLd9WQygAZs+ zB5mO;Q!CXgfeGGtf@GeAX3`0C`UV%N;pJsVirPctW~0v!1t{kB8S4Cx(r@v0ZL` z<%!$}VtJd-)_z|wqwL~ZiFsfiBra97&BHE5Lz7sTIv*VG;ZPl_KYZ6M_NUMA$L}|b z+NJRSFBA~x1^llHh#Q*zNr9W4EQdq2EWEV8twSs4;+ZhyY)A$RU8b(qQOR6rpS!Qo z9Ku3vd!b{VD;LtqB?Bxq7AW-C{^3V9pt~f7O_4G&@X~#dzSssn^1Y(raZI!bXSBtY zSc4&MS+x1sm8pn}SM+HNTESw+g9jHjGvHCyQ}mK!1(RJ1E*;P}M4-d{AMb@(BI`ze zrutodgn9BbD||V~RW02ewO2_4GuL6#ncX4sl0K6=Vg4|{JM2z@Oy$Nt+H z`($08ozOj^Xj`00c4=aIn;@H+ znHhJ_0gpKxt_D`NK1 zj(op_18QNhNBUeh=>AqQsW06U>yHKEdGH)`Uh5&JEVF`!Th}))T;1U%XT}>4)`+Le z&Uh0Z@Csh-wk~nR?rF^3nc;zi$dgZ8d#&L<{OaNL$)0dbd$*;`)&_1jhEf9}c%FF0 zpbT}dv_WQLQC`hqPc)cO)Z@iAIGDWHZuNOjXiywR=PP9*MT0`4jD1EcR&R*j6eA)n K)bweeX7(SGdFR#u delta 141 zcmeBp$-dzn`veUpgXa^qEEw50CLfiY{2_y5vw>6@9 zE{(|*G6kCt$Ye23{v{K^w1IE3PyU|G4vIIJCO;@zuz82dgUMj+3wA)YE9~-^JYiSB r Date: Sat, 5 Nov 2016 12:47:32 -0400 Subject: [PATCH 27/27] updated failing tests --- tests/test_mg_basic/results_true.dat | 2 +- tests/test_mg_nuclide/results_true.dat | 2 +- tests/test_mg_tallies/results_true.dat | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_mg_basic/results_true.dat b/tests/test_mg_basic/results_true.dat index 656c39347d..2192c3746d 100644 --- a/tests/test_mg_basic/results_true.dat +++ b/tests/test_mg_basic/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.086853E+00 2.677280E-02 +1.086852E+00 2.677280E-02 diff --git a/tests/test_mg_nuclide/results_true.dat b/tests/test_mg_nuclide/results_true.dat index 656c39347d..2192c3746d 100644 --- a/tests/test_mg_nuclide/results_true.dat +++ b/tests/test_mg_nuclide/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.086853E+00 2.677280E-02 +1.086852E+00 2.677280E-02 diff --git a/tests/test_mg_tallies/results_true.dat b/tests/test_mg_tallies/results_true.dat index bc6ee3d924..a765c0ba02 100644 --- a/tests/test_mg_tallies/results_true.dat +++ b/tests/test_mg_tallies/results_true.dat @@ -1 +1 @@ -1edf0c3e5557b2f480bca714e85f4503ae25ee055fb6b9a6ebdfa917200f0a20bd31925ef66f859ff3cf3476f7a899b802bab7431f706a08f5f2a7cfa35130c1 \ No newline at end of file +3d2ce1b8bdd558fe9f8560e8bb91455e1fedd80a47349344399e22f5b0fac1391f1721e7f12a42bb0c458fd6c87ebf9fa38fe9539fcf69292b21cebf8e5f8989 \ No newline at end of file