From 8e10d9e00fefb104692a9fc21978d8ae467b5cb2 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 17 Oct 2016 19:15:11 -0400 Subject: [PATCH 01/60] seem to have the input side for the MuFilter working, now on to the library generation side --- openmc/filter.py | 313 +++++++++++++++++++++++++++++++---------- openmc/mgxs/library.py | 82 +++++++++-- openmc/mgxs/mgxs.py | 210 ++++++++++++++++++--------- openmc/mgxs_library.py | 39 +++-- openmc/tallies.py | 3 +- 5 files changed, 474 insertions(+), 173 deletions(-) diff --git a/openmc/filter.py b/openmc/filter.py index d11af96f5..91ceb2931 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -105,7 +105,8 @@ class Filter(with_metaclass(FilterMeta, object)): """Return all subclasses and their subclasses, etc.""" subs = cls.__subclasses__() subsubs = [grand for s in subs for grand in s.__subclasses__()] - return subs + subsubs + subsubsubs = [grand for s in subsubs for grand in s.__subclasses__()] + return subs + subsubs + subsubsubs @classmethod def from_hdf5(cls, group, **kwargs): @@ -777,7 +778,116 @@ class MeshFilter(Filter): return df -class EnergyFilter(Filter): +class RealFilter(Filter): + """Tally modifier that describes phase-space and other characteristics + + Parameters + ---------- + bins : Iterable of Real + A grid of bin values. + + Attributes + ---------- + bins : Iterable of Real + A grid of bin values. + num_bins : Integral + The number of filter bins + stride : Integral + The number of filter, nuclide and score bins within each of this + filter's bins. + + """ + + def __gt__(self, other): + if type(self) is type(other): + # Compare largest/smallest bin edges in filters + # This logic is used when merging tallies with real filters + return self.bins[0] >= other.bins[-1] + else: + return super(RealFilter, self).__gt__(other) + + @property + def num_bins(self): + return len(self.bins) - 1 + + @num_bins.setter + def num_bins(self, num_bins): + cv.check_type('filter num_bins', num_bins, Integral) + cv.check_greater_than('filter num_bins', num_bins, 0, equality=True) + self._num_bins = num_bins + + def can_merge(self, other): + if type(self) is not type(other): + return False + + if self.bins[0] == other.bins[-1]: + # This low energy edge coincides with other's high edge + return True + elif self.bins[-1] == other.bins[0]: + # This high energy edge coincides with other's low edge + return True + else: + return False + + def merge(self, other): + if not self.can_merge(other): + msg = 'Unable to merge "{0}" with "{1}" ' \ + 'filters'.format(self.type, other.type) + raise ValueError(msg) + + # Merge unique filter bins + merged_bins = np.concatenate((self.bins, other.bins)) + merged_bins = np.unique(merged_bins) + + # Create a new filter with these bins + return type(self)(sorted(merged_bins)) + + def is_subset(self, other): + """Determine if another filter is a subset of this filter. + + If all of the bins in the other filter are included as bins in this + filter, then it is a subset of this filter. + + Parameters + ---------- + other : openmc.Filter + The filter to query as a subset of this filter + + Returns + ------- + bool + Whether or not the other filter is a subset of this filter + + """ + + if type(self) is not type(other): + return False + elif len(self.bins) != len(other.bins): + return False + else: + return np.allclose(self.bins, other.bins) + + def get_bin_index(self, filter_bin): + # Use lower energy bound to find index for RealFilters + deltas = np.abs(self.bins - filter_bin[1]) / filter_bin[1] + min_delta = np.min(deltas) + if min_delta < 1E-3: + return deltas.argmin() - 1 + else: + msg = 'Unable to get the bin index for Filter since "{0}" ' \ + 'is not one of the bins'.format(filter_bin) + raise ValueError(msg) + + def get_bin(self, bin_index): + cv.check_type('bin_index', bin_index, Integral) + cv.check_greater_than('bin_index', bin_index, 0, equality=True) + cv.check_less_than('bin_index', bin_index, self.num_bins) + + # Construct 2-tuple of lower, upper bins for real-valued filters + return (self.bins[bin_index], self.bins[bin_index + 1]) + + +class EnergyFilter(RealFilter): """Bins tally events based on incident particle energy. Parameters @@ -797,24 +907,6 @@ class EnergyFilter(Filter): """ - def __gt__(self, other): - if type(self) is type(other): - # Compare largest/smallest energy bin edges in energy filters - # This logic is used when merging tallies with energy filters - return self.bins[0] >= other.bins[-1] - else: - return super(EnergyFilter, self).__gt__(other) - - @property - def num_bins(self): - return len(self.bins) - 1 - - @num_bins.setter - def num_bins(self, num_bins): - cv.check_type('filter num_bins', num_bins, Integral) - cv.check_greater_than('filter num_bins', num_bins, 0, equality=True) - self._num_bins = num_bins - def check_bins(self, bins): for edge in bins: if not isinstance(edge, Real): @@ -835,59 +927,6 @@ class EnergyFilter(Filter): 'increasing'.format(bins, self.type) raise ValueError(msg) - def can_merge(self, other): - if type(self) is not type(other): - return False - - if self.bins[0] == other.bins[-1]: - # This low energy edge coincides with other's high energy edge - return True - elif self.bins[-1] == other.bins[0]: - # This high energy edge coincides with other's low energy edge - return True - else: - return False - - def merge(self, other): - if not self.can_merge(other): - msg = 'Unable to merge "{0}" with "{1}" ' \ - 'filters'.format(self.type, other.type) - raise ValueError(msg) - - # Merge unique filter bins - merged_bins = np.concatenate((self.bins, other.bins)) - merged_bins = np.unique(merged_bins) - - # Create a new filter with these bins - return type(self)(sorted(merged_bins)) - - def is_subset(self, other): - if type(self) is not type(other): - return False - elif len(self.bins) != len(other.bins): - return False - else: - return np.allclose(self.bins, other.bins) - - def get_bin_index(self, filter_bin): - # Use lower energy bound to find index for energy Filters - deltas = np.abs(self.bins - filter_bin[1]) / filter_bin[1] - min_delta = np.min(deltas) - if min_delta < 1E-3: - return deltas.argmin() - 1 - else: - msg = 'Unable to get the bin index for Filter since "{0}" ' \ - 'is not one of the bins'.format(filter_bin) - raise ValueError(msg) - - def get_bin(self, bin_index): - cv.check_type('bin_index', bin_index, Integral) - cv.check_greater_than('bin_index', bin_index, 0, equality=True) - cv.check_less_than('bin_index', bin_index, self.num_bins) - - # Construct 2-tuple of lower, upper energies for energy(out) filters - return (self.bins[bin_index], self.bins[bin_index+1]) - def get_pandas_dataframe(self, data_size, **kwargs): """Builds a Pandas DataFrame for the Filter's bins. @@ -1231,7 +1270,7 @@ class DistribcellFilter(Filter): return df -class MuFilter(Filter): +class MuFilter(RealFilter): """Bins tally events based on particle scattering angle. Parameters @@ -1259,8 +1298,82 @@ class MuFilter(Filter): """ + def check_bins(self, bins): + for edge in bins: + if not isinstance(edge, Real): + msg = 'Unable to add bin edge "{0}" to a "{1}" ' \ + 'since it is a non-integer or floating point ' \ + 'value'.format(edge, type(self)) + raise ValueError(msg) + elif edge < -1.: + msg = 'Unable to add bin edge "{0}" to a "{1}" ' \ + 'since it is less than -1'.format(edge, type(self)) + raise ValueError(msg) + elif edge > 1.: + msg = 'Unable to add bin edge "{0}" to a "{1}" ' \ + 'since it is greater than 1'.format(edge, type(self)) + raise ValueError(msg) -class PolarFilter(Filter): + # Check that bin edges are monotonically increasing + for index in range(1, len(bins)): + if bins[index] < bins[index-1]: + msg = 'Unable to add bin edges "{0}" to a "{1}" Filter ' \ + 'since they are not monotonically ' \ + 'increasing'.format(bins, self.type) + raise ValueError(msg) + + def get_pandas_dataframe(self, data_size, **kwargs): + """Builds a Pandas DataFrame for the Filter's bins. + + This method constructs a Pandas DataFrame object for the filter with + columns annotated by filter bin information. This is a helper method + for :meth:`Tally.get_pandas_dataframe`. + + Parameters + ---------- + data_size : Integral + The total number of bins in the tally corresponding to this filter + + Returns + ------- + pandas.DataFrame + A Pandas DataFrame with one column of the lower energy bound and one + column of upper energy bound for each filter bin. The number of + rows in the DataFrame is the same as the total number of bins in the + corresponding tally, with the filter bin appropriately tiled to map + to the corresponding tally bins. + + Raises + ------ + ImportError + When Pandas is not installed + + See also + -------- + Tally.get_pandas_dataframe(), CrossFilter.get_pandas_dataframe() + + """ + + # Initialize Pandas DataFrame + import pandas as pd + df = pd.DataFrame() + + # Extract the lower and upper energy bounds, then repeat and tile + # them as necessary to account for other filters. + lo_bins = np.repeat(self.bins[:-1], self.stride) + hi_bins = np.repeat(self.bins[1:], self.stride) + tile_factor = data_size / len(lo_bins) + lo_bins = np.tile(lo_bins, tile_factor) + hi_bins = np.tile(hi_bins, tile_factor) + + # Add the new energy columns to the DataFrame. + df.loc[:, self.short_name.lower() + ' low'] = lo_bins + df.loc[:, self.short_name.lower() + ' high'] = hi_bins + + return df + + +class PolarFilter(RealFilter): """Bins tally events based on the incident particle's direction. Parameters @@ -1288,6 +1401,30 @@ class PolarFilter(Filter): """ + def check_bins(self, bins): + for edge in bins: + if not isinstance(edge, Real): + msg = 'Unable to add bin edge "{0}" to a "{1}" ' \ + 'since it is a non-integer or floating point ' \ + 'value'.format(edge, type(self)) + raise ValueError(msg) + elif edge < 0.: + msg = 'Unable to add bin edge "{0}" to a "{1}" ' \ + 'since it is less than 0'.format(edge, type(self)) + raise ValueError(msg) + elif edge > np.pi: + msg = 'Unable to add bin edge "{0}" to a "{1}" ' \ + 'since it is greater than pi'.format(edge, type(self)) + raise ValueError(msg) + + # Check that bin edges are monotonically increasing + for index in range(1, len(bins)): + if bins[index] < bins[index-1]: + msg = 'Unable to add bin edges "{0}" to a "{1}" Filter ' \ + 'since they are not monotonically ' \ + 'increasing'.format(bins, self.type) + raise ValueError(msg) + def get_pandas_dataframe(self, data_size, **kwargs): """Builds a Pandas DataFrame for the Filter's bins. @@ -1338,7 +1475,7 @@ class PolarFilter(Filter): return df -class AzimuthalFilter(Filter): +class AzimuthalFilter(RealFilter): """Bins tally events based on the incident particle's direction. Parameters @@ -1366,6 +1503,30 @@ class AzimuthalFilter(Filter): """ + def check_bins(self, bins): + for edge in bins: + if not isinstance(edge, Real): + msg = 'Unable to add bin edge "{0}" to a "{1}" ' \ + 'since it is a non-integer or floating point ' \ + 'value'.format(edge, type(self)) + raise ValueError(msg) + elif edge < -np.pi: + msg = 'Unable to add bin edge "{0}" to a "{1}" ' \ + 'since it is less than -pi'.format(edge, type(self)) + raise ValueError(msg) + elif edge > np.pi: + msg = 'Unable to add bin edge "{0}" to a "{1}" ' \ + 'since it is greater than pi'.format(edge, type(self)) + raise ValueError(msg) + + # Check that bin edges are monotonically increasing + for index in range(1, len(bins)): + if bins[index] < bins[index-1]: + msg = 'Unable to add bin edges "{0}" to a "{1}" Filter ' \ + 'since they are not monotonically ' \ + 'increasing'.format(bins, self.type) + raise ValueError(msg) + def get_pandas_dataframe(self, data_size, distribcell_paths=True): """Builds a Pandas DataFrame for the Filter's bins. diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index c03aa7877..96bfa6fab 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -62,15 +62,23 @@ class Library(object): The spatial domain(s) for which MGXS in the Library are computed correction : {'P0', None} Apply the P0 correction to scattering matrices if set to 'P0' + scatter_format : {'legendre', or 'histogram'} + Representation of the angular scattering distribution (default is + 'legendre') legendre_order : int - The highest legendre moment in the scattering matrices (default is 0) + The highest Legendre moment in the scattering matrix; this is used if + :attr:`ScatterMatrixXS.scatter_format` is 'legendre'. (default is 0) + histogram_bins : int + The number of equally-spaced bins for the histogram representation of + the angular scattering distribution; this is used if + :attr:`ScatterMatrixXS.scatter_format` is 'histogram'. (default is 16) energy_groups : openmc.mgxs.EnergyGroups Energy group structure for energy condensation delayed_groups : list of int Delayed groups to filter out the xs estimator : str or None - The tally estimator used to compute multi-group cross sections. If None, - the default for each MGXS type is used. + The tally estimator used to compute multi-group cross sections. + If None, the default for each MGXS type is used. tally_trigger : openmc.Trigger An (optional) tally precision trigger given to each tally used to compute the cross section @@ -104,7 +112,9 @@ class Library(object): self._energy_groups = None self._delayed_groups = None self._correction = 'P0' + self._scatter_format = 'legendre' self._legendre_order = 0 + self._histogram_bins = 16 self._tally_trigger = None self._all_mgxs = OrderedDict() self._sp_filename = None @@ -133,7 +143,9 @@ class Library(object): clone._domain_type = self.domain_type clone._domains = copy.deepcopy(self.domains) clone._correction = self.correction + clone._scatter_format = self.scatter_format clone._legendre_order = self.legendre_order + clone._histogram_bins = self.histogram_bins clone._energy_groups = copy.deepcopy(self.energy_groups, memo) clone._delayed_groups = copy.deepcopy(self.delayed_groups, memo) clone._tally_trigger = copy.deepcopy(self.tally_trigger, memo) @@ -212,10 +224,18 @@ class Library(object): def correction(self): return self._correction + @property + def scatter_format(self): + return self._scatter_format + @property def legendre_order(self): return self._legendre_order + @property + def histogram_bins(self): + return self._histogram_bins + @property def tally_trigger(self): return self._tally_trigger @@ -355,26 +375,57 @@ class Library(object): def correction(self, correction): cv.check_value('correction', correction, ('P0', None)) - if correction == 'P0' and self.legendre_order > 0: - warn('The P0 correction will be ignored since the scattering ' - 'order "{}" is greater than zero'.format(self.legendre_order)) + if self.scatter_format == 'legendre': + if correction == 'P0' and self.legendre_order > 0: + msg = 'The P0 correction will be ignored since the ' \ + 'scattering order {} is greater than '\ + 'zero'.format(self.legendre_order) + warn(msg) + elif self.scatter_format == 'histogram': + msg = 'The P0 correction will be ignored since the ' \ + 'scatter format is set to histogram' + warn(msg) self._correction = correction + @scatter_format.setter + def scatter_format(self, scatter_format): + cv.check_value('scatter_format', scatter_format, openmc.mgxs.MU_TREATMENTS) + self._scatter_format = scatter_format + @legendre_order.setter def legendre_order(self, legendre_order): cv.check_type('legendre_order', legendre_order, Integral) - cv.check_greater_than('legendre_order', legendre_order, 0, equality=True) + cv.check_greater_than('legendre_order', legendre_order, 0, + equality=True) cv.check_less_than('legendre_order', legendre_order, 10, equality=True) - if self.correction == 'P0' and legendre_order > 0: - msg = 'The P0 correction will be ignored since the scattering ' \ - 'order {} is greater than zero'.format(self.legendre_order) - warn(msg, RuntimeWarning) - self.correction = None + if self.scatter_format == 'legendre': + if self.correction == 'P0' and legendre_order > 0: + msg = 'The P0 correction will be ignored since the ' \ + 'scattering order {} is greater than '\ + 'zero'.format(self.legendre_order) + warn(msg, RuntimeWarning) + self.correction = None + elif self.scatter_format == 'histogram': + msg = 'The legendre order will be ignored since the ' \ + 'scatter format is set to histogram' + warn(msg) self._legendre_order = legendre_order + @histogram_bins.setter + def histogram_bins(self, histogram_bins): + cv.check_type('histogram_bins', histogram_bins, Integral) + cv.check_greater_than('histogram_bins', histogram_bins, 0) + + if self.scatter_format == 'legendre': + msg = 'The histogram bins will be ignored since the ' \ + 'scatter format is set to legendre' + warn(msg) + + self._histogram_bins = histogram_bins + @tally_trigger.setter def tally_trigger(self, tally_trigger): cv.check_type('tally trigger', tally_trigger, openmc.Trigger) @@ -443,7 +494,9 @@ class Library(object): # Specify whether to use a transport ('P0') correction if isinstance(mgxs, openmc.mgxs.ScatterMatrixXS): mgxs.correction = self.correction + mgxs.scatter_format = self.scatter_format mgxs.legendre_order = self.legendre_order + mgxs.histogram_bins = self.histogram_bins self.all_mgxs[domain.id][mgxs_type] = mgxs @@ -901,15 +954,14 @@ class Library(object): xsdata = openmc.XSdata(name, self.energy_groups) if order is None: - # Set the order to the Library's order (the defualt behavior) + # Set the order to the Library's order (the default behavior) xsdata.order = self.legendre_order else: # Set the order of the xsdata object to the minimum of # the provided order or the Library's order. xsdata.order = min(order, self.legendre_order) - # Right now only 'legendre' data and isotropic weighting is supported - self.scatter_format = 'legendre' + # Right now only isotropic weighting is supported self.representation = 'isotropic' if nuclide != 'total': diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 65802f2ef..cafda1ecf 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -60,6 +60,9 @@ _DOMAINS = (openmc.Cell, openmc.Material, openmc.Mesh) +# Supported ScatterMatrixXS and NuScatterMatrixXS angular distribution types +MU_TREATMENTS = ('legendre', 'histogram') + class MGXS(object): """An abstract multi-group cross section for some energy group structure @@ -3212,8 +3215,8 @@ class NuScatterXS(MGXS): class ScatterMatrixXS(MatrixMGXS): - r"""A scattering matrix multi-group cross section for one or more Legendre - moments. + r"""A scattering matrix multi-group cross section with the cosine of the + change-in-angle represented as one or more Legendre moments or a histogram. This class can be used for both OpenMC input generation and tally data post-processing to compute spatially-homogenized and energy-integrated @@ -3231,7 +3234,7 @@ class ScatterMatrixXS(MatrixMGXS): For a spatial domain :math:`V`, incoming energy group :math:`[E_{g'},E_{g'-1}]`, and outgoing energy group :math:`[E_g,E_{g-1}]`, - the scattering moments are calculated as: + the Legendre scattering moments are calculated as: .. math:: @@ -3271,9 +3274,18 @@ class ScatterMatrixXS(MatrixMGXS): Attributes ---------- correction : 'P0' or None - Apply the P0 correction to scattering matrices if set to 'P0' + Apply the P0 correction to scattering matrices if set to 'P0'; this is + used only if :attr:`ScatterMatrixXS.scatter_format` is 'legendre' + scatter_format : {'legendre', or 'histogram'} + Representation of the angular scattering distribution (default is + 'legendre') legendre_order : int - The highest Legendre moment in the scattering matrix (default is 0) + The highest Legendre moment in the scattering matrix; this is used if + :attr:`ScatterMatrixXS.scatter_format` is 'legendre'. (default is 0) + histogram_bins : int + The number of equally-spaced bins for the histogram representation of + the angular scattering distribution; this is used if + :attr:`ScatterMatrixXS.scatter_format` is 'histogram'. (default is 16) name : str, optional Name of the multi-group cross section rxn_type : str @@ -3340,7 +3352,9 @@ class ScatterMatrixXS(MatrixMGXS): groups, by_nuclide, name) self._rxn_type = 'scatter' self._correction = 'P0' + self._scatter_format = 'legendre' self._legendre_order = 0 + self._histogram_bins = 16 self._hdf5_key = 'scatter matrix' self._estimator = 'analog' self._valid_estimators = ['analog'] @@ -3348,26 +3362,39 @@ class ScatterMatrixXS(MatrixMGXS): def __deepcopy__(self, memo): clone = super(ScatterMatrixXS, self).__deepcopy__(memo) clone._correction = self.correction + clone._scatter_format = self.scatter_format clone._legendre_order = self.legendre_order + clone._histogram_bins = self.histogram_bins return clone @property def correction(self): return self._correction + @property + def scatter_format(self): + return self._scatter_format + @property def legendre_order(self): return self._legendre_order + @property + def histogram_bins(self): + return self._histogram_bins + @property def scores(self): scores = ['flux'] - if self.correction == 'P0' and self.legendre_order == 0: - scores += ['{}-0'.format(self.rxn_type), - '{}-1'.format(self.rxn_type)] - else: - scores += ['{}-P{}'.format(self.rxn_type, self.legendre_order)] + if self.scatter_format == 'legendre': + if self.correction == 'P0' and self.legendre_order == 0: + scores += ['{}-0'.format(self.rxn_type), + '{}-1'.format(self.rxn_type)] + else: + scores += ['{}-P{}'.format(self.rxn_type, self.legendre_order)] + elif self.scatter_format == 'histogram': + scores += [self.rxn_type] return scores @@ -3377,10 +3404,14 @@ class ScatterMatrixXS(MatrixMGXS): energy = openmc.EnergyFilter(group_edges) energyout = openmc.EnergyoutFilter(group_edges) - if self.correction == 'P0' and self.legendre_order == 0: - filters = [[energy], [energy, energyout], [energyout]] - else: - filters = [[energy], [energy, energyout]] + if self.scatter_format == 'legendre': + if self.correction == 'P0' and self.legendre_order == 0: + filters = [[energy], [energy, energyout], [energyout]] + else: + filters = [[energy], [energy, energyout]] + elif self.scatter_format == 'histogram': + bins = np.linspace(-1., 1., num=self.histogram_bins, endpoint=True) + filters = [[energy], [energy, energyout, openmc.MuFilter(bins)]] return filters @@ -3388,20 +3419,24 @@ class ScatterMatrixXS(MatrixMGXS): def rxn_rate_tally(self): if self._rxn_rate_tally is None: + if self.scatter_format == 'legendre': + # If using P0 correction subtract scatter-1 from the diagonal + if self.correction == 'P0' and self.legendre_order == 0: + scatter_p0 = self.tallies['{}-0'.format(self.rxn_type)] + scatter_p1 = self.tallies['{}-1'.format(self.rxn_type)] + energy_filter = scatter_p0.find_filter(openmc.EnergyFilter) + energy_filter = copy.deepcopy(energy_filter) + scatter_p1 = scatter_p1.diagonalize_filter(energy_filter) + self._rxn_rate_tally = scatter_p0 - scatter_p1 - # If using P0 correction subtract scatter-1 from the diagonal - if self.correction == 'P0' and self.legendre_order == 0: - scatter_p0 = self.tallies['{}-0'.format(self.rxn_type)] - scatter_p1 = self.tallies['{}-1'.format(self.rxn_type)] - energy_filter = scatter_p0.find_filter(openmc.EnergyFilter) - energy_filter = copy.deepcopy(energy_filter) - scatter_p1 = scatter_p1.diagonalize_filter(energy_filter) - self._rxn_rate_tally = scatter_p0 - scatter_p1 - - # Extract scattering moment reaction rate Tally - else: - tally_key = '{}-P{}'.format(self.rxn_type, self.legendre_order) - self._rxn_rate_tally = self.tallies[tally_key] + # Extract scattering moment reaction rate Tally + else: + tally_key = '{}-P{}'.format(self.rxn_type, + self.legendre_order) + self._rxn_rate_tally = self.tallies[tally_key] + elif self.scatter_format == 'histogram': + # Extract scattering rate distribution tally + self._rxn_rate_tally = self.tallies[self.rxn_type] self._rxn_rate_tally.sparse = self.sparse @@ -3411,27 +3446,52 @@ class ScatterMatrixXS(MatrixMGXS): def correction(self, correction): cv.check_value('correction', correction, ('P0', None)) - if correction == 'P0' and self.legendre_order > 0: - msg = 'The P0 correction will be ignored since the scattering ' \ - 'order {} is greater than zero'.format(self.legendre_order) + if self.scatter_format == 'legendre': + if correction == 'P0' and self.legendre_order > 0: + msg = 'The P0 correction will be ignored since the ' \ + 'scattering order {} is greater than '\ + 'zero'.format(self.legendre_order) + warnings.warn(msg) + elif self.scatter_format == 'histogram': + msg = 'The P0 correction will be ignored since the ' \ + 'scatter format is set to histogram' warnings.warn(msg) self._correction = correction + @scatter_format.setter + def scatter_format(self, scatter_format): + cv.check_value('scatter_format', scatter_format, MU_TREATMENTS) + self._scatter_format = scatter_format + @legendre_order.setter def legendre_order(self, legendre_order): cv.check_type('legendre_order', legendre_order, Integral) - cv.check_greater_than('legendre_order', legendre_order, 0, equality=True) + cv.check_greater_than('legendre_order', legendre_order, 0, + equality=True) cv.check_less_than('legendre_order', legendre_order, 10, equality=True) - if self.correction == 'P0' and legendre_order > 0: - msg = 'The P0 correction will be ignored since the scattering ' \ - 'order {} is greater than zero'.format(self.legendre_order) - warnings.warn(msg, RuntimeWarning) - self.correction = None + if self.scatter_format == 'legendre': + if self.correction == 'P0' and legendre_order > 0: + msg = 'The P0 correction will be ignored since the ' \ + 'scattering order {} is greater than '\ + 'zero'.format(self.legendre_order) + warnings.warn(msg, RuntimeWarning) + self.correction = None + elif self.scatter_format == 'histogram': + msg = 'The legendre order will be ignored since the ' \ + 'scatter format is set to histogram' + warnings.warn(msg) self._legendre_order = legendre_order + @histogram_bins.setter + def histogram_bins(self, histogram_bins): + cv.check_type('histogram_bins', histogram_bins, Integral) + cv.check_greater_than('histogram_bins', histogram_bins, 0) + + self._histogram_bins = histogram_bins + def load_from_statepoint(self, statepoint): """Extracts tallies in an OpenMC StatePoint with the data needed to compute multi-group cross sections. @@ -3461,12 +3521,16 @@ class ScatterMatrixXS(MatrixMGXS): self._rxn_rate_tally = None self._loaded_sp = False - # Expand scores to match the format in the statepoint - # e.g., "scatter-P2" -> "scatter-0", "scatter-1", "scatter-2" - if self.correction != 'P0' or self.legendre_order != 0: - tally_key = '{}-P{}'.format(self.rxn_type, self.legendre_order) - self.tallies[tally_key].scores = \ - [self.rxn_type + '-{}'.format(i) for i in range(self.legendre_order+1)] + if self.scatter_format == 'legendre': + # Expand scores to match the format in the statepoint + # e.g., "scatter-P2" -> "scatter-0", "scatter-1", "scatter-2" + if self.correction != 'P0' or self.legendre_order != 0: + tally_key = '{}-P{}'.format(self.rxn_type, self.legendre_order) + self.tallies[tally_key].scores = \ + [self.rxn_type + '-{}'.format(i) + for i in range(self.legendre_order + 1)] + elif self.scatter_format == 'histogram': + self.tallies[self.rxn_type].scores = [self.rxn_type] super(ScatterMatrixXS, self).load_from_statepoint(statepoint) @@ -3513,7 +3577,7 @@ class ScatterMatrixXS(MatrixMGXS): slice_xs._xs_tally = None # Slice the Legendre order if needed - if legendre_order != 'same': + if legendre_order != 'same' and self.scatter_format == 'legendre': cv.check_type('legendre_order', legendre_order, Integral) cv.check_less_than('legendre_order', legendre_order, self.legendre_order, equality=True) @@ -3522,7 +3586,8 @@ class ScatterMatrixXS(MatrixMGXS): # Slice the scattering tally tally_key = '{}-P{}'.format(self.rxn_type, self.legendre_order) expand_scores = \ - [self.rxn_type + '-{}'.format(i) for i in range(self.legendre_order+1)] + [self.rxn_type + '-{}'.format(i) + for i in range(self.legendre_order + 1)] slice_xs.tallies[tally_key] = \ slice_xs.tallies[tally_key].get_slice(scores=expand_scores) @@ -3553,7 +3618,8 @@ class ScatterMatrixXS(MatrixMGXS): This method constructs a 5D NumPy array for the requested multi-group cross section data for one or more subdomains (1st dimension), energy groups in (2nd dimension), energy groups out - (3rd dimension), nuclides (4th dimension), and moments (5th dimension). + (3rd dimension), nuclides (4th dimension), and moments/histograms + (5th dimension). NOTE: The scattering moments are not multiplied by the :math:`(2l+1)/2` prefactor in the expansion of the scattering source into Legendre @@ -3642,7 +3708,7 @@ class ScatterMatrixXS(MatrixMGXS): filter_bins.append((self.energy_groups.get_group_bounds(group),)) # Construct CrossScore for requested scattering moment - if moment != 'all': + if moment != 'all' and self.scatter_format == 'legendre': cv.check_type('moment', moment, Integral) cv.check_greater_than('moment', moment, 0, equality=True) cv.check_less_than( @@ -3760,28 +3826,38 @@ class ScatterMatrixXS(MatrixMGXS): df = super(ScatterMatrixXS, self).get_pandas_dataframe( groups, nuclides, xs_type, distribcell_paths) - # Add a moment column to dataframe - if self.legendre_order > 0: - # Insert a column corresponding to the Legendre moments - moments = ['P{}'.format(i) for i in range(self.legendre_order+1)] - moments = np.tile(moments, int(df.shape[0] / len(moments))) - df['moment'] = moments + if self.scatter_format == 'legendre': + # Add a moment column to dataframe + if self.legendre_order > 0: + # Insert a column corresponding to the Legendre moments + moments = ['P{}'.format(i) + for i in range(self.legendre_order + 1)] + moments = np.tile(moments, int(df.shape[0] / len(moments))) + df['moment'] = moments - # Place the moment column before the mean column - columns = df.columns.tolist() - mean_index = [i for i, s in enumerate(columns) if 'mean' in s][0] - if self.domain_type == 'mesh': - df = df[columns[:mean_index] + [('moment', '')] + columns[mean_index:-1]] - else: - df = df[columns[:mean_index] + ['moment'] + columns[mean_index:-1]] + # Place the moment column before the mean column + columns = df.columns.tolist() + mean_index \ + = [i for i, s in enumerate(columns) if 'mean' in s][0] + if self.domain_type == 'mesh': + df = df[columns[:mean_index] + [('moment', '')] + + columns[mean_index:-1]] + else: + df = df[columns[:mean_index] + ['moment'] + + columns[mean_index:-1]] - # Select rows corresponding to requested scattering moment - if moment != 'all': - cv.check_type('moment', moment, Integral) - cv.check_greater_than('moment', moment, 0, equality=True) - cv.check_less_than( - 'moment', moment, self.legendre_order, equality=True) - df = df[df['moment'] == 'P{}'.format(moment)] + # Select rows corresponding to requested scattering moment + if moment != 'all': + cv.check_type('moment', moment, Integral) + cv.check_greater_than('moment', moment, 0, equality=True) + cv.check_less_than( + 'moment', moment, self.legendre_order, equality=True) + df = df[df['moment'] == 'P{}'.format(moment)] + + elif self.scatter_format == 'histogram': + # Add a change-in-angle (mu) column to dataframe + ###TODO NOT SURE I NEED TO DO THIS + pass return df @@ -3832,7 +3908,7 @@ class ScatterMatrixXS(MatrixMGXS): cv.check_value('xs_type', xs_type, ['macro', 'micro']) - if self.correction != 'P0': + if self.correction != 'P0' and self.scatter_format == 'legendre': rxn_type = '{0} (P{1})'.format(self.rxn_type, moment) else: rxn_type = self.rxn_type diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 35dff1223..5504b6e7c 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1008,21 +1008,26 @@ class XSdata(object): check_type('temperature', temperature, Real) check_value('temperature', temperature, self.temperatures) - if self.scatter_format != 'legendre': - msg = 'Anisotropic scattering representations other than ' \ - 'Legendre expansions have not yet been implemented in ' \ - 'openmc.mgxs.' - raise ValueError(msg) + # Set the value of scatter_format based on the same value within + # scatter + self.scatter_format = scatter.scatter_format # If the user has not defined XSdata.order, then we will set # the order based on the data within scatter. - # Otherwise, we will check to see that XSdata.order to match + # Otherwise, we will check to see that XSdata.order matches # the order of scatter - if self.order is None: - self.order = scatter.legendre_order - else: - check_value('legendre_order', scatter.legendre_order, - [self.order]) + if self.scatter_format == 'legendre': + if self.order is None: + self.order = scatter.legendre_order + else: + check_value('legendre_order', scatter.legendre_order, + [self.order]) + elif self.scatter_format == 'histogram': + if self.order is None: + self.order = scatter.histogram_bins + else: + check_value('histogram_bins', scatter.histogram_bins, + [self.order]) i = np.where(self.temperatures == temperature)[0][0] if self.representation == 'isotropic': @@ -1030,10 +1035,16 @@ class XSdata(object): self._scatter_matrix[i] = np.zeros((self.num_orders, self.energy_groups.num_groups, self.energy_groups.num_groups)) - for moment in range(self.num_orders): - self._scatter_matrix[i][moment, :, :] = \ + if self.scatter_format == 'legendre': + for moment in range(self.num_orders): + self._scatter_matrix[i][moment, :, :] = \ + scatter.get_xs(nuclides=nuclide, xs_type=xs_type, + moment=moment, subdomains=subdomain) + else: + self._scatter_matrix[i][:, :, :] = \ scatter.get_xs(nuclides=nuclide, xs_type=xs_type, - moment=moment, subdomains=subdomain) + subdomains=subdomain) + import pdb; pdb.set_trace() elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' diff --git a/openmc/tallies.py b/openmc/tallies.py index f9daa7a22..6922e77ac 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1301,7 +1301,8 @@ class Tally(object): # Create list of 2-tuples for energy boundary bins elif isinstance(self_filter, (openmc.EnergyFilter, - openmc.EnergyoutFilter)): + openmc.EnergyoutFilter, openmc.MuFilter, + openmc.PolarFilter, openmc.AzimuthalFilter)): bins = [] for k in range(self_filter.num_bins): bins.append((self_filter.bins[k], self_filter.bins[k+1])) From f126d4387ada157e88126a3e013ec95e7dbde5d8 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 18 Oct 2016 05:15:51 -0400 Subject: [PATCH 02/60] working on the writing of the MGXS lib --- openmc/filter.py | 21 +++++++++++++++------ openmc/mgxs/library.py | 36 ++++++++++++++---------------------- openmc/mgxs/mgxs.py | 19 +++++++++++++++---- openmc/mgxs_library.py | 18 +++++++++++------- 4 files changed, 55 insertions(+), 39 deletions(-) diff --git a/openmc/filter.py b/openmc/filter.py index 91ceb2931..fef7a25b0 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -868,15 +868,13 @@ class RealFilter(Filter): return np.allclose(self.bins, other.bins) def get_bin_index(self, filter_bin): - # Use lower energy bound to find index for RealFilters - deltas = np.abs(self.bins - filter_bin[1]) / filter_bin[1] - min_delta = np.min(deltas) - if min_delta < 1E-3: - return deltas.argmin() - 1 - else: + i = np.where(self.bins == filter_bin[1])[0] + if len(i) == 0: msg = 'Unable to get the bin index for Filter since "{0}" ' \ 'is not one of the bins'.format(filter_bin) raise ValueError(msg) + else: + return i[0] - 1 def get_bin(self, bin_index): cv.check_type('bin_index', bin_index, Integral) @@ -907,6 +905,17 @@ class EnergyFilter(RealFilter): """ + def get_bin_index(self, filter_bin): + # Use lower energy bound to find index for RealFilters + deltas = np.abs(self.bins - filter_bin[1]) / filter_bin[1] + min_delta = np.min(deltas) + if min_delta < 1E-3: + return deltas.argmin() - 1 + else: + msg = 'Unable to get the bin index for Filter since "{0}" ' \ + 'is not one of the bins'.format(filter_bin) + raise ValueError(msg) + def check_bins(self, bins): for edge in bins: if not isinstance(edge, Real): diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 96bfa6fab..46d404e4f 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -875,13 +875,13 @@ class Library(object): return pickle.load(open(full_filename, 'rb')) def get_xsdata(self, domain, xsdata_name, nuclide='total', xs_type='macro', - order=None, subdomain=None): + subdomain=None): """Generates an openmc.XSdata object describing a multi-group cross section dataset for writing to an openmc.MGXSLibrary object. Note that this method does not build an XSdata object with nested temperature tables. The temperature of each - XSdata object will be left at the default value of 300K. + XSdata object will be left at the default value of 294K. Parameters ---------- @@ -896,10 +896,6 @@ class Library(object): Provide the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. If the Library object is not tallied by nuclide this will be set to 'macro' regardless. - order : int - Scattering order for this data entry. Default is None, - which will set the XSdata object to use the order of the - Library. subdomain : iterable of int This parameter is not used unless using a mesh domain. In that case, the subdomain is an [i,j,k] index (1-based indexing) of the @@ -929,10 +925,6 @@ class Library(object): cv.check_type('xsdata_name', xsdata_name, basestring) cv.check_type('nuclide', nuclide, basestring) cv.check_value('xs_type', xs_type, ['macro', 'micro']) - cv.check_type('order', order, (type(None), Integral)) - if order is not None: - cv.check_greater_than('order', order, 0, equality=True) - cv.check_less_than('order', order, 10, equality=True) if subdomain is not None: cv.check_iterable_type('subdomain', subdomain, Integral, max_depth=3) @@ -953,14 +945,6 @@ class Library(object): name += '_' + nuclide xsdata = openmc.XSdata(name, self.energy_groups) - if order is None: - # Set the order to the Library's order (the default behavior) - xsdata.order = self.legendre_order - else: - # Set the order of the xsdata object to the minimum of - # the provided order or the Library's order. - xsdata.order = min(order, self.legendre_order) - # Right now only isotropic weighting is supported self.representation = 'isotropic' @@ -1033,6 +1017,7 @@ class Library(object): using_multiplicity = False if using_multiplicity: + # import pdb; pdb.set_trace() nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') xsdata.set_scatter_matrix_mgxs(nuscatt_mgxs, xs_type=xs_type, nuclide=[nuclide], @@ -1049,10 +1034,17 @@ class Library(object): # accounted for approximately by using an adjusted # absorption cross section. if 'total' in self.mgxs_types or 'transport' in self.mgxs_types: - for i in range(len(xsdata.temperatures)): - xsdata._absorption[i] = \ - np.subtract(xsdata._total[i], np.sum( - xsdata._scatter_matrix[i][0, :, :], axis=1)) + if xsdata.scatter_format == 'legendre': + for i in range(len(xsdata.temperatures)): + xsdata._absorption[i] = \ + np.subtract(xsdata._total[i], np.sum( + xsdata._scatter_matrix[i][0, :, :], axis=1)) + elif xsdata.scatter_format == 'histogram': + for i in range(len(xsdata.temperatures)): + xsdata._absorption[i] = \ + np.subtract(xsdata._total[i], np.sum(np.sum( + xsdata._scatter_matrix[i][:, :, :], axis=0), + axis=1)) return xsdata diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index cafda1ecf..c30cc87ac 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -3410,7 +3410,8 @@ class ScatterMatrixXS(MatrixMGXS): else: filters = [[energy], [energy, energyout]] elif self.scatter_format == 'histogram': - bins = np.linspace(-1., 1., num=self.histogram_bins, endpoint=True) + bins = np.linspace(-1., 1., num=self.histogram_bins + 1, + endpoint=True) filters = [[energy], [energy, energyout, openmc.MuFilter(bins)]] return filters @@ -3758,9 +3759,19 @@ class ScatterMatrixXS(MatrixMGXS): else: num_out_groups = len(out_groups) + if self.scatter_format == 'histogram': + num_mu_bins = self.histogram_bins + else: + num_mu_bins = 1 + # Reshape tally data array with separate axes for domain and energy - num_subdomains = int(xs.shape[0] / (num_in_groups * num_out_groups)) - new_shape = (num_subdomains, num_in_groups, num_out_groups) + num_subdomains = int(xs.shape[0] / + (num_mu_bins * num_in_groups * num_out_groups)) + if self.scatter_format == 'histogram': + new_shape = (num_subdomains, num_in_groups, num_out_groups, + num_mu_bins) + else: + new_shape = (num_subdomains, num_in_groups, num_out_groups) new_shape += xs.shape[1:] xs = np.reshape(xs, new_shape) @@ -3771,7 +3782,7 @@ class ScatterMatrixXS(MatrixMGXS): # Reverse data if user requested increasing energy groups since # tally data is stored in order of increasing energies if order_groups == 'increasing': - xs = xs[:, ::-1, ::-1, :] + xs = xs[:, ::-1, ::-1, ...] if squeeze: xs = np.squeeze(xs) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 5504b6e7c..c78b9ff0c 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1031,21 +1031,21 @@ class XSdata(object): i = np.where(self.temperatures == temperature)[0][0] if self.representation == 'isotropic': - # Get the scattering orders in the outermost dimension - self._scatter_matrix[i] = np.zeros((self.num_orders, - self.energy_groups.num_groups, - self.energy_groups.num_groups)) if self.scatter_format == 'legendre': + # Get the scattering orders in the outermost dimension + self._scatter_matrix[i] = np.zeros((self.num_orders, + self.energy_groups.num_groups, + self.energy_groups.num_groups)) for moment in range(self.num_orders): self._scatter_matrix[i][moment, :, :] = \ scatter.get_xs(nuclides=nuclide, xs_type=xs_type, moment=moment, subdomains=subdomain) else: - self._scatter_matrix[i][:, :, :] = \ + self._scatter_matrix[i] = \ scatter.get_xs(nuclides=nuclide, xs_type=xs_type, subdomains=subdomain) - import pdb; pdb.set_trace() - + # self._scatter_matrix[i] = \ + # np.swapaxes(self._scatter_matrix[i], 0, 2) elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -1124,6 +1124,10 @@ class XSdata(object): scatt = scatter.get_xs(nuclides=nuclide, xs_type=xs_type, moment=0, subdomains=subdomain) + if scatter.scatter_format == 'histogram': + scatt = np.sum(scatt, axis=4) + if nuscatter.scatter_format == 'histogram': + nuscatt = np.sum(nuscatt, axis=4) self._multiplicity_matrix[i] = np.divide(nuscatt, scatt) elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' From 45fb4201f643cb49045e3af36c8a771953d5e995 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 23 Oct 2016 13:14:46 -0400 Subject: [PATCH 03/60] Fixed angular indexing --- openmc/mgxs/mgxs.py | 5 +++++ openmc/mgxs_library.py | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index fb81e4c31..470fd01d0 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -3776,6 +3776,11 @@ class ScatterMatrixXS(MatrixMGXS): if order_groups == 'increasing': xs = xs[:, ::-1, ::-1, ...] + # Place the histogram bins before the outgoing group index + if self.scatter_format == 'histogram': + xs = np.swapaxes(xs, 3, 1) + xs = np.swapaxes(xs, 3, 2) + if squeeze: xs = np.squeeze(xs) xs = np.atleast_2d(xs) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 8a7d771ac..6256da352 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1043,8 +1043,6 @@ class XSdata(object): self._scatter_matrix[i] = \ scatter.get_xs(nuclides=nuclide, xs_type=xs_type, subdomains=subdomain) - # self._scatter_matrix[i] = \ - # np.swapaxes(self._scatter_matrix[i], 0, 2) elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -1124,9 +1122,9 @@ class XSdata(object): xs_type=xs_type, moment=0, subdomains=subdomain) if scatter.scatter_format == 'histogram': - scatt = np.sum(scatt, axis=4) + scatt = np.sum(scatt, axis=0) if nuscatter.scatter_format == 'histogram': - nuscatt = np.sum(nuscatt, axis=4) + nuscatt = np.sum(nuscatt, axis=0) self._multiplicity_matrix[i] = np.divide(nuscatt, scatt) elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' From 4e50b6e8c7330fbea96438cf35e807b33f70b705 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 5 Nov 2016 16:55:34 -0400 Subject: [PATCH 04/60] Ability to read in a cross_sections.xml from python and initial capability for plotting macroscopic xs --- openmc/data/library.py | 36 ++++++++++++++ openmc/material.py | 109 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) diff --git a/openmc/data/library.py b/openmc/data/library.py index 0485af064..3e01c2464 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -22,6 +22,12 @@ class DataLibrary(EqualityMixin): def __init__(self): self.libraries = [] + def __getitem__(self, material): + for library in self.libraries: + if material in library['materials']: + return library + return None + def register_file(self, filename): """Register a file with the data library. @@ -78,3 +84,33 @@ class DataLibrary(EqualityMixin): tree = ET.ElementTree(root) tree.write(path, xml_declaration=True, encoding='utf-8', method='xml') + + @classmethod + def from_xml(cls, path): + """Read cross section data library from an XML file. + + Parameters + ---------- + path : str + Path to XML file to read. + + """ + + data = cls() + + tree = ET.parse(path) + root = tree.getroot() + if root.find('directory') is not None: + directory = root.find('directory').text + else: + directory = os.path.dirname(path) + + for lib_element in root.findall('library'): + filename = os.path.join(directory, lib_element.attrib['path']) + filetype = lib_element.attrib['type'] + materials = lib_element.attrib['materials'].split() + library = {'path': filename, 'type': filetype, + 'materials': materials} + data.libraries.append(library) + + return data diff --git a/openmc/material.py b/openmc/material.py index c265c9069..271acfd8f 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -6,6 +6,9 @@ from xml.etree import ElementTree as ET import sys from six import string_types +from scipy.interpolate import interp1d +import numpy as np +import h5py import openmc import openmc.data @@ -27,6 +30,13 @@ def reset_auto_material_id(): DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/cm3', 'atom/b-cm', 'atom/cm3', 'sum', 'macro'] +# Supported keywords for material xs plotting +_PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', + 'absorption'] +# MTs to sum to generate associated plot_types +_PLOT_TYPES_MT = {'total': (1,), 'scatter': (2, 4), 'elastic': (2,), + 'inelastic': (1,), 'fission': (18,), 'absorption': (102,)} + class Material(object): """A material composed of a collection of nuclides/elements that can be @@ -581,6 +591,105 @@ class Material(object): return nuclides + def plot_xs(self, library, types, labels=None): + """Creates a figure of macroscopic cross sections for this material + + Parameters + ---------- + library : openmc.data.DataLibrary + Library of data to use for plotting. + types : int, tuples of int, {'total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption'} or list thereof + The type of cross sections to include in the plot. This can either + be an MT number, a tuple of MT numbers (indicating they are to be + summed before plotting) or a string describing a common type. + These values can be either a single value, or an iterable + in the case of multiple sets per plot. + labels : str or list of str, optional + Labels to use in the plot legend for each type requested. + Single string (if there is only one type) or a list of strings + with a length matching the length of types. + + Returns + ------- + fig : matplotlib.figure.Figure + Matplotlib Figure of the generated macroscopic cross section + + """ + + # Check types + # ## Need to add error messages in some ELSEs + # ## Need to add in label handling + if isinstance(types, Integral): + cv.check_greater_than('types', types, 0) + elif isinstance(types, list): + for line in types: + if isinstance(line, Integral): + cv.check_greater_than('line in types', line, 0) + elif isinstance(line, tuple): + for entry in line: + if isinstance(entry, Integral): + cv.check_greater_than('entry in line in types', + entry, 0) + elif line in _PLOT_TYPES: + # Replace with the MTs to sum to simplify downstream code + line = _PLOT_TYPES_MT[line] + + # Convert temperature to format for accessing in the library + if self.temperature is not None: + T = "{}K".format(int(round(self.temperature))) + else: + T = None + + if isinstance(types, (Integral, str)): + types_ = [(types,)] + elif isinstance(types, tuple): + types_ = types + + # Now we can create the data sets to be plotted + xs = [] + E = [] + percent = [] + + for n, nuclide in enumerate(self.nuclides): + nuc, pct, units = nuclide + # import pdb; pdb.set_trace() + percent.append(pct) + lib = library[nuc] + if lib is not None: + nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) + # ## Need to check temperatures + nucT = T + # ## + E.append(nuc.energy[nucT]) + xs.append([]) + for l, line in enumerate(types_): + # Get the reaction from the nuclide + for mt in line: + funcs = [] + if mt in nuc: + funcs.append(nuc[mt].xs[nucT]) + # ## What if funcs is empty? + xs[-1].append(openmc.data.Sum(funcs)) + else: + raise ValueError(nuclide + " not in library") + + # Condense the data for every nuclide + # First create a union energy grid + unionE = E[0] + for n in range(1, len(E)): + unionE = np.union1d(unionE, E[n]) + + # Now we can combine all the nuclidic data + data = np.zeros((len(types_), len(self.nuclides))) + for l in range(len(types_)): + for n in range(len(self.nuclides)): + # ## + density = percent[n] + # ## + data[l, n] += density * xs[n][l](unionE) + + return data + def _get_nuclide_xml(self, nuclide, distrib=False): xml_element = ET.Element("nuclide") xml_element.set("name", nuclide[0].name) From ddf642e1956e3524084cedf12cfa014bdaf5c69b Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 6 Nov 2016 08:26:16 -0500 Subject: [PATCH 05/60] Incorporated ability to include densities and to plot s(a,b) data when in the material --- openmc/data/function.py | 57 ++++++++ openmc/material.py | 317 ++++++++++++++++++++++++++++++++++------ 2 files changed, 327 insertions(+), 47 deletions(-) diff --git a/openmc/data/function.py b/openmc/data/function.py index e9ecf82c5..634bf5664 100644 --- a/openmc/data/function.py +++ b/openmc/data/function.py @@ -432,6 +432,63 @@ class Sum(EqualityMixin): self._functions = functions +class Piecewise(EqualityMixin): + """Piecewise composition of multiple functions. + + This class allows you to create a callable object which is composed + of other callable objects each over a set domain. + + Parameters + ---------- + functions : Iterable of Callable + Functions which are to be combined in a piecewise fashion + breakpoints : Iterable of float + The breakpoints between each function. The functions + in the functions attribute must be provided in order of + increasing domains. + + Attributes + ---------- + functions : Iterable of Callable + Functions which are to be combined in a piecewise fashion + breakpoints : Iterable of float + The breakpoints between each function + + """ + + def __init__(self, functions, breakpoints): + self.functions = functions + self.breakpoints = breakpoints + + def __call__(self, x): + i = np.searchsorted(self.breakpoints, x) + if isinstance(x, Iterable): + ans = np.empty_like(x) + for j in range(len(i)): + ans[j] = self.functions[i[j]](x[j]) + return ans + else: + return self.functions[i](x) + + @property + def functions(self): + return self._functions + + @property + def breakpoints(self): + return self._breakpoints + + @functions.setter + def functions(self, functions): + cv.check_type('functions', functions, Iterable, Callable) + self._functions = functions + + @breakpoints.setter + def breakpoints(self, breakpoints): + cv.check_iterable_type('breakpoints', breakpoints, Real) + self._breakpoints = breakpoints + + class ResonancesWithBackground(EqualityMixin): """Cross section in resolved resonance region. diff --git a/openmc/material.py b/openmc/material.py index 271acfd8f..46734a42f 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -6,9 +6,9 @@ from xml.etree import ElementTree as ET import sys from six import string_types -from scipy.interpolate import interp1d import numpy as np -import h5py +import scipy.constants as sc +from matplotlib import pyplot as plt import openmc import openmc.data @@ -32,10 +32,27 @@ DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/cm3', 'atom/b-cm', 'atom/cm3', 'sum', # Supported keywords for material xs plotting _PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', - 'absorption'] + 'absorption', 'non-fission capture', 'n-alpha'] # MTs to sum to generate associated plot_types -_PLOT_TYPES_MT = {'total': (1,), 'scatter': (2, 4), 'elastic': (2,), - 'inelastic': (1,), 'fission': (18,), 'absorption': (102,)} +_PLOT_TYPES_MT = {'total': (2, 3,), + 'scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, + 30, 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, + 152, 153, 154, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 183, 184, 185, 186, 187, 188, 189, + 190, 194, 195, 196, 198, 199, 200, 875, 891), + 'elastic': (2,), + 'inelastic': (4, 11, 16, 17, 22, 23, 24, 25, 28, 29, + 30, 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, + 152, 153, 154, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 183, 184, 185, 186, 187, 188, 189, + 190, 194, 195, 196, 198, 199, 200, 875, 891), + 'fission': (18,), 'absorption': (27,), + 'non-fission capture': (101,), + 'n-alpha': (107,)} class Material(object): @@ -580,7 +597,7 @@ class Material(object): nuclides = OrderedDict() for nuclide, density, density_type in self._nuclides: - nuclides[nuclide.name] = (nuclide, density) + nuclides[nuclide.name] = (nuclide, density, density_type) for ele, ele_pct, ele_pct_type, enr in self._elements: @@ -591,23 +608,26 @@ class Material(object): return nuclides - def plot_xs(self, library, types, labels=None): + def plot_xs(self, library, types, temperature=294., Erange=(1.E-5, 20.E6)): """Creates a figure of macroscopic cross sections for this material Parameters ---------- library : openmc.data.DataLibrary Library of data to use for plotting. - types : int, tuples of int, {'total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption'} or list thereof + types : int, tuples of int, {'total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption', 'non-fission capture', 'n-alpha'} or list thereof The type of cross sections to include in the plot. This can either be an MT number, a tuple of MT numbers (indicating they are to be summed before plotting) or a string describing a common type. These values can be either a single value, or an iterable in the case of multiple sets per plot. - labels : str or list of str, optional - Labels to use in the plot legend for each type requested. - Single string (if there is only one type) or a list of strings - with a length matching the length of types. + temperature : float, optional + Temperature in Kelvin to plot. If not specified, a default + temperature of 294K will be plotted. Note that the nearest + temperature in the library for each nuclide will be used as opposed + to using any interpolation. + Erange: tuple of floats + Energy range (in eV) to plot the cross section within Returns ------- @@ -616,63 +636,269 @@ class Material(object): """ + E, data, labels = self.calculate_xs(library, types, temperature) + + # Generate the plot + fig = plt.figure() + ax = fig.add_subplot(111) + iE_max = np.searchsorted(E, Erange[1]) + min_data = np.finfo(np.float64).max + max_data = np.finfo(np.float64).min + for i in range(len(data)): + if np.sum(data[i, :]) > 0.: + ax.loglog(E, data[i, :], label=labels[i]) + min_data = min(min_data, np.min(data[i, :iE_max])) + max_data = max(max_data, np.max(data[i, :iE_max])) + + ax.set_xlabel('Energy [eV]') + ax.set_ylabel('Macroscopic Cross Section [1/cm]') + ax.legend(loc='best') + ax.set_xlim(Erange) + ax.set_ylim(min_data, max_data) + if self.name is not None: + title = 'Macroscopic Cross Section for ' + self.name + ax.set_title(title) + + return fig + + def calculate_xs(self, library, types, temperature=294.): + """Calculates macroscopic cross sections of a requested type + + Parameters + ---------- + library : openmc.data.DataLibrary + Library of data to use for plotting. + types : int, tuples of int, {'total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption', 'n-alpha'} or list thereof + The type of cross sections to include in the plot. This can either + be an MT number, a tuple of MT numbers (indicating they are to be + summed before plotting) or a string describing a common type. + These values can be either a single value, or an iterable + in the case of multiple sets per plot. + temperature: float, optional + Temperature in Kelvin to plot. If not specified, a default + temperature of 294K will be plotted. Note that the nearest + temperature in the library for each nuclide will be used as opposed + to using any interpolation. + + Returns + ------- + unionE: numpy.array + Energies at which cross sections are calculated, in units of eV + data: numpy.ndarray + Macroscopic cross sections calculated at the energy grid described + by unionE + labels: Iterable of string-type + Name of cross section type for every type requested + + """ + # Check types - # ## Need to add error messages in some ELSEs - # ## Need to add in label handling if isinstance(types, Integral): cv.check_greater_than('types', types, 0) + labels = [openmc.data.REACTION_NAME[types]] + elif types in _PLOT_TYPES: + labels = [types] + # Replace with the MTs to sum to simplify downstream code + types = _PLOT_TYPES_MT[types] elif isinstance(types, list): - for line in types: - if isinstance(line, Integral): - cv.check_greater_than('line in types', line, 0) - elif isinstance(line, tuple): - for entry in line: + labels = [] + for t in range(len(types)): + if isinstance(types[t], Integral): + cv.check_greater_than('type in types', types[t], 0) + labels.append(openmc.data.REACTION_NAME[types[t]]) + elif isinstance(types[t], tuple): + labels.append('') + for e, entry in enumerate(types[t]): if isinstance(entry, Integral): - cv.check_greater_than('entry in line in types', + cv.check_greater_than('entry in type in types', entry, 0) - elif line in _PLOT_TYPES: + if e == len(types[t]) - 1: + labels[-1] += openmc.data.REACTION_NAME + else: + labels[-1] += openmc.data.REACTION_NAME + ' + ' + else: + raise ValueError("Invalid entry, " + "{}, in types".format(str(entry))) + elif types[t] in _PLOT_TYPES: + labels.append(types[t]) # Replace with the MTs to sum to simplify downstream code - line = _PLOT_TYPES_MT[line] + types[t] = _PLOT_TYPES_MT[types[t]] + else: + raise ValueError("Invalid type, " + "{}, in types".format(str(types[t]))) - # Convert temperature to format for accessing in the library + # Convert temperature to format needed for access in the library if self.temperature is not None: - T = "{}K".format(int(round(self.temperature))) + strT = "{}K".format(int(round(self.temperature))) + T = self.temperature else: - T = None + # ## What about default temperature? + cv.check_type('temperature', temperature, Real) + strT = "{}K".format(int(round(temperature))) + T = temperature if isinstance(types, (Integral, str)): types_ = [(types,)] elif isinstance(types, tuple): + types_ = [types] + else: types_ = types + # Expand elements in to nuclides + nuclides = self.get_nuclide_densities() + + sum_density = False + if self.density_units == 'sum': + sum_density = True + density = 0. + elif self.density_units == 'macro': + density = self.density + elif self.density_units == 'g/cc' or self.density_units == 'g/cm3': + density = -self.density + elif self.density_units == 'kg/m3': + density = -0.001 * self.density + elif self.density_units == 'atom/b-cm': + density = self.density + elif self.density_units == 'atom/cm3' or self.density_units == 'atom/cc': + density = 1.E-24 * self.density + + # For ease of processing split out nuc, nuc_density, + # and nuc_density_type in to separate arrays + nucs = [] + nuc_densities = [] + nuc_density_types = [] + for nuclide in nuclides.items(): + nuc, nuc_data = nuclide + nuc, nuc_density, nuc_density_type = nuc_data + nucs.append(nuc) + nuc_densities.append(nuc_density) + nuc_density_types.append(nuc_density_type) + + if sum_density: + density = np.sum(nuc_densities) + percent_in_atom = np.all(nuc_density_types == 'ao') + density_in_atom = density > 0. + sum_percent = 0. + + # Pre-determine the nuclides which need s(a,b) data + sabs = {} + for nuc in nucs: + sabs[nuc.name] = None + + for sab_name in self._sab: + sab = openmc.data.ThermalScattering.from_hdf5( + library[sab_name]['path']) + for nuc in sab.nuclides: + sabs[nuc] = library[sab_name]['path'] + # Now we can create the data sets to be plotted xs = [] E = [] - percent = [] - - for n, nuclide in enumerate(self.nuclides): - nuc, pct, units = nuclide - # import pdb; pdb.set_trace() - percent.append(pct) - lib = library[nuc] + awrs = [] + n = -1 + for nuclide in nuclides.items(): + n += 1 + lib = library[nuclide[0]] + # nuc, nuc_data = nuclide + # lib = library[nuc] if lib is not None: nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) - # ## Need to check temperatures - nucT = T - # ## - E.append(nuc.energy[nucT]) + awrs.append(nuc.atomic_weight_ratio) + if not percent_in_atom: + nuc_densities[n] = -nuc_densities[n] / awrs[-1] + # Obtain the nearest temperature + if strT in nuc.temperatures: + nucT = strT + else: + data_Ts = nuc.temperatures + for t in range(len(data_Ts)): + # Take off the "K" and convert to a float + data_Ts[t] = float(data_Ts[t][:-1]) + min_delta = np.finfo(np.float64).max + closest_t = -1 + for t in data_Ts: + if abs(data_Ts[t] - T) < min_delta: + closest_t = t + nucT = "{}K".format(int(round(data_Ts[closest_t]))) + + # Create an energy grid composed of either the S(a,b) and + # nuclide's grid, or just the nuclide's grid, depending on if + # the S(a,b) data is available for this nuclide + sab_tab = sabs[nucs[n].name] + if sab_tab: + sab = openmc.data.ThermalScattering.from_hdf5(sab_tab) + # Obtain the nearest temperature + if strT in sab.temperatures: + sabT = strT + else: + data_Ts = sab.temperatures + for t in range(len(data_Ts)): + # Take off the "K" and convert to a float + data_Ts[t] = float(data_Ts[t][:-1]) + min_delta = np.finfo(np.float64).max + closest_t = -1 + for t in data_Ts: + if abs(data_Ts[t] - T) < min_delta: + closest_t = t + sabT = "{}K".format(int(round(data_Ts[closest_t]))) + grid = nuc.energy[nucT] + sab_Emax = 0. + sab_funcs = [] + if sab.elastic_xs: + elastic = sab.elastic_xs[sabT] + if isinstance(elastic, openmc.data.CoherentElastic): + grid = np.union1d(grid, elastic.bragg_edges) + if elastic.bragg_edges[-1] > sab_Emax: + sab_Emax = elastic.bragg_edges[-1] + elif isinstance(elastic, openmc.data.Tabulated1D): + grid = np.union1d(grid, elastic.x) + if elastic.x[-1] > sab_Emax: + sab_Emax = elastic.x[-1] + sab_funcs.append(elastic) + if sab.inelastic_xs: + inelastic = sab.inelastic_xs[sabT] + grid = np.union1d(grid, inelastic.x) + if inelastic.x[-1] > sab_Emax: + sab_Emax = inelastic.x[-1] + sab_funcs.append(inelastic) + E.append(grid) + else: + E.append(nuc.energy[nucT]) xs.append([]) for l, line in enumerate(types_): - # Get the reaction from the nuclide + # Get the reaction xs data from the nuclide + funcs = [] for mt in line: - funcs = [] - if mt in nuc: + if mt == 2: + if sab_tab: + # Then we need to do a piece-wise function of + # The S(a,b) and non-thermal data + sab_sum = openmc.data.Sum(sab_funcs) + pw_funcs = openmc.data.Piecewise( + [sab_sum, nuc[mt].xs[nucT]], + [sab_Emax]) + funcs.append(pw_funcs) + else: + funcs.append(nuc[mt].xs[nucT]) + elif mt in nuc: funcs.append(nuc[mt].xs[nucT]) - # ## What if funcs is empty? xs[-1].append(openmc.data.Sum(funcs)) else: raise ValueError(nuclide + " not in library") + # Now that we have the awr, lets finish calculating densities + sum_percent = np.sum(nuc_densities) + nuc_densities = nuc_densities / sum_percent + if not density_in_atom: + sum_percent = 0. + for n, nuc in enumerate(nucs): + x = nuc_densities[n] + sum_percent += x * awrs[n] + sum_percent = 1. / sum_percent + density = -density * sum_percent * \ + sc.Avogadro / sc.value('neutron mass in u') * 1.E-24 + nuc_densities = density * nuc_densities + # Condense the data for every nuclide # First create a union energy grid unionE = E[0] @@ -680,15 +906,12 @@ class Material(object): unionE = np.union1d(unionE, E[n]) # Now we can combine all the nuclidic data - data = np.zeros((len(types_), len(self.nuclides))) + data = np.zeros((len(types_), len(unionE))) for l in range(len(types_)): - for n in range(len(self.nuclides)): - # ## - density = percent[n] - # ## - data[l, n] += density * xs[n][l](unionE) + for n in range(len(nuclides)): + data[l, :] += nuc_densities[n] * xs[n][l](unionE) - return data + return unionE, data, labels def _get_nuclide_xml(self, nuclide, distrib=False): xml_element = ET.Element("nuclide") From 32f70cd21ac9a00337879dedb9260dc6def7e8a9 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 6 Nov 2016 08:47:12 -0500 Subject: [PATCH 06/60] Separated out routine to calculate the atom densities from the xs calculation routine --- openmc/material.py | 135 ++++++++++++++++++++++++++++++--------------- 1 file changed, 91 insertions(+), 44 deletions(-) diff --git a/openmc/material.py b/openmc/material.py index 46734a42f..39549dbd1 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -608,6 +608,94 @@ class Material(object): return nuclides + def get_nuclide_atom_densities(self, library): + """Returns all nuclides in the material and their atomic densities in + units of atom/b-cm + + Parameters + ---------- + library : openmc.data.DataLibrary + Library of data to use for plotting. + + Returns + ------- + nuclides : dict + Dictionary whose keys are nuclide names and values are 2-tuples of + (nuclide, density in atom/b-cm) + + """ + + # Expand elements in to nuclides + nuclides = self.get_nuclide_densities() + + sum_density = False + if self.density_units == 'sum': + sum_density = True + density = 0. + elif self.density_units == 'macro': + density = self.density + elif self.density_units == 'g/cc' or self.density_units == 'g/cm3': + density = -self.density + elif self.density_units == 'kg/m3': + density = -0.001 * self.density + elif self.density_units == 'atom/b-cm': + density = self.density + elif self.density_units == 'atom/cm3' or self.density_units == 'atom/cc': + density = 1.E-24 * self.density + + # For ease of processing split out nuc, nuc_density, + # and nuc_density_type in to separate arrays + nucs = [] + nuc_densities = [] + nuc_density_types = [] + for nuclide in nuclides.items(): + nuc, nuc_data = nuclide + nuc, nuc_density, nuc_density_type = nuc_data + nucs.append(nuc) + nuc_densities.append(nuc_density) + nuc_density_types.append(nuc_density_type) + + if sum_density: + density = np.sum(nuc_densities) + percent_in_atom = np.all(nuc_density_types == 'ao') + density_in_atom = density > 0. + sum_percent = 0. + + awrs = [] + n = -1 + for nuclide in nuclides.items(): + n += 1 + lib = library[nuclide[0]] + if lib is not None: + nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) + awrs.append(nuc.atomic_weight_ratio) + if not percent_in_atom: + nuc_densities[n] = -nuc_densities[n] / awrs[-1] + else: + raise ValueError(nuclide + " not in library") + + # Now that we have the awr, lets finish calculating densities + sum_percent = np.sum(nuc_densities) + nuc_densities = nuc_densities / sum_percent + if not density_in_atom: + sum_percent = 0. + for n, nuc in enumerate(nucs): + x = nuc_densities[n] + sum_percent += x * awrs[n] + sum_percent = 1. / sum_percent + density = -density * sum_percent * \ + sc.Avogadro / sc.value('neutron mass in u') * 1.E-24 + nuc_densities = density * nuc_densities + + result = OrderedDict() + n = -1 + for nuc in nucs: + n += 1 + result[nuc] = (nuc, nuc_densities[n]) + + nuclides = result + return nuclides + def plot_xs(self, library, types, temperature=294., Erange=(1.E-5, 20.E6)): """Creates a figure of macroscopic cross sections for this material @@ -732,7 +820,6 @@ class Material(object): strT = "{}K".format(int(round(self.temperature))) T = self.temperature else: - # ## What about default temperature? cv.check_type('temperature', temperature, Real) strT = "{}K".format(int(round(temperature))) T = temperature @@ -744,41 +831,18 @@ class Material(object): else: types_ = types - # Expand elements in to nuclides - nuclides = self.get_nuclide_densities() - - sum_density = False - if self.density_units == 'sum': - sum_density = True - density = 0. - elif self.density_units == 'macro': - density = self.density - elif self.density_units == 'g/cc' or self.density_units == 'g/cm3': - density = -self.density - elif self.density_units == 'kg/m3': - density = -0.001 * self.density - elif self.density_units == 'atom/b-cm': - density = self.density - elif self.density_units == 'atom/cm3' or self.density_units == 'atom/cc': - density = 1.E-24 * self.density + # Expand elements in to nuclides with atomic densities + nuclides = self.get_nuclide_atom_densities(library) # For ease of processing split out nuc, nuc_density, # and nuc_density_type in to separate arrays nucs = [] nuc_densities = [] - nuc_density_types = [] for nuclide in nuclides.items(): nuc, nuc_data = nuclide - nuc, nuc_density, nuc_density_type = nuc_data + nuc, nuc_density = nuc_data nucs.append(nuc) nuc_densities.append(nuc_density) - nuc_density_types.append(nuc_density_type) - - if sum_density: - density = np.sum(nuc_densities) - percent_in_atom = np.all(nuc_density_types == 'ao') - density_in_atom = density > 0. - sum_percent = 0. # Pre-determine the nuclides which need s(a,b) data sabs = {} @@ -794,7 +858,6 @@ class Material(object): # Now we can create the data sets to be plotted xs = [] E = [] - awrs = [] n = -1 for nuclide in nuclides.items(): n += 1 @@ -803,9 +866,6 @@ class Material(object): # lib = library[nuc] if lib is not None: nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) - awrs.append(nuc.atomic_weight_ratio) - if not percent_in_atom: - nuc_densities[n] = -nuc_densities[n] / awrs[-1] # Obtain the nearest temperature if strT in nuc.temperatures: nucT = strT @@ -886,19 +946,6 @@ class Material(object): else: raise ValueError(nuclide + " not in library") - # Now that we have the awr, lets finish calculating densities - sum_percent = np.sum(nuc_densities) - nuc_densities = nuc_densities / sum_percent - if not density_in_atom: - sum_percent = 0. - for n, nuc in enumerate(nucs): - x = nuc_densities[n] - sum_percent += x * awrs[n] - sum_percent = 1. / sum_percent - density = -density * sum_percent * \ - sc.Avogadro / sc.value('neutron mass in u') * 1.E-24 - nuc_densities = density * nuc_densities - # Condense the data for every nuclide # First create a union energy grid unionE = E[0] From 273e0a32cef1f3e828aba4b3e5caf1c297bf7a71 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 6 Nov 2016 12:42:31 -0500 Subject: [PATCH 07/60] Minor cleanup --- openmc/material.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/openmc/material.py b/openmc/material.py index 39549dbd1..587abf3e1 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -32,7 +32,8 @@ DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/cm3', 'atom/b-cm', 'atom/cm3', 'sum', # Supported keywords for material xs plotting _PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', - 'absorption', 'non-fission capture', 'n-alpha'] + 'absorption', 'capture', 'n-alpha'] + # MTs to sum to generate associated plot_types _PLOT_TYPES_MT = {'total': (2, 3,), 'scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, @@ -51,7 +52,7 @@ _PLOT_TYPES_MT = {'total': (2, 3,), 180, 181, 183, 184, 185, 186, 187, 188, 189, 190, 194, 195, 196, 198, 199, 200, 875, 891), 'fission': (18,), 'absorption': (27,), - 'non-fission capture': (101,), + 'capture': (101,), 'n-alpha': (107,)} @@ -620,11 +621,13 @@ class Material(object): Returns ------- nuclides : dict - Dictionary whose keys are nuclide names and values are 2-tuples of + Dictionary whose keys are nuclide names and values are tuples of (nuclide, density in atom/b-cm) """ + cv.check_type('library', library, openmc.data.DataLibrary) + # Expand elements in to nuclides nuclides = self.get_nuclide_densities() @@ -672,7 +675,7 @@ class Material(object): if not percent_in_atom: nuc_densities[n] = -nuc_densities[n] / awrs[-1] else: - raise ValueError(nuclide + " not in library") + raise ValueError(nuclide[0] + " not in library") # Now that we have the awr, lets finish calculating densities sum_percent = np.sum(nuc_densities) @@ -687,13 +690,12 @@ class Material(object): sc.Avogadro / sc.value('neutron mass in u') * 1.E-24 nuc_densities = density * nuc_densities - result = OrderedDict() + nuclides = OrderedDict() n = -1 for nuc in nucs: n += 1 - result[nuc] = (nuc, nuc_densities[n]) + nuclides[nuc] = (nuc, nuc_densities[n]) - nuclides = result return nuclides def plot_xs(self, library, types, temperature=294., Erange=(1.E-5, 20.E6)): @@ -703,7 +705,7 @@ class Material(object): ---------- library : openmc.data.DataLibrary Library of data to use for plotting. - types : int, tuples of int, {'total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption', 'non-fission capture', 'n-alpha'} or list thereof + types : int, tuples of int, {'total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption', 'capture', 'n-alpha'} or list thereof The type of cross sections to include in the plot. This can either be an MT number, a tuple of MT numbers (indicating they are to be summed before plotting) or a string describing a common type. @@ -781,6 +783,7 @@ class Material(object): """ # Check types + cv.check_type('library', library, openmc.data.DataLibrary) if isinstance(types, Integral): cv.check_greater_than('types', types, 0) labels = [openmc.data.REACTION_NAME[types]] @@ -834,17 +837,16 @@ class Material(object): # Expand elements in to nuclides with atomic densities nuclides = self.get_nuclide_atom_densities(library) - # For ease of processing split out nuc, nuc_density, - # and nuc_density_type in to separate arrays + # For ease of processing split out nuc and nuc_density nucs = [] nuc_densities = [] for nuclide in nuclides.items(): - nuc, nuc_data = nuclide + nuc_name, nuc_data = nuclide nuc, nuc_density = nuc_data nucs.append(nuc) nuc_densities.append(nuc_density) - # Pre-determine the nuclides which need s(a,b) data + # Identify the nuclides which need S(a,b) data sabs = {} for nuc in nucs: sabs[nuc.name] = None @@ -862,8 +864,6 @@ class Material(object): for nuclide in nuclides.items(): n += 1 lib = library[nuclide[0]] - # nuc, nuc_data = nuclide - # lib = library[nuc] if lib is not None: nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) # Obtain the nearest temperature @@ -944,7 +944,7 @@ class Material(object): funcs.append(nuc[mt].xs[nucT]) xs[-1].append(openmc.data.Sum(funcs)) else: - raise ValueError(nuclide + " not in library") + raise ValueError(nuclide[0] + " not in library") # Condense the data for every nuclide # First create a union energy grid From 739dd53c9bb14ea96a93eb4651a400eedf294d75 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 6 Nov 2016 15:48:36 -0500 Subject: [PATCH 08/60] Yay! Now can handle data operations aside from summing, allowing for cheaper calculations of multi-MT datasets (i.e., its easier to find scatter when its just total-absorption), and I put in the ability to get nu-fission and nu-scatter by way of the product yield. Whew. --- openmc/data/function.py | 55 +++++++++++ openmc/material.py | 206 ++++++++++++++++++++++------------------ 2 files changed, 171 insertions(+), 90 deletions(-) diff --git a/openmc/data/function.py b/openmc/data/function.py index 634bf5664..489910c15 100644 --- a/openmc/data/function.py +++ b/openmc/data/function.py @@ -397,6 +397,61 @@ class Polynomial(np.polynomial.Polynomial, Function1D): return cls(dataset.value) +class Combination(EqualityMixin): + """Combination of multiple functions with a user-defined operator + + This class allows you to create a callable object which represents the + combination of other callable objects by way of a user-defined operator. + + Parameters + ---------- + functions : Iterable of Callable + Functions which are to be added together + operations : Iterable of numpy.ufunc + Operations to perform between functions; note that the standard order + of operations (i.e., PEMDAS) will not be followed + + + Attributes + ---------- + functions : Iterable of Callable + Functions which are to be added together + operations : Iterable of numpy.ufunc + Operations to perform between functions + + """ + + def __init__(self, functions, operations): + self.functions = functions + self.operations = operations + + def __call__(self, x): + ans = np.zeros_like(x) + for i, operation in enumerate(self.operations): + ans = operation(ans, self.functions[i](x)) + return ans + + @property + def functions(self): + return self._functions + + @functions.setter + def functions(self, functions): + cv.check_type('functions', functions, Iterable, Callable) + self._functions = functions + + @property + def operations(self): + return self._operations + + @operations.setter + def operations(self, operations): + cv.check_type('operations', operations, Iterable, np.ufunc) + length = len(self.functions) + cv.check_length('operations', operations, length, length_max=length) + self._operations = operations + + class Sum(EqualityMixin): """Sum of multiple functions. diff --git a/openmc/material.py b/openmc/material.py index 587abf3e1..0a6402b78 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -3,7 +3,6 @@ from copy import deepcopy from numbers import Real, Integral import warnings from xml.etree import ElementTree as ET -import sys from six import string_types import numpy as np @@ -30,30 +29,60 @@ def reset_auto_material_id(): DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/cm3', 'atom/b-cm', 'atom/cm3', 'sum', 'macro'] -# Supported keywords for material xs plotting +# Supported keywords for material xs plotting _PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', - 'absorption', 'capture', 'n-alpha'] + 'absorption', 'capture', 'nu-fission', 'nu-scatter'] -# MTs to sum to generate associated plot_types -_PLOT_TYPES_MT = {'total': (2, 3,), - 'scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, - 30, 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, - 152, 153, 154, 156, 157, 158, 159, 160, 161, - 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 183, 184, 185, 186, 187, 188, 189, - 190, 194, 195, 196, 198, 199, 200, 875, 891), - 'elastic': (2,), - 'inelastic': (4, 11, 16, 17, 22, 23, 24, 25, 28, 29, - 30, 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, - 152, 153, 154, 156, 157, 158, 159, 160, 161, - 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 183, 184, 185, 186, 187, 188, 189, - 190, 194, 195, 196, 198, 199, 200, 875, 891), - 'fission': (18,), 'absorption': (27,), - 'capture': (101,), - 'n-alpha': (107,)} +# MTs to combine to generate associated plot_types +_PLOT_TYPES_MT = {'total': (1,), 'scatter': (1, 27), 'elastic': (2,), + 'inelastic': (1, 27, 2), 'fission': (18,), + 'absorption': (27,), 'capture': (101,), + 'nu-fission': (18,), + 'nu-scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, + 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, + 153, 154, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 183, 184, 190, 194, 196, 198, 199, 200, + 875, 891)} +# Operations to use when combining MTs the first np.add is used in reference +# to zero +_PLOT_TYPES_OP = {'total': (np.add,), 'scatter': (np.add, np.subtract), + 'elastic': (np.add,), + 'inelastic': (np.add, np.subtract, np.subtract), + 'fission': (np.add,), 'absorption': (np.add,), + 'capture': (np.add,), 'nu-fission': (np.add,), + 'nu-scatter': (np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add)} +# Whether or not to multiply the reaction by the yield as well +_PLOT_TYPES_YIELD = {'total': (False,), 'scatter': (False, False), + 'elastic': (False,), 'inelastic': (False, False, False), + 'fission': (False,), 'absorption': (False,), + 'capture': (False,), 'nu-fission': (True,), + 'nu-scatter': (True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True)} class Material(object): @@ -705,18 +734,16 @@ class Material(object): ---------- library : openmc.data.DataLibrary Library of data to use for plotting. - types : int, tuples of int, {'total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption', 'capture', 'n-alpha'} or list thereof - The type of cross sections to include in the plot. This can either - be an MT number, a tuple of MT numbers (indicating they are to be - summed before plotting) or a string describing a common type. - These values can be either a single value, or an iterable - in the case of multiple sets per plot. + types : Iterable of {'total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption'} + The type of cross sections to include in the plot. In addition to + the above, a custom string can be used which includes MT numbers + and operations to perform such as '2 + 3' temperature : float, optional Temperature in Kelvin to plot. If not specified, a default temperature of 294K will be plotted. Note that the nearest temperature in the library for each nuclide will be used as opposed to using any interpolation. - Erange: tuple of floats + Erange : tuple of floats Energy range (in eV) to plot the cross section within Returns @@ -726,7 +753,7 @@ class Material(object): """ - E, data, labels = self.calculate_xs(library, types, temperature) + E, data = self.calculate_xs(library, types, temperature) # Generate the plot fig = plt.figure() @@ -736,7 +763,7 @@ class Material(object): max_data = np.finfo(np.float64).min for i in range(len(data)): if np.sum(data[i, :]) > 0.: - ax.loglog(E, data[i, :], label=labels[i]) + ax.loglog(E, data[i, :], label=types[i]) min_data = min(min_data, np.min(data[i, :iE_max])) max_data = max(max_data, np.max(data[i, :iE_max])) @@ -758,13 +785,11 @@ class Material(object): ---------- library : openmc.data.DataLibrary Library of data to use for plotting. - types : int, tuples of int, {'total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption', 'n-alpha'} or list thereof - The type of cross sections to include in the plot. This can either - be an MT number, a tuple of MT numbers (indicating they are to be - summed before plotting) or a string describing a common type. - These values can be either a single value, or an iterable - in the case of multiple sets per plot. - temperature: float, optional + types : Iterable of {'total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption'} + The type of cross sections to include in the plot. In addition to + the above, a custom string can be used which includes MT numbers + and operations to perform such as '2 + 3' + temperature : float, optional Temperature in Kelvin to plot. If not specified, a default temperature of 294K will be plotted. Note that the nearest temperature in the library for each nuclide will be used as opposed @@ -772,51 +797,30 @@ class Material(object): Returns ------- - unionE: numpy.array + unionE : numpy.array Energies at which cross sections are calculated, in units of eV - data: numpy.ndarray + data : numpy.ndarray Macroscopic cross sections calculated at the energy grid described by unionE - labels: Iterable of string-type - Name of cross section type for every type requested """ # Check types cv.check_type('library', library, openmc.data.DataLibrary) - if isinstance(types, Integral): - cv.check_greater_than('types', types, 0) - labels = [openmc.data.REACTION_NAME[types]] - elif types in _PLOT_TYPES: - labels = [types] - # Replace with the MTs to sum to simplify downstream code - types = _PLOT_TYPES_MT[types] - elif isinstance(types, list): - labels = [] - for t in range(len(types)): - if isinstance(types[t], Integral): - cv.check_greater_than('type in types', types[t], 0) - labels.append(openmc.data.REACTION_NAME[types[t]]) - elif isinstance(types[t], tuple): - labels.append('') - for e, entry in enumerate(types[t]): - if isinstance(entry, Integral): - cv.check_greater_than('entry in type in types', - entry, 0) - if e == len(types[t]) - 1: - labels[-1] += openmc.data.REACTION_NAME - else: - labels[-1] += openmc.data.REACTION_NAME + ' + ' - else: - raise ValueError("Invalid entry, " - "{}, in types".format(str(entry))) - elif types[t] in _PLOT_TYPES: - labels.append(types[t]) - # Replace with the MTs to sum to simplify downstream code - types[t] = _PLOT_TYPES_MT[types[t]] - else: - raise ValueError("Invalid type, " - "{}, in types".format(str(types[t]))) + cv.check_iterable_type('types', types, str) + + # Parse the types + mts = [] + ops = [] + yields = [] + for line in types: + if line in _PLOT_TYPES: + mts.append(_PLOT_TYPES_MT[line]) + yields.append(_PLOT_TYPES_YIELD[line]) + ops.append(_PLOT_TYPES_OP[line]) + else: + # Not a built-in type, we have to parse it ourselves + raise NotImplementedError() # Convert temperature to format needed for access in the library if self.temperature is not None: @@ -827,13 +831,6 @@ class Material(object): strT = "{}K".format(int(round(temperature))) T = temperature - if isinstance(types, (Integral, str)): - types_ = [(types,)] - elif isinstance(types, tuple): - types_ = [types] - else: - types_ = types - # Expand elements in to nuclides with atomic densities nuclides = self.get_nuclide_atom_densities(library) @@ -925,10 +922,11 @@ class Material(object): else: E.append(nuc.energy[nucT]) xs.append([]) - for l, line in enumerate(types_): + for i, mt_set in enumerate(mts): # Get the reaction xs data from the nuclide funcs = [] - for mt in line: + op = ops[i] + for mt, yield_check in zip(mt_set, yields[i]): if mt == 2: if sab_tab: # Then we need to do a piece-wise function of @@ -941,8 +939,36 @@ class Material(object): else: funcs.append(nuc[mt].xs[nucT]) elif mt in nuc: - funcs.append(nuc[mt].xs[nucT]) - xs[-1].append(openmc.data.Sum(funcs)) + if yield_check: + found_it = False + for prod in nuc[mt].products: + if prod.particle == 'neutron' and \ + prod.emission_mode == 'total': + func = openmc.data.Combination( + [nuc[mt].xs[nucT], prod.yield_], + [np.add, np.multiply]) + funcs.append(func) + found_it = True + break + if not found_it: + for prod in nuc[mt].products: + if prod.particle == 'neutron' and \ + prod.emission_mode == 'prompt': + func = openmc.data.Combination( + [nuc[mt].xs[nucT], + prod.yield_], + [np.add, np.multiply]) + funcs.append(func) + found_it = True + break + if not found_it: + # Assume the yield is 1 + funcs.append(nuc[mt].xs[nucT]) + else: + funcs.append(nuc[mt].xs[nucT]) + else: + funcs.append(lambda x: 0.) + xs[-1].append(openmc.data.Combination(funcs, op)) else: raise ValueError(nuclide[0] + " not in library") @@ -953,12 +979,12 @@ class Material(object): unionE = np.union1d(unionE, E[n]) # Now we can combine all the nuclidic data - data = np.zeros((len(types_), len(unionE))) - for l in range(len(types_)): + data = np.zeros((len(mts), len(unionE))) + for l in range(len(mts)): for n in range(len(nuclides)): data[l, :] += nuc_densities[n] * xs[n][l](unionE) - return unionE, data, labels + return unionE, data def _get_nuclide_xml(self, nuclide, distrib=False): xml_element = ET.Element("nuclide") From 3f610d03ca66fe318560875aa816e7dccfed052f Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 6 Nov 2016 19:43:32 -0500 Subject: [PATCH 09/60] Added the ability to divide by a type, so now we can easily (and not with complicated routines within calculate_xs) get nu-scatter/scatter, nu-fission/fission and something like a moderating ratio (just needs xi). --- openmc/material.py | 59 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/openmc/material.py b/openmc/material.py index 0a6402b78..1e0ff5661 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -31,7 +31,7 @@ DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/cm3', 'atom/b-cm', 'atom/cm3', 'sum', # Supported keywords for material xs plotting _PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', - 'absorption', 'capture', 'nu-fission', 'nu-scatter'] + 'absorption', 'capture', 'nu-fission', 'nu-scatter', 'unity'] # MTs to combine to generate associated plot_types _PLOT_TYPES_MT = {'total': (1,), 'scatter': (1, 27), 'elastic': (2,), @@ -44,7 +44,8 @@ _PLOT_TYPES_MT = {'total': (1,), 'scatter': (1, 27), 'elastic': (2,), 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 183, 184, 190, 194, 196, 198, 199, 200, - 875, 891)} + 875, 891), + 'unity': (0,)} # Operations to use when combining MTs the first np.add is used in reference # to zero _PLOT_TYPES_OP = {'total': (np.add,), 'scatter': (np.add, np.subtract), @@ -64,7 +65,8 @@ _PLOT_TYPES_OP = {'total': (np.add,), 'scatter': (np.add, np.subtract), np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, - np.add)} + np.add), + 'unity': (np.add,)} # Whether or not to multiply the reaction by the yield as well _PLOT_TYPES_YIELD = {'total': (False,), 'scatter': (False, False), 'elastic': (False,), 'inelastic': (False, False, False), @@ -82,7 +84,8 @@ _PLOT_TYPES_YIELD = {'total': (False,), 'scatter': (False, False), True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, - True)} + True), + 'unity': (False,)} class Material(object): @@ -727,17 +730,20 @@ class Material(object): return nuclides - def plot_xs(self, library, types, temperature=294., Erange=(1.E-5, 20.E6)): + def plot_xs(self, library, types, divisor_types=None, temperature=294., + Erange=(1.E-5, 20.E6)): """Creates a figure of macroscopic cross sections for this material Parameters ---------- library : openmc.data.DataLibrary Library of data to use for plotting. - types : Iterable of {'total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption'} - The type of cross sections to include in the plot. In addition to - the above, a custom string can be used which includes MT numbers - and operations to perform such as '2 + 3' + types : Iterable of values of _PLOT_TYPES + The type of cross sections to include in the plot. + divisor_types : Iterable of values of _PLOT_TYPES, optional + Cross section types which will divide those produced by types before + plotting. A type of 'unity' can be used to effectively not divide + some types. temperature : float, optional Temperature in Kelvin to plot. If not specified, a default temperature of 294K will be plotted. Note that the nearest @@ -755,6 +761,26 @@ class Material(object): E, data = self.calculate_xs(library, types, temperature) + if divisor_types: + cv.check_length('divisor types', divisor_types, len(types), + len(types)) + Ediv, data_div = self.calculate_xs(library, divisor_types, + temperature) + + # Create a new union grid, interpolate data and data_div on to that + # grid, and then do the actual division + Enum = E[:] + E = np.union1d(Enum, Ediv) + data_new = np.zeros((len(types), len(E))) + # import pdb; pdb.set_trace() + for l in range(len(types)): + data_new[l, :] = \ + np.divide(np.interp(E, Enum, data[l, :]), + np.interp(E, Ediv, data_div[l, :])) + if divisor_types[l] != 'unity': + types[l] = types[l] + ' / ' + divisor_types[l] + data = data_new + # Generate the plot fig = plt.figure() ax = fig.add_subplot(111) @@ -785,10 +811,8 @@ class Material(object): ---------- library : openmc.data.DataLibrary Library of data to use for plotting. - types : Iterable of {'total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption'} - The type of cross sections to include in the plot. In addition to - the above, a custom string can be used which includes MT numbers - and operations to perform such as '2 + 3' + types : Iterable of values of _PLOT_TYPES + The type of cross sections to include in the plot. temperature : float, optional Temperature in Kelvin to plot. If not specified, a default temperature of 294K will be plotted. Note that the nearest @@ -966,6 +990,8 @@ class Material(object): funcs.append(nuc[mt].xs[nucT]) else: funcs.append(nuc[mt].xs[nucT]) + elif mt == 0: + funcs.append(lambda x: 1.) else: funcs.append(lambda x: 0.) xs[-1].append(openmc.data.Combination(funcs, op)) @@ -981,8 +1007,11 @@ class Material(object): # Now we can combine all the nuclidic data data = np.zeros((len(mts), len(unionE))) for l in range(len(mts)): - for n in range(len(nuclides)): - data[l, :] += nuc_densities[n] * xs[n][l](unionE) + if types[l] == 'unity': + data[l, :] = 1. + else: + for n in range(len(nuclides)): + data[l, :] += nuc_densities[n] * xs[n][l](unionE) return unionE, data From 0f9c4455a5bf5a8af1037abcf4cae52ad47c1726 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 7 Nov 2016 18:58:26 -0500 Subject: [PATCH 10/60] Cleanup of function --- openmc/data/function.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/openmc/data/function.py b/openmc/data/function.py index 489910c15..e87f0a9c4 100644 --- a/openmc/data/function.py +++ b/openmc/data/function.py @@ -401,7 +401,8 @@ class Combination(EqualityMixin): """Combination of multiple functions with a user-defined operator This class allows you to create a callable object which represents the - combination of other callable objects by way of a user-defined operator. + combination of other callable objects by way of a series of user-defined + operators connecting each of the callable objects. Parameters ---------- @@ -409,7 +410,7 @@ class Combination(EqualityMixin): Functions which are to be added together operations : Iterable of numpy.ufunc Operations to perform between functions; note that the standard order - of operations (i.e., PEMDAS) will not be followed + of operations (i.e., PEMDAS) will not be followed. Attributes @@ -491,7 +492,7 @@ class Piecewise(EqualityMixin): """Piecewise composition of multiple functions. This class allows you to create a callable object which is composed - of other callable objects each over a set domain. + of multiple other callable objects, each applying to a specific interval Parameters ---------- @@ -500,7 +501,7 @@ class Piecewise(EqualityMixin): breakpoints : Iterable of float The breakpoints between each function. The functions in the functions attribute must be provided in order of - increasing domains. + increasing intervals. Attributes ---------- From 131fdce5b34836412f7570cf5ee3ec3fac903048 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 7 Nov 2016 19:47:29 -0500 Subject: [PATCH 11/60] fixing failing tests --- openmc/material.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/openmc/material.py b/openmc/material.py index 1e0ff5661..a1281fef1 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -6,8 +6,6 @@ from xml.etree import ElementTree as ET from six import string_types import numpy as np -import scipy.constants as sc -from matplotlib import pyplot as plt import openmc import openmc.data @@ -732,7 +730,8 @@ class Material(object): def plot_xs(self, library, types, divisor_types=None, temperature=294., Erange=(1.E-5, 20.E6)): - """Creates a figure of macroscopic cross sections for this material + """Creates a figure of continuous-energy macroscopic cross sections + for this material Parameters ---------- @@ -759,6 +758,8 @@ class Material(object): """ + from matplotlib import pyplot as plt + E, data = self.calculate_xs(library, types, temperature) if divisor_types: @@ -805,7 +806,8 @@ class Material(object): return fig def calculate_xs(self, library, types, temperature=294.): - """Calculates macroscopic cross sections of a requested type + """Calculates continuous-energy macroscopic cross sections of a + requested type Parameters ---------- @@ -829,6 +831,8 @@ class Material(object): """ + import scipy.constants as sc + # Check types cv.check_type('library', library, openmc.data.DataLibrary) cv.check_iterable_type('types', types, str) From 8de82dcbd32f26ae198f635247c5012623e161dc Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 8 Nov 2016 20:29:33 -0500 Subject: [PATCH 12/60] Modifications to support new function routine --- openmc/material.py | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/openmc/material.py b/openmc/material.py index a1281fef1..37dbe0d2d 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -46,11 +46,10 @@ _PLOT_TYPES_MT = {'total': (1,), 'scatter': (1, 27), 'elastic': (2,), 'unity': (0,)} # Operations to use when combining MTs the first np.add is used in reference # to zero -_PLOT_TYPES_OP = {'total': (np.add,), 'scatter': (np.add, np.subtract), - 'elastic': (np.add,), - 'inelastic': (np.add, np.subtract, np.subtract), - 'fission': (np.add,), 'absorption': (np.add,), - 'capture': (np.add,), 'nu-fission': (np.add,), +_PLOT_TYPES_OP = {'total': (), 'scatter': (np.subtract,), 'elastic': (), + 'inelastic': (np.subtract, np.subtract), + 'fission': (), 'absorption': (), + 'capture': (), 'nu-fission': (), 'nu-scatter': (np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, @@ -62,9 +61,8 @@ _PLOT_TYPES_OP = {'total': (np.add,), 'scatter': (np.add, np.subtract), np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add), - 'unity': (np.add,)} + np.add, np.add, np.add, np.add, np.add), + 'unity': ()} # Whether or not to multiply the reaction by the yield as well _PLOT_TYPES_YIELD = {'total': (False,), 'scatter': (False, False), 'elastic': (False,), 'inelastic': (False, False, False), @@ -656,6 +654,8 @@ class Material(object): """ + import scipy.constants as sc + cv.check_type('library', library, openmc.data.DataLibrary) # Expand elements in to nuclides @@ -698,7 +698,7 @@ class Material(object): n = -1 for nuclide in nuclides.items(): n += 1 - lib = library[nuclide[0]] + lib = library.get_by_materials(nuclide[0]) if lib is not None: nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) awrs.append(nuc.atomic_weight_ratio) @@ -878,9 +878,9 @@ class Material(object): for sab_name in self._sab: sab = openmc.data.ThermalScattering.from_hdf5( - library[sab_name]['path']) + library.get_by_materials(sab_name)['path']) for nuc in sab.nuclides: - sabs[nuc] = library[sab_name]['path'] + sabs[nuc] = library.get_by_materials(sab_name)['path'] # Now we can create the data sets to be plotted xs = [] @@ -888,7 +888,7 @@ class Material(object): n = -1 for nuclide in nuclides.items(): n += 1 - lib = library[nuclide[0]] + lib = library.get_by_materials(nuclide[0]) if lib is not None: nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) # Obtain the nearest temperature @@ -974,7 +974,7 @@ class Material(object): prod.emission_mode == 'total': func = openmc.data.Combination( [nuc[mt].xs[nucT], prod.yield_], - [np.add, np.multiply]) + [np.multiply]) funcs.append(func) found_it = True break @@ -984,8 +984,7 @@ class Material(object): prod.emission_mode == 'prompt': func = openmc.data.Combination( [nuc[mt].xs[nucT], - prod.yield_], - [np.add, np.multiply]) + prod.yield_], [np.multiply]) funcs.append(func) found_it = True break From 76991a223f62c666b3f7fefcf1e9a94f61d74af3 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 9 Nov 2016 18:10:41 -0500 Subject: [PATCH 13/60] Extended plots to elements and nuclides --- openmc/__init__.py | 1 + openmc/element.py | 209 +++++++++++++++++++++++++++++++++- openmc/material.py | 267 +++++++++++-------------------------------- openmc/nuclide.py | 272 +++++++++++++++++++++++++++++++++++++++++++- openmc/plot_data.py | 57 ++++++++++ 5 files changed, 597 insertions(+), 209 deletions(-) create mode 100644 openmc/plot_data.py diff --git a/openmc/__init__.py b/openmc/__init__.py index 48f43be91..98de9b70d 100644 --- a/openmc/__init__.py +++ b/openmc/__init__.py @@ -24,6 +24,7 @@ from openmc.statepoint import * from openmc.summary import * from openmc.particle_restart import * from openmc.mixin import * +from openmc.plot_data import * try: from openmc.opencg_compatible import * diff --git a/openmc/element.py b/openmc/element.py index d56c3b350..90bde474d 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -5,10 +5,12 @@ import os from six import string_types from xml.etree import ElementTree as ET +import numpy as np import openmc -from openmc.checkvalue import check_type, check_length +import openmc.checkvalue as cv from openmc.data import NATURAL_ABUNDANCE, atomic_mass +from openmc.plot_data import * class Element(object): @@ -80,8 +82,8 @@ class Element(object): @name.setter def name(self, name): - check_type('element name', name, string_types) - check_length('element name', name, 1, 2) + cv.check_type('element name', name, string_types) + cv.check_length('element name', name, 1, 2) self._name = name @scattering.setter @@ -212,7 +214,7 @@ class Element(object): # its natural nuclides else: for nuclide in natural_nuclides: - abundances[nuclide] = NATURAL_ABUNDNACE[nuclide] + abundances[nuclide] = NATURAL_ABUNDANCE[nuclide] # Modify mole fractions if enrichment provided if enrichment is not None: @@ -257,3 +259,202 @@ class Element(object): isotopes.append((nuc, percent*abundance, percent_type)) return isotopes + + def plot_xs(self, types, divisor_types=None, temperature=294., + Erange=(1.E-5, 20.E6), enrichment=None, cross_sections=None): + """Creates a figure of continuous-energy microscopic cross sections + for this element + + Parameters + ---------- + types : Iterable of values of PLOT_TYPES + The type of cross sections to include in the plot. + divisor_types : Iterable of values of PLOT_TYPES, optional + Cross section types which will divide those produced by types + before plotting. A type of 'unity' can be used to effectively not + divide some types. + temperature : float, optional + Temperature in Kelvin to plot. If not specified, a default + temperature of 294K will be plotted. Note that the nearest + temperature in the library for each nuclide will be used as opposed + to using any interpolation. + Erange : tuple of floats + Energy range (in eV) to plot the cross section within + enrichment : float, optional + Enrichment for U235 in weight percent. For example, input 4.95 for + 4.95 weight percent enriched U. Default is None + (natural composition). + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. + + Returns + ------- + fig : matplotlib.figure.Figure + Matplotlib Figure of the generated macroscopic cross section + + """ + + from matplotlib import pyplot as plt + + E, data = self.calculate_xs(types, temperature, cross_sections) + + if divisor_types: + cv.check_length('divisor types', divisor_types, len(types), + len(types)) + Ediv, data_div = self.calculate_xs(divisor_types, temperature, + cross_sections) + + # Create a new union grid, interpolate data and data_div on to that + # grid, and then do the actual division + Enum = E[:] + E = np.union1d(Enum, Ediv) + data_new = np.zeros((len(types), len(E))) + + for l in range(len(types)): + data_new[l, :] = \ + np.divide(np.interp(E, Enum, data[l, :]), + np.interp(E, Ediv, data_div[l, :])) + if divisor_types[l] != 'unity': + types[l] = types[l] + ' / ' + divisor_types[l] + data = data_new + + # Generate the plot + fig = plt.figure() + ax = fig.add_subplot(111) + iE_max = np.searchsorted(E, Erange[1]) + min_data = np.finfo(np.float64).max + max_data = np.finfo(np.float64).min + for i in range(len(data)): + if np.sum(data[i, :]) > 0.: + ax.loglog(E, data[i, :], label=types[i]) + min_data = min(min_data, np.min(data[i, :iE_max])) + max_data = max(max_data, np.max(data[i, :iE_max])) + + ax.set_xlabel('Energy [eV]') + ax.set_ylabel('Elemental Cross Section [1/cm]') + ax.legend(loc='best') + ax.set_xlim(Erange) + ax.set_ylim(min_data, max_data) + if self.name is not None: + title = 'Cross Section for ' + self.name + ax.set_title(title) + + return fig + + def calculate_xs(self, types, temperature=294., enrichment=None, + cross_sections=None): + """Calculates continuous-energy macroscopic cross sections of a + requested type + + Parameters + ---------- + types : Iterable of values of PLOT_TYPES + The type of cross sections to calculate + temperature : float, optional + Temperature in Kelvin to plot. If not specified, a default + temperature of 294K will be plotted. Note that the nearest + temperature in the library for each nuclide will be used as opposed + to using any interpolation. + enrichment : float, optional + Enrichment for U235 in weight percent. For example, input 4.95 for + 4.95 weight percent enriched U. Default is None + (natural composition). + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. + + Returns + ------- + unionE : numpy.array + Energies at which cross sections are calculated, in units of eV + data : numpy.ndarray + Macroscopic cross sections calculated at the energy grid described + by unionE + + """ + + # Check types + if cross_sections is not None: + cv.check_type('cross_sections', cross_sections, str) + cv.check_iterable_type('types', types, str) + + # Parse the types + mts = [] + ops = [] + yields = [] + for line in types: + if line in PLOT_TYPES: + mts.append(PLOT_TYPES_MT[line]) + yields.append(PLOT_TYPES_YIELD[line]) + ops.append(PLOT_TYPES_OP[line]) + else: + # Not a built-in type, we have to parse it ourselves + raise NotImplementedError() + + cv.check_type('temperature', temperature, Real) + + # Expand elements in to nuclides with atomic densities + nuclides = self.expand(100., 'ao', enrichment=enrichment, + cross_sections=cross_sections) + + # If cross_sections is None, get the cross sections from the + # OPENMC_CROSS_SECTIONS environment variable + if cross_sections is None: + cross_sections = os.environ.get('OPENMC_CROSS_SECTIONS') + + # If a cross_sections library is present, check natural nuclides + # against the nuclides in the library + if cross_sections is not None: + library = openmc.data.DataLibrary.from_xml(cross_sections) + else: + raise ValueError("cross_sections or OPENMC_CROSS_SECTIONS " + "environmental variable must be set") + + # For ease of processing split out nuc and nuc_density + nucs = [] + nuc_fractions = [] + for nuclide in nuclides.items(): + nuc_name, nuc_data = nuclide + nuc, nuc_fraction, nuc_fraction_type = nuc_data + nucs.append(nuc) + nuc_fractions.append(nuc_fraction) + + # Identify the nuclides which need S(a,b) data + sabs = {} + for nuc in nucs: + sabs[nuc.name] = None + + if sab_name: + sab = openmc.data.ThermalScattering.from_hdf5(sab_name) + for nuc in sab.nuclides: + sabs[nuc] = library.get_by_materials(sab_name)['path'] + + # Now we can create the data sets to be plotted + xs = [] + E = [] + n = -1 + for nuclide in nuclides.items(): + n += 1 + # import pdb; pdb.set_trace() + nuc_obj = openmc.Nuclide(nuclide[0].name) + sab_tab = sabs[nucs[n].name] + temp_E, temp_xs = nuc_obj.calculate_xs(types, temperature, sab_tab, + cross_sections) + E.append(temp_E) + xs.append(temp_xs) + + # Condense the data for every nuclide + # First create a union energy grid + unionE = E[0] + for n in range(1, len(E)): + unionE = np.union1d(unionE, E[n]) + + # Now we can combine all the nuclidic data + data = np.zeros((len(mts), len(unionE))) + for l in range(len(mts)): + if types[l] == 'unity': + data[l, :] = 1. + else: + for n in range(len(nuclides)): + data[l, :] += nuc_fractions[n] * xs[n][l](unionE) + + return unionE, data diff --git a/openmc/material.py b/openmc/material.py index 37dbe0d2d..c357da721 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -3,6 +3,7 @@ from copy import deepcopy from numbers import Real, Integral import warnings from xml.etree import ElementTree as ET +import os from six import string_types import numpy as np @@ -11,6 +12,7 @@ import openmc import openmc.data import openmc.checkvalue as cv from openmc.clean_xml import sort_xml_elements, clean_xml_indentation +from openmc.plot_data import * # A static variable for auto-generated Material IDs @@ -27,62 +29,6 @@ def reset_auto_material_id(): DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/cm3', 'atom/b-cm', 'atom/cm3', 'sum', 'macro'] -# Supported keywords for material xs plotting -_PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', - 'absorption', 'capture', 'nu-fission', 'nu-scatter', 'unity'] - -# MTs to combine to generate associated plot_types -_PLOT_TYPES_MT = {'total': (1,), 'scatter': (1, 27), 'elastic': (2,), - 'inelastic': (1, 27, 2), 'fission': (18,), - 'absorption': (27,), 'capture': (101,), - 'nu-fission': (18,), - 'nu-scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, - 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, - 153, 154, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 183, 184, 190, 194, 196, 198, 199, 200, - 875, 891), - 'unity': (0,)} -# Operations to use when combining MTs the first np.add is used in reference -# to zero -_PLOT_TYPES_OP = {'total': (), 'scatter': (np.subtract,), 'elastic': (), - 'inelastic': (np.subtract, np.subtract), - 'fission': (), 'absorption': (), - 'capture': (), 'nu-fission': (), - 'nu-scatter': (np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add), - 'unity': ()} -# Whether or not to multiply the reaction by the yield as well -_PLOT_TYPES_YIELD = {'total': (False,), 'scatter': (False, False), - 'elastic': (False,), 'inelastic': (False, False, False), - 'fission': (False,), 'absorption': (False,), - 'capture': (False,), 'nu-fission': (True,), - 'nu-scatter': (True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True), - 'unity': (False,)} - class Material(object): """A material composed of a collection of nuclides/elements that can be @@ -637,14 +583,14 @@ class Material(object): return nuclides - def get_nuclide_atom_densities(self, library): + def get_nuclide_atom_densities(self, cross_sections=None): """Returns all nuclides in the material and their atomic densities in units of atom/b-cm Parameters ---------- - library : openmc.data.DataLibrary - Library of data to use for plotting. + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. Returns ------- @@ -656,7 +602,20 @@ class Material(object): import scipy.constants as sc - cv.check_type('library', library, openmc.data.DataLibrary) + cv.check_type('cross_sections', cross_sections, str) + + # If cross_sections is None, get the cross sections from the + # OPENMC_CROSS_SECTIONS environment variable + if cross_sections is None: + cross_sections = os.environ.get('OPENMC_CROSS_SECTIONS') + + # If a cross_sections library is present, check natural nuclides + # against the nuclides in the library + if cross_sections is not None: + library = openmc.data.DataLibrary.from_xml(cross_sections) + else: + raise ValueError("cross_sections or OPENMC_CROSS_SECTIONS " + "environmental variable must be set") # Expand elements in to nuclides nuclides = self.get_nuclide_densities() @@ -728,28 +687,28 @@ class Material(object): return nuclides - def plot_xs(self, library, types, divisor_types=None, temperature=294., - Erange=(1.E-5, 20.E6)): + def plot_xs(self, types, divisor_types=None, temperature=294., + Erange=(1.E-5, 20.E6), cross_sections=None): """Creates a figure of continuous-energy macroscopic cross sections for this material Parameters ---------- - library : openmc.data.DataLibrary - Library of data to use for plotting. - types : Iterable of values of _PLOT_TYPES + types : Iterable of values of PLOT_TYPES The type of cross sections to include in the plot. - divisor_types : Iterable of values of _PLOT_TYPES, optional - Cross section types which will divide those produced by types before - plotting. A type of 'unity' can be used to effectively not divide - some types. + divisor_types : Iterable of values of PLOT_TYPES, optional + Cross section types which will divide those produced by types + before plotting. A type of 'unity' can be used to effectively not + divide some types. temperature : float, optional Temperature in Kelvin to plot. If not specified, a default temperature of 294K will be plotted. Note that the nearest temperature in the library for each nuclide will be used as opposed to using any interpolation. - Erange : tuple of floats + Erange : tuple of floats, optional Energy range (in eV) to plot the cross section within + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. Returns ------- @@ -760,20 +719,20 @@ class Material(object): from matplotlib import pyplot as plt - E, data = self.calculate_xs(library, types, temperature) + E, data = self.calculate_xs(types, temperature, cross_sections) if divisor_types: cv.check_length('divisor types', divisor_types, len(types), len(types)) - Ediv, data_div = self.calculate_xs(library, divisor_types, - temperature) + Ediv, data_div = self.calculate_xs(divisor_types, temperature, + cross_sections) # Create a new union grid, interpolate data and data_div on to that # grid, and then do the actual division Enum = E[:] E = np.union1d(Enum, Ediv) data_new = np.zeros((len(types), len(E))) - # import pdb; pdb.set_trace() + for l in range(len(types)): data_new[l, :] = \ np.divide(np.interp(E, Enum, data[l, :]), @@ -805,21 +764,21 @@ class Material(object): return fig - def calculate_xs(self, library, types, temperature=294.): + def calculate_xs(self, types, temperature=294., cross_sections=None): """Calculates continuous-energy macroscopic cross sections of a requested type Parameters ---------- - library : openmc.data.DataLibrary - Library of data to use for plotting. - types : Iterable of values of _PLOT_TYPES - The type of cross sections to include in the plot. + types : Iterable of values of PLOT_TYPES + The type of cross sections to calculate temperature : float, optional Temperature in Kelvin to plot. If not specified, a default temperature of 294K will be plotted. Note that the nearest temperature in the library for each nuclide will be used as opposed to using any interpolation. + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. Returns ------- @@ -831,10 +790,9 @@ class Material(object): """ - import scipy.constants as sc - # Check types - cv.check_type('library', library, openmc.data.DataLibrary) + if cross_sections is not None: + cv.check_type('cross_sections', cross_sections, str) cv.check_iterable_type('types', types, str) # Parse the types @@ -842,25 +800,35 @@ class Material(object): ops = [] yields = [] for line in types: - if line in _PLOT_TYPES: - mts.append(_PLOT_TYPES_MT[line]) - yields.append(_PLOT_TYPES_YIELD[line]) - ops.append(_PLOT_TYPES_OP[line]) + if line in PLOT_TYPES: + mts.append(PLOT_TYPES_MT[line]) + yields.append(PLOT_TYPES_YIELD[line]) + ops.append(PLOT_TYPES_OP[line]) else: # Not a built-in type, we have to parse it ourselves raise NotImplementedError() - # Convert temperature to format needed for access in the library if self.temperature is not None: - strT = "{}K".format(int(round(self.temperature))) T = self.temperature else: cv.check_type('temperature', temperature, Real) - strT = "{}K".format(int(round(temperature))) T = temperature + # If cross_sections is None, get the cross sections from the + # OPENMC_CROSS_SECTIONS environment variable + if cross_sections is None: + cross_sections = os.environ.get('OPENMC_CROSS_SECTIONS') + + # If a cross_sections library is present, check natural nuclides + # against the nuclides in the library + if cross_sections is not None: + library = openmc.data.DataLibrary.from_xml(cross_sections) + else: + raise ValueError("cross_sections or OPENMC_CROSS_SECTIONS " + "environmental variable must be set") + # Expand elements in to nuclides with atomic densities - nuclides = self.get_nuclide_atom_densities(library) + nuclides = self.get_nuclide_atom_densities(cross_sections) # For ease of processing split out nuc and nuc_density nucs = [] @@ -888,118 +856,13 @@ class Material(object): n = -1 for nuclide in nuclides.items(): n += 1 - lib = library.get_by_materials(nuclide[0]) - if lib is not None: - nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) - # Obtain the nearest temperature - if strT in nuc.temperatures: - nucT = strT - else: - data_Ts = nuc.temperatures - for t in range(len(data_Ts)): - # Take off the "K" and convert to a float - data_Ts[t] = float(data_Ts[t][:-1]) - min_delta = np.finfo(np.float64).max - closest_t = -1 - for t in data_Ts: - if abs(data_Ts[t] - T) < min_delta: - closest_t = t - nucT = "{}K".format(int(round(data_Ts[closest_t]))) - - # Create an energy grid composed of either the S(a,b) and - # nuclide's grid, or just the nuclide's grid, depending on if - # the S(a,b) data is available for this nuclide - sab_tab = sabs[nucs[n].name] - if sab_tab: - sab = openmc.data.ThermalScattering.from_hdf5(sab_tab) - # Obtain the nearest temperature - if strT in sab.temperatures: - sabT = strT - else: - data_Ts = sab.temperatures - for t in range(len(data_Ts)): - # Take off the "K" and convert to a float - data_Ts[t] = float(data_Ts[t][:-1]) - min_delta = np.finfo(np.float64).max - closest_t = -1 - for t in data_Ts: - if abs(data_Ts[t] - T) < min_delta: - closest_t = t - sabT = "{}K".format(int(round(data_Ts[closest_t]))) - grid = nuc.energy[nucT] - sab_Emax = 0. - sab_funcs = [] - if sab.elastic_xs: - elastic = sab.elastic_xs[sabT] - if isinstance(elastic, openmc.data.CoherentElastic): - grid = np.union1d(grid, elastic.bragg_edges) - if elastic.bragg_edges[-1] > sab_Emax: - sab_Emax = elastic.bragg_edges[-1] - elif isinstance(elastic, openmc.data.Tabulated1D): - grid = np.union1d(grid, elastic.x) - if elastic.x[-1] > sab_Emax: - sab_Emax = elastic.x[-1] - sab_funcs.append(elastic) - if sab.inelastic_xs: - inelastic = sab.inelastic_xs[sabT] - grid = np.union1d(grid, inelastic.x) - if inelastic.x[-1] > sab_Emax: - sab_Emax = inelastic.x[-1] - sab_funcs.append(inelastic) - E.append(grid) - else: - E.append(nuc.energy[nucT]) - xs.append([]) - for i, mt_set in enumerate(mts): - # Get the reaction xs data from the nuclide - funcs = [] - op = ops[i] - for mt, yield_check in zip(mt_set, yields[i]): - if mt == 2: - if sab_tab: - # Then we need to do a piece-wise function of - # The S(a,b) and non-thermal data - sab_sum = openmc.data.Sum(sab_funcs) - pw_funcs = openmc.data.Piecewise( - [sab_sum, nuc[mt].xs[nucT]], - [sab_Emax]) - funcs.append(pw_funcs) - else: - funcs.append(nuc[mt].xs[nucT]) - elif mt in nuc: - if yield_check: - found_it = False - for prod in nuc[mt].products: - if prod.particle == 'neutron' and \ - prod.emission_mode == 'total': - func = openmc.data.Combination( - [nuc[mt].xs[nucT], prod.yield_], - [np.multiply]) - funcs.append(func) - found_it = True - break - if not found_it: - for prod in nuc[mt].products: - if prod.particle == 'neutron' and \ - prod.emission_mode == 'prompt': - func = openmc.data.Combination( - [nuc[mt].xs[nucT], - prod.yield_], [np.multiply]) - funcs.append(func) - found_it = True - break - if not found_it: - # Assume the yield is 1 - funcs.append(nuc[mt].xs[nucT]) - else: - funcs.append(nuc[mt].xs[nucT]) - elif mt == 0: - funcs.append(lambda x: 1.) - else: - funcs.append(lambda x: 0.) - xs[-1].append(openmc.data.Combination(funcs, op)) - else: - raise ValueError(nuclide[0] + " not in library") + # import pdb; pdb.set_trace() + nuc_obj = openmc.Nuclide(nuclide[0].name) + sab_tab = sabs[nucs[n].name] + temp_E, temp_xs = nuc_obj.calculate_xs(types, T, sab_tab, + cross_sections) + E.append(temp_E) + xs.append(temp_xs) # Condense the data for every nuclide # First create a union energy grid diff --git a/openmc/nuclide.py b/openmc/nuclide.py index 55afd4e9c..31b658a1c 100644 --- a/openmc/nuclide.py +++ b/openmc/nuclide.py @@ -1,10 +1,13 @@ -from numbers import Integral +from numbers import Integral, Real import sys import warnings +import os from six import string_types -from openmc.checkvalue import check_type +import openmc.checkvalue as cv +from openmc.plot_data import * +import openmc.data class Nuclide(object): @@ -72,7 +75,7 @@ class Nuclide(object): @name.setter def name(self, name): - check_type('name', name, string_types) + cv.check_type('name', name, string_types) self._name = name if '-' in name: @@ -93,3 +96,266 @@ class Nuclide(object): raise ValueError(msg) self._scattering = scattering + + def plot_xs(self, types, divisor_types=None, temperature=294., + Erange=(1.E-5, 20.E6), sab_name=None, cross_sections=None): + """Creates a figure of continuous-energy cross sections for this + nuclide + + Parameters + ---------- + types : Iterable of values of PLOT_TYPES + The type of cross sections to include in the plot + divisor_types : Iterable of values of PLOT_TYPES, optional + Cross section types which will divide those produced by types + before plotting. A type of 'unity' can be used to effectively not + divide some types. + temperature : float, optional + Temperature in Kelvin to plot. If not specified, a default + temperature of 294K will be plotted. Note that the nearest + temperature in the library for each nuclide will be used as opposed + to using any interpolation. + Erange : tuple of floats + Energy range (in eV) to plot the cross section within + sab_name : str, optional + Name of S(a,b) library to apply to MT=2 data when applicable. + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. + + Returns + ------- + fig : matplotlib.figure.Figure + Matplotlib Figure of the generated macroscopic cross section + + """ + + from matplotlib import pyplot as plt + + E, data = self.calculate_xs(types, temperature, sab_name, + cross_sections) + + if divisor_types: + cv.check_length('divisor types', divisor_types, len(types), + len(types)) + Ediv, data_div = self.calculate_xs(divisor_types, temperature, + sab_name, cross_sections) + + # Create a new union grid, interpolate data and data_div on to that + # grid, and then do the actual division + Enum = E[:] + E = np.union1d(Enum, Ediv) + data_new = [] + + for l in range(len(types)): + data_new.append(openmc.data.Combination([data[l], data_div[l]], + [np.divide])) + if divisor_types[l] != 'unity': + types[l] = types[l] + ' / ' + divisor_types[l] + data = data_new + + # Generate the plot + fig = plt.figure() + ax = fig.add_subplot(111) + iE_max = np.searchsorted(E, Erange[1]) + min_data = np.finfo(np.float64).max + max_data = np.finfo(np.float64).min + for i in range(len(data)): + to_plot = data[i](E) + if np.sum(to_plot) > 0.: + ax.loglog(E, to_plot, label=types[i]) + min_data = min(min_data, np.min(to_plot[:iE_max])) + max_data = max(max_data, np.max(to_plot[:iE_max])) + + ax.set_xlabel('Energy [eV]') + ax.set_ylabel('Microscopic Cross Section [b]') + ax.legend(loc='best') + ax.set_xlim(Erange) + ax.set_ylim(min_data, max_data) + if self.name is not None: + title = 'Microscopic Cross Section for ' + self.name + ax.set_title(title) + + return fig + + def calculate_xs(self, types, temperature=294., sab_name=None, + cross_sections=None): + """Calculates continuous-energy cross sections of a requested type + + Parameters + ---------- + types : Iterable of values of PLOT_TYPES + The type of cross sections to calculate + temperature : float, optional + Temperature in Kelvin to plot. If not specified, a default + temperature of 294K will be plotted. Note that the nearest + temperature in the library for each nuclide will be used as opposed + to using any interpolation. + sab_name : str, optional + Name of S(a,b) library to apply to MT=2 data when applicable. + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. + + Returns + ------- + E : numpy.array + Energies at which cross sections are calculated, in units of eV + data : numpy.ndarray + Cross sections calculated at the energy grid described by unionE + + """ + + # Check types + if cross_sections is not None: + cv.check_type('cross_sections', cross_sections, str) + cv.check_iterable_type('types', types, str) + if sab_name: + cv.check_type('sab_name', sab_name, str) + + # Parse the types + mts = [] + ops = [] + yields = [] + for line in types: + if line in openmc.plot_data.PLOT_TYPES: + mts.append(PLOT_TYPES_MT[line]) + yields.append(PLOT_TYPES_YIELD[line]) + ops.append(PLOT_TYPES_OP[line]) + else: + # Not a built-in type, we have to parse it ourselves + raise NotImplementedError() + + # If cross_sections is None, get the cross sections from the + # OPENMC_CROSS_SECTIONS environment variable + if cross_sections is None: + cross_sections = os.environ.get('OPENMC_CROSS_SECTIONS') + + # If a cross_sections library is present, check natural nuclides + # against the nuclides in the library + if cross_sections is not None: + library = openmc.data.DataLibrary.from_xml(cross_sections) + else: + raise ValueError("cross_sections or OPENMC_CROSS_SECTIONS " + "environmental variable must be set") + + # Convert temperature to format needed for access in the library + cv.check_type('temperature', temperature, Real) + strT = "{}K".format(int(round(temperature))) + T = temperature + + # Now we can create the data sets to be plotted + E = [] + xs = [] + lib = library.get_by_materials(self.name) + if lib is not None: + nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) + # Obtain the nearest temperature + if strT in nuc.temperatures: + nucT = strT + else: + data_Ts = nuc.temperatures + for t in range(len(data_Ts)): + # Take off the "K" and convert to a float + data_Ts[t] = float(data_Ts[t][:-1]) + min_delta = np.finfo(np.float64).max + closest_t = -1 + for t in data_Ts: + if abs(data_Ts[t] - T) < min_delta: + closest_t = t + nucT = "{}K".format(int(round(data_Ts[closest_t]))) + + # Prep S(a,b) data if needed + if sab_name: + sab = openmc.data.ThermalScattering.from_hdf5(sab_name) + # Obtain the nearest temperature + if strT in sab.temperatures: + sabT = strT + else: + data_Ts = sab.temperatures + for t in range(len(data_Ts)): + # Take off the "K" and convert to a float + data_Ts[t] = float(data_Ts[t][:-1]) + min_delta = np.finfo(np.float64).max + closest_t = -1 + for t in data_Ts: + if abs(data_Ts[t] - T) < min_delta: + closest_t = t + sabT = "{}K".format(int(round(data_Ts[closest_t]))) + + # Create an energy grid composed the S(a,b) and + # the nuclide's grid + grid = nuc.energy[nucT] + sab_Emax = 0. + sab_funcs = [] + if sab.elastic_xs: + elastic = sab.elastic_xs[sabT] + if isinstance(elastic, openmc.data.CoherentElastic): + grid = np.union1d(grid, elastic.bragg_edges) + if elastic.bragg_edges[-1] > sab_Emax: + sab_Emax = elastic.bragg_edges[-1] + elif isinstance(elastic, openmc.data.Tabulated1D): + grid = np.union1d(grid, elastic.x) + if elastic.x[-1] > sab_Emax: + sab_Emax = elastic.x[-1] + sab_funcs.append(elastic) + if sab.inelastic_xs: + inelastic = sab.inelastic_xs[sabT] + grid = np.union1d(grid, inelastic.x) + if inelastic.x[-1] > sab_Emax: + sab_Emax = inelastic.x[-1] + sab_funcs.append(inelastic) + E = grid + else: + E = nuc.energy[nucT] + + for i, mt_set in enumerate(mts): + # Get the reaction xs data from the nuclide + funcs = [] + op = ops[i] + for mt, yield_check in zip(mt_set, yields[i]): + if mt == 2: + if sab_name: + # Then we need to do a piece-wise function of + # The S(a,b) and non-thermal data + sab_sum = openmc.data.Sum(sab_funcs) + pw_funcs = openmc.data.Regions1D( + [sab_sum, nuc[mt].xs[nucT]], + [sab_Emax]) + funcs.append(pw_funcs) + else: + funcs.append(nuc[mt].xs[nucT]) + elif mt in nuc: + if yield_check: + found_it = False + for prod in nuc[mt].products: + if prod.particle == 'neutron' and \ + prod.emission_mode == 'total': + func = openmc.data.Combination( + [nuc[mt].xs[nucT], prod.yield_], + [np.multiply]) + funcs.append(func) + found_it = True + break + if not found_it: + for prod in nuc[mt].products: + if prod.particle == 'neutron' and \ + prod.emission_mode == 'prompt': + func = openmc.data.Combination( + [nuc[mt].xs[nucT], + prod.yield_], [np.multiply]) + funcs.append(func) + found_it = True + break + if not found_it: + # Assume the yield is 1 + funcs.append(nuc[mt].xs[nucT]) + else: + funcs.append(nuc[mt].xs[nucT]) + elif mt == 0: + funcs.append(lambda x: 1.) + else: + funcs.append(lambda x: 0.) + xs.append(openmc.data.Combination(funcs, op)) + else: + raise ValueError(nuclide[0] + " not in library") + + return E, xs diff --git a/openmc/plot_data.py b/openmc/plot_data.py new file mode 100644 index 000000000..03e929b52 --- /dev/null +++ b/openmc/plot_data.py @@ -0,0 +1,57 @@ +import numpy as np + +# Supported keywords for material xs plotting +PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', + 'absorption', 'capture', 'nu-fission', 'nu-scatter', 'unity'] + +# MTs to combine to generate associated plot_types +PLOT_TYPES_MT = {'total': (2, 3,), 'scatter': (1, 27), 'elastic': (2,), + 'inelastic': (1, 27, 2), 'fission': (18,), + 'absorption': (27,), 'capture': (101,), + 'nu-fission': (18,), + 'nu-scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, + 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, + 153, 154, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 183, 184, 190, 194, 196, 198, 199, 200, + 875, 891), + 'unity': (0,)} +# Operations to use when combining MTs the first np.add is used in reference +# to zero +PLOT_TYPES_OP = {'total': (np.add,), 'scatter': (np.subtract,), 'elastic': (), + 'inelastic': (np.subtract, np.subtract), + 'fission': (), 'absorption': (), + 'capture': (), 'nu-fission': (), + 'nu-scatter': (np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add), + 'unity': ()} +# Whether or not to multiply the reaction by the yield as well +PLOT_TYPES_YIELD = {'total': (False, False), 'scatter': (False, False), + 'elastic': (False,), 'inelastic': (False, False, False), + 'fission': (False,), 'absorption': (False,), + 'capture': (False,), 'nu-fission': (True,), + 'nu-scatter': (True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True, True, True, True, True, + True), + 'unity': (False,)} From 7524637e2351670b4d8d3ca56c291dfafd0e16fc Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 11 Nov 2016 05:20:38 -0500 Subject: [PATCH 14/60] Added kwargs to plots, switched to taking a file string for the cross_sections.xml file instead of an initialized DataLibrary, and avoided precision issues when calculating the inelastic xs --- openmc/element.py | 16 +++++++--------- openmc/material.py | 19 ++++++++----------- openmc/nuclide.py | 16 +++++++--------- openmc/plot_data.py | 36 +++++++++++++++++++++++++++++++++--- 4 files changed, 55 insertions(+), 32 deletions(-) diff --git a/openmc/element.py b/openmc/element.py index 90bde474d..80777fcfe 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -261,7 +261,8 @@ class Element(object): return isotopes def plot_xs(self, types, divisor_types=None, temperature=294., - Erange=(1.E-5, 20.E6), enrichment=None, cross_sections=None): + Erange=(1.E-5, 20.E6), enrichment=None, cross_sections=None, + **kwargs): """Creates a figure of continuous-energy microscopic cross sections for this element @@ -286,6 +287,9 @@ class Element(object): (natural composition). cross_sections : str, optional Location of cross_sections.xml file. Default is None. + **kwargs + All keyword arguments are passed to + :func:`matplotlib.pyplot.figure`. Returns ------- @@ -319,22 +323,16 @@ class Element(object): data = data_new # Generate the plot - fig = plt.figure() + fig = plt.figure(**kwargs) ax = fig.add_subplot(111) - iE_max = np.searchsorted(E, Erange[1]) - min_data = np.finfo(np.float64).max - max_data = np.finfo(np.float64).min for i in range(len(data)): if np.sum(data[i, :]) > 0.: ax.loglog(E, data[i, :], label=types[i]) - min_data = min(min_data, np.min(data[i, :iE_max])) - max_data = max(max_data, np.max(data[i, :iE_max])) ax.set_xlabel('Energy [eV]') ax.set_ylabel('Elemental Cross Section [1/cm]') ax.legend(loc='best') ax.set_xlim(Erange) - ax.set_ylim(min_data, max_data) if self.name is not None: title = 'Cross Section for ' + self.name ax.set_title(title) @@ -426,7 +424,7 @@ class Element(object): if sab_name: sab = openmc.data.ThermalScattering.from_hdf5(sab_name) for nuc in sab.nuclides: - sabs[nuc] = library.get_by_materials(sab_name)['path'] + sabs[nuc] = library.get_by_material(sab_name)['path'] # Now we can create the data sets to be plotted xs = [] diff --git a/openmc/material.py b/openmc/material.py index c357da721..36f728ad1 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -657,7 +657,7 @@ class Material(object): n = -1 for nuclide in nuclides.items(): n += 1 - lib = library.get_by_materials(nuclide[0]) + lib = library.get_by_material(nuclide[0]) if lib is not None: nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) awrs.append(nuc.atomic_weight_ratio) @@ -688,7 +688,7 @@ class Material(object): return nuclides def plot_xs(self, types, divisor_types=None, temperature=294., - Erange=(1.E-5, 20.E6), cross_sections=None): + Erange=(1.E-5, 20.E6), cross_sections=None, **kwargs): """Creates a figure of continuous-energy macroscopic cross sections for this material @@ -709,6 +709,9 @@ class Material(object): Energy range (in eV) to plot the cross section within cross_sections : str, optional Location of cross_sections.xml file. Default is None. + **kwargs + All keyword arguments are passed to + :func:`matplotlib.pyplot.figure`. Returns ------- @@ -742,22 +745,16 @@ class Material(object): data = data_new # Generate the plot - fig = plt.figure() + fig = plt.figure(**kwargs) ax = fig.add_subplot(111) - iE_max = np.searchsorted(E, Erange[1]) - min_data = np.finfo(np.float64).max - max_data = np.finfo(np.float64).min for i in range(len(data)): if np.sum(data[i, :]) > 0.: ax.loglog(E, data[i, :], label=types[i]) - min_data = min(min_data, np.min(data[i, :iE_max])) - max_data = max(max_data, np.max(data[i, :iE_max])) ax.set_xlabel('Energy [eV]') ax.set_ylabel('Macroscopic Cross Section [1/cm]') ax.legend(loc='best') ax.set_xlim(Erange) - ax.set_ylim(min_data, max_data) if self.name is not None: title = 'Macroscopic Cross Section for ' + self.name ax.set_title(title) @@ -846,9 +843,9 @@ class Material(object): for sab_name in self._sab: sab = openmc.data.ThermalScattering.from_hdf5( - library.get_by_materials(sab_name)['path']) + library.get_by_material(sab_name)['path']) for nuc in sab.nuclides: - sabs[nuc] = library.get_by_materials(sab_name)['path'] + sabs[nuc] = library.get_by_material(sab_name)['path'] # Now we can create the data sets to be plotted xs = [] diff --git a/openmc/nuclide.py b/openmc/nuclide.py index 31b658a1c..938b6a666 100644 --- a/openmc/nuclide.py +++ b/openmc/nuclide.py @@ -98,7 +98,8 @@ class Nuclide(object): self._scattering = scattering def plot_xs(self, types, divisor_types=None, temperature=294., - Erange=(1.E-5, 20.E6), sab_name=None, cross_sections=None): + Erange=(1.E-5, 20.E6), sab_name=None, cross_sections=None, + **kwargs): """Creates a figure of continuous-energy cross sections for this nuclide @@ -121,6 +122,9 @@ class Nuclide(object): Name of S(a,b) library to apply to MT=2 data when applicable. cross_sections : str, optional Location of cross_sections.xml file. Default is None. + **kwargs + All keyword arguments are passed to + :func:`matplotlib.pyplot.figure`. Returns ------- @@ -154,23 +158,17 @@ class Nuclide(object): data = data_new # Generate the plot - fig = plt.figure() + fig = plt.figure(**kwargs) ax = fig.add_subplot(111) - iE_max = np.searchsorted(E, Erange[1]) - min_data = np.finfo(np.float64).max - max_data = np.finfo(np.float64).min for i in range(len(data)): to_plot = data[i](E) if np.sum(to_plot) > 0.: ax.loglog(E, to_plot, label=types[i]) - min_data = min(min_data, np.min(to_plot[:iE_max])) - max_data = max(max_data, np.max(to_plot[:iE_max])) ax.set_xlabel('Energy [eV]') ax.set_ylabel('Microscopic Cross Section [b]') ax.legend(loc='best') ax.set_xlim(Erange) - ax.set_ylim(min_data, max_data) if self.name is not None: title = 'Microscopic Cross Section for ' + self.name ax.set_title(title) @@ -245,7 +243,7 @@ class Nuclide(object): # Now we can create the data sets to be plotted E = [] xs = [] - lib = library.get_by_materials(self.name) + lib = library.get_by_material(self.name) if lib is not None: nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) # Obtain the nearest temperature diff --git a/openmc/plot_data.py b/openmc/plot_data.py index 03e929b52..ff3d799a2 100644 --- a/openmc/plot_data.py +++ b/openmc/plot_data.py @@ -6,7 +6,14 @@ PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', # MTs to combine to generate associated plot_types PLOT_TYPES_MT = {'total': (2, 3,), 'scatter': (1, 27), 'elastic': (2,), - 'inelastic': (1, 27, 2), 'fission': (18,), + 'inelastic': (4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, + 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, + 153, 154, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 183, 184, 190, 194, 196, 198, 199, 200, + 875, 891), + 'fission': (18,), 'absorption': (27,), 'capture': (101,), 'nu-fission': (18,), 'nu-scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, @@ -20,7 +27,18 @@ PLOT_TYPES_MT = {'total': (2, 3,), 'scatter': (1, 27), 'elastic': (2,), # Operations to use when combining MTs the first np.add is used in reference # to zero PLOT_TYPES_OP = {'total': (np.add,), 'scatter': (np.subtract,), 'elastic': (), - 'inelastic': (np.subtract, np.subtract), + 'inelastic': (np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add, np.add, + np.add, np.add, np.add, np.add), 'fission': (), 'absorption': (), 'capture': (), 'nu-fission': (), 'nu-scatter': (np.add, np.add, np.add, np.add, np.add, @@ -38,7 +56,19 @@ PLOT_TYPES_OP = {'total': (np.add,), 'scatter': (np.subtract,), 'elastic': (), 'unity': ()} # Whether or not to multiply the reaction by the yield as well PLOT_TYPES_YIELD = {'total': (False, False), 'scatter': (False, False), - 'elastic': (False,), 'inelastic': (False, False, False), + 'elastic': (False,), + 'inelastic': (False, False, False, False, False, + False, False, False, False, False, + False, False, False, False, False, + False, False, False, False, False, + False, False, False, False, False, + False, False, False, False, False, + False, False, False, False, False, + False, False, False, False, False, + False, False, False, False, False, + False, False, False, False, False, + False, False, False, False, False, + False, False, False, False, False), 'fission': (False,), 'absorption': (False,), 'capture': (False,), 'nu-fission': (True,), 'nu-scatter': (True, True, True, True, True, From 4fe275b38163131947c75aab8ed4b63980a25183 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 11 Nov 2016 06:22:38 -0500 Subject: [PATCH 15/60] Code and resultant plot cleanup; also ensured every plot type explicitly included MT=2 so that S(a,b) data could properly be spliced in --- openmc/element.py | 76 ++++++++++++++++++++++++--------------------- openmc/material.py | 38 +++++++++++------------ openmc/nuclide.py | 13 ++++++-- openmc/plot_data.py | 74 +++++++++++++------------------------------ 4 files changed, 91 insertions(+), 110 deletions(-) diff --git a/openmc/element.py b/openmc/element.py index 80777fcfe..b1cd19e9b 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -1,4 +1,5 @@ from collections import OrderedDict +from numbers import Real import re import sys import os @@ -256,13 +257,13 @@ class Element(object): for nuclide, abundance in abundances.items(): nuc = openmc.Nuclide(nuclide) nuc.scattering = self.scattering - isotopes.append((nuc, percent*abundance, percent_type)) + isotopes.append((nuc, percent * abundance, percent_type)) return isotopes def plot_xs(self, types, divisor_types=None, temperature=294., - Erange=(1.E-5, 20.E6), enrichment=None, cross_sections=None, - **kwargs): + Erange=(1.E-5, 20.E6), sab_name=None, cross_sections=None, + enrichment=None, **kwargs): """Creates a figure of continuous-energy microscopic cross sections for this element @@ -281,12 +282,14 @@ class Element(object): to using any interpolation. Erange : tuple of floats Energy range (in eV) to plot the cross section within + sab_name : str, optional + Name of S(a,b) library to apply to MT=2 data when applicable. + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. enrichment : float, optional Enrichment for U235 in weight percent. For example, input 4.95 for 4.95 weight percent enriched U. Default is None (natural composition). - cross_sections : str, optional - Location of cross_sections.xml file. Default is None. **kwargs All keyword arguments are passed to :func:`matplotlib.pyplot.figure`. @@ -300,13 +303,14 @@ class Element(object): from matplotlib import pyplot as plt - E, data = self.calculate_xs(types, temperature, cross_sections) + E, data = self.calculate_xs(types, temperature, sab_name, + cross_sections) if divisor_types: cv.check_length('divisor types', divisor_types, len(types), len(types)) Ediv, data_div = self.calculate_xs(divisor_types, temperature, - cross_sections) + sab_name, cross_sections) # Create a new union grid, interpolate data and data_div on to that # grid, and then do the actual division @@ -326,11 +330,20 @@ class Element(object): fig = plt.figure(**kwargs) ax = fig.add_subplot(111) for i in range(len(data)): + # Set to loglog or semilogx depending on if we are plotting a data + # type which we expect to vary linearly + if types[i] in PLOT_TYPES_LINEAR: + plot_func = ax.semilogx + else: + plot_func = ax.loglog if np.sum(data[i, :]) > 0.: - ax.loglog(E, data[i, :], label=types[i]) + plot_func(E, data[i, :], label=types[i]) ax.set_xlabel('Energy [eV]') - ax.set_ylabel('Elemental Cross Section [1/cm]') + if divisor_types: + ax.set_ylabel('Elemental Cross Section') + else: + ax.set_ylabel('Elemental Cross Section [b]') ax.legend(loc='best') ax.set_xlim(Erange) if self.name is not None: @@ -339,8 +352,8 @@ class Element(object): return fig - def calculate_xs(self, types, temperature=294., enrichment=None, - cross_sections=None): + def calculate_xs(self, types, temperature=294., sab_name=None, + cross_sections=None, enrichment=None): """Calculates continuous-energy macroscopic cross sections of a requested type @@ -353,12 +366,14 @@ class Element(object): temperature of 294K will be plotted. Note that the nearest temperature in the library for each nuclide will be used as opposed to using any interpolation. + sab_name : str, optional + Name of S(a,b) library to apply to MT=2 data when applicable. + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. enrichment : float, optional Enrichment for U235 in weight percent. For example, input 4.95 for 4.95 weight percent enriched U. Default is None (natural composition). - cross_sections : str, optional - Location of cross_sections.xml file. Default is None. Returns ------- @@ -390,10 +405,6 @@ class Element(object): cv.check_type('temperature', temperature, Real) - # Expand elements in to nuclides with atomic densities - nuclides = self.expand(100., 'ao', enrichment=enrichment, - cross_sections=cross_sections) - # If cross_sections is None, get the cross sections from the # OPENMC_CROSS_SECTIONS environment variable if cross_sections is None: @@ -407,20 +418,17 @@ class Element(object): raise ValueError("cross_sections or OPENMC_CROSS_SECTIONS " "environmental variable must be set") + # Expand elements in to nuclides with atomic densities + nuclides = self.expand(100., 'ao', enrichment=enrichment, + cross_sections=cross_sections) + # For ease of processing split out nuc and nuc_density - nucs = [] - nuc_fractions = [] - for nuclide in nuclides.items(): - nuc_name, nuc_data = nuclide - nuc, nuc_fraction, nuc_fraction_type = nuc_data - nucs.append(nuc) - nuc_fractions.append(nuc_fraction) + nuc_fractions = [nuclide[1] for nuclide in nuclides] - # Identify the nuclides which need S(a,b) data + # Identify the nuclides which have S(a,b) data sabs = {} - for nuc in nucs: - sabs[nuc.name] = None - + for nuclide in nuclides: + sabs[nuclide[0].name] = None if sab_name: sab = openmc.data.ThermalScattering.from_hdf5(sab_name) for nuc in sab.nuclides: @@ -429,14 +437,10 @@ class Element(object): # Now we can create the data sets to be plotted xs = [] E = [] - n = -1 - for nuclide in nuclides.items(): - n += 1 - # import pdb; pdb.set_trace() - nuc_obj = openmc.Nuclide(nuclide[0].name) - sab_tab = sabs[nucs[n].name] - temp_E, temp_xs = nuc_obj.calculate_xs(types, temperature, sab_tab, - cross_sections) + for nuclide in nuclides: + sab_tab = sabs[nuclide[0].name] + temp_E, temp_xs = nuclide[0].calculate_xs(types, temperature, + sab_tab, cross_sections) E.append(temp_E) xs.append(temp_xs) diff --git a/openmc/material.py b/openmc/material.py index 3b6c784b3..ec68913ca 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -773,11 +773,20 @@ class Material(object): fig = plt.figure(**kwargs) ax = fig.add_subplot(111) for i in range(len(data)): + # Set to loglog or semilogx depending on if we are plotting a data + # type which we expect to vary linearly + if types[i] in PLOT_TYPES_LINEAR: + plot_func = ax.semilogx + else: + plot_func = ax.loglog if np.sum(data[i, :]) > 0.: - ax.loglog(E, data[i, :], label=types[i]) + plot_func(E, data[i, :], label=types[i]) ax.set_xlabel('Energy [eV]') - ax.set_ylabel('Macroscopic Cross Section [1/cm]') + if divisor_types: + ax.set_ylabel('Macroscopic Cross Section') + else: + ax.set_ylabel('Macroscopic Cross Section [1/cm]') ax.legend(loc='best') ax.set_xlim(Erange) if self.name is not None: @@ -853,19 +862,12 @@ class Material(object): nuclides = self.get_nuclide_atom_densities(cross_sections) # For ease of processing split out nuc and nuc_density - nucs = [] - nuc_densities = [] - for nuclide in nuclides.items(): - nuc_name, nuc_data = nuclide - nuc, nuc_density = nuc_data - nucs.append(nuc) - nuc_densities.append(nuc_density) + nuc_densities = [nuclide[1][1] for nuclide in nuclides.items()] - # Identify the nuclides which need S(a,b) data + # Identify the nuclides which have S(a,b) data sabs = {} - for nuc in nucs: - sabs[nuc.name] = None - + for nuclide in nuclides.items(): + sabs[nuclide[0].name] = None for sab_name in self._sab: sab = openmc.data.ThermalScattering.from_hdf5( library.get_by_material(sab_name)['path']) @@ -875,14 +877,10 @@ class Material(object): # Now we can create the data sets to be plotted xs = [] E = [] - n = -1 for nuclide in nuclides.items(): - n += 1 - # import pdb; pdb.set_trace() - nuc_obj = openmc.Nuclide(nuclide[0].name) - sab_tab = sabs[nucs[n].name] - temp_E, temp_xs = nuc_obj.calculate_xs(types, T, sab_tab, - cross_sections) + sab_tab = sabs[nuclide[0].name] + temp_E, temp_xs = nuclide[0].calculate_xs(types, T, sab_tab, + cross_sections) E.append(temp_E) xs.append(temp_xs) diff --git a/openmc/nuclide.py b/openmc/nuclide.py index 938b6a666..fda44c43a 100644 --- a/openmc/nuclide.py +++ b/openmc/nuclide.py @@ -162,11 +162,20 @@ class Nuclide(object): ax = fig.add_subplot(111) for i in range(len(data)): to_plot = data[i](E) + # Set to loglog or semilogx depending on if we are plotting a data + # type which we expect to vary linearly + if types[i] in PLOT_TYPES_LINEAR: + plot_func = ax.semilogx + else: + plot_func = ax.loglog if np.sum(to_plot) > 0.: - ax.loglog(E, to_plot, label=types[i]) + plot_func(E, to_plot, label=types[i]) ax.set_xlabel('Energy [eV]') - ax.set_ylabel('Microscopic Cross Section [b]') + if divisor_types: + ax.set_ylabel('Microscopic Cross Section') + else: + ax.set_ylabel('Microscopic Cross Section [b]') ax.legend(loc='best') ax.set_xlim(Erange) if self.name is not None: diff --git a/openmc/plot_data.py b/openmc/plot_data.py index ff3d799a2..ac59c16ea 100644 --- a/openmc/plot_data.py +++ b/openmc/plot_data.py @@ -5,7 +5,15 @@ PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption', 'capture', 'nu-fission', 'nu-scatter', 'unity'] # MTs to combine to generate associated plot_types -PLOT_TYPES_MT = {'total': (2, 3,), 'scatter': (1, 27), 'elastic': (2,), +PLOT_TYPES_MT = {'total': (2, 3,), + 'scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, + 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, + 153, 154, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 183, 184, 190, 194, 196, 198, 199, 200, + 875, 891), + 'elastic': (2,), 'inelastic': (4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, 153, 154, 156, 157, 158, 159, 160, 161, 162, @@ -26,62 +34,24 @@ PLOT_TYPES_MT = {'total': (2, 3,), 'scatter': (1, 27), 'elastic': (2,), 'unity': (0,)} # Operations to use when combining MTs the first np.add is used in reference # to zero -PLOT_TYPES_OP = {'total': (np.add,), 'scatter': (np.subtract,), 'elastic': (), - 'inelastic': (np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add), +PLOT_TYPES_OP = {'total': (np.add,), + 'scatter': (np.add,) * (len(PLOT_TYPES_MT['scatter']) - 1), + 'elastic': (), + 'inelastic': (np.add,) * (len(PLOT_TYPES_MT['inelastic']) - 1), 'fission': (), 'absorption': (), 'capture': (), 'nu-fission': (), - 'nu-scatter': (np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add, - np.add, np.add, np.add, np.add, np.add), + 'nu-scatter': (np.add,) * (len(PLOT_TYPES_MT['nu-scatter']) - 1), 'unity': ()} + # Whether or not to multiply the reaction by the yield as well -PLOT_TYPES_YIELD = {'total': (False, False), 'scatter': (False, False), +PLOT_TYPES_YIELD = {'total': (False, False), + 'scatter': (False,) * len(PLOT_TYPES_MT['scatter']), 'elastic': (False,), - 'inelastic': (False, False, False, False, False, - False, False, False, False, False, - False, False, False, False, False, - False, False, False, False, False, - False, False, False, False, False, - False, False, False, False, False, - False, False, False, False, False, - False, False, False, False, False, - False, False, False, False, False, - False, False, False, False, False, - False, False, False, False, False, - False, False, False, False, False), + 'inelastic': (False,) * len(PLOT_TYPES_MT['inelastic']), 'fission': (False,), 'absorption': (False,), 'capture': (False,), 'nu-fission': (True,), - 'nu-scatter': (True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True, True, True, True, True, - True), + 'nu-scatter': (True,) * len(PLOT_TYPES_MT['nu-scatter']), 'unity': (False,)} + +# Types of plots to plot linearly in y +PLOT_TYPES_LINEAR = ['nu-fission / fission', 'nu-scatter / scatter'] From 240028d13dc620e4e52ed1e1f16c0cebb019158f Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 11 Nov 2016 14:50:24 -0500 Subject: [PATCH 16/60] Added ability to provide an axis to the plot_xs routines, and added a type for slowing-down power so we can plot moderating ratios. Why not right? --- openmc/element.py | 21 ++++++++++++++++----- openmc/material.py | 26 ++++++++++++++++++-------- openmc/nuclide.py | 27 +++++++++++++++++++++------ openmc/plot_data.py | 25 +++++++++++++++++++++---- 4 files changed, 76 insertions(+), 23 deletions(-) diff --git a/openmc/element.py b/openmc/element.py index b1cd19e9b..d90cdf4fc 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -261,7 +261,7 @@ class Element(object): return isotopes - def plot_xs(self, types, divisor_types=None, temperature=294., + def plot_xs(self, types, divisor_types=None, temperature=294., axis=None, Erange=(1.E-5, 20.E6), sab_name=None, cross_sections=None, enrichment=None, **kwargs): """Creates a figure of continuous-energy microscopic cross sections @@ -280,6 +280,9 @@ class Element(object): temperature of 294K will be plotted. Note that the nearest temperature in the library for each nuclide will be used as opposed to using any interpolation. + axis : matplotlib.axes, optional + A previously generated axis to use for plotting. If not specified, + a new axis and figure will be generated. Erange : tuple of floats Energy range (in eV) to plot the cross section within sab_name : str, optional @@ -297,7 +300,10 @@ class Element(object): Returns ------- fig : matplotlib.figure.Figure - Matplotlib Figure of the generated macroscopic cross section + If axis is None, then a Matplotlib Figure of the generated + macroscopic cross section will be returned. Otherwise, a value of + None will be returned as the figure and axes have already been + generated. """ @@ -327,8 +333,12 @@ class Element(object): data = data_new # Generate the plot - fig = plt.figure(**kwargs) - ax = fig.add_subplot(111) + if axis is None: + fig = plt.figure(**kwargs) + ax = fig.add_subplot(111) + else: + fig = None + ax = axis for i in range(len(data)): # Set to loglog or semilogx depending on if we are plotting a data # type which we expect to vary linearly @@ -337,11 +347,12 @@ class Element(object): else: plot_func = ax.loglog if np.sum(data[i, :]) > 0.: + print('max = {:.2E}'.format(np.max(data[i, :]))) plot_func(E, data[i, :], label=types[i]) ax.set_xlabel('Energy [eV]') if divisor_types: - ax.set_ylabel('Elemental Cross Section') + ax.set_ylabel('Elemental Data') else: ax.set_ylabel('Elemental Cross Section [b]') ax.legend(loc='best') diff --git a/openmc/material.py b/openmc/material.py index ec68913ca..ed54bffc3 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -666,8 +666,7 @@ class Material(object): nuc_densities = [] nuc_density_types = [] for nuclide in nuclides.items(): - nuc, nuc_data = nuclide - nuc, nuc_density, nuc_density_type = nuc_data + nuc, nuc_density, nuc_density_type = nuclide[1] nucs.append(nuc) nuc_densities.append(nuc_density) nuc_density_types.append(nuc_density_type) @@ -713,7 +712,8 @@ class Material(object): return nuclides def plot_xs(self, types, divisor_types=None, temperature=294., - Erange=(1.E-5, 20.E6), cross_sections=None, **kwargs): + axis=None, Erange=(1.E-5, 20.E6), cross_sections=None, + **kwargs): """Creates a figure of continuous-energy macroscopic cross sections for this material @@ -730,6 +730,9 @@ class Material(object): temperature of 294K will be plotted. Note that the nearest temperature in the library for each nuclide will be used as opposed to using any interpolation. + axis : matplotlib.axes, optional + A previously generated axis to use for plotting. If not specified, + a new axis and figure will be generated. Erange : tuple of floats, optional Energy range (in eV) to plot the cross section within cross_sections : str, optional @@ -740,8 +743,11 @@ class Material(object): Returns ------- - fig : matplotlib.figure.Figure - Matplotlib Figure of the generated macroscopic cross section + fig : matplotlib.figure.Figure or None + If axis is None, then a Matplotlib Figure of the generated + macroscopic cross section will be returned. Otherwise, a value of + None will be returned as the figure and axes have already been + generated. """ @@ -770,8 +776,12 @@ class Material(object): data = data_new # Generate the plot - fig = plt.figure(**kwargs) - ax = fig.add_subplot(111) + if axis is None: + fig = plt.figure(**kwargs) + ax = fig.add_subplot(111) + else: + fig = None + ax = axis for i in range(len(data)): # Set to loglog or semilogx depending on if we are plotting a data # type which we expect to vary linearly @@ -784,7 +794,7 @@ class Material(object): ax.set_xlabel('Energy [eV]') if divisor_types: - ax.set_ylabel('Macroscopic Cross Section') + ax.set_ylabel('Macroscopic Data') else: ax.set_ylabel('Macroscopic Cross Section [1/cm]') ax.legend(loc='best') diff --git a/openmc/nuclide.py b/openmc/nuclide.py index fda44c43a..b549da896 100644 --- a/openmc/nuclide.py +++ b/openmc/nuclide.py @@ -97,7 +97,7 @@ class Nuclide(object): self._scattering = scattering - def plot_xs(self, types, divisor_types=None, temperature=294., + def plot_xs(self, types, divisor_types=None, temperature=294., axis=None, Erange=(1.E-5, 20.E6), sab_name=None, cross_sections=None, **kwargs): """Creates a figure of continuous-energy cross sections for this @@ -116,6 +116,9 @@ class Nuclide(object): temperature of 294K will be plotted. Note that the nearest temperature in the library for each nuclide will be used as opposed to using any interpolation. + axis : matplotlib.axes, optional + A previously generated axis to use for plotting. If not specified, + a new axis and figure will be generated. Erange : tuple of floats Energy range (in eV) to plot the cross section within sab_name : str, optional @@ -129,7 +132,10 @@ class Nuclide(object): Returns ------- fig : matplotlib.figure.Figure - Matplotlib Figure of the generated macroscopic cross section + If axis is None, then a Matplotlib Figure of the generated + macroscopic cross section will be returned. Otherwise, a value of + None will be returned as the figure and axes have already been + generated. """ @@ -158,8 +164,12 @@ class Nuclide(object): data = data_new # Generate the plot - fig = plt.figure(**kwargs) - ax = fig.add_subplot(111) + if axis is None: + fig = plt.figure(**kwargs) + ax = fig.add_subplot(111) + else: + fig = None + ax = axis for i in range(len(data)): to_plot = data[i](E) # Set to loglog or semilogx depending on if we are plotting a data @@ -173,7 +183,7 @@ class Nuclide(object): ax.set_xlabel('Energy [eV]') if divisor_types: - ax.set_ylabel('Microscopic Cross Section') + ax.set_ylabel('Microscopic Data') else: ax.set_ylabel('Microscopic Cross Section [b]') ax.legend(loc='best') @@ -357,8 +367,13 @@ class Nuclide(object): funcs.append(nuc[mt].xs[nucT]) else: funcs.append(nuc[mt].xs[nucT]) - elif mt == 0: + elif mt == UNITY_MT: funcs.append(lambda x: 1.) + elif mt == XI_MT: + awr = nuc.atomic_weight_ratio + alpha = ((awr - 1.) / (awr + 1.))**2 + xi = 1. + alpha * np.log(alpha) / (1. - alpha) + funcs.append(lambda x: xi) else: funcs.append(lambda x: 0.) xs.append(openmc.data.Combination(funcs, op)) diff --git a/openmc/plot_data.py b/openmc/plot_data.py index ac59c16ea..ed87f2f00 100644 --- a/openmc/plot_data.py +++ b/openmc/plot_data.py @@ -2,7 +2,12 @@ import numpy as np # Supported keywords for material xs plotting PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', - 'absorption', 'capture', 'nu-fission', 'nu-scatter', 'unity'] + 'absorption', 'capture', 'nu-fission', 'nu-scatter', 'unity', + 'slowing-down power'] + +# Special MT values +UNITY_MT = -1 +XI_MT = -2 # MTs to combine to generate associated plot_types PLOT_TYPES_MT = {'total': (2, 3,), @@ -31,7 +36,15 @@ PLOT_TYPES_MT = {'total': (2, 3,), 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 183, 184, 190, 194, 196, 198, 199, 200, 875, 891), - 'unity': (0,)} + 'unity': (UNITY_MT,), + 'slowing-down power': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, + 29, 30, 32, 33, 34, 35, 36, 37, 41, 42, + 44, 45, 152, 153, 154, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 183, + 184, 190, 194, 196, 198, 199, 200, 875, + 891, XI_MT)} # Operations to use when combining MTs the first np.add is used in reference # to zero PLOT_TYPES_OP = {'total': (np.add,), @@ -41,7 +54,9 @@ PLOT_TYPES_OP = {'total': (np.add,), 'fission': (), 'absorption': (), 'capture': (), 'nu-fission': (), 'nu-scatter': (np.add,) * (len(PLOT_TYPES_MT['nu-scatter']) - 1), - 'unity': ()} + 'unity': (), + 'slowing-down power': + (np.add,) * (len(PLOT_TYPES_MT['slowing-down power']) - 2) + (np.multiply,)} # Whether or not to multiply the reaction by the yield as well PLOT_TYPES_YIELD = {'total': (False, False), @@ -51,7 +66,9 @@ PLOT_TYPES_YIELD = {'total': (False, False), 'fission': (False,), 'absorption': (False,), 'capture': (False,), 'nu-fission': (True,), 'nu-scatter': (True,) * len(PLOT_TYPES_MT['nu-scatter']), - 'unity': (False,)} + 'unity': (False,), + 'slowing-down power': + (True,) * len(PLOT_TYPES_MT['slowing-down power'])} # Types of plots to plot linearly in y PLOT_TYPES_LINEAR = ['nu-fission / fission', 'nu-scatter / scatter'] From 2a50aff588fed0224699456a9e319bfb298a4610 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 11 Nov 2016 15:20:40 -0500 Subject: [PATCH 17/60] Pre-PR cleanup and addition of ability to read MT in types --- openmc/element.py | 18 ++---------------- openmc/material.py | 19 ++----------------- openmc/nuclide.py | 13 +++++++++---- 3 files changed, 13 insertions(+), 37 deletions(-) diff --git a/openmc/element.py b/openmc/element.py index d90cdf4fc..6fe988195 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -400,20 +400,6 @@ class Element(object): if cross_sections is not None: cv.check_type('cross_sections', cross_sections, str) cv.check_iterable_type('types', types, str) - - # Parse the types - mts = [] - ops = [] - yields = [] - for line in types: - if line in PLOT_TYPES: - mts.append(PLOT_TYPES_MT[line]) - yields.append(PLOT_TYPES_YIELD[line]) - ops.append(PLOT_TYPES_OP[line]) - else: - # Not a built-in type, we have to parse it ourselves - raise NotImplementedError() - cv.check_type('temperature', temperature, Real) # If cross_sections is None, get the cross sections from the @@ -462,8 +448,8 @@ class Element(object): unionE = np.union1d(unionE, E[n]) # Now we can combine all the nuclidic data - data = np.zeros((len(mts), len(unionE))) - for l in range(len(mts)): + data = np.zeros((len(types), len(unionE))) + for l in range(len(types)): if types[l] == 'unity': data[l, :] = 1. else: diff --git a/openmc/material.py b/openmc/material.py index ed54bffc3..1889a4765 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -834,21 +834,6 @@ class Material(object): # Check types if cross_sections is not None: cv.check_type('cross_sections', cross_sections, str) - cv.check_iterable_type('types', types, str) - - # Parse the types - mts = [] - ops = [] - yields = [] - for line in types: - if line in PLOT_TYPES: - mts.append(PLOT_TYPES_MT[line]) - yields.append(PLOT_TYPES_YIELD[line]) - ops.append(PLOT_TYPES_OP[line]) - else: - # Not a built-in type, we have to parse it ourselves - raise NotImplementedError() - if self.temperature is not None: T = self.temperature else: @@ -901,8 +886,8 @@ class Material(object): unionE = np.union1d(unionE, E[n]) # Now we can combine all the nuclidic data - data = np.zeros((len(mts), len(unionE))) - for l in range(len(mts)): + data = np.zeros((len(types), len(unionE))) + for l in range(len(types)): if types[l] == 'unity': data[l, :] = 1. else: diff --git a/openmc/nuclide.py b/openmc/nuclide.py index b549da896..439aedf48 100644 --- a/openmc/nuclide.py +++ b/openmc/nuclide.py @@ -200,8 +200,10 @@ class Nuclide(object): Parameters ---------- - types : Iterable of values of PLOT_TYPES - The type of cross sections to calculate + types : Iterable of str or Integral + The type of cross sections to calculate; values can either be those + in openmc.PLOT_TYPES or integers which correspond to reaction + channel (MT) numbers. temperature : float, optional Temperature in Kelvin to plot. If not specified, a default temperature of 294K will be plotted. Note that the nearest @@ -224,7 +226,6 @@ class Nuclide(object): # Check types if cross_sections is not None: cv.check_type('cross_sections', cross_sections, str) - cv.check_iterable_type('types', types, str) if sab_name: cv.check_type('sab_name', sab_name, str) @@ -239,7 +240,11 @@ class Nuclide(object): ops.append(PLOT_TYPES_OP[line]) else: # Not a built-in type, we have to parse it ourselves - raise NotImplementedError() + cv.check_type('MT in types', line, Integral) + cv.check_greater_than('MT in types', line, 0) + mts.append((line,)) + yields.append((False,)) + ops.append(()) # If cross_sections is None, get the cross sections from the # OPENMC_CROSS_SECTIONS environment variable From d4f4166ba7ec48be7328a565f4fc4bc467557331 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 11 Nov 2016 20:37:03 -0500 Subject: [PATCH 18/60] resolved most of the comments from @samuelshaner --- openmc/data/library.py | 20 ++++++++-- openmc/element.py | 65 ++++++++++++++------------------ openmc/material.py | 85 +++++++++++++++--------------------------- openmc/nuclide.py | 58 +++++++++++++--------------- openmc/plot_data.py | 14 ++++--- 5 files changed, 110 insertions(+), 132 deletions(-) diff --git a/openmc/data/library.py b/openmc/data/library.py index 9f6d93146..3beb25543 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -5,6 +5,7 @@ import h5py from openmc.mixin import EqualityMixin from openmc.clean_xml import clean_xml_indentation +from openmc.checkvalue import check_type class DataLibrary(EqualityMixin): @@ -95,13 +96,14 @@ class DataLibrary(EqualityMixin): method='xml') @classmethod - def from_xml(cls, path): + def from_xml(cls, path=None): """Read cross section data library from an XML file. Parameters ---------- - path : str - Path to XML file to read. + path : str, optional + Path to XML file to read. If not provided, the + `OPENMC_CROSS_SECTIONS` environment variable will be used. Returns ------- @@ -112,6 +114,18 @@ class DataLibrary(EqualityMixin): data = cls() + # If cross_sections is None, get the cross sections from the + # OPENMC_CROSS_SECTIONS environment variable + if path is None: + path = os.environ.get('OPENMC_CROSS_SECTIONS') + + # Check to make sure there was an environmental variable. + if path is None: + raise ValueError("Either path or OPENMC_CROSS_SECTIONS " + "environmental variable must be set") + + check_type('path', path, str) + tree = ET.parse(path) root = tree.getroot() if root.find('directory') is not None: diff --git a/openmc/element.py b/openmc/element.py index 6fe988195..905cdc6c9 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -262,7 +262,7 @@ class Element(object): return isotopes def plot_xs(self, types, divisor_types=None, temperature=294., axis=None, - Erange=(1.E-5, 20.E6), sab_name=None, cross_sections=None, + energy_range=(1.E-5, 20.E6), sab_name=None, cross_sections=None, enrichment=None, **kwargs): """Creates a figure of continuous-energy microscopic cross sections for this element @@ -283,7 +283,7 @@ class Element(object): axis : matplotlib.axes, optional A previously generated axis to use for plotting. If not specified, a new axis and figure will be generated. - Erange : tuple of floats + energy_range : tuple of floats Energy range (in eV) to plot the cross section within sab_name : str, optional Name of S(a,b) library to apply to MT=2 data when applicable. @@ -324,12 +324,12 @@ class Element(object): E = np.union1d(Enum, Ediv) data_new = np.zeros((len(types), len(E))) - for l in range(len(types)): - data_new[l, :] = \ - np.divide(np.interp(E, Enum, data[l, :]), - np.interp(E, Ediv, data_div[l, :])) - if divisor_types[l] != 'unity': - types[l] = types[l] + ' / ' + divisor_types[l] + for line in range(len(types)): + data_new[line, :] = \ + np.divide(np.interp(E, Enum, data[line, :]), + np.interp(E, Ediv, data_div[line, :])) + if divisor_types[line] != 'unity': + types[line] = types[line] + ' / ' + divisor_types[line] data = data_new # Generate the plot @@ -339,13 +339,14 @@ class Element(object): else: fig = None ax = axis + # Set to loglog or semilogx depending on if we are plotting a data + # type which we expect to vary linearly + if set(types).issubset(PLOT_TYPES_LINEAR): + plot_func = ax.semilogx + else: + plot_func = ax.loglog + # Plot the data for i in range(len(data)): - # Set to loglog or semilogx depending on if we are plotting a data - # type which we expect to vary linearly - if types[i] in PLOT_TYPES_LINEAR: - plot_func = ax.semilogx - else: - plot_func = ax.loglog if np.sum(data[i, :]) > 0.: print('max = {:.2E}'.format(np.max(data[i, :]))) plot_func(E, data[i, :], label=types[i]) @@ -356,7 +357,7 @@ class Element(object): else: ax.set_ylabel('Elemental Cross Section [b]') ax.legend(loc='best') - ax.set_xlim(Erange) + ax.set_xlim(energy_range) if self.name is not None: title = 'Cross Section for ' + self.name ax.set_title(title) @@ -388,11 +389,11 @@ class Element(object): Returns ------- - unionE : numpy.array + energy_grid : numpy.array Energies at which cross sections are calculated, in units of eV data : numpy.ndarray Macroscopic cross sections calculated at the energy grid described - by unionE + by energy_grid """ @@ -402,18 +403,8 @@ class Element(object): cv.check_iterable_type('types', types, str) cv.check_type('temperature', temperature, Real) - # If cross_sections is None, get the cross sections from the - # OPENMC_CROSS_SECTIONS environment variable - if cross_sections is None: - cross_sections = os.environ.get('OPENMC_CROSS_SECTIONS') - - # If a cross_sections library is present, check natural nuclides - # against the nuclides in the library - if cross_sections is not None: - library = openmc.data.DataLibrary.from_xml(cross_sections) - else: - raise ValueError("cross_sections or OPENMC_CROSS_SECTIONS " - "environmental variable must be set") + # Load the library + library = openmc.data.DataLibrary.from_xml(cross_sections) # Expand elements in to nuclides with atomic densities nuclides = self.expand(100., 'ao', enrichment=enrichment, @@ -443,17 +434,17 @@ class Element(object): # Condense the data for every nuclide # First create a union energy grid - unionE = E[0] + energy_grid = E[0] for n in range(1, len(E)): - unionE = np.union1d(unionE, E[n]) + energy_grid = np.union1d(energy_grid, E[n]) # Now we can combine all the nuclidic data - data = np.zeros((len(types), len(unionE))) - for l in range(len(types)): - if types[l] == 'unity': - data[l, :] = 1. + data = np.zeros((len(types), len(energy_grid))) + for line in range(len(types)): + if types[line] == 'unity': + data[line, :] = 1. else: for n in range(len(nuclides)): - data[l, :] += nuc_fractions[n] * xs[n][l](unionE) + data[line, :] += nuc_fractions[n] * xs[n][line](energy_grid) - return unionE, data + return energy_grid, data diff --git a/openmc/material.py b/openmc/material.py index 1889a4765..cd80b2089 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -627,20 +627,8 @@ class Material(object): import scipy.constants as sc - cv.check_type('cross_sections', cross_sections, str) - - # If cross_sections is None, get the cross sections from the - # OPENMC_CROSS_SECTIONS environment variable - if cross_sections is None: - cross_sections = os.environ.get('OPENMC_CROSS_SECTIONS') - - # If a cross_sections library is present, check natural nuclides - # against the nuclides in the library - if cross_sections is not None: - library = openmc.data.DataLibrary.from_xml(cross_sections) - else: - raise ValueError("cross_sections or OPENMC_CROSS_SECTIONS " - "environmental variable must be set") + # Load the library + library = openmc.data.DataLibrary.from_xml(cross_sections) # Expand elements in to nuclides nuclides = self.get_nuclide_densities() @@ -704,15 +692,13 @@ class Material(object): nuc_densities = density * nuc_densities nuclides = OrderedDict() - n = -1 - for nuc in nucs: - n += 1 + for n, nuc in enumerate(nucs): nuclides[nuc] = (nuc, nuc_densities[n]) return nuclides def plot_xs(self, types, divisor_types=None, temperature=294., - axis=None, Erange=(1.E-5, 20.E6), cross_sections=None, + axis=None, energy_range=(1.E-5, 20.E6), cross_sections=None, **kwargs): """Creates a figure of continuous-energy macroscopic cross sections for this material @@ -733,7 +719,7 @@ class Material(object): axis : matplotlib.axes, optional A previously generated axis to use for plotting. If not specified, a new axis and figure will be generated. - Erange : tuple of floats, optional + energy_range : tuple of floats, optional Energy range (in eV) to plot the cross section within cross_sections : str, optional Location of cross_sections.xml file. Default is None. @@ -767,12 +753,12 @@ class Material(object): E = np.union1d(Enum, Ediv) data_new = np.zeros((len(types), len(E))) - for l in range(len(types)): - data_new[l, :] = \ - np.divide(np.interp(E, Enum, data[l, :]), - np.interp(E, Ediv, data_div[l, :])) - if divisor_types[l] != 'unity': - types[l] = types[l] + ' / ' + divisor_types[l] + for line in range(len(types)): + data_new[line, :] = \ + np.divide(np.interp(E, Enum, data[line, :]), + np.interp(E, Ediv, data_div[line, :])) + if divisor_types[line] != 'unity': + types[line] = types[line] + ' / ' + divisor_types[line] data = data_new # Generate the plot @@ -782,13 +768,14 @@ class Material(object): else: fig = None ax = axis + # Set to loglog or semilogx depending on if we are plotting a data + # type which we expect to vary linearly + if set(types).issubset(PLOT_TYPES_LINEAR): + plot_func = ax.semilogx + else: + plot_func = ax.loglog + # Plot the data for i in range(len(data)): - # Set to loglog or semilogx depending on if we are plotting a data - # type which we expect to vary linearly - if types[i] in PLOT_TYPES_LINEAR: - plot_func = ax.semilogx - else: - plot_func = ax.loglog if np.sum(data[i, :]) > 0.: plot_func(E, data[i, :], label=types[i]) @@ -798,7 +785,7 @@ class Material(object): else: ax.set_ylabel('Macroscopic Cross Section [1/cm]') ax.legend(loc='best') - ax.set_xlim(Erange) + ax.set_xlim(energy_range) if self.name is not None: title = 'Macroscopic Cross Section for ' + self.name ax.set_title(title) @@ -823,11 +810,11 @@ class Material(object): Returns ------- - unionE : numpy.array + energy_grid : numpy.array Energies at which cross sections are calculated, in units of eV data : numpy.ndarray Macroscopic cross sections calculated at the energy grid described - by unionE + by energy_grid """ @@ -840,18 +827,8 @@ class Material(object): cv.check_type('temperature', temperature, Real) T = temperature - # If cross_sections is None, get the cross sections from the - # OPENMC_CROSS_SECTIONS environment variable - if cross_sections is None: - cross_sections = os.environ.get('OPENMC_CROSS_SECTIONS') - - # If a cross_sections library is present, check natural nuclides - # against the nuclides in the library - if cross_sections is not None: - library = openmc.data.DataLibrary.from_xml(cross_sections) - else: - raise ValueError("cross_sections or OPENMC_CROSS_SECTIONS " - "environmental variable must be set") + # Load the library + library = openmc.data.DataLibrary.from_xml(cross_sections) # Expand elements in to nuclides with atomic densities nuclides = self.get_nuclide_atom_densities(cross_sections) @@ -881,20 +858,20 @@ class Material(object): # Condense the data for every nuclide # First create a union energy grid - unionE = E[0] + energy_grid = E[0] for n in range(1, len(E)): - unionE = np.union1d(unionE, E[n]) + energy_grid = np.union1d(energy_grid, E[n]) # Now we can combine all the nuclidic data - data = np.zeros((len(types), len(unionE))) - for l in range(len(types)): - if types[l] == 'unity': - data[l, :] = 1. + data = np.zeros((len(types), len(energy_grid))) + for line in range(len(types)): + if types[line] == 'unity': + data[line, :] = 1. else: for n in range(len(nuclides)): - data[l, :] += nuc_densities[n] * xs[n][l](unionE) + data[line, :] += nuc_densities[n] * xs[n][line](energy_grid) - return unionE, data + return energy_grid, data def _get_nuclide_xml(self, nuclide, distrib=False): xml_element = ET.Element("nuclide") diff --git a/openmc/nuclide.py b/openmc/nuclide.py index 439aedf48..c42d4f8d5 100644 --- a/openmc/nuclide.py +++ b/openmc/nuclide.py @@ -98,10 +98,9 @@ class Nuclide(object): self._scattering = scattering def plot_xs(self, types, divisor_types=None, temperature=294., axis=None, - Erange=(1.E-5, 20.E6), sab_name=None, cross_sections=None, + energy_range=(1.E-5, 20.E6), sab_name=None, cross_sections=None, **kwargs): - """Creates a figure of continuous-energy cross sections for this - nuclide + """Creates a figure of continuous-energy cross sections for this nuclide Parameters ---------- @@ -119,7 +118,7 @@ class Nuclide(object): axis : matplotlib.axes, optional A previously generated axis to use for plotting. If not specified, a new axis and figure will be generated. - Erange : tuple of floats + energy_range : tuple of floats Energy range (in eV) to plot the cross section within sab_name : str, optional Name of S(a,b) library to apply to MT=2 data when applicable. @@ -156,11 +155,12 @@ class Nuclide(object): E = np.union1d(Enum, Ediv) data_new = [] - for l in range(len(types)): - data_new.append(openmc.data.Combination([data[l], data_div[l]], + for line in range(len(types)): + data_new.append(openmc.data.Combination([data[line], + data_div[line]], [np.divide])) - if divisor_types[l] != 'unity': - types[l] = types[l] + ' / ' + divisor_types[l] + if divisor_types[line] != 'unity': + types[line] = types[line] + ' / ' + divisor_types[line] data = data_new # Generate the plot @@ -170,14 +170,15 @@ class Nuclide(object): else: fig = None ax = axis + # Set to loglog or semilogx depending on if we are plotting a data + # type which we expect to vary linearly + if set(types).issubset(PLOT_TYPES_LINEAR): + plot_func = ax.semilogx + else: + plot_func = ax.loglog + # Plot the data for i in range(len(data)): to_plot = data[i](E) - # Set to loglog or semilogx depending on if we are plotting a data - # type which we expect to vary linearly - if types[i] in PLOT_TYPES_LINEAR: - plot_func = ax.semilogx - else: - plot_func = ax.loglog if np.sum(to_plot) > 0.: plot_func(E, to_plot, label=types[i]) @@ -187,7 +188,7 @@ class Nuclide(object): else: ax.set_ylabel('Microscopic Cross Section [b]') ax.legend(loc='best') - ax.set_xlim(Erange) + ax.set_xlim(energy_range) if self.name is not None: title = 'Microscopic Cross Section for ' + self.name ax.set_title(title) @@ -216,10 +217,11 @@ class Nuclide(object): Returns ------- - E : numpy.array + energy_grid : numpy.array Energies at which cross sections are calculated, in units of eV data : numpy.ndarray - Cross sections calculated at the energy grid described by unionE + Cross sections calculated at the energy grid described by + energy_grid """ @@ -246,18 +248,8 @@ class Nuclide(object): yields.append((False,)) ops.append(()) - # If cross_sections is None, get the cross sections from the - # OPENMC_CROSS_SECTIONS environment variable - if cross_sections is None: - cross_sections = os.environ.get('OPENMC_CROSS_SECTIONS') - - # If a cross_sections library is present, check natural nuclides - # against the nuclides in the library - if cross_sections is not None: - library = openmc.data.DataLibrary.from_xml(cross_sections) - else: - raise ValueError("cross_sections or OPENMC_CROSS_SECTIONS " - "environmental variable must be set") + # Load the library + library = openmc.data.DataLibrary.from_xml(cross_sections) # Convert temperature to format needed for access in the library cv.check_type('temperature', temperature, Real) @@ -265,7 +257,7 @@ class Nuclide(object): T = temperature # Now we can create the data sets to be plotted - E = [] + energy_grid = [] xs = [] lib = library.get_by_material(self.name) if lib is not None: @@ -325,9 +317,9 @@ class Nuclide(object): if inelastic.x[-1] > sab_Emax: sab_Emax = inelastic.x[-1] sab_funcs.append(inelastic) - E = grid + energy_grid = grid else: - E = nuc.energy[nucT] + energy_grid = nuc.energy[nucT] for i, mt_set in enumerate(mts): # Get the reaction xs data from the nuclide @@ -385,4 +377,4 @@ class Nuclide(object): else: raise ValueError(nuclide[0] + " not in library") - return E, xs + return energy_grid, xs diff --git a/openmc/plot_data.py b/openmc/plot_data.py index ed87f2f00..1efeda00c 100644 --- a/openmc/plot_data.py +++ b/openmc/plot_data.py @@ -3,7 +3,7 @@ import numpy as np # Supported keywords for material xs plotting PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption', 'capture', 'nu-fission', 'nu-scatter', 'unity', - 'slowing-down power'] + 'slowing-down power', 'damage'] # Special MT values UNITY_MT = -1 @@ -44,7 +44,8 @@ PLOT_TYPES_MT = {'total': (2, 3,), 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 183, 184, 190, 194, 196, 198, 199, 200, 875, - 891, XI_MT)} + 891, XI_MT), + 'damage': (444,)} # Operations to use when combining MTs the first np.add is used in reference # to zero PLOT_TYPES_OP = {'total': (np.add,), @@ -56,7 +57,8 @@ PLOT_TYPES_OP = {'total': (np.add,), 'nu-scatter': (np.add,) * (len(PLOT_TYPES_MT['nu-scatter']) - 1), 'unity': (), 'slowing-down power': - (np.add,) * (len(PLOT_TYPES_MT['slowing-down power']) - 2) + (np.multiply,)} + (np.add,) * (len(PLOT_TYPES_MT['slowing-down power']) - 2) + (np.multiply,), + 'damage': ()} # Whether or not to multiply the reaction by the yield as well PLOT_TYPES_YIELD = {'total': (False, False), @@ -68,7 +70,9 @@ PLOT_TYPES_YIELD = {'total': (False, False), 'nu-scatter': (True,) * len(PLOT_TYPES_MT['nu-scatter']), 'unity': (False,), 'slowing-down power': - (True,) * len(PLOT_TYPES_MT['slowing-down power'])} + (True,) * len(PLOT_TYPES_MT['slowing-down power']), + 'damage': (False,)} # Types of plots to plot linearly in y -PLOT_TYPES_LINEAR = ['nu-fission / fission', 'nu-scatter / scatter'] +PLOT_TYPES_LINEAR = {'nu-fission / fission', 'nu-scatter / scatter', + 'nu-fission / absorption', 'fission / absorption'} From 995ba2669482d79941dee5018c8dd32934df30c0 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 11 Nov 2016 21:58:31 -0500 Subject: [PATCH 19/60] Moved plotting and calculate_xs routines to plotter, condensed code as needed. --- openmc/__init__.py | 2 +- openmc/element.py | 192 -------------- openmc/material.py | 178 ------------- openmc/nuclide.py | 287 --------------------- openmc/plot_data.py | 78 ------ openmc/plotter.py | 604 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 605 insertions(+), 736 deletions(-) delete mode 100644 openmc/plot_data.py create mode 100644 openmc/plotter.py diff --git a/openmc/__init__.py b/openmc/__init__.py index 98de9b70d..0685a80b1 100644 --- a/openmc/__init__.py +++ b/openmc/__init__.py @@ -24,7 +24,7 @@ from openmc.statepoint import * from openmc.summary import * from openmc.particle_restart import * from openmc.mixin import * -from openmc.plot_data import * +from openmc.plotter import * try: from openmc.opencg_compatible import * diff --git a/openmc/element.py b/openmc/element.py index 905cdc6c9..edfbee136 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -1,17 +1,13 @@ from collections import OrderedDict -from numbers import Real import re -import sys import os from six import string_types from xml.etree import ElementTree as ET -import numpy as np import openmc import openmc.checkvalue as cv from openmc.data import NATURAL_ABUNDANCE, atomic_mass -from openmc.plot_data import * class Element(object): @@ -260,191 +256,3 @@ class Element(object): isotopes.append((nuc, percent * abundance, percent_type)) return isotopes - - def plot_xs(self, types, divisor_types=None, temperature=294., axis=None, - energy_range=(1.E-5, 20.E6), sab_name=None, cross_sections=None, - enrichment=None, **kwargs): - """Creates a figure of continuous-energy microscopic cross sections - for this element - - Parameters - ---------- - types : Iterable of values of PLOT_TYPES - The type of cross sections to include in the plot. - divisor_types : Iterable of values of PLOT_TYPES, optional - Cross section types which will divide those produced by types - before plotting. A type of 'unity' can be used to effectively not - divide some types. - temperature : float, optional - Temperature in Kelvin to plot. If not specified, a default - temperature of 294K will be plotted. Note that the nearest - temperature in the library for each nuclide will be used as opposed - to using any interpolation. - axis : matplotlib.axes, optional - A previously generated axis to use for plotting. If not specified, - a new axis and figure will be generated. - energy_range : tuple of floats - Energy range (in eV) to plot the cross section within - sab_name : str, optional - Name of S(a,b) library to apply to MT=2 data when applicable. - cross_sections : str, optional - Location of cross_sections.xml file. Default is None. - enrichment : float, optional - Enrichment for U235 in weight percent. For example, input 4.95 for - 4.95 weight percent enriched U. Default is None - (natural composition). - **kwargs - All keyword arguments are passed to - :func:`matplotlib.pyplot.figure`. - - Returns - ------- - fig : matplotlib.figure.Figure - If axis is None, then a Matplotlib Figure of the generated - macroscopic cross section will be returned. Otherwise, a value of - None will be returned as the figure and axes have already been - generated. - - """ - - from matplotlib import pyplot as plt - - E, data = self.calculate_xs(types, temperature, sab_name, - cross_sections) - - if divisor_types: - cv.check_length('divisor types', divisor_types, len(types), - len(types)) - Ediv, data_div = self.calculate_xs(divisor_types, temperature, - sab_name, cross_sections) - - # Create a new union grid, interpolate data and data_div on to that - # grid, and then do the actual division - Enum = E[:] - E = np.union1d(Enum, Ediv) - data_new = np.zeros((len(types), len(E))) - - for line in range(len(types)): - data_new[line, :] = \ - np.divide(np.interp(E, Enum, data[line, :]), - np.interp(E, Ediv, data_div[line, :])) - if divisor_types[line] != 'unity': - types[line] = types[line] + ' / ' + divisor_types[line] - data = data_new - - # Generate the plot - if axis is None: - fig = plt.figure(**kwargs) - ax = fig.add_subplot(111) - else: - fig = None - ax = axis - # Set to loglog or semilogx depending on if we are plotting a data - # type which we expect to vary linearly - if set(types).issubset(PLOT_TYPES_LINEAR): - plot_func = ax.semilogx - else: - plot_func = ax.loglog - # Plot the data - for i in range(len(data)): - if np.sum(data[i, :]) > 0.: - print('max = {:.2E}'.format(np.max(data[i, :]))) - plot_func(E, data[i, :], label=types[i]) - - ax.set_xlabel('Energy [eV]') - if divisor_types: - ax.set_ylabel('Elemental Data') - else: - ax.set_ylabel('Elemental Cross Section [b]') - ax.legend(loc='best') - ax.set_xlim(energy_range) - if self.name is not None: - title = 'Cross Section for ' + self.name - ax.set_title(title) - - return fig - - def calculate_xs(self, types, temperature=294., sab_name=None, - cross_sections=None, enrichment=None): - """Calculates continuous-energy macroscopic cross sections of a - requested type - - Parameters - ---------- - types : Iterable of values of PLOT_TYPES - The type of cross sections to calculate - temperature : float, optional - Temperature in Kelvin to plot. If not specified, a default - temperature of 294K will be plotted. Note that the nearest - temperature in the library for each nuclide will be used as opposed - to using any interpolation. - sab_name : str, optional - Name of S(a,b) library to apply to MT=2 data when applicable. - cross_sections : str, optional - Location of cross_sections.xml file. Default is None. - enrichment : float, optional - Enrichment for U235 in weight percent. For example, input 4.95 for - 4.95 weight percent enriched U. Default is None - (natural composition). - - Returns - ------- - energy_grid : numpy.array - Energies at which cross sections are calculated, in units of eV - data : numpy.ndarray - Macroscopic cross sections calculated at the energy grid described - by energy_grid - - """ - - # Check types - if cross_sections is not None: - cv.check_type('cross_sections', cross_sections, str) - cv.check_iterable_type('types', types, str) - cv.check_type('temperature', temperature, Real) - - # Load the library - library = openmc.data.DataLibrary.from_xml(cross_sections) - - # Expand elements in to nuclides with atomic densities - nuclides = self.expand(100., 'ao', enrichment=enrichment, - cross_sections=cross_sections) - - # For ease of processing split out nuc and nuc_density - nuc_fractions = [nuclide[1] for nuclide in nuclides] - - # Identify the nuclides which have S(a,b) data - sabs = {} - for nuclide in nuclides: - sabs[nuclide[0].name] = None - if sab_name: - sab = openmc.data.ThermalScattering.from_hdf5(sab_name) - for nuc in sab.nuclides: - sabs[nuc] = library.get_by_material(sab_name)['path'] - - # Now we can create the data sets to be plotted - xs = [] - E = [] - for nuclide in nuclides: - sab_tab = sabs[nuclide[0].name] - temp_E, temp_xs = nuclide[0].calculate_xs(types, temperature, - sab_tab, cross_sections) - E.append(temp_E) - xs.append(temp_xs) - - # Condense the data for every nuclide - # First create a union energy grid - energy_grid = E[0] - for n in range(1, len(E)): - energy_grid = np.union1d(energy_grid, E[n]) - - # Now we can combine all the nuclidic data - data = np.zeros((len(types), len(energy_grid))) - for line in range(len(types)): - if types[line] == 'unity': - data[line, :] = 1. - else: - for n in range(len(nuclides)): - data[line, :] += nuc_fractions[n] * xs[n][line](energy_grid) - - return energy_grid, data diff --git a/openmc/material.py b/openmc/material.py index cd80b2089..16d1fd147 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -3,7 +3,6 @@ from copy import deepcopy from numbers import Real, Integral import warnings from xml.etree import ElementTree as ET -import os from six import string_types import numpy as np @@ -12,7 +11,6 @@ import openmc import openmc.data import openmc.checkvalue as cv from openmc.clean_xml import sort_xml_elements, clean_xml_indentation -from openmc.plot_data import * # A static variable for auto-generated Material IDs @@ -697,182 +695,6 @@ class Material(object): return nuclides - def plot_xs(self, types, divisor_types=None, temperature=294., - axis=None, energy_range=(1.E-5, 20.E6), cross_sections=None, - **kwargs): - """Creates a figure of continuous-energy macroscopic cross sections - for this material - - Parameters - ---------- - types : Iterable of values of PLOT_TYPES - The type of cross sections to include in the plot. - divisor_types : Iterable of values of PLOT_TYPES, optional - Cross section types which will divide those produced by types - before plotting. A type of 'unity' can be used to effectively not - divide some types. - temperature : float, optional - Temperature in Kelvin to plot. If not specified, a default - temperature of 294K will be plotted. Note that the nearest - temperature in the library for each nuclide will be used as opposed - to using any interpolation. - axis : matplotlib.axes, optional - A previously generated axis to use for plotting. If not specified, - a new axis and figure will be generated. - energy_range : tuple of floats, optional - Energy range (in eV) to plot the cross section within - cross_sections : str, optional - Location of cross_sections.xml file. Default is None. - **kwargs - All keyword arguments are passed to - :func:`matplotlib.pyplot.figure`. - - Returns - ------- - fig : matplotlib.figure.Figure or None - If axis is None, then a Matplotlib Figure of the generated - macroscopic cross section will be returned. Otherwise, a value of - None will be returned as the figure and axes have already been - generated. - - """ - - from matplotlib import pyplot as plt - - E, data = self.calculate_xs(types, temperature, cross_sections) - - if divisor_types: - cv.check_length('divisor types', divisor_types, len(types), - len(types)) - Ediv, data_div = self.calculate_xs(divisor_types, temperature, - cross_sections) - - # Create a new union grid, interpolate data and data_div on to that - # grid, and then do the actual division - Enum = E[:] - E = np.union1d(Enum, Ediv) - data_new = np.zeros((len(types), len(E))) - - for line in range(len(types)): - data_new[line, :] = \ - np.divide(np.interp(E, Enum, data[line, :]), - np.interp(E, Ediv, data_div[line, :])) - if divisor_types[line] != 'unity': - types[line] = types[line] + ' / ' + divisor_types[line] - data = data_new - - # Generate the plot - if axis is None: - fig = plt.figure(**kwargs) - ax = fig.add_subplot(111) - else: - fig = None - ax = axis - # Set to loglog or semilogx depending on if we are plotting a data - # type which we expect to vary linearly - if set(types).issubset(PLOT_TYPES_LINEAR): - plot_func = ax.semilogx - else: - plot_func = ax.loglog - # Plot the data - for i in range(len(data)): - if np.sum(data[i, :]) > 0.: - plot_func(E, data[i, :], label=types[i]) - - ax.set_xlabel('Energy [eV]') - if divisor_types: - ax.set_ylabel('Macroscopic Data') - else: - ax.set_ylabel('Macroscopic Cross Section [1/cm]') - ax.legend(loc='best') - ax.set_xlim(energy_range) - if self.name is not None: - title = 'Macroscopic Cross Section for ' + self.name - ax.set_title(title) - - return fig - - def calculate_xs(self, types, temperature=294., cross_sections=None): - """Calculates continuous-energy macroscopic cross sections of a - requested type - - Parameters - ---------- - types : Iterable of values of PLOT_TYPES - The type of cross sections to calculate - temperature : float, optional - Temperature in Kelvin to plot. If not specified, a default - temperature of 294K will be plotted. Note that the nearest - temperature in the library for each nuclide will be used as opposed - to using any interpolation. - cross_sections : str, optional - Location of cross_sections.xml file. Default is None. - - Returns - ------- - energy_grid : numpy.array - Energies at which cross sections are calculated, in units of eV - data : numpy.ndarray - Macroscopic cross sections calculated at the energy grid described - by energy_grid - - """ - - # Check types - if cross_sections is not None: - cv.check_type('cross_sections', cross_sections, str) - if self.temperature is not None: - T = self.temperature - else: - cv.check_type('temperature', temperature, Real) - T = temperature - - # Load the library - library = openmc.data.DataLibrary.from_xml(cross_sections) - - # Expand elements in to nuclides with atomic densities - nuclides = self.get_nuclide_atom_densities(cross_sections) - - # For ease of processing split out nuc and nuc_density - nuc_densities = [nuclide[1][1] for nuclide in nuclides.items()] - - # Identify the nuclides which have S(a,b) data - sabs = {} - for nuclide in nuclides.items(): - sabs[nuclide[0].name] = None - for sab_name in self._sab: - sab = openmc.data.ThermalScattering.from_hdf5( - library.get_by_material(sab_name)['path']) - for nuc in sab.nuclides: - sabs[nuc] = library.get_by_material(sab_name)['path'] - - # Now we can create the data sets to be plotted - xs = [] - E = [] - for nuclide in nuclides.items(): - sab_tab = sabs[nuclide[0].name] - temp_E, temp_xs = nuclide[0].calculate_xs(types, T, sab_tab, - cross_sections) - E.append(temp_E) - xs.append(temp_xs) - - # Condense the data for every nuclide - # First create a union energy grid - energy_grid = E[0] - for n in range(1, len(E)): - energy_grid = np.union1d(energy_grid, E[n]) - - # Now we can combine all the nuclidic data - data = np.zeros((len(types), len(energy_grid))) - for line in range(len(types)): - if types[line] == 'unity': - data[line, :] = 1. - else: - for n in range(len(nuclides)): - data[line, :] += nuc_densities[n] * xs[n][line](energy_grid) - - return energy_grid, data - def _get_nuclide_xml(self, nuclide, distrib=False): xml_element = ET.Element("nuclide") xml_element.set("name", nuclide[0].name) diff --git a/openmc/nuclide.py b/openmc/nuclide.py index c42d4f8d5..03062ee0e 100644 --- a/openmc/nuclide.py +++ b/openmc/nuclide.py @@ -1,13 +1,8 @@ -from numbers import Integral, Real -import sys import warnings -import os from six import string_types import openmc.checkvalue as cv -from openmc.plot_data import * -import openmc.data class Nuclide(object): @@ -96,285 +91,3 @@ class Nuclide(object): raise ValueError(msg) self._scattering = scattering - - def plot_xs(self, types, divisor_types=None, temperature=294., axis=None, - energy_range=(1.E-5, 20.E6), sab_name=None, cross_sections=None, - **kwargs): - """Creates a figure of continuous-energy cross sections for this nuclide - - Parameters - ---------- - types : Iterable of values of PLOT_TYPES - The type of cross sections to include in the plot - divisor_types : Iterable of values of PLOT_TYPES, optional - Cross section types which will divide those produced by types - before plotting. A type of 'unity' can be used to effectively not - divide some types. - temperature : float, optional - Temperature in Kelvin to plot. If not specified, a default - temperature of 294K will be plotted. Note that the nearest - temperature in the library for each nuclide will be used as opposed - to using any interpolation. - axis : matplotlib.axes, optional - A previously generated axis to use for plotting. If not specified, - a new axis and figure will be generated. - energy_range : tuple of floats - Energy range (in eV) to plot the cross section within - sab_name : str, optional - Name of S(a,b) library to apply to MT=2 data when applicable. - cross_sections : str, optional - Location of cross_sections.xml file. Default is None. - **kwargs - All keyword arguments are passed to - :func:`matplotlib.pyplot.figure`. - - Returns - ------- - fig : matplotlib.figure.Figure - If axis is None, then a Matplotlib Figure of the generated - macroscopic cross section will be returned. Otherwise, a value of - None will be returned as the figure and axes have already been - generated. - - """ - - from matplotlib import pyplot as plt - - E, data = self.calculate_xs(types, temperature, sab_name, - cross_sections) - - if divisor_types: - cv.check_length('divisor types', divisor_types, len(types), - len(types)) - Ediv, data_div = self.calculate_xs(divisor_types, temperature, - sab_name, cross_sections) - - # Create a new union grid, interpolate data and data_div on to that - # grid, and then do the actual division - Enum = E[:] - E = np.union1d(Enum, Ediv) - data_new = [] - - for line in range(len(types)): - data_new.append(openmc.data.Combination([data[line], - data_div[line]], - [np.divide])) - if divisor_types[line] != 'unity': - types[line] = types[line] + ' / ' + divisor_types[line] - data = data_new - - # Generate the plot - if axis is None: - fig = plt.figure(**kwargs) - ax = fig.add_subplot(111) - else: - fig = None - ax = axis - # Set to loglog or semilogx depending on if we are plotting a data - # type which we expect to vary linearly - if set(types).issubset(PLOT_TYPES_LINEAR): - plot_func = ax.semilogx - else: - plot_func = ax.loglog - # Plot the data - for i in range(len(data)): - to_plot = data[i](E) - if np.sum(to_plot) > 0.: - plot_func(E, to_plot, label=types[i]) - - ax.set_xlabel('Energy [eV]') - if divisor_types: - ax.set_ylabel('Microscopic Data') - else: - ax.set_ylabel('Microscopic Cross Section [b]') - ax.legend(loc='best') - ax.set_xlim(energy_range) - if self.name is not None: - title = 'Microscopic Cross Section for ' + self.name - ax.set_title(title) - - return fig - - def calculate_xs(self, types, temperature=294., sab_name=None, - cross_sections=None): - """Calculates continuous-energy cross sections of a requested type - - Parameters - ---------- - types : Iterable of str or Integral - The type of cross sections to calculate; values can either be those - in openmc.PLOT_TYPES or integers which correspond to reaction - channel (MT) numbers. - temperature : float, optional - Temperature in Kelvin to plot. If not specified, a default - temperature of 294K will be plotted. Note that the nearest - temperature in the library for each nuclide will be used as opposed - to using any interpolation. - sab_name : str, optional - Name of S(a,b) library to apply to MT=2 data when applicable. - cross_sections : str, optional - Location of cross_sections.xml file. Default is None. - - Returns - ------- - energy_grid : numpy.array - Energies at which cross sections are calculated, in units of eV - data : numpy.ndarray - Cross sections calculated at the energy grid described by - energy_grid - - """ - - # Check types - if cross_sections is not None: - cv.check_type('cross_sections', cross_sections, str) - if sab_name: - cv.check_type('sab_name', sab_name, str) - - # Parse the types - mts = [] - ops = [] - yields = [] - for line in types: - if line in openmc.plot_data.PLOT_TYPES: - mts.append(PLOT_TYPES_MT[line]) - yields.append(PLOT_TYPES_YIELD[line]) - ops.append(PLOT_TYPES_OP[line]) - else: - # Not a built-in type, we have to parse it ourselves - cv.check_type('MT in types', line, Integral) - cv.check_greater_than('MT in types', line, 0) - mts.append((line,)) - yields.append((False,)) - ops.append(()) - - # Load the library - library = openmc.data.DataLibrary.from_xml(cross_sections) - - # Convert temperature to format needed for access in the library - cv.check_type('temperature', temperature, Real) - strT = "{}K".format(int(round(temperature))) - T = temperature - - # Now we can create the data sets to be plotted - energy_grid = [] - xs = [] - lib = library.get_by_material(self.name) - if lib is not None: - nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) - # Obtain the nearest temperature - if strT in nuc.temperatures: - nucT = strT - else: - data_Ts = nuc.temperatures - for t in range(len(data_Ts)): - # Take off the "K" and convert to a float - data_Ts[t] = float(data_Ts[t][:-1]) - min_delta = np.finfo(np.float64).max - closest_t = -1 - for t in data_Ts: - if abs(data_Ts[t] - T) < min_delta: - closest_t = t - nucT = "{}K".format(int(round(data_Ts[closest_t]))) - - # Prep S(a,b) data if needed - if sab_name: - sab = openmc.data.ThermalScattering.from_hdf5(sab_name) - # Obtain the nearest temperature - if strT in sab.temperatures: - sabT = strT - else: - data_Ts = sab.temperatures - for t in range(len(data_Ts)): - # Take off the "K" and convert to a float - data_Ts[t] = float(data_Ts[t][:-1]) - min_delta = np.finfo(np.float64).max - closest_t = -1 - for t in data_Ts: - if abs(data_Ts[t] - T) < min_delta: - closest_t = t - sabT = "{}K".format(int(round(data_Ts[closest_t]))) - - # Create an energy grid composed the S(a,b) and - # the nuclide's grid - grid = nuc.energy[nucT] - sab_Emax = 0. - sab_funcs = [] - if sab.elastic_xs: - elastic = sab.elastic_xs[sabT] - if isinstance(elastic, openmc.data.CoherentElastic): - grid = np.union1d(grid, elastic.bragg_edges) - if elastic.bragg_edges[-1] > sab_Emax: - sab_Emax = elastic.bragg_edges[-1] - elif isinstance(elastic, openmc.data.Tabulated1D): - grid = np.union1d(grid, elastic.x) - if elastic.x[-1] > sab_Emax: - sab_Emax = elastic.x[-1] - sab_funcs.append(elastic) - if sab.inelastic_xs: - inelastic = sab.inelastic_xs[sabT] - grid = np.union1d(grid, inelastic.x) - if inelastic.x[-1] > sab_Emax: - sab_Emax = inelastic.x[-1] - sab_funcs.append(inelastic) - energy_grid = grid - else: - energy_grid = nuc.energy[nucT] - - for i, mt_set in enumerate(mts): - # Get the reaction xs data from the nuclide - funcs = [] - op = ops[i] - for mt, yield_check in zip(mt_set, yields[i]): - if mt == 2: - if sab_name: - # Then we need to do a piece-wise function of - # The S(a,b) and non-thermal data - sab_sum = openmc.data.Sum(sab_funcs) - pw_funcs = openmc.data.Regions1D( - [sab_sum, nuc[mt].xs[nucT]], - [sab_Emax]) - funcs.append(pw_funcs) - else: - funcs.append(nuc[mt].xs[nucT]) - elif mt in nuc: - if yield_check: - found_it = False - for prod in nuc[mt].products: - if prod.particle == 'neutron' and \ - prod.emission_mode == 'total': - func = openmc.data.Combination( - [nuc[mt].xs[nucT], prod.yield_], - [np.multiply]) - funcs.append(func) - found_it = True - break - if not found_it: - for prod in nuc[mt].products: - if prod.particle == 'neutron' and \ - prod.emission_mode == 'prompt': - func = openmc.data.Combination( - [nuc[mt].xs[nucT], - prod.yield_], [np.multiply]) - funcs.append(func) - found_it = True - break - if not found_it: - # Assume the yield is 1 - funcs.append(nuc[mt].xs[nucT]) - else: - funcs.append(nuc[mt].xs[nucT]) - elif mt == UNITY_MT: - funcs.append(lambda x: 1.) - elif mt == XI_MT: - awr = nuc.atomic_weight_ratio - alpha = ((awr - 1.) / (awr + 1.))**2 - xi = 1. + alpha * np.log(alpha) / (1. - alpha) - funcs.append(lambda x: xi) - else: - funcs.append(lambda x: 0.) - xs.append(openmc.data.Combination(funcs, op)) - else: - raise ValueError(nuclide[0] + " not in library") - - return energy_grid, xs diff --git a/openmc/plot_data.py b/openmc/plot_data.py deleted file mode 100644 index 1efeda00c..000000000 --- a/openmc/plot_data.py +++ /dev/null @@ -1,78 +0,0 @@ -import numpy as np - -# Supported keywords for material xs plotting -PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', - 'absorption', 'capture', 'nu-fission', 'nu-scatter', 'unity', - 'slowing-down power', 'damage'] - -# Special MT values -UNITY_MT = -1 -XI_MT = -2 - -# MTs to combine to generate associated plot_types -PLOT_TYPES_MT = {'total': (2, 3,), - 'scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, - 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, - 153, 154, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 183, 184, 190, 194, 196, 198, 199, 200, - 875, 891), - 'elastic': (2,), - 'inelastic': (4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, - 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, - 153, 154, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 183, 184, 190, 194, 196, 198, 199, 200, - 875, 891), - 'fission': (18,), - 'absorption': (27,), 'capture': (101,), - 'nu-fission': (18,), - 'nu-scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, - 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, - 153, 154, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 183, 184, 190, 194, 196, 198, 199, 200, - 875, 891), - 'unity': (UNITY_MT,), - 'slowing-down power': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, - 29, 30, 32, 33, 34, 35, 36, 37, 41, 42, - 44, 45, 152, 153, 154, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 179, 180, 181, 183, - 184, 190, 194, 196, 198, 199, 200, 875, - 891, XI_MT), - 'damage': (444,)} -# Operations to use when combining MTs the first np.add is used in reference -# to zero -PLOT_TYPES_OP = {'total': (np.add,), - 'scatter': (np.add,) * (len(PLOT_TYPES_MT['scatter']) - 1), - 'elastic': (), - 'inelastic': (np.add,) * (len(PLOT_TYPES_MT['inelastic']) - 1), - 'fission': (), 'absorption': (), - 'capture': (), 'nu-fission': (), - 'nu-scatter': (np.add,) * (len(PLOT_TYPES_MT['nu-scatter']) - 1), - 'unity': (), - 'slowing-down power': - (np.add,) * (len(PLOT_TYPES_MT['slowing-down power']) - 2) + (np.multiply,), - 'damage': ()} - -# Whether or not to multiply the reaction by the yield as well -PLOT_TYPES_YIELD = {'total': (False, False), - 'scatter': (False,) * len(PLOT_TYPES_MT['scatter']), - 'elastic': (False,), - 'inelastic': (False,) * len(PLOT_TYPES_MT['inelastic']), - 'fission': (False,), 'absorption': (False,), - 'capture': (False,), 'nu-fission': (True,), - 'nu-scatter': (True,) * len(PLOT_TYPES_MT['nu-scatter']), - 'unity': (False,), - 'slowing-down power': - (True,) * len(PLOT_TYPES_MT['slowing-down power']), - 'damage': (False,)} - -# Types of plots to plot linearly in y -PLOT_TYPES_LINEAR = {'nu-fission / fission', 'nu-scatter / scatter', - 'nu-fission / absorption', 'fission / absorption'} diff --git a/openmc/plotter.py b/openmc/plotter.py new file mode 100644 index 000000000..0e604c8c1 --- /dev/null +++ b/openmc/plotter.py @@ -0,0 +1,604 @@ +from numbers import Integral, Real + +import numpy as np +from matplotlib import pyplot as plt + +import openmc.checkvalue as cv +import openmc.data + +# Supported keywords for material xs plotting +PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', + 'absorption', 'capture', 'nu-fission', 'nu-scatter', 'unity', + 'slowing-down power', 'damage'] + +# Special MT values +UNITY_MT = -1 +XI_MT = -2 + +# MTs to combine to generate associated plot_types +PLOT_TYPES_MT = {'total': (2, 3,), + 'scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, + 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, + 153, 154, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 183, 184, 190, 194, 196, 198, 199, 200, + 875, 891), + 'elastic': (2,), + 'inelastic': (4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, + 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, + 153, 154, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 183, 184, 190, 194, 196, 198, 199, 200, + 875, 891), + 'fission': (18,), + 'absorption': (27,), 'capture': (101,), + 'nu-fission': (18,), + 'nu-scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, + 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, + 153, 154, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 183, 184, 190, 194, 196, 198, 199, 200, + 875, 891), + 'unity': (UNITY_MT,), + 'slowing-down power': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, + 29, 30, 32, 33, 34, 35, 36, 37, 41, 42, + 44, 45, 152, 153, 154, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 183, + 184, 190, 194, 196, 198, 199, 200, 875, + 891, XI_MT), + 'damage': (444,)} +# Operations to use when combining MTs the first np.add is used in reference +# to zero +PLOT_TYPES_OP = {'total': (np.add,), + 'scatter': (np.add,) * (len(PLOT_TYPES_MT['scatter']) - 1), + 'elastic': (), + 'inelastic': (np.add,) * (len(PLOT_TYPES_MT['inelastic']) - 1), + 'fission': (), 'absorption': (), + 'capture': (), 'nu-fission': (), + 'nu-scatter': (np.add,) * (len(PLOT_TYPES_MT['nu-scatter']) - 1), + 'unity': (), + 'slowing-down power': + (np.add,) * (len(PLOT_TYPES_MT['slowing-down power']) - 2) + (np.multiply,), + 'damage': ()} + +# Whether or not to multiply the reaction by the yield as well +PLOT_TYPES_YIELD = {'total': (False, False), + 'scatter': (False,) * len(PLOT_TYPES_MT['scatter']), + 'elastic': (False,), + 'inelastic': (False,) * len(PLOT_TYPES_MT['inelastic']), + 'fission': (False,), 'absorption': (False,), + 'capture': (False,), 'nu-fission': (True,), + 'nu-scatter': (True,) * len(PLOT_TYPES_MT['nu-scatter']), + 'unity': (False,), + 'slowing-down power': + (True,) * len(PLOT_TYPES_MT['slowing-down power']), + 'damage': (False,)} + +# Types of plots to plot linearly in y +PLOT_TYPES_LINEAR = {'nu-fission / fission', 'nu-scatter / scatter', + 'nu-fission / absorption', 'fission / absorption'} + + +def plot_xs(this, types, divisor_types=None, temperature=294., axis=None, + energy_range=(1.E-5, 20.E6), sab_name=None, cross_sections=None, + enrichment=None, **kwargs): + """Creates a figure of continuous-energy cross sections for this item + + Parameters + ---------- + this : openmc.Element, openmc.Nuclide, or openmc.Material + Object to source data from + types : Iterable of values of PLOT_TYPES + The type of cross sections to include in the plot. + divisor_types : Iterable of values of PLOT_TYPES, optional + Cross section types which will divide those produced by types + before plotting. A type of 'unity' can be used to effectively not + divide some types. + temperature : float, optional + Temperature in Kelvin to plot. If not specified, a default + temperature of 294K will be plotted. Note that the nearest + temperature in the library for each nuclide will be used as opposed + to using any interpolation. + axis : matplotlib.axes, optional + A previously generated axis to use for plotting. If not specified, + a new axis and figure will be generated. + energy_range : tuple of floats + Energy range (in eV) to plot the cross section within + sab_name : str, optional + Name of S(a,b) library to apply to MT=2 data when applicable; only used + for items which are instances of openmc.Element or openmc.Nuclide + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. + enrichment : float, optional + Enrichment for U235 in weight percent. For example, input 4.95 for + 4.95 weight percent enriched U. Default is None. This is only used for + items which are instances of openmc.Element + **kwargs + All keyword arguments are passed to + :func:`matplotlib.pyplot.figure`. + + Returns + ------- + fig : matplotlib.figure.Figure + If axis is None, then a Matplotlib Figure of the generated + cross section will be returned. Otherwise, a value of + None will be returned as the figure and axes have already been + generated. + + """ + + if isinstance(this, openmc.Nuclide): + data_type = 'nuclide' + elif isinstance(this, openmc.Element): + data_type = 'element' + elif isinstance(this, openmc.Material): + data_type = 'material' + else: + raise TypeError("Invalid type for plotting") + + E, data = calculate_xs(this, types, temperature, sab_name, cross_sections) + + if divisor_types: + cv.check_length('divisor types', divisor_types, len(types), + len(types)) + Ediv, data_div = calculate_xs(this, divisor_types, temperature, + sab_name, cross_sections) + + # Create a new union grid, interpolate data and data_div on to that + # grid, and then do the actual division + Enum = E[:] + E = np.union1d(Enum, Ediv) + if data_type == 'nuclide': + data_new = [] + else: + data_new = np.zeros((len(types), len(E))) + + for line in range(len(types)): + if data_type == 'nuclide': + data_new.append(openmc.data.Combination([data[line], + data_div[line]], + [np.divide])) + else: + data_new[line, :] = \ + np.divide(np.interp(E, Enum, data[line, :]), + np.interp(E, Ediv, data_div[line, :])) + if divisor_types[line] != 'unity': + types[line] = types[line] + ' / ' + divisor_types[line] + data = data_new + + # Generate the plot + if axis is None: + fig = plt.figure(**kwargs) + ax = fig.add_subplot(111) + else: + fig = None + ax = axis + # Set to loglog or semilogx depending on if we are plotting a data + # type which we expect to vary linearly + if set(types).issubset(PLOT_TYPES_LINEAR): + plot_func = ax.semilogx + else: + plot_func = ax.loglog + # Plot the data + for i in range(len(data)): + if data_type == 'nuclide': + to_plot = data[i](E) + else: + to_plot = data[i, :] + if np.sum(to_plot) > 0.: + plot_func(E, to_plot, label=types[i]) + + ax.set_xlabel('Energy [eV]') + if divisor_types: + ax.set_ylabel('Data') + else: + ax.set_ylabel('Cross Section [b]') + ax.legend(loc='best') + ax.set_xlim(energy_range) + if this.name is not None: + title = 'Cross Section for ' + this.name + ax.set_title(title) + + return fig + + +def calculate_xs(this, types, temperature=294., sab_name=None, + cross_sections=None, enrichment=None): + """Calculates continuous-energy cross sections of a requested type + + Parameters + ---------- + this : openmc.Element, openmc.Nuclide, or openmc.Material + Object to source data from + types : Iterable of values of PLOT_TYPES + The type of cross sections to calculate + temperature : float, optional + Temperature in Kelvin to plot. If not specified, a default + temperature of 294K will be plotted. Note that the nearest + temperature in the library for each nuclide will be used as opposed + to using any interpolation. + sab_name : str, optional + Name of S(a,b) library to apply to MT=2 data when applicable. + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. + enrichment : float, optional + Enrichment for U235 in weight percent. For example, input 4.95 for + 4.95 weight percent enriched U. Default is None + (natural composition). + + Returns + ------- + energy_grid : numpy.array + Energies at which cross sections are calculated, in units of eV + data : numpy.ndarray + Cross sections calculated at the energy grid described by energy_grid + + """ + + # Check types + cv.check_type('temperature', temperature, Real) + if sab_name: + cv.check_type('sab_name', sab_name, str) + if enrichment: + cv.check_type('enrichment', enrichment, Real) + + if isinstance(this, openmc.Nuclide): + energy_grid, data = _calculate_xs_nuclide(this, types, temperature, + sab_name, cross_sections) + elif isinstance(this, openmc.Element): + energy_grid, data = _calculate_xs_element(this, types, temperature, + sab_name, cross_sections, + enrichment) + elif isinstance(this, openmc.Material): + energy_grid, data = _calculate_xs_material(this, types, temperature, + cross_sections) + else: + raise TypeError("Invalid type") + + return energy_grid, data + + +def _calculate_xs_element(this, types, temperature=294., sab_name=None, + cross_sections=None, enrichment=None): + """Calculates continuous-energy cross sections of a requested type + + Parameters + ---------- + this : openmc.Element + Element object to source data from + types : Iterable of values of PLOT_TYPES + The type of cross sections to calculate + temperature : float, optional + Temperature in Kelvin to plot. If not specified, a default + temperature of 294K will be plotted. Note that the nearest + temperature in the library for each nuclide will be used as opposed + to using any interpolation. + sab_name : str, optional + Name of S(a,b) library to apply to MT=2 data when applicable. + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. + enrichment : float, optional + Enrichment for U235 in weight percent. For example, input 4.95 for + 4.95 weight percent enriched U. Default is None + (natural composition). + + Returns + ------- + energy_grid : numpy.array + Energies at which cross sections are calculated, in units of eV + data : numpy.ndarray + Macroscopic cross sections calculated at the energy grid described + by energy_grid + + """ + + # Load the library + library = openmc.data.DataLibrary.from_xml(cross_sections) + + # Expand elements in to nuclides with atomic densities + nuclides = this.expand(100., 'ao', enrichment=enrichment, + cross_sections=cross_sections) + + # For ease of processing split out nuc and nuc_density + nuc_fractions = [nuclide[1] for nuclide in nuclides] + + # Identify the nuclides which have S(a,b) data + sabs = {} + for nuclide in nuclides: + sabs[nuclide[0].name] = None + if sab_name: + sab = openmc.data.ThermalScattering.from_hdf5(sab_name) + for nuc in sab.nuclides: + sabs[nuc] = library.get_by_material(sab_name)['path'] + + # Now we can create the data sets to be plotted + xs = [] + E = [] + for nuclide in nuclides: + sab_tab = sabs[nuclide[0].name] + temp_E, temp_xs = calculate_xs(nuclide[0], types, temperature, sab_tab, + cross_sections) + E.append(temp_E) + xs.append(temp_xs) + + # Condense the data for every nuclide + # First create a union energy grid + energy_grid = E[0] + for n in range(1, len(E)): + energy_grid = np.union1d(energy_grid, E[n]) + + # Now we can combine all the nuclidic data + data = np.zeros((len(types), len(energy_grid))) + for line in range(len(types)): + if types[line] == 'unity': + data[line, :] = 1. + else: + for n in range(len(nuclides)): + data[line, :] += nuc_fractions[n] * xs[n][line](energy_grid) + + return energy_grid, data + + +def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, + cross_sections=None): + """Calculates continuous-energy cross sections of a requested type + + Parameters + ---------- + this : openmc.Nuclide + Nuclide object to source data from + types : Iterable of str or Integral + The type of cross sections to calculate; values can either be those + in openmc.PLOT_TYPES or integers which correspond to reaction + channel (MT) numbers. + temperature : float, optional + Temperature in Kelvin to plot. If not specified, a default + temperature of 294K will be plotted. Note that the nearest + temperature in the library for each nuclide will be used as opposed + to using any interpolation. + sab_name : str, optional + Name of S(a,b) library to apply to MT=2 data when applicable. + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. + + Returns + ------- + energy_grid : numpy.array + Energies at which cross sections are calculated, in units of eV + data : numpy.ndarray + Cross sections calculated at the energy grid described by + energy_grid + + """ + + # Parse the types + mts = [] + ops = [] + yields = [] + for line in types: + if line in PLOT_TYPES: + mts.append(PLOT_TYPES_MT[line]) + yields.append(PLOT_TYPES_YIELD[line]) + ops.append(PLOT_TYPES_OP[line]) + else: + # Not a built-in type, we have to parse it ourselves + cv.check_type('MT in types', line, Integral) + cv.check_greater_than('MT in types', line, 0) + mts.append((line,)) + yields.append((False,)) + ops.append(()) + + # Load the library + library = openmc.data.DataLibrary.from_xml(cross_sections) + + # Convert temperature to format needed for access in the library + strT = "{}K".format(int(round(temperature))) + T = temperature + + # Now we can create the data sets to be plotted + energy_grid = [] + xs = [] + lib = library.get_by_material(this.name) + if lib is not None: + nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) + # Obtain the nearest temperature + if strT in nuc.temperatures: + nucT = strT + else: + data_Ts = nuc.temperatures + for t in range(len(data_Ts)): + # Take off the "K" and convert to a float + data_Ts[t] = float(data_Ts[t][:-1]) + min_delta = np.finfo(np.float64).max + closest_t = -1 + for t in data_Ts: + if abs(data_Ts[t] - T) < min_delta: + closest_t = t + nucT = "{}K".format(int(round(data_Ts[closest_t]))) + + # Prep S(a,b) data if needed + if sab_name: + sab = openmc.data.ThermalScattering.from_hdf5(sab_name) + # Obtain the nearest temperature + if strT in sab.temperatures: + sabT = strT + else: + data_Ts = sab.temperatures + for t in range(len(data_Ts)): + # Take off the "K" and convert to a float + data_Ts[t] = float(data_Ts[t][:-1]) + min_delta = np.finfo(np.float64).max + closest_t = -1 + for t in data_Ts: + if abs(data_Ts[t] - T) < min_delta: + closest_t = t + sabT = "{}K".format(int(round(data_Ts[closest_t]))) + + # Create an energy grid composed the S(a,b) and + # the nuclide's grid + grid = nuc.energy[nucT] + sab_Emax = 0. + sab_funcs = [] + if sab.elastic_xs: + elastic = sab.elastic_xs[sabT] + if isinstance(elastic, openmc.data.CoherentElastic): + grid = np.union1d(grid, elastic.bragg_edges) + if elastic.bragg_edges[-1] > sab_Emax: + sab_Emax = elastic.bragg_edges[-1] + elif isinstance(elastic, openmc.data.Tabulated1D): + grid = np.union1d(grid, elastic.x) + if elastic.x[-1] > sab_Emax: + sab_Emax = elastic.x[-1] + sab_funcs.append(elastic) + if sab.inelastic_xs: + inelastic = sab.inelastic_xs[sabT] + grid = np.union1d(grid, inelastic.x) + if inelastic.x[-1] > sab_Emax: + sab_Emax = inelastic.x[-1] + sab_funcs.append(inelastic) + energy_grid = grid + else: + energy_grid = nuc.energy[nucT] + + for i, mt_set in enumerate(mts): + # Get the reaction xs data from the nuclide + funcs = [] + op = ops[i] + for mt, yield_check in zip(mt_set, yields[i]): + if mt == 2: + if sab_name: + # Then we need to do a piece-wise function of + # The S(a,b) and non-thermal data + sab_sum = openmc.data.Sum(sab_funcs) + pw_funcs = openmc.data.Regions1D( + [sab_sum, nuc[mt].xs[nucT]], + [sab_Emax]) + funcs.append(pw_funcs) + else: + funcs.append(nuc[mt].xs[nucT]) + elif mt in nuc: + if yield_check: + found_it = False + for prod in nuc[mt].products: + if prod.particle == 'neutron' and \ + prod.emission_mode == 'total': + func = openmc.data.Combination( + [nuc[mt].xs[nucT], prod.yield_], + [np.multiply]) + funcs.append(func) + found_it = True + break + if not found_it: + for prod in nuc[mt].products: + if prod.particle == 'neutron' and \ + prod.emission_mode == 'prompt': + func = openmc.data.Combination( + [nuc[mt].xs[nucT], + prod.yield_], [np.multiply]) + funcs.append(func) + found_it = True + break + if not found_it: + # Assume the yield is 1 + funcs.append(nuc[mt].xs[nucT]) + else: + funcs.append(nuc[mt].xs[nucT]) + elif mt == UNITY_MT: + funcs.append(lambda x: 1.) + elif mt == XI_MT: + awr = nuc.atomic_weight_ratio + alpha = ((awr - 1.) / (awr + 1.))**2 + xi = 1. + alpha * np.log(alpha) / (1. - alpha) + funcs.append(lambda x: xi) + else: + funcs.append(lambda x: 0.) + xs.append(openmc.data.Combination(funcs, op)) + else: + raise ValueError(this.name + " not in library") + + return energy_grid, xs + + +def _calculate_xs_material(this, types, temperature=294., cross_sections=None): + """Calculates continuous-energy macroscopic cross sections of a + requested type + + Parameters + ---------- + this : openmc.Material + Material object to source data from + types : Iterable of values of PLOT_TYPES + The type of cross sections to calculate + temperature : float, optional + Temperature in Kelvin to plot. If not specified, a default + temperature of 294K will be plotted. Note that the nearest + temperature in the library for each nuclide will be used as opposed + to using any interpolation. + cross_sections : str, optional + Location of cross_sections.xml file. Default is None. + + Returns + ------- + energy_grid : numpy.array + Energies at which cross sections are calculated, in units of eV + data : numpy.ndarray + Macroscopic cross sections calculated at the energy grid described + by energy_grid + + """ + + if this.temperature is not None: + T = this.temperature + else: + T = temperature + + # Load the library + library = openmc.data.DataLibrary.from_xml(cross_sections) + + # Expand elements in to nuclides with atomic densities + nuclides = this.get_nuclide_atom_densities(cross_sections) + + # For ease of processing split out nuc and nuc_density + nuc_densities = [nuclide[1][1] for nuclide in nuclides.items()] + + # Identify the nuclides which have S(a,b) data + sabs = {} + for nuclide in nuclides.items(): + sabs[nuclide[0].name] = None + for sab_name in this._sab: + sab = openmc.data.ThermalScattering.from_hdf5( + library.get_by_material(sab_name)['path']) + for nuc in sab.nuclides: + sabs[nuc] = library.get_by_material(sab_name)['path'] + + # Now we can create the data sets to be plotted + xs = [] + E = [] + for nuclide in nuclides.items(): + sab_tab = sabs[nuclide[0].name] + temp_E, temp_xs = calculate_xs(nuclide[0], types, T, sab_tab, + cross_sections) + E.append(temp_E) + xs.append(temp_xs) + + # Condense the data for every nuclide + # First create a union energy grid + energy_grid = E[0] + for n in range(1, len(E)): + energy_grid = np.union1d(energy_grid, E[n]) + + # Now we can combine all the nuclidic data + data = np.zeros((len(types), len(energy_grid))) + for line in range(len(types)): + if types[line] == 'unity': + data[line, :] = 1. + else: + for n in range(len(nuclides)): + data[line, :] += nuc_densities[n] * xs[n][line](energy_grid) + + return energy_grid, data From ba5a6714a23e9fd6f1444a9b60e50f4c2537461a Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 11 Nov 2016 22:13:14 -0500 Subject: [PATCH 20/60] Forgot enrichment --- openmc/plotter.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openmc/plotter.py b/openmc/plotter.py index 0e604c8c1..4201abf9d 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -141,13 +141,14 @@ def plot_xs(this, types, divisor_types=None, temperature=294., axis=None, else: raise TypeError("Invalid type for plotting") - E, data = calculate_xs(this, types, temperature, sab_name, cross_sections) + E, data = calculate_xs(this, types, temperature, sab_name, cross_sections, + enrichment) if divisor_types: cv.check_length('divisor types', divisor_types, len(types), len(types)) Ediv, data_div = calculate_xs(this, divisor_types, temperature, - sab_name, cross_sections) + sab_name, cross_sections, enrichment) # Create a new union grid, interpolate data and data_div on to that # grid, and then do the actual division From 00268a3c55b3070d55d6ec4ce253b12326cde647 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 11 Nov 2016 22:18:12 -0500 Subject: [PATCH 21/60] Fixed Travis failure: moved matplotlib import to plot_xs instead of at the module level --- openmc/plotter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openmc/plotter.py b/openmc/plotter.py index 4201abf9d..09b7b1bf8 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -1,7 +1,6 @@ from numbers import Integral, Real import numpy as np -from matplotlib import pyplot as plt import openmc.checkvalue as cv import openmc.data @@ -132,6 +131,8 @@ def plot_xs(this, types, divisor_types=None, temperature=294., axis=None, """ + from matplotlib import pyplot as plt + if isinstance(this, openmc.Nuclide): data_type = 'nuclide' elif isinstance(this, openmc.Element): From 50a40795976ea5db3a7e34110b9a105115800b5c Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 12 Nov 2016 09:40:07 -0500 Subject: [PATCH 22/60] minor changes --- openmc/mgxs/mgxs.py | 4 ++-- openmc/mgxs_library.py | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 2fb7459b0..324cbe56c 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -3776,10 +3776,10 @@ class ScatterMatrixXS(MatrixMGXS): if order_groups == 'increasing': xs = xs[:, ::-1, ::-1, ...] - # Place the histogram bins before the outgoing group index + # Place the histogram bins before the incoming groups if self.scatter_format == 'histogram': - xs = np.swapaxes(xs, 3, 1) xs = np.swapaxes(xs, 3, 2) + xs = np.swapaxes(xs, 2, 1) if squeeze: xs = np.squeeze(xs) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 290b25424..e3af59632 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1738,11 +1738,18 @@ class XSdata(object): 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] + if self.scatter_format == 'legendre': + nz = np.nonzero(self._scatter_matrix[i][0, g_in, :]) + elif self.scatter_format == 'histogram': + nz = np.nonzero(np.sum( + self._scatter_matrix[i][:, g_in, :], axis=0)) + if len(nz[0]) == 0: + g_out_bounds[g_in, 0] = 0 + g_out_bounds[g_in, 1] = 0 + else: + 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] From 2455388315919dca1080fd060d8e2765eea5fd92 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 13 Nov 2016 13:29:45 -0500 Subject: [PATCH 23/60] Fixed array ordering of scattering matrix --- openmc/mgxs/library.py | 25 +++++++++++++++++----- openmc/mgxs/mgxs.py | 17 ++++++++------- openmc/mgxs_library.py | 43 ++++++++++++++++++++------------------ scripts/openmc-update-mgxs | 40 +++++++++++++++++++++++------------ src/mgxs_header.F90 | 6 +++--- src/scattdata_header.F90 | 4 ++-- 6 files changed, 84 insertions(+), 51 deletions(-) diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 05cabf496..97bb6d96b 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -287,7 +287,7 @@ class Library(object): def by_nuclide(self, by_nuclide): cv.check_type('by_nuclide', by_nuclide, bool) - if by_nuclide == True and self.domain_type == 'mesh': + if by_nuclide and self.domain_type == 'mesh': raise ValueError('Unable to create MGXS library by nuclide with ' 'mesh domain') @@ -297,7 +297,7 @@ class Library(object): def domain_type(self, domain_type): cv.check_value('domain type', domain_type, openmc.mgxs.DOMAIN_TYPES) - if self.by_nuclide == True and domain_type == 'mesh': + if self.by_nuclide and domain_type == 'mesh': raise ValueError('Unable to create MGXS library by nuclide with ' 'mesh domain') @@ -372,7 +372,15 @@ class Library(object): @scatter_format.setter def scatter_format(self, scatter_format): - cv.check_value('scatter_format', scatter_format, openmc.mgxs.MU_TREATMENTS) + cv.check_value('scatter_format', scatter_format, + openmc.mgxs.MU_TREATMENTS) + + if scatter_format == 'histogram' and self.correction == 'P0': + msg = 'The P0 correction will be ignored since the ' \ + 'scatter format is set to histogram' + warn(msg) + self.correction = None + self._scatter_format = scatter_format @legendre_order.setter @@ -405,6 +413,13 @@ class Library(object): msg = 'The histogram bins will be ignored since the ' \ 'scatter format is set to legendre' warn(msg) + elif self.scatter_format == 'histogram': + if self.correction == 'P0': + msg = 'The P0 correction will be ignored since ' \ + 'a histogram representation of the scattering '\ + 'kernel is requested' + warn(msg, RuntimeWarning) + self.correction = None self._histogram_bins = histogram_bins @@ -471,7 +486,7 @@ class Library(object): mgxs.delayed_groups = None else: delayed_groups \ - = list(range(1,self.num_delayed_groups+1)) + = list(range(1, self.num_delayed_groups + 1)) mgxs.delayed_groups = delayed_groups # If a tally trigger was specified, add it to the MGXS @@ -1351,7 +1366,7 @@ class Library(object): 'scattering matrix is not provided.') # Total or transport can be present, but if using # self.correction=="P0", then we should use transport. - if (((self.correction is "P0") and + if (((self.correction == "P0") and ('nu-transport' not in self.mgxs_types))): error_flag = True warn('A "nu-transport" MGXS type is required since a "P0" ' diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 324cbe56c..036feac74 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -3775,15 +3775,16 @@ class ScatterMatrixXS(MatrixMGXS): # tally data is stored in order of increasing energies if order_groups == 'increasing': xs = xs[:, ::-1, ::-1, ...] - - # Place the histogram bins before the incoming groups - if self.scatter_format == 'histogram': - xs = np.swapaxes(xs, 3, 2) - xs = np.swapaxes(xs, 2, 1) - + # import pdb; pdb.set_trace() if squeeze: - xs = np.squeeze(xs) - xs = np.atleast_2d(xs) + # We want to squeeze out everything but the in_groups, out_groups, + # and, if needed, num_mu_bins dimension. These must not be squeezed + # so 1-group problems have the correct shape. + if self.scatter_format == 'histogram': + axes = (5, 4, 0) + else: + axes = (4, 3, 0) + xs = np.squeeze(xs, axis=axes) return xs diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index e3af59632..5256dd102 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -15,7 +15,7 @@ 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]", "[G][DG]", +_XS_SHAPES = ["[G][G'][Order]", "[G]", "[G']", "[G][G']", "[DG]", "[G][DG]", "[G'][DG]"] @@ -134,7 +134,7 @@ class XSdata(object): 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][G'][Order]: scatter_matrix [G]: total, absorption, fission, kappa_fission, nu_fission, prompt_nu_fission, inverse_velocity @@ -298,9 +298,9 @@ class XSdata(object): 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) + self._xs_shapes["[G][G'][Order]"] \ + = (self.energy_groups.num_groups, + self.energy_groups.num_groups, self.num_orders) # If representation is by angle prepend num polar and num azim if self.representation == 'angle': @@ -718,7 +718,7 @@ class XSdata(object): """ # Get the accepted shapes for this xs - shapes = [self.xs_shapes["[Order][G][G']"]] + shapes = [self.xs_shapes["[G][G'][Order]"]] # Convert to a numpy array so we can easily get the shape for checking scatter = np.asarray(scatter) @@ -1534,11 +1534,10 @@ class XSdata(object): if self.representation == 'isotropic': if self.scatter_format == 'legendre': # Get the scattering orders in the outermost dimension - self._scatter_matrix[i] = np.zeros((self.num_orders, - self.energy_groups.num_groups, - self.energy_groups.num_groups)) + self._scatter_matrix[i] = \ + np.zeros(self.xs_shapes["[G][G'][Order]"]) for moment in range(self.num_orders): - self._scatter_matrix[i][moment, :, :] = \ + self._scatter_matrix[i][:, :, moment] = \ scatter.get_xs(nuclides=nuclide, xs_type=xs_type, moment=moment, subdomains=subdomain) else: @@ -1657,7 +1656,7 @@ 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']") + grp.attrs['scatter_shape'] = np.string_("[G][G'][Order]") if self.scatter_format is not None: grp.attrs['scatter_format'] = np.string_(self.scatter_format) if self.order is not None: @@ -1736,14 +1735,13 @@ 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): if self.scatter_format == 'legendre': - nz = np.nonzero(self._scatter_matrix[i][0, g_in, :]) + nz = np.nonzero(self._scatter_matrix[i][g_in, :, 0]) elif self.scatter_format == 'histogram': nz = np.nonzero(np.sum( - self._scatter_matrix[i][:, g_in, :], axis=0)) + self._scatter_matrix[i][g_in, :, :], axis=1)) if len(nz[0]) == 0: g_out_bounds[g_in, 0] = 0 g_out_bounds[g_in, 1] = 0 @@ -1757,8 +1755,8 @@ class XSdata(object): for g_in in range(G): for g_out in range(g_out_bounds[g_in, 0], g_out_bounds[g_in, 1] + 1): - for l in range(len(matrix[:, g_in, g_out])): - flat_scatt.append(matrix[l, g_in, g_out]) + for l in range(len(matrix[g_in, g_out, :])): + flat_scatt.append(matrix[g_in, g_out, l]) # And write it. scatt_grp = xs_grp.create_group('scatter_data') @@ -1767,7 +1765,6 @@ class XSdata(object): # Repeat for multiplicity if self._multiplicity_matrix[i] is not None: - # Now create the flattened scatter matrix array matrix = self._multiplicity_matrix[i][:, :] flat_mult = [] @@ -1793,7 +1790,13 @@ class XSdata(object): for p in range(Np): for a in range(Na): for g_in in range(G): - matrix = self._scatter_matrix[i][p, a, 0, g_in, :] + if self.scatter_format == 'legendre': + matrix = \ + self._scatter_matrix[i][p, a, g_in, :, 0] + elif self.scatter_format == 'histogram': + matrix = \ + np.sum(self._scatter_matrix[i][p, a, g_in, :, :], + axis=1) 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] @@ -1806,8 +1809,8 @@ class XSdata(object): for g_in in range(G): for g_out in range(g_out_bounds[p, a, g_in, 0], g_out_bounds[p, a, g_in, 1] + 1): - for l in range(len(matrix[:, g_in, g_out])): - flat_scatt.append(matrix[l, g_in, g_out]) + for l in range(len(matrix[g_in, g_out, :])): + flat_scatt.append(matrix[g_in, g_out, l]) # And write it. scatt_grp = xs_grp.create_group('scatter_data') diff --git a/scripts/openmc-update-mgxs b/scripts/openmc-update-mgxs index cad48d0e3..54a553f77 100755 --- a/scripts/openmc-update-mgxs +++ b/scripts/openmc-update-mgxs @@ -23,12 +23,10 @@ optional arguments: from __future__ import print_function import os -from shutil import move import warnings import xml.etree.ElementTree as ET import argparse -import h5py import numpy as np import openmc.mgxs_library @@ -51,7 +49,7 @@ def parse_args(): if args['output'] == '': filename = args['input'].name - extension = filenameos.path.splitext() + extension = os.path.splitext(filename) if extension == '.xml': filename = filename[:filename.rfind('.')] + '.h5' args['output'] = filename @@ -84,6 +82,8 @@ if __name__ == '__main__': temp = tree.find('group_structure').text.strip() temp = np.array(temp.split()) group_structure = temp.astype(np.float) + # Convert from MeV to eV + group_structure *= 1.e6 energy_groups = openmc.mgxs.EnergyGroups(group_structure) temp = tree.find('inverse-velocity') if temp is not None: @@ -103,7 +103,7 @@ if __name__ == '__main__': temperature = get_data(xsdata_elem, 'kT') if temperature is not None: temperature = \ - float(temperature) / openmc.data.K_BOLTZMANN + float(temperature) / openmc.data.K_BOLTZMANN * 1.E6 else: temperature = 294. temperatures = [temperature] @@ -163,7 +163,7 @@ if __name__ == '__main__': if temp is not None: temp = np.array(temp.split(), dtype=float) total = temp.astype(np.float) - total.shape = xsd[i].vector_shape + total.shape = xsd[i].xs_shapes['[G]'] xsd[i].set_total(total, temperature) if inverse_velocity is not None: @@ -172,41 +172,55 @@ if __name__ == '__main__': temp = get_data(xsdata_elem, 'absorption') temp = np.array(temp.split()) absorption = temp.astype(np.float) - absorption.shape = xsd[i].vector_shape + absorption.shape = xsd[i].xs_shapes['[G]'] xsd[i].set_absorption(absorption, temperature) temp = get_data(xsdata_elem, 'scatter') temp = np.array(temp.split()) scatter = temp.astype(np.float) - scatter.shape = xsd[i].pn_matrix_shape + # This is now a flattened-array of something that started with a + # shape of [Order][G][G']; we need to unflatten and then switch the + # ordering + in_shape = (order_dim, energy_groups.num_groups, + energy_groups.num_groups) + if representation == 'angle': + in_shape = (n_pol, n_azi) + in_shape + scatter.shape = in_shape + scatter = np.swapaxes(scatter, 2, 3) + scatter = np.swapaxes(scatter, 3, 4) + else: + scatter.shape = in_shape + scatter = np.swapaxes(scatter, 0, 1) + scatter = np.swapaxes(scatter, 1, 2) + xsd[i].set_scatter_matrix(scatter, temperature) temp = get_data(xsdata_elem, 'multiplicity') if temp is not None: temp = np.array(temp.split()) multiplicity = temp.astype(np.float) - multiplicity.shape = xsd[i].matrix_shape + multiplicity.shape = xsd[i].xs_shapes["[G][G']"] xsd[i].set_multiplicity_matrix(multiplicity, temperature) temp = get_data(xsdata_elem, 'fission') if temp is not None: temp = np.array(temp.split()) fission = temp.astype(np.float) - fission.shape = xsd[i].vector_shape + fission.shape = xsd[i].xs_shapes['[G]'] xsd[i].set_fission(fission, temperature) temp = get_data(xsdata_elem, 'kappa_fission') if temp is not None: temp = np.array(temp.split()) kappa_fission = temp.astype(np.float) - kappa_fission.shape = xsd[i].vector_shape + kappa_fission.shape = xsd[i].xs_shapes['[G]'] xsd[i].set_kappa_fission(kappa_fission, temperature) temp = get_data(xsdata_elem, 'chi') if temp is not None: temp = np.array(temp.split()) chi = temp.astype(np.float) - chi.shape = xsd[i].vector_shape + chi.shape = xsd[i].xs_shapes['[G]'] xsd[i].set_chi(chi, temperature) else: chi = None @@ -216,9 +230,9 @@ if __name__ == '__main__': temp = np.array(temp.split()) nu_fission = temp.astype(np.float) if chi is not None: - nu_fission.shape = xsd[i].vector_shape + nu_fission.shape = xsd[i].xs_shapes['[G]'] else: - nu_fission.shape = xsd[i].matrix_shape + nu_fission.shape = xsd[i].xs_shapes["[G][G']"] xsd[i].set_nu_fission(nu_fission, temperature) # Build library as we go, but first we have enough to initialize it diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 17104d508..4fb1f7272 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -355,7 +355,7 @@ module mgxs_header if (attribute_exists(xs_id, "scatter_shape")) then call read_attribute(temp_str, xs_id, "scatter_shape") temp_str = trim(temp_str) - if (to_lower(temp_str) /= "[order][g][g']") then + if (to_lower(temp_str) /= "[g][g'][order]") then call fatal_error("Invalid scatter_shape option!") end if end if @@ -1794,8 +1794,8 @@ module mgxs_header order_dim = order + 1 end if - ! Convert temp_1d to a jagged array ((gin) % data(l, gout)) for passing - ! to ScattData + ! Convert temp_1d to a jagged array ((gin) % data(l, gout)) for + ! passing to ScattData allocate(input_scatt(energy_groups, this % n_azi, this % n_pol)) index = 1 diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index 6004cbd19..684be88b8 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -274,7 +274,7 @@ contains ! Get this by summing the un-normalized P0 coefficient in matrix ! over all outgoing groups do gin = 1, groups - this % scattxs(gin) = sum(matrix(gin) % data(1, :), dim=1) + this % scattxs(gin) = sum(matrix(gin) % data(:, :)) end do allocate(energy(groups)) @@ -282,7 +282,7 @@ contains ! while also normalizing matrix itself (making CDF of f(mu=1)=1) do gin = 1, groups allocate(energy(gin) % data(gmin(gin):gmax(gin))) - do gout = 1, groups + do gout = gmin(gin), gmax(gin) norm = sum(matrix(gin) % data(:, gout)) energy(gin) % data(gout) = norm if (norm /= ZERO) then From 7c4ed737afe8b9ece0b35523bd7c7030962548a6 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 13 Nov 2016 14:38:57 -0500 Subject: [PATCH 24/60] Fixing failing tests --- openmc/mgxs/mgxs.py | 9 ++++- tests/1d_mgxs.h5 | Bin 128136 -> 134280 bytes tests/test_tallies/inputs_true.dat | 2 +- tests/test_tallies/results_true.dat | 2 +- tests/test_tallies/test_tallies.py | 51 ++++++++++------------------ 5 files changed, 28 insertions(+), 36 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 036feac74..1337b1fa7 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -3784,7 +3784,14 @@ class ScatterMatrixXS(MatrixMGXS): axes = (5, 4, 0) else: axes = (4, 3, 0) - xs = np.squeeze(xs, axis=axes) + # Squeeze will return a ValueError if the axis has a size greater + # than 1, so try each axis in axes one at a time, catching the + # ValueError as needed. + for axis in axes: + try: + xs = np.squeeze(xs, axis=axis) + except ValueError: + pass return xs diff --git a/tests/1d_mgxs.h5 b/tests/1d_mgxs.h5 index e3b85c24163fe4020435db5c5d674575f2b65be0..8f28e02cbcfb2d51e94d81bafdd97ba1220313d3 100644 GIT binary patch delta 1872 zcmeBp$=)%OV}d3V57S2N^&FEQ>6%Udp}}a#>mD2Jt{xlhUzCzs6ua4vGeiZ4-1K|- zj82;)^o%5MDA@eZZ3$2=9-G0F{Wz^Q2P9mQ!66SZ{6_67aU2T31{6%Yh12qV>!0Z0 za2V9(cRwlOP_TL5e;Z947H`kfWc=fbOA;6+XDo0@%B^I~@($)<@L*tJU|?Wm;A0SB z;9w|DPAn-&Es8JBNGwPNic2ywG6(=^5M~5o2A~=cfUp^Wx)>Nb{y=yTQefgiQK}lt z1h$as#xm2!SWsXBgNxdMz)Blq*=S=dJ8g`GBt5E!EhlYU%S9VwxoKl855(Aw2cI); zyx_-J@9ymH1J2N(oDT%Z86L!sMk$&Z7$CV6QXpWHhh#V0@{oK3m#@dL0FndX3NYj$ zNg201Bu(O$ha@hTd_ATQA;|=$08<_k-?-%=5rp3P1aq9E?7p0^Y#YVdWk$Nlx!{i0J7L%_jOHI7Mwz+`Q zNQHo!$qHHunepMj*Zq&XK z$FB-xR>8De1YPxD{UIF!E{FK=?k7b8>NY?4FQtjsRof?MGTw5 Date: Sun, 13 Nov 2016 14:56:57 -0500 Subject: [PATCH 25/60] Fixed final failing test --- tests/test_mg_tallies/results_true.dat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_mg_tallies/results_true.dat b/tests/test_mg_tallies/results_true.dat index a765c0ba0..8ab726bbb 100644 --- a/tests/test_mg_tallies/results_true.dat +++ b/tests/test_mg_tallies/results_true.dat @@ -1 +1 @@ -3d2ce1b8bdd558fe9f8560e8bb91455e1fedd80a47349344399e22f5b0fac1391f1721e7f12a42bb0c458fd6c87ebf9fa38fe9539fcf69292b21cebf8e5f8989 \ No newline at end of file +864328b2c4f3c4bfa9c80c756acbedac6fbdf3d502c03c2f2a3e7461b774729c47a55341c9515eff246e1bd445485f0d0a05a5712663ee499046afdbe0c77aef \ No newline at end of file From df7ae534138080dedfa3e351cfe068b64f54dd2a Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 13 Nov 2016 15:27:06 -0500 Subject: [PATCH 26/60] Cleaned up mgxs_library and made sure the mgxs-part-iv notebook was up to date --- .../pythonapi/examples/mgxs-part-iv.ipynb | 217 ++++++++++-------- openmc/mgxs_library.py | 140 +++++------ 2 files changed, 172 insertions(+), 185 deletions(-) diff --git a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb index cd011d862..312bb8ee6 100644 --- a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb @@ -429,7 +429,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "" ] @@ -575,7 +575,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/romano/openmc/openmc/mgxs/library.py:370: RuntimeWarning: The P0 correction will be ignored since the scattering order 0 is greater than zero\n", + "/home/nelsonag/git/openmc/openmc/mgxs/library.py:398: RuntimeWarning: The P0 correction will be ignored since the scattering order 0 is greater than zero\n", " warn(msg, RuntimeWarning)\n" ] } @@ -731,9 +731,9 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | da5563eddb5f2c2d6b2c9839d518de40962b78f2\n", - " Date/Time | 2016-10-31 12:36:52\n", - " OpenMP Threads | 4\n", + " Git SHA1 | 1a921e7d08fc41b72bf1dd65cd17e922222b78b1\n", + " Date/Time | 2016-11-13 15:24:57\n", + " OpenMP Threads | 8\n", "\n", " ===========================================================================\n", " ========================> INITIALIZATION <=========================\n", @@ -743,12 +743,12 @@ " Reading geometry XML file...\n", " Reading materials XML file...\n", " Reading cross sections XML file...\n", - " Reading U235 from /home/romano/openmc/scripts/nndc_hdf5/U235.h5\n", - " Reading U238 from /home/romano/openmc/scripts/nndc_hdf5/U238.h5\n", - " Reading O16 from /home/romano/openmc/scripts/nndc_hdf5/O16.h5\n", - " Reading Zr90 from /home/romano/openmc/scripts/nndc_hdf5/Zr90.h5\n", - " Reading H1 from /home/romano/openmc/scripts/nndc_hdf5/H1.h5\n", - " Reading B10 from /home/romano/openmc/scripts/nndc_hdf5/B10.h5\n", + " Reading U235 from /opt/xsdata/nndc/U235.h5\n", + " Reading U238 from /opt/xsdata/nndc/U238.h5\n", + " Reading O16 from /opt/xsdata/nndc/O16.h5\n", + " Reading Zr90 from /opt/xsdata/nndc/Zr90.h5\n", + " Reading H1 from /opt/xsdata/nndc/H1.h5\n", + " Reading B10 from /opt/xsdata/nndc/B10.h5\n", " Maximum neutron transport energy: 2.00000E+07 eV for U235\n", " Reading tallies XML file...\n", " Building neighboring cells lists for each surface...\n", @@ -819,20 +819,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 5.3479E-01 seconds\n", - " Reading cross sections = 3.8403E-01 seconds\n", - " Total time in simulation = 3.9455E+01 seconds\n", - " Time in transport only = 3.9331E+01 seconds\n", - " Time in inactive batches = 4.6776E+00 seconds\n", - " Time in active batches = 3.4778E+01 seconds\n", - " Time synchronizing fission bank = 1.0514E-02 seconds\n", - " Sampling source sites = 7.2826E-03 seconds\n", - " SEND/RECV source sites = 3.1267E-03 seconds\n", - " Time accumulating tallies = 3.7644E-04 seconds\n", - " Total time for finalization = 7.7600E-06 seconds\n", - " Total time elapsed = 4.0029E+01 seconds\n", - " Calculation Rate (inactive) = 10689.2 neutrons/second\n", - " Calculation Rate (active) = 5750.82 neutrons/second\n", + " Total time for initialization = 2.4361E-01 seconds\n", + " Reading cross sections = 1.6584E-01 seconds\n", + " Total time in simulation = 7.3766E+00 seconds\n", + " Time in transport only = 7.3482E+00 seconds\n", + " Time in inactive batches = 8.5442E-01 seconds\n", + " Time in active batches = 6.5222E+00 seconds\n", + " Time synchronizing fission bank = 4.9435E-03 seconds\n", + " Sampling source sites = 3.3815E-03 seconds\n", + " SEND/RECV source sites = 1.5249E-03 seconds\n", + " Time accumulating tallies = 9.5694E-05 seconds\n", + " Total time for finalization = 2.9260E-06 seconds\n", + " Total time elapsed = 7.6377E+00 seconds\n", + " Calculation Rate (inactive) = 58519.0 neutrons/second\n", + " Calculation Rate (active) = 30664.7 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -970,7 +970,20 @@ "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/nelsonag/git/openmc/openmc/tallies.py:1944: RuntimeWarning: invalid value encountered in true_divide\n", + " self_rel_err = data['self']['std. dev.'] / data['self']['mean']\n", + "/home/nelsonag/git/openmc/openmc/tallies.py:1945: RuntimeWarning: invalid value encountered in true_divide\n", + " other_rel_err = data['other']['std. dev.'] / data['other']['mean']\n", + "/home/nelsonag/git/openmc/openmc/tallies.py:1946: RuntimeWarning: invalid value encountered in true_divide\n", + " new_tally._mean = data['self']['mean'] / data['other']['mean']\n" + ] + } + ], "source": [ "# Create a MGXS File which can then be written to disk\n", "mgxs_file = mgxs_lib.create_mg_library(xs_type='macro', xsdata_names=['fuel', 'zircaloy', 'water'])\n", @@ -1107,9 +1120,9 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | da5563eddb5f2c2d6b2c9839d518de40962b78f2\n", - " Date/Time | 2016-10-31 12:37:32\n", - " OpenMP Threads | 4\n", + " Git SHA1 | 1a921e7d08fc41b72bf1dd65cd17e922222b78b1\n", + " Date/Time | 2016-11-13 15:25:05\n", + " OpenMP Threads | 8\n", "\n", " ===========================================================================\n", " ========================> INITIALIZATION <=========================\n", @@ -1133,56 +1146,56 @@ "\n", " Bat./Gen. k Average k \n", " ========= ======== ==================== \n", - " 1/1 1.00711 \n", - " 2/1 1.01538 \n", - " 3/1 1.01664 \n", - " 4/1 1.03592 \n", - " 5/1 1.00771 \n", - " 6/1 1.00555 \n", - " 7/1 1.02573 \n", - " 8/1 1.04322 \n", - " 9/1 1.02270 \n", - " 10/1 1.02354 \n", - " 11/1 1.02023 \n", - " 12/1 1.03047 1.02535 +/- 0.00512\n", - " 13/1 1.04476 1.03182 +/- 0.00711\n", - " 14/1 1.02223 1.02942 +/- 0.00557\n", - " 15/1 1.02082 1.02770 +/- 0.00465\n", - " 16/1 1.01472 1.02554 +/- 0.00437\n", - " 17/1 1.02104 1.02489 +/- 0.00375\n", - " 18/1 1.04471 1.02737 +/- 0.00408\n", - " 19/1 1.02806 1.02745 +/- 0.00360\n", - " 20/1 1.02044 1.02675 +/- 0.00330\n", - " 21/1 1.02592 1.02667 +/- 0.00298\n", - " 22/1 1.02242 1.02632 +/- 0.00275\n", - " 23/1 0.99969 1.02427 +/- 0.00325\n", - " 24/1 1.02213 1.02412 +/- 0.00301\n", - " 25/1 1.02080 1.02390 +/- 0.00281\n", - " 26/1 1.01033 1.02305 +/- 0.00277\n", - " 27/1 1.02881 1.02339 +/- 0.00262\n", - " 28/1 1.01649 1.02300 +/- 0.00250\n", - " 29/1 1.03817 1.02380 +/- 0.00250\n", - " 30/1 1.00958 1.02309 +/- 0.00247\n", - " 31/1 1.01811 1.02285 +/- 0.00236\n", - " 32/1 1.02709 1.02305 +/- 0.00226\n", - " 33/1 1.01823 1.02284 +/- 0.00217\n", - " 34/1 1.01208 1.02239 +/- 0.00213\n", - " 35/1 1.01380 1.02204 +/- 0.00207\n", - " 36/1 1.02358 1.02210 +/- 0.00199\n", - " 37/1 1.03653 1.02264 +/- 0.00199\n", - " 38/1 1.03117 1.02294 +/- 0.00194\n", - " 39/1 1.00915 1.02247 +/- 0.00193\n", - " 40/1 1.03107 1.02275 +/- 0.00189\n", - " 41/1 1.02316 1.02277 +/- 0.00182\n", - " 42/1 1.02677 1.02289 +/- 0.00177\n", - " 43/1 0.99361 1.02200 +/- 0.00193\n", - " 44/1 1.04841 1.02278 +/- 0.00203\n", - " 45/1 0.99768 1.02206 +/- 0.00210\n", - " 46/1 1.02694 1.02220 +/- 0.00204\n", - " 47/1 1.03540 1.02256 +/- 0.00202\n", - " 48/1 1.03539 1.02289 +/- 0.00199\n", - " 49/1 1.02498 1.02295 +/- 0.00194\n", - " 50/1 1.00692 1.02255 +/- 0.00193\n", + " 1/1 0.98369 \n", + " 2/1 1.01520 \n", + " 3/1 1.03642 \n", + " 4/1 1.02658 \n", + " 5/1 1.03102 \n", + " 6/1 1.05382 \n", + " 7/1 1.01978 \n", + " 8/1 1.01753 \n", + " 9/1 1.02420 \n", + " 10/1 0.99889 \n", + " 11/1 1.04874 \n", + " 12/1 1.01382 1.03128 +/- 0.01746\n", + " 13/1 1.03987 1.03414 +/- 0.01048\n", + " 14/1 1.02282 1.03131 +/- 0.00793\n", + " 15/1 1.03282 1.03162 +/- 0.00615\n", + " 16/1 0.99669 1.02579 +/- 0.00769\n", + " 17/1 1.00052 1.02218 +/- 0.00743\n", + " 18/1 1.01124 1.02082 +/- 0.00658\n", + " 19/1 1.00629 1.01920 +/- 0.00602\n", + " 20/1 1.05322 1.02260 +/- 0.00637\n", + " 21/1 1.00763 1.02124 +/- 0.00592\n", + " 22/1 1.01841 1.02101 +/- 0.00541\n", + " 23/1 1.03430 1.02203 +/- 0.00508\n", + " 24/1 1.03064 1.02264 +/- 0.00474\n", + " 25/1 1.03272 1.02331 +/- 0.00447\n", + " 26/1 1.01226 1.02262 +/- 0.00424\n", + " 27/1 1.00883 1.02181 +/- 0.00406\n", + " 28/1 1.02712 1.02211 +/- 0.00384\n", + " 29/1 1.03146 1.02260 +/- 0.00367\n", + " 30/1 1.02964 1.02295 +/- 0.00350\n", + " 31/1 0.99832 1.02178 +/- 0.00353\n", + " 32/1 1.03420 1.02234 +/- 0.00341\n", + " 33/1 1.01860 1.02218 +/- 0.00326\n", + " 34/1 1.03328 1.02264 +/- 0.00316\n", + " 35/1 1.01865 1.02248 +/- 0.00303\n", + " 36/1 1.02643 1.02264 +/- 0.00292\n", + " 37/1 1.01070 1.02219 +/- 0.00284\n", + " 38/1 1.01871 1.02207 +/- 0.00274\n", + " 39/1 0.98827 1.02090 +/- 0.00289\n", + " 40/1 1.01740 1.02079 +/- 0.00279\n", + " 41/1 1.02920 1.02106 +/- 0.00272\n", + " 42/1 1.02496 1.02118 +/- 0.00263\n", + " 43/1 1.04288 1.02184 +/- 0.00264\n", + " 44/1 1.03749 1.02230 +/- 0.00260\n", + " 45/1 1.04338 1.02290 +/- 0.00259\n", + " 46/1 1.03146 1.02314 +/- 0.00253\n", + " 47/1 1.04668 1.02377 +/- 0.00254\n", + " 48/1 1.02707 1.02386 +/- 0.00248\n", + " 49/1 1.02589 1.02391 +/- 0.00241\n", + " 50/1 1.02100 1.02384 +/- 0.00235\n", " Creating state point statepoint.50.h5...\n", "\n", " ===========================================================================\n", @@ -1192,27 +1205,27 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 3.6445E-02 seconds\n", - " Reading cross sections = 4.9377E-03 seconds\n", - " Total time in simulation = 3.0983E+01 seconds\n", - " Time in transport only = 3.0902E+01 seconds\n", - " Time in inactive batches = 3.2106E+00 seconds\n", - " Time in active batches = 2.7772E+01 seconds\n", - " Time synchronizing fission bank = 9.7451E-03 seconds\n", - " Sampling source sites = 6.9236E-03 seconds\n", - " SEND/RECV source sites = 2.6796E-03 seconds\n", - " Time accumulating tallies = 3.2976E-04 seconds\n", - " Total time for finalization = 7.4870E-06 seconds\n", - " Total time elapsed = 3.1057E+01 seconds\n", - " Calculation Rate (inactive) = 15573.4 neutrons/second\n", - " Calculation Rate (active) = 7201.41 neutrons/second\n", + " Total time for initialization = 2.5229E-02 seconds\n", + " Reading cross sections = 1.1001E-02 seconds\n", + " Total time in simulation = 7.3074E+00 seconds\n", + " Time in transport only = 7.2846E+00 seconds\n", + " Time in inactive batches = 6.2995E-01 seconds\n", + " Time in active batches = 6.6774E+00 seconds\n", + " Time synchronizing fission bank = 4.8069E-03 seconds\n", + " Sampling source sites = 3.3693E-03 seconds\n", + " SEND/RECV source sites = 1.3618E-03 seconds\n", + " Time accumulating tallies = 8.0542E-05 seconds\n", + " Total time for finalization = 2.9260E-06 seconds\n", + " Total time elapsed = 7.3508E+00 seconds\n", + " Calculation Rate (inactive) = 79370.9 neutrons/second\n", + " Calculation Rate (active) = 29951.7 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", - " k-effective (Collision) = 1.02346 +/- 0.00203\n", - " k-effective (Track-length) = 1.02255 +/- 0.00193\n", - " k-effective (Absorption) = 1.02775 +/- 0.00139\n", - " Combined k-effective = 1.02594 +/- 0.00120\n", + " k-effective (Collision) = 1.02315 +/- 0.00205\n", + " k-effective (Track-length) = 1.02384 +/- 0.00235\n", + " k-effective (Absorption) = 1.02372 +/- 0.00194\n", + " Combined k-effective = 1.02369 +/- 0.00173\n", " Leakage Fraction = 0.00000 +/- 0.00000\n", "\n" ] @@ -1294,8 +1307,8 @@ "output_type": "stream", "text": [ "Continuous-Energy keff = 1.024739\n", - "Multi-Group keff = 1.025941\n", - "bias [pcm]: -120.2\n" + "Multi-Group keff = 1.023689\n", + "bias [pcm]: 105.0\n" ] } ], @@ -1392,7 +1405,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 40, @@ -1401,9 +1414,9 @@ }, { "data": { - "image/png": "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\nz6tq0gAAAABJRU5ErkJggg==\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 5256dd102..1f13e18ee 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1735,108 +1735,82 @@ 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): - if self.scatter_format == 'legendre': - nz = np.nonzero(self._scatter_matrix[i][g_in, :, 0]) - elif self.scatter_format == 'histogram': - nz = np.nonzero(np.sum( - self._scatter_matrix[i][g_in, :, :], axis=1)) - if len(nz[0]) == 0: - g_out_bounds[g_in, 0] = 0 - g_out_bounds[g_in, 1] = 0 - else: - g_out_bounds[g_in, 0] = nz[0][0] - g_out_bounds[g_in, 1] = nz[0][-1] - - # Now create the flattened scatter matrix array - matrix = self._scatter_matrix[i] - flat_scatt = [] - for g_in in range(G): - for g_out in range(g_out_bounds[g_in, 0], - g_out_bounds[g_in, 1] + 1): - for l in range(len(matrix[g_in, g_out, :])): - flat_scatt.append(matrix[g_in, g_out, l]) - - # And write it. - scatt_grp = xs_grp.create_group('scatter_data') - scatt_grp.create_dataset("scatter_matrix", - data=np.array(flat_scatt)) - - # Repeat for multiplicity - if self._multiplicity_matrix[i] is not None: - # Now create the flattened scatter matrix array - matrix = self._multiplicity_matrix[i][:, :] - flat_mult = [] - for g_in in range(G): - for g_out in range(g_out_bounds[g_in, 0], - g_out_bounds[g_in, 1] + 1): - flat_mult.append(matrix[g_in, g_out]) - - scatt_grp.create_dataset("multiplicity matrix", - data=np.array(flat_mult)) - - # And finally, adjust g_out_bounds for 1-based group counting - # and write it. - g_out_bounds[:, :] += 1 - scatt_grp.create_dataset("g_min", data=g_out_bounds[:, 0]) - scatt_grp.create_dataset("g_max", data=g_out_bounds[:, 1]) - + Np = 1 + Na = 1 elif self.representation == 'angle': Np = self.num_polar Na = self.num_azimuthal - g_out_bounds = np.zeros((Np, Na, G, 2), dtype=np.int) - for p in range(Np): - for a in range(Na): - for g_in in range(G): - if self.scatter_format == 'legendre': + 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): + if self.scatter_format == 'legendre': + if self.representation == 'isotropic': + matrix = \ + self._scatter_matrix[i][g_in, :, 0] + elif self.representation == 'angle': matrix = \ self._scatter_matrix[i][p, a, g_in, :, 0] - elif self.scatter_format == 'histogram': + elif self.scatter_format == 'histogram': + if self.representation == 'isotropic': + matrix = \ + np.sum(self._scatter_matrix[i][g_in, :, :], + axis=1) + elif self.representation == 'angle': matrix = \ np.sum(self._scatter_matrix[i][p, a, g_in, :, :], axis=1) - 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] + nz = np.nonzero(matrix) + g_out_bounds[p, a, g_in, 0] = nz[0][0] + g_out_bounds[p, a, g_in, 1] = nz[0][-1] + + # Now create the flattened scatter matrix array + flat_scatt = [] + for p in range(Np): + for a in range(Na): + if self.representation == 'isotropic': + matrix = self._scatter_matrix[i][:, :, :] + elif self.representation == 'angle': + matrix = self._scatter_matrix[i][p, a, :, :, :] + for g_in in range(G): + for g_out in range(g_out_bounds[p, a, g_in, 0], + g_out_bounds[p, a, g_in, 1] + 1): + for l in range(len(matrix[g_in, g_out, :])): + flat_scatt.append(matrix[g_in, g_out, l]) + + # 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_scatt = [] + flat_mult = [] for p in range(Np): for a in range(Na): - matrix = self._scatter_matrix[i][p, a, :, :, :] + if self.representation == 'isotropic': + matrix = self._multiplicity_matrix[i][:, :] + elif self.representation == 'angle': + matrix = self._multiplicity_matrix[i][p, a, :, :] for g_in in range(G): for g_out in range(g_out_bounds[p, a, g_in, 0], g_out_bounds[p, a, g_in, 1] + 1): - for l in range(len(matrix[g_in, g_out, :])): - flat_scatt.append(matrix[g_in, g_out, l]) + flat_mult.append(matrix[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)) + scatt_grp.create_dataset("multiplicity_matrix", + data=np.array(flat_mult)) - # Repeat for multiplicity - if self._multiplicity_matrix[i] is not None: - - # Now create the flattened scatter matrix array - flat_mult = [] - for p in range(Np): - for a in range(Na): - matrix = self._multiplicity_matrix[i][p, a, :, :] - for g_in in range(G): - for g_out in range(g_out_bounds[p, a, g_in, 0], - g_out_bounds[p, a, g_in, 1] + 1): - flat_mult.append(matrix[g_in, g_out]) - - # And write it. - scatt_grp.create_dataset("multiplicity_matrix", - data=np.array(flat_mult)) - - # And finally, adjust g_out_bounds for 1-based group counting - # and write it. - g_out_bounds[:, :, :, :] += 1 + # And finally, adjust g_out_bounds for 1-based group counting + # and write it. + g_out_bounds[:, :, :, :] += 1 + if self.representation == 'isotropic': + scatt_grp.create_dataset("g_min", data=g_out_bounds[0, 0, :, 0]) + scatt_grp.create_dataset("g_max", data=g_out_bounds[0, 0, :, 1]) + elif self.representation == 'angle': scatt_grp.create_dataset("g_min", data=g_out_bounds[:, :, :, 0]) scatt_grp.create_dataset("g_max", data=g_out_bounds[:, :, :, 1]) From 5af55a74d49520665da4e852522249ab93e00bfe Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 13 Nov 2016 15:38:19 -0500 Subject: [PATCH 27/60] Removed errant pdb import --- openmc/mgxs/mgxs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 1337b1fa7..06527d5c2 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -3775,7 +3775,7 @@ class ScatterMatrixXS(MatrixMGXS): # tally data is stored in order of increasing energies if order_groups == 'increasing': xs = xs[:, ::-1, ::-1, ...] - # import pdb; pdb.set_trace() + if squeeze: # We want to squeeze out everything but the in_groups, out_groups, # and, if needed, num_mu_bins dimension. These must not be squeezed From 51babd69782c7282e92420dd5279a99a49f55b92 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 13 Nov 2016 21:54:12 -0500 Subject: [PATCH 28/60] Minor ylabel changes --- openmc/plotter.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/openmc/plotter.py b/openmc/plotter.py index 09b7b1bf8..31fb57f5e 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -61,7 +61,7 @@ PLOT_TYPES_OP = {'total': (np.add,), 'capture': (), 'nu-fission': (), 'nu-scatter': (np.add,) * (len(PLOT_TYPES_MT['nu-scatter']) - 1), 'unity': (), - 'slowing-down power': + 'slowing-down power': (np.add,) * (len(PLOT_TYPES_MT['slowing-down power']) - 2) + (np.multiply,), 'damage': ()} @@ -197,9 +197,20 @@ def plot_xs(this, types, divisor_types=None, temperature=294., axis=None, ax.set_xlabel('Energy [eV]') if divisor_types: - ax.set_ylabel('Data') + if data_type == 'nuclide': + ylabel = 'Nuclidic Microscopic Data' + elif data_type == 'element': + ylabel = 'Elemental Microscopic Data' + elif data_type == 'material': + ylabel = 'Macroscopic Data' else: - ax.set_ylabel('Cross Section [b]') + if data_type == 'nuclide': + ylabel = 'Microscopic Cross Section [b]' + elif data_type == 'element': + ylabel = 'Elemental Cross Section [b]' + elif data_type == 'material': + ylabel = 'Macroscopic Cross Section [1/cm]' + ax.set_ylabel(ylabel) ax.legend(loc='best') ax.set_xlim(energy_range) if this.name is not None: From a428ccb2315ba6b362475890ef8f838f5d0077f9 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 13 Nov 2016 21:54:36 -0500 Subject: [PATCH 29/60] And one minor editorial :-( --- openmc/plotter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/plotter.py b/openmc/plotter.py index 31fb57f5e..b8eda28e6 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -5,7 +5,7 @@ import numpy as np import openmc.checkvalue as cv import openmc.data -# Supported keywords for material xs plotting +# Supported keywords for xs plotting PLOT_TYPES = ['total', 'scatter', 'elastic', 'inelastic', 'fission', 'absorption', 'capture', 'nu-fission', 'nu-scatter', 'unity', 'slowing-down power', 'damage'] From a29e719c501afd198c42de22d4b15a862518defc Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 14 Nov 2016 19:07:16 -0500 Subject: [PATCH 30/60] Removed mistake from a poor merge --- openmc/mgxs/library.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 97bb6d96b..513884d96 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -946,6 +946,7 @@ class Library(object): if nuclide != 'total': name += '_' + nuclide xsdata = openmc.XSdata(name, self.energy_groups) + xsdata.num_delayed_groups = self.num_delayed_groups # Right now only isotropic weighting is supported self.representation = 'isotropic' From ecd3112e21d0cb6908e116e7e224f9cab166a133 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 14 Nov 2016 20:47:38 -0500 Subject: [PATCH 31/60] Updating example problems for the new format --- .../python/pincell_multigroup/build-xml.py | 10 ++++++++-- examples/xml/pincell_multigroup/mgxs.h5 | Bin 16696 -> 16696 bytes 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index ee74233c1..cc57b61e2 100644 --- a/examples/python/pincell_multigroup/build-xml.py +++ b/examples/python/pincell_multigroup/build-xml.py @@ -1,3 +1,5 @@ +import numpy as np + import openmc import openmc.mgxs @@ -26,7 +28,7 @@ uo2_xsdata.set_total( 0.5644058]) uo2_xsdata.set_absorption([8.0248E-03, 3.7174E-03, 2.6769E-02, 9.6236E-02, 3.0020E-02, 1.1126E-01, 2.8278E-01]) -uo2_xsdata.set_scatter_matrix( +scatter_matrix = np.array( [[[0.1275370, 0.0423780, 0.0000094, 0.0000000, 0.0000000, 0.0000000, 0.0000000], [0.0000000, 0.3244560, 0.0016314, 0.0000000, 0.0000000, 0.0000000, 0.0000000], [0.0000000, 0.0000000, 0.4509400, 0.0026792, 0.0000000, 0.0000000, 0.0000000], @@ -34,6 +36,8 @@ uo2_xsdata.set_scatter_matrix( [0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000], [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090], [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]]) +scatter_matrix = np.swapaxes(np.swapaxes(scatter_matrix, 0, 1), 1, 2) +uo2_xsdata.set_scatter_matrix(scatter_matrix) uo2_xsdata.set_fission([7.21206E-03, 8.19301E-04, 6.45320E-03, 1.85648E-02, 1.78084E-02, 8.30348E-02, 2.16004E-01]) @@ -50,7 +54,7 @@ h2o_xsdata.set_total([0.15920605, 0.412969593, 0.59030986, 0.58435, h2o_xsdata.set_absorption([6.0105E-04, 1.5793E-05, 3.3716E-04, 1.9406E-03, 5.7416E-03, 1.5001E-02, 3.7239E-02]) -h2o_xsdata.set_scatter_matrix( +scatter_matrix = np.array( [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0.0000000], [0.0000000, 0.2823340, 0.1299400, 0.0006234, 0.0000480, 0.0000074, 0.0000010], [0.0000000, 0.0000000, 0.3452560, 0.2245700, 0.0169990, 0.0026443, 0.0005034], @@ -58,6 +62,8 @@ h2o_xsdata.set_scatter_matrix( [0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290], [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200], [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]]) +scatter_matrix = np.swapaxes(np.swapaxes(scatter_matrix, 0, 1), 1, 2) +h2o_xsdata.set_scatter_matrix(scatter_matrix) mg_cross_sections_file = openmc.MGXSLibrary(groups) mg_cross_sections_file.add_xsdatas([uo2_xsdata, h2o_xsdata]) diff --git a/examples/xml/pincell_multigroup/mgxs.h5 b/examples/xml/pincell_multigroup/mgxs.h5 index 1d5561b0006a8afb89663ca33573eedaabad7a91..ae3b17e90f2dafb1a350d9bd1392d61254f2a37c 100644 GIT binary patch delta 194 zcmdnd#JHo0af2r(k9%yiyLxQ2e^E+m(PUoT$&(i-N^IiFVPW2wp|v@mPn8$Mm^@## zeY2d*IYzMPds$uxb{34{%@$t3bm$l d^9J)X5Yy`|&oYCJ@VAAUHQyd$*5vo Date: Mon, 14 Nov 2016 20:48:13 -0500 Subject: [PATCH 32/60] One more minor typo --- openmc/data/library.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/data/library.py b/openmc/data/library.py index 3beb25543..34cd380a5 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -114,7 +114,7 @@ class DataLibrary(EqualityMixin): data = cls() - # If cross_sections is None, get the cross sections from the + # If path is None, get the cross sections from the # OPENMC_CROSS_SECTIONS environment variable if path is None: path = os.environ.get('OPENMC_CROSS_SECTIONS') From b8d9fe461f22e59437af10023a20eaf8cd92bbe4 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 16 Nov 2016 21:47:07 -0500 Subject: [PATCH 33/60] Resolving @paulromano comments --- openmc/data/data.py | 6 ++++ openmc/material.py | 17 ++++----- openmc/plotter.py | 85 +++++++++++++++------------------------------ 3 files changed, 40 insertions(+), 68 deletions(-) diff --git a/openmc/data/data.py b/openmc/data/data.py index a3e715812..92be7cade 100644 --- a/openmc/data/data.py +++ b/openmc/data/data.py @@ -186,3 +186,9 @@ K_BOLTZMANN = 8.6173324e-5 # Used for converting units in ACE data EV_PER_MEV = 1.0e6 + +# Avogadro's constant from CODATA 2010 +AVOGADRO = 6.02214129E23 + +# Neutron mass from CODATA 2010 in units of amu +NEUTRON_MASS = 1.008664916 diff --git a/openmc/material.py b/openmc/material.py index 16d1fd147..ece75be19 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -664,17 +664,12 @@ class Material(object): sum_percent = 0. awrs = [] - n = -1 - for nuclide in nuclides.items(): - n += 1 - lib = library.get_by_material(nuclide[0]) - if lib is not None: - nuc = openmc.data.IncidentNeutron.from_hdf5(lib['path']) - awrs.append(nuc.atomic_weight_ratio) - if not percent_in_atom: - nuc_densities[n] = -nuc_densities[n] / awrs[-1] + for n, nuclide in enumerate(nuclides.items()): + awr = openmc.data.atomic_mass(nuclide[0]) + if awr is not None: + awrs.append(awr / openmc.data.NEUTRON_MASS) else: - raise ValueError(nuclide[0] + " not in library") + raise ValueError(nuclide[0] + " is invalid") # Now that we have the awr, lets finish calculating densities sum_percent = np.sum(nuc_densities) @@ -686,7 +681,7 @@ class Material(object): sum_percent += x * awrs[n] sum_percent = 1. / sum_percent density = -density * sum_percent * \ - sc.Avogadro / sc.value('neutron mass in u') * 1.E-24 + openmc.data.AVOGADRO / openmc.data.NEUTRON_MASS * 1.E-24 nuc_densities = density * nuc_densities nuclides = OrderedDict() diff --git a/openmc/plotter.py b/openmc/plotter.py index b8eda28e6..f0275dda6 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -15,42 +15,18 @@ UNITY_MT = -1 XI_MT = -2 # MTs to combine to generate associated plot_types -PLOT_TYPES_MT = {'total': (2, 3,), - 'scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, - 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, - 153, 154, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 183, 184, 190, 194, 196, 198, 199, 200, - 875, 891), - 'elastic': (2,), - 'inelastic': (4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, - 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, - 153, 154, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 183, 184, 190, 194, 196, 198, 199, 200, - 875, 891), - 'fission': (18,), - 'absorption': (27,), 'capture': (101,), - 'nu-fission': (18,), - 'nu-scatter': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, 29, 30, - 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 152, - 153, 154, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 183, 184, 190, 194, 196, 198, 199, 200, - 875, 891), - 'unity': (UNITY_MT,), - 'slowing-down power': (2, 4, 11, 16, 17, 22, 23, 24, 25, 28, - 29, 30, 32, 33, 34, 35, 36, 37, 41, 42, - 44, 45, 152, 153, 154, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 179, 180, 181, 183, - 184, 190, 194, 196, 198, 199, 200, 875, - 891, XI_MT), - 'damage': (444,)} +_INELASTIC = [mt for mt in openmc.data.SUM_RULES[3] if mt not in [5, 27]] +PLOT_TYPES_MT = {'total': openmc.data.SUM_RULES[1], + 'scatter': [2] + _INELASTIC, + 'elastic': [2], + 'inelastic': _INELASTIC, + 'fission': [18], + 'absorption': [27], 'capture': [101], + 'nu-fission': [18], + 'nu-scatter': [2] + _INELASTIC, + 'unity': [UNITY_MT], + 'slowing-down power': [2] + _INELASTIC + [XI_MT], + 'damage': [444]} # Operations to use when combining MTs the first np.add is used in reference # to zero PLOT_TYPES_OP = {'total': (np.add,), @@ -84,8 +60,7 @@ PLOT_TYPES_LINEAR = {'nu-fission / fission', 'nu-scatter / scatter', def plot_xs(this, types, divisor_types=None, temperature=294., axis=None, - energy_range=(1.E-5, 20.E6), sab_name=None, cross_sections=None, - enrichment=None, **kwargs): + sab_name=None, cross_sections=None, enrichment=None, **kwargs): """Creates a figure of continuous-energy cross sections for this item Parameters @@ -106,8 +81,6 @@ def plot_xs(this, types, divisor_types=None, temperature=294., axis=None, axis : matplotlib.axes, optional A previously generated axis to use for plotting. If not specified, a new axis and figure will be generated. - energy_range : tuple of floats - Energy range (in eV) to plot the cross section within sab_name : str, optional Name of S(a,b) library to apply to MT=2 data when applicable; only used for items which are instances of openmc.Element or openmc.Nuclide @@ -212,10 +185,10 @@ def plot_xs(this, types, divisor_types=None, temperature=294., axis=None, ylabel = 'Macroscopic Cross Section [1/cm]' ax.set_ylabel(ylabel) ax.legend(loc='best') - ax.set_xlim(energy_range) + # Set to the most likely expected range + ax.set_xlim((1.E-5, 20.E6)) if this.name is not None: - title = 'Cross Section for ' + this.name - ax.set_title(title) + ax.set_title('Cross Section for ' + this.name) return fig @@ -246,7 +219,7 @@ def calculate_xs(this, types, temperature=294., sab_name=None, Returns ------- - energy_grid : numpy.array + energy_grid : numpy.ndarray Energies at which cross sections are calculated, in units of eV data : numpy.ndarray Cross sections calculated at the energy grid described by energy_grid @@ -302,7 +275,7 @@ def _calculate_xs_element(this, types, temperature=294., sab_name=None, Returns ------- - energy_grid : numpy.array + energy_grid : numpy.ndarray Energies at which cross sections are calculated, in units of eV data : numpy.ndarray Macroscopic cross sections calculated at the energy grid described @@ -381,7 +354,7 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, Returns ------- - energy_grid : numpy.array + energy_grid : numpy.ndarray Energies at which cross sections are calculated, in units of eV data : numpy.ndarray Cross sections calculated at the energy grid described by @@ -405,6 +378,7 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, mts.append((line,)) yields.append((False,)) ops.append(()) + print(mts) # Load the library library = openmc.data.DataLibrary.from_xml(cross_sections) @@ -427,7 +401,7 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, for t in range(len(data_Ts)): # Take off the "K" and convert to a float data_Ts[t] = float(data_Ts[t][:-1]) - min_delta = np.finfo(np.float64).max + min_delta = float('inf') closest_t = -1 for t in data_Ts: if abs(data_Ts[t] - T) < min_delta: @@ -496,7 +470,6 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, funcs.append(nuc[mt].xs[nucT]) elif mt in nuc: if yield_check: - found_it = False for prod in nuc[mt].products: if prod.particle == 'neutron' and \ prod.emission_mode == 'total': @@ -504,9 +477,8 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, [nuc[mt].xs[nucT], prod.yield_], [np.multiply]) funcs.append(func) - found_it = True break - if not found_it: + else: for prod in nuc[mt].products: if prod.particle == 'neutron' and \ prod.emission_mode == 'prompt': @@ -514,11 +486,10 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, [nuc[mt].xs[nucT], prod.yield_], [np.multiply]) funcs.append(func) - found_it = True break - if not found_it: - # Assume the yield is 1 - funcs.append(nuc[mt].xs[nucT]) + else: + # Assume the yield is 1 + funcs.append(nuc[mt].xs[nucT]) else: funcs.append(nuc[mt].xs[nucT]) elif mt == UNITY_MT: @@ -557,7 +528,7 @@ def _calculate_xs_material(this, types, temperature=294., cross_sections=None): Returns ------- - energy_grid : numpy.array + energy_grid : numpy.ndarray Energies at which cross sections are calculated, in units of eV data : numpy.ndarray Macroscopic cross sections calculated at the energy grid described @@ -602,8 +573,8 @@ def _calculate_xs_material(this, types, temperature=294., cross_sections=None): # Condense the data for every nuclide # First create a union energy grid energy_grid = E[0] - for n in range(1, len(E)): - energy_grid = np.union1d(energy_grid, E[n]) + for grid in E[1:]: + energy_grid = np.union1d(energy_grid, grid) # Now we can combine all the nuclidic data data = np.zeros((len(types), len(energy_grid))) From 1a62b59dc3f6ed2c4a3f746553d4a2eb103ecb8b Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Thu, 17 Nov 2016 17:17:38 -0500 Subject: [PATCH 34/60] Resolved @samuelshaner comments --- openmc/material.py | 5 ----- openmc/plotter.py | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/openmc/material.py b/openmc/material.py index ece75be19..84d790feb 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -623,11 +623,6 @@ class Material(object): """ - import scipy.constants as sc - - # Load the library - library = openmc.data.DataLibrary.from_xml(cross_sections) - # Expand elements in to nuclides nuclides = self.get_nuclide_densities() diff --git a/openmc/plotter.py b/openmc/plotter.py index f0275dda6..626450456 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -165,6 +165,7 @@ def plot_xs(this, types, divisor_types=None, temperature=294., axis=None, to_plot = data[i](E) else: to_plot = data[i, :] + to_plot = np.nan_to_num(to_plot) if np.sum(to_plot) > 0.: plot_func(E, to_plot, label=types[i]) @@ -287,7 +288,7 @@ def _calculate_xs_element(this, types, temperature=294., sab_name=None, library = openmc.data.DataLibrary.from_xml(cross_sections) # Expand elements in to nuclides with atomic densities - nuclides = this.expand(100., 'ao', enrichment=enrichment, + nuclides = this.expand(1., 'ao', enrichment=enrichment, cross_sections=cross_sections) # For ease of processing split out nuc and nuc_density @@ -378,7 +379,6 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, mts.append((line,)) yields.append((False,)) ops.append(()) - print(mts) # Load the library library = openmc.data.DataLibrary.from_xml(cross_sections) From 2395f9a96c1ecf8cbc3705ea7ebc88baf9dcf4c7 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 7 Nov 2016 11:34:09 -0600 Subject: [PATCH 35/60] Add FissionProductYields class and Decay class --- docs/source/conf.py | 2 +- docs/source/pythonapi/index.rst | 2 + openmc/data/__init__.py | 1 + openmc/data/decay.py | 458 ++++++++++++++++++++++++++++++++ openmc/data/endf.py | 21 +- setup.py | 1 + 6 files changed, 474 insertions(+), 11 deletions(-) create mode 100644 openmc/data/decay.py diff --git a/docs/source/conf.py b/docs/source/conf.py index 672217c84..4e21ec20b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -25,7 +25,7 @@ except ImportError: MOCK_MODULES = ['numpy', 'numpy.polynomial', 'numpy.polynomial.polynomial', - 'h5py', 'pandas', 'opencg'] + 'h5py', 'pandas', 'uncertainties', 'opencg'] sys.modules.update((mod_name, MagicMock()) for mod_name in MOCK_MODULES) import numpy as np diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index e364452b1..b86107f37 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -373,6 +373,8 @@ Core Classes openmc.data.CoherentElastic openmc.data.FissionEnergyRelease openmc.data.DataLibrary + openmc.data.Decay + openmc.data.FissionProductYields Core Functions -------------- diff --git a/openmc/data/__init__.py b/openmc/data/__init__.py index 373136538..c361a204d 100644 --- a/openmc/data/__init__.py +++ b/openmc/data/__init__.py @@ -6,6 +6,7 @@ HDF5_VERSION = (HDF5_VERSION_MAJOR, HDF5_VERSION_MINOR) from .data import * from .neutron import * +from .decay import * from .reaction import * from .ace import * from .angle_distribution import * diff --git a/openmc/data/decay.py b/openmc/data/decay.py new file mode 100644 index 000000000..35bc11345 --- /dev/null +++ b/openmc/data/decay.py @@ -0,0 +1,458 @@ +from collections import Iterable, namedtuple +from io import StringIO +from math import log +from numbers import Real +import re +from warnings import warn + +from six import string_types +import numpy as np +try: + from uncertainties import ufloat, unumpy, UFloat +except ImportError: + ufloat = UFloat = namedtuple('UFloat', ['nominal_value', 'std_dev']) + +import openmc.checkvalue as cv +from openmc.mixin import EqualityMixin +from .data import ATOMIC_SYMBOL, ATOMIC_NUMBER +from .endf import Evaluation, get_head_record, get_list_record, get_tab1_record + + +# Gives name and (change in A, change in Z) resulting from decay +_DECAY_MODES = { + 0: ('gamma', (0, 0)), + 1: ('beta-', (0, 1)), + 2: ('ec/beta+', (0, -1)), + 3: ('IT', (0, 0)), + 4: ('alpha', (-4, -2)), + 5: ('n', (-1, 0)), + 6: ('sf', None), + 7: ('p', (-1, -1)), + 8: ('e-', (0, 0)), + 9: ('xray', (0, 0)), + 10: ('unknown', None) +} + +_RADIATION_TYPES = { + 0: 'gamma', + 1: 'beta-', + 2: 'ec/beta+', + 4: 'alpha', + 5: 'n', + 6: 'sf', + 7: 'p', + 8: 'e-', + 9: 'xray', + 10: 'anti-neutrino', + 11: 'neutrino' +} + + +def get_decay_modes(value): + """Return sequence of decay modes given an ENDF RTYP value. + + Parameters + ---------- + value : float + ENDF definition of sequence of decay modes + + Returns + ------- + list of str + List of successive decays, e.g. ('beta-', 'neutron') + + """ + return [_DECAY_MODES[int(x)][0] for x in + str(value).strip('0').replace('.', '')] + + +class FissionProductYields(EqualityMixin): + """Independent and cumulative fission product yields. + + Parameters + ---------- + ev_or_filename : str of openmc.data.endf.Evaluation + ENDF fission product yield evaluation to read from. If given as a + string, it is assumed to be the filename for the ENDF file. + + Attributes + ---------- + cumulative : list of dict + Cumulative yields for each tabulated energy. Each item in the list is a + dictionary whose keys are nuclide names and values are cumulative + yields. The i-th dictionary corresponds to the i-th energy. + energies : Iterable of float or None + Energies at which fission product yields are tabulated. + independent : list of dict + Independent yields for each tabulated energy. Each item in the list is a + dictionary whose keys are nuclide names and values are independent + yields. The i-th dictionary corresponds to the i-th energy. + nuclide : dict + Properties of the fissioning nuclide. + + """ + def __init__(self, ev_or_filename): + # Define function that can be used to read both independent and + # cumulative yields + def get_yields(file_obj): + # Determine number of energies + n_energy = get_head_record(file_obj)[2] + if n_energy > 1: + energies = np.zeros(n_energy) + else: + energies = None + + data = [] + for i in range(n_energy): + # Determine i-th energy and number of products + items, values = get_list_record(file_obj) + if n_energy > 1: + energies[i] = items[0] + n_products = items[5] + + # Get yields for i-th energy + yields = {} + for j in range(n_products): + Z, A = divmod(int(values[4*j]), 1000) + excited_state = int(values[4*j + 1]) + name = ATOMIC_SYMBOL[Z] + str(A) + if excited_state > 0: + name += '_e{}'.format(excited_state) + yield_j = ufloat(values[4*j + 2], values[4*j + 3]) + yields[name] = yield_j + + data.append(yields) + + return energies, data + + # Get evaluation if str is passed + if isinstance(ev_or_filename, Evaluation): + ev = ev_or_filename + else: + ev = Evaluation(ev_or_filename) + + # Assign basic nuclide properties + self.nuclide = { + 'name': ev.gnd_name, + 'atomic_number': ev.target['atomic_number'], + 'mass_number': ev.target['mass_number'], + 'isomeric_state': ev.target['isomeric_state'] + } + + # Read independent yields + if (8, 454) in ev.section: + file_obj = StringIO(ev.section[8, 454]) + self.energies, self.independent = get_yields(file_obj) + + # Read cumulative yields + if (8, 459) in ev.section: + file_obj = StringIO(ev.section[8, 459]) + energies, self.cumulative = get_yields(file_obj) + assert np.all(energies == self.energies) + + @classmethod + def from_endf(cls, filename): + """Generate fission product yield data from an ENDF evaluation + + Parameters + ---------- + ev_or_filename : str or openmc.data.endf.Evaluation + ENDF fission product yield evaluation to read from. If given as a + string, it is assumed to be the filename for the ENDF file. + + Returns + ------- + openmc.data.FissionProductYields + Fission product yield data + + """ + return cls(filename) + + +class DecayMode(EqualityMixin): + """Radioactive decay mode. + + Parameters + ---------- + parent : str + Parent decaying nuclide + modes : list of str + Successive decay modes + daughter_state : int + Metastable state of the daughter nuclide + energy : uncertainties.UFloat + Total decay energy in eV available in the decay process. + branching_ratio : uncertainties.UFloat + Fraction of the decay of the parent nuclide which proceeds by this mode. + + Attributes + ---------- + branching_ratio : uncertainties.UFloat + Fraction of the decay of the parent nuclide which proceeds by this mode. + daughter : str + Name of daughter nuclide produced from decay + energy : uncertainties.UFloat + Total decay energy in eV available in the decay process. + modes : list of str + Successive decay modes + parent : str + Parent decaying nuclide + + """ + + def __init__(self, parent, modes, daughter_state, energy, + branching_ratio): + self._daughter_state = daughter_state + self.parent = parent + self.modes = modes + self.energy = energy + self.branching_ratio = branching_ratio + + def __repr__(self): + return (' {}, {}>'.format( + ','.join(self.modes), self.parent, self.daughter, + self.branching_ratio)) + + @property + def branching_ratio(self): + return self._branching_ratio + + @property + def daughter(self): + # Determine atomic number and mass number of parent + symbol, A = re.match(r'([A-Zn][a-z]*)(\d+)', self.parent).groups() + A = int(A) + Z = ATOMIC_NUMBER[symbol] + + # Process changes + for mode in self.modes: + for name, changes in _DECAY_MODES.values(): + if name == mode: + if changes is not None: + delta_A, delta_Z = changes + A += delta_A + Z += delta_Z + + if self._daughter_state > 0: + return '{}{}_m{}'.format(ATOMIC_SYMBOL[Z], A, self._daughter_state) + else: + return '{}{}'.format(ATOMIC_SYMBOL[Z], A) + + @property + def energy(self): + return self._energy + + @property + def modes(self): + return self._modes + + @property + def parent(self): + return self._parent + + @branching_ratio.setter + def branching_ratio(self, branching_ratio): + cv.check_type('branching ratio', branching_ratio, UFloat) + cv.check_greater_than('branching ratio', + branching_ratio.nominal_value, 0.0, True) + if branching_ratio.nominal_value == 0.0: + warn('Decay mode {} of parent {} has a zero branching ratio.' + .format(self.modes, self.parent)) + cv.check_greater_than('branching ratio uncertainty', + branching_ratio.std_dev, 0.0, True) + self._branching_ratio = branching_ratio + + @energy.setter + def energy(self, energy): + cv.check_type('decay energy', energy, UFloat) + cv.check_greater_than('decay energy', energy.nominal_value, 0.0, True) + cv.check_greater_than('decay energy uncertainty', + energy.std_dev, 0.0, True) + self._energy = energy + + @modes.setter + def modes(self, modes): + cv.check_type('decay modes', modes, Iterable, string_types) + self._modes = modes + + @parent.setter + def parent(self, parent): + cv.check_type('parent nuclide', parent, string_types) + self._parent = parent + + +class Decay(EqualityMixin): + """Radioactive decay data. + + Parameters + ---------- + ev_or_filename : str of openmc.data.endf.Evaluation + ENDF radioactive decay data evaluation to read from. If given as a + string, it is assumed to be the filename for the ENDF file. + + Attributes + ---------- + average_energies : dict + Average decay energies in eV of each type of radiation for decay heat + applications. + decay_constant : uncertainties.UFloat + Decay constant in inverse seconds. + half_life : uncertainties.UFloat + Half-life of the decay in seconds. + modes : list + Decay mode information for each mode of decay. + nuclide : dict + Dictionary describing decaying nuclide with keys 'name', + 'excited_state', 'mass', 'stable', 'spin', and 'parity'. + spectra : dict + Resulting radiation spectra for each radiation type. + + """ + def __init__(self, ev_or_filename): + # Get evaluation if str is passed + if isinstance(ev_or_filename, Evaluation): + ev = ev_or_filename + else: + ev = Evaluation(ev_or_filename) + #assert ev.info['sublibrary'] == 'Radioactive decay data' + + file_obj = StringIO(ev.section[8, 457]) + + self.nuclide = {} + self.modes = [] + self.spectra = {} + self.average_energies = {} + + # Get head record + items = get_head_record(file_obj) + Z, A = divmod(items[0], 1000) + metastable = items[3] + self.nuclide['atomic_number'] = Z + self.nuclide['mass_number'] = A + self.nuclide['isomeric_state'] = metastable + if metastable > 0: + self.nuclide['name'] = '{}{}_m{}'.format(ATOMIC_SYMBOL[Z], A, + metastable) + else: + self.nuclide['name'] = '{}{}'.format(ATOMIC_SYMBOL[Z], A) + self.nuclide['mass'] = items[1] # AWR + self.nuclide['excited_state'] = items[2] # State of the original nuclide + self.nuclide['stable'] = (items[4] == 1) # Nucleus stability flag + + # Determine if radioactive/stable + if not self.nuclide['stable']: + NSP = items[5] # Number of radiation types + + # Half-life and decay energies + items, values = get_list_record(file_obj) + self.half_life = ufloat(items[0], items[1]) + NC = items[4]//2 + pairs = [x for x in zip(values[::2], values[1::2])] + ex = self.average_energies + ex['light'] = ufloat(*pairs[0]) + ex['electromagnetic'] = ufloat(*pairs[1]) + ex['heavy'] = ufloat(*pairs[2]) + if NC == 17: + ex['beta-'] = ufloat(*pairs[3]) + ex['beta+'] = ufloat(*pairs[4]) + ex['auger'] = ufloat(*pairs[5]) + ex['conversion'] = ufloat(*pairs[6]) + ex['gamma'] = ufloat(*pairs[7]) + ex['xray'] = ufloat(*pairs[8]) + ex['Bremsstrahlung'] = ufloat(*pairs[9]) + ex['annihilation'] = ufloat(*pairs[10]) + ex['alpha'] = ufloat(*pairs[11]) + ex['recoil'] = ufloat(*pairs[12]) + ex['SF'] = ufloat(*pairs[13]) + ex['neutron'] = ufloat(*pairs[14]) + ex['proton'] = ufloat(*pairs[15]) + ex['neutrino'] = ufloat(*pairs[16]) + + items, values = get_list_record(file_obj) + spin = items[0] + if spin == -77.777: + self.nuclide['spin'] = None + else: + self.nuclide['spin'] = spin + self.nuclide['parity'] = items[1] # Parity of the nuclide + + # Decay mode information + n_modes = items[5] # Number of decay modes + for i in range(n_modes): + decay_type = get_decay_modes(values[6*i]) + isomeric_state = int(values[6*i + 1]) + energy = ufloat(*values[6*i + 2:6*i + 4]) + branching_ratio = ufloat(*values[6*i + 4:6*(i + 1)]) + + mode = DecayMode(self.nuclide['name'], decay_type, isomeric_state, + energy, branching_ratio) + self.modes.append(mode) + + discrete_type = {0.0: None, 1.0: 'allowed', 2.0: 'first-forbidden', + 3.0: 'second-forbidden', 4.0: 'third-forbidden', + 5.0: 'fourth-forbidden', 6.0: 'fifth-forbidden'} + + # Read spectra + for i in range(NSP): + spectrum = {} + + items, values = get_list_record(file_obj) + # Decay radiation type + spectrum['type'] = _RADIATION_TYPES[items[1]] + # Continuous spectrum flag + spectrum['continuous_flag'] = {0: 'discrete', 1: 'continuous', + 2: 'both'}[items[2]] + spectrum['discrete_normalization'] = ufloat(*values[0:2]) + spectrum['energy_average'] = ufloat(*values[2:4]) + spectrum['continuous_normalization'] = ufloat(*values[4:6]) + + NER = items[5] # Number of tabulated discrete energies + + if not spectrum['continuous_flag'] == 'continuous': + # Information about discrete spectrum + spectrum['discrete'] = [] + for j in range(NER): + items, values = get_list_record(file_obj) + di = {} + di['energy'] = ufloat(*items[0:2]) + di['from_mode'] = get_decay_modes(values[0]) + di['type'] = discrete_type[values[1]] + di['intensity'] = ufloat(*values[2:4]) + if spectrum['type'] == 'ec/beta+': + di['positron_intensity'] = ufloat(*values[4:6]) + elif spectrum['type'] == 'gamma': + di['internal_pair'] = ufloat(*values[4:6]) + if len(values) >= 8: + di['total_internal_conversion'] = ufloat(*values[6:8]) + if len(values) == 12: + di['k_shell_conversion'] = ufloat(*values[8:10]) + di['l_shell_conversion'] = ufloat(*values[10:12]) + spectrum['discrete'].append(di) + + if not spectrum['continuous_flag'] == 'discrete': + # Read continuous spectrum + ci = {} + params, ci['probability'] = get_tab1_record(file_obj) + ci['type'] = get_decay_modes(params[0]) + + # Read covariance (Ek, Fk) table + LCOV = params[3] + if LCOV != 0: + items, values = get_list_record(file_obj) + ci['covariance_lb'] = items[3] + ci['covariance'] = zip(values[0::2], values[1::2]) + + spectrum['continuous'] = ci + + # Add spectrum to dictionary + self.spectra[spectrum['type']] = spectrum + + else: + items, values = get_list_record(file_obj) + items, values = get_list_record(file_obj) + self.nuclide['spin'] = items[0] + self.nuclide['parity'] = items[1] + + @property + def decay_constant(self): + return log(2.)/self.half_life diff --git a/openmc/data/endf.py b/openmc/data/endf.py index c0049f977..0197b65e4 100644 --- a/openmc/data/endf.py +++ b/openmc/data/endf.py @@ -17,6 +17,7 @@ from collections import OrderedDict, Iterable import numpy as np from numpy.polynomial.polynomial import Polynomial +from .data import ATOMIC_SYMBOL from .function import Tabulated1D, INTERPOLATION_SCHEME from openmc.stats.univariate import Uniform, Tabular, Legendre @@ -47,16 +48,6 @@ SUM_RULES = {1: [2, 3], _ENDF_FLOAT_RE = re.compile(r'([\s\-\+]?\d*\.\d+)([\+\-]\d+)') -def radiation_type(value): - p = {0: 'gamma', 1: 'beta-', 2: 'ec/beta+', 3: 'IT', - 4: 'alpha', 5: 'neutron', 6: 'sf', 7: 'proton', - 8: 'e-', 9: 'xray', 10: 'unknown'} - if value % 1.0 == 0: - return p[int(value)] - else: - return (p[int(value)], p[int(10*value % 10)]) - - def float_endf(s): """Convert string of floating point number in ENDF to float. @@ -396,6 +387,16 @@ class Evaluation(object): mod = 0 self.reaction_list.append((mf, mt, nc, mod)) + @property + def gnd_name(self): + symbol = ATOMIC_SYMBOL[self.target['atomic_number']] + A = self.target['mass_number'] + m = self.target['isomeric_state'] + if m > 0: + return '{}{}_m{}'.format(symbol, A, m) + else: + return '{}{}'.format(symbol, A) + class Tabulated2D(object): """Metadata for a two-dimensional function. diff --git a/setup.py b/setup.py index 0885c28a8..befb9c0d2 100755 --- a/setup.py +++ b/setup.py @@ -43,6 +43,7 @@ if have_setuptools: # Optional dependencies 'extras_require': { + 'decay': ['uncertainties'], 'pandas': ['pandas>=0.17.0'], 'sparse' : ['scipy'], 'vtk': ['vtk', 'silomesh'], From c34460d647adc52a39e3f44ee98db6e2ac11ed22 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 18 Nov 2016 06:52:21 -0600 Subject: [PATCH 36/60] Make spaces per indent configurable for clean_xml_indentation --- openmc/clean_xml.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openmc/clean_xml.py b/openmc/clean_xml.py index 564281a5c..6aaf64c66 100644 --- a/openmc/clean_xml.py +++ b/openmc/clean_xml.py @@ -65,25 +65,25 @@ def sort_xml_elements(tree): tree.extend(sorted_elements) -def clean_xml_indentation(element, level=0): +def clean_xml_indentation(element, level=0, spaces_per_level=4): """ copy and paste from http://effbot.org/zone/elementent-lib.htm#prettyprint it basically walks your tree and adds spaces and newlines so the tree is printed in a nice way """ - i = "\n" + level*" " + i = "\n" + level*spaces_per_level*" " if len(element): if not element.text or not element.text.strip(): - element.text = i + " " + element.text = i + spaces_per_level*" " if not element.tail or not element.tail.strip(): element.tail = i for sub_element in element: - clean_xml_indentation(sub_element, level+1) + clean_xml_indentation(sub_element, level+1, spaces_per_level) if not sub_element.tail or not sub_element.tail.strip(): sub_element.tail = i From e5ecfb18b982e9d9992a5dde918efedb93a706af Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 18 Nov 2016 06:52:47 -0600 Subject: [PATCH 37/60] Add (n,2n) level reactions to REACTION_NAME --- openmc/data/reaction.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/openmc/data/reaction.py b/openmc/data/reaction.py index 23b864bf3..08930fa65 100644 --- a/openmc/data/reaction.py +++ b/openmc/data/reaction.py @@ -55,13 +55,14 @@ REACTION_NAME = {1: '(n,total)', 2: '(n,elastic)', 4: '(n,level)', 195: '(n,4n2a)', 196: '(n,4npa)', 197: '(n,3p)', 198: '(n,n3p)', 199: '(n,3n2pa)', 200: '(n,5n2p)', 444: '(n,damage)', 649: '(n,pc)', 699: '(n,dc)', 749: '(n,tc)', 799: '(n,3Hec)', - 849: '(n,ac)'} -REACTION_NAME.update({i: '(n,n{})'.format(i-50) for i in range(50, 91)}) -REACTION_NAME.update({i: '(n,p{})'.format(i-600) for i in range(600, 649)}) -REACTION_NAME.update({i: '(n,d{})'.format(i-650) for i in range(650, 699)}) -REACTION_NAME.update({i: '(n,t{})'.format(i-700) for i in range(700, 749)}) -REACTION_NAME.update({i: '(n,3He{})'.format(i-750) for i in range(750, 799)}) -REACTION_NAME.update({i: '(n,a{})'.format(i-800) for i in range(800, 849)}) + 849: '(n,ac)', 891: '(n,2nc)'} +REACTION_NAME.update({i: '(n,n{})'.format(i - 50) for i in range(50, 91)}) +REACTION_NAME.update({i: '(n,p{})'.format(i - 600) for i in range(600, 649)}) +REACTION_NAME.update({i: '(n,d{})'.format(i - 650) for i in range(650, 699)}) +REACTION_NAME.update({i: '(n,t{})'.format(i - 700) for i in range(700, 749)}) +REACTION_NAME.update({i: '(n,3He{})'.format(i - 750) for i in range(750, 799)}) +REACTION_NAME.update({i: '(n,a{})'.format(i - 800) for i in range(800, 849)}) +REACTION_NAME.update({i: '(n,2n{})'.format(i - 875) for i in range(875, 891)}) def _get_products(ev, mt): From fb4d9df41b86b8c68f9b185d0fc85f0fad157155 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 18 Nov 2016 06:54:15 -0600 Subject: [PATCH 38/60] Make sure LaboratoryAngleEnergy has a to_hdf5() method --- openmc/data/laboratory.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openmc/data/laboratory.py b/openmc/data/laboratory.py index be449b79a..0a8908362 100644 --- a/openmc/data/laboratory.py +++ b/openmc/data/laboratory.py @@ -137,3 +137,6 @@ class LaboratoryAngleEnergy(AngleEnergy): energy_out.append(energy_out_i) return cls(tab2.breakpoints, tab2.interpolation, energy, mu, energy_out) + + def to_hdf5(self, group): + raise NotImplementedError From 643eaf53cbbfe133df54f38c5bb0d0c23cb93442 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 18 Nov 2016 11:04:34 -0600 Subject: [PATCH 39/60] Add function to read all ENDF evaluations from a single file --- docs/source/pythonapi/index.rst | 1 + openmc/data/endf.py | 39 +++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index b86107f37..fc01b99e7 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -478,6 +478,7 @@ Functions openmc.data.endf.float_endf openmc.data.endf.get_cont_record + openmc.data.endf.get_evaluations openmc.data.endf.get_head_record openmc.data.endf.get_tab1_record openmc.data.endf.get_tab2_record diff --git a/openmc/data/endf.py b/openmc/data/endf.py index 0197b65e4..34553ad2d 100644 --- a/openmc/data/endf.py +++ b/openmc/data/endf.py @@ -14,6 +14,7 @@ import os from math import pi from collections import OrderedDict, Iterable +from six import string_types import numpy as np from numpy.polynomial.polynomial import Polynomial @@ -249,14 +250,40 @@ def get_tab2_record(file_obj): return params, Tabulated2D(breakpoints, interpolation) +def get_evaluations(filename): + """Return a list of all evaluations within an ENDF file. + + Parameters + ---------- + filename : str + Path to ENDF-6 formatted file + + Returns + ------- + list + A list of :class:`openmc.data.endf.Evaluation` instances. + + """ + evaluations = [] + with open(filename, 'r') as fh: + while True: + pos = fh.tell() + line = fh.readline() + if line[66:70] == ' -1': + break + fh.seek(pos) + evaluations.append(Evaluation(fh)) + return evaluations + class Evaluation(object): """ENDF material evaluation with multiple files/sections Parameters ---------- - filename : str - Path to ENDF file to read + filename_or_obj : str or file-like + Path to ENDF file to read or an open file positioned at the start of an + ENDF material Attributes ---------- @@ -273,8 +300,11 @@ class Evaluation(object): indicator (MOD). """ - def __init__(self, filename): - fh = open(filename, 'r') + def __init__(self, filename_or_obj): + if isinstance(filename_or_obj, string_types): + fh = open(filename_or_obj, 'r') + else: + fh = filename_or_obj self.section = {} self.info = {} self.target = {} @@ -304,6 +334,7 @@ class Evaluation(object): # If end of material reached, exit loop if MAT == 0: + fh.readline() break section_data = '' From b4c556db828f23e52f8ff1d4a3c188dfc2e8b58d Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Fri, 18 Nov 2016 19:55:24 -0500 Subject: [PATCH 40/60] incorporated MT=5, simplified yield usage in the plotter --- openmc/data/library.py | 3 +- openmc/material.py | 7 +---- openmc/plotter.py | 65 +++++++++++++++++++++--------------------- 3 files changed, 36 insertions(+), 39 deletions(-) diff --git a/openmc/data/library.py b/openmc/data/library.py index 34cd380a5..c179f78f8 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -1,5 +1,6 @@ import os import xml.etree.ElementTree as ET +from six import string_types import h5py @@ -124,7 +125,7 @@ class DataLibrary(EqualityMixin): raise ValueError("Either path or OPENMC_CROSS_SECTIONS " "environmental variable must be set") - check_type('path', path, str) + check_type('path', path, string_types) tree = ET.parse(path) root = tree.getroot() diff --git a/openmc/material.py b/openmc/material.py index 84d790feb..08b001e47 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -606,15 +606,10 @@ class Material(object): return nuclides - def get_nuclide_atom_densities(self, cross_sections=None): + def get_nuclide_atom_densities(self): """Returns all nuclides in the material and their atomic densities in units of atom/b-cm - Parameters - ---------- - cross_sections : str, optional - Location of cross_sections.xml file. Default is None. - Returns ------- nuclides : dict diff --git a/openmc/plotter.py b/openmc/plotter.py index 626450456..e20363ca4 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -1,4 +1,5 @@ from numbers import Integral, Real +from six import string_types import numpy as np @@ -15,7 +16,7 @@ UNITY_MT = -1 XI_MT = -2 # MTs to combine to generate associated plot_types -_INELASTIC = [mt for mt in openmc.data.SUM_RULES[3] if mt not in [5, 27]] +_INELASTIC = [mt for mt in openmc.data.SUM_RULES[3] if mt != 27] PLOT_TYPES_MT = {'total': openmc.data.SUM_RULES[1], 'scatter': [2] + _INELASTIC, 'elastic': [2], @@ -41,19 +42,6 @@ PLOT_TYPES_OP = {'total': (np.add,), (np.add,) * (len(PLOT_TYPES_MT['slowing-down power']) - 2) + (np.multiply,), 'damage': ()} -# Whether or not to multiply the reaction by the yield as well -PLOT_TYPES_YIELD = {'total': (False, False), - 'scatter': (False,) * len(PLOT_TYPES_MT['scatter']), - 'elastic': (False,), - 'inelastic': (False,) * len(PLOT_TYPES_MT['inelastic']), - 'fission': (False,), 'absorption': (False,), - 'capture': (False,), 'nu-fission': (True,), - 'nu-scatter': (True,) * len(PLOT_TYPES_MT['nu-scatter']), - 'unity': (False,), - 'slowing-down power': - (True,) * len(PLOT_TYPES_MT['slowing-down power']), - 'damage': (False,)} - # Types of plots to plot linearly in y PLOT_TYPES_LINEAR = {'nu-fission / fission', 'nu-scatter / scatter', 'nu-fission / absorption', 'fission / absorption'} @@ -230,7 +218,7 @@ def calculate_xs(this, types, temperature=294., sab_name=None, # Check types cv.check_type('temperature', temperature, Real) if sab_name: - cv.check_type('sab_name', sab_name, str) + cv.check_type('sab_name', sab_name, string_types) if enrichment: cv.check_type('enrichment', enrichment, Real) @@ -370,15 +358,18 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, for line in types: if line in PLOT_TYPES: mts.append(PLOT_TYPES_MT[line]) - yields.append(PLOT_TYPES_YIELD[line]) + if line.startswith('nu'): + yields.append(True) + else: + yields.append(False) ops.append(PLOT_TYPES_OP[line]) else: # Not a built-in type, we have to parse it ourselves cv.check_type('MT in types', line, Integral) cv.check_greater_than('MT in types', line, 0) mts.append((line,)) - yields.append((False,)) ops.append(()) + yields.append(False) # Load the library library = openmc.data.DataLibrary.from_xml(cross_sections) @@ -456,7 +447,7 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, # Get the reaction xs data from the nuclide funcs = [] op = ops[i] - for mt, yield_check in zip(mt_set, yields[i]): + for mt in mt_set: if mt == 2: if sab_name: # Then we need to do a piece-wise function of @@ -468,28 +459,38 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, funcs.append(pw_funcs) else: funcs.append(nuc[mt].xs[nucT]) + elif mt == 5 and mt in nuc: + # Only consider the (n,misc) products if neutrons are + # included in the outgoing channel since (n,misc) is only + # explicitly needed for scatter cross sections. + for prod in nuc[mt].products: + if prod.particle == 'neutron' and \ + prod.emission_mode in ('total', 'prompt'): + if yields[i]: + func = openmc.data.Combination( + [nuc[mt].xs[nucT], prod.yield_], + [np.multiply]) + else: + func = nuc[mt].xs[nucT] + + funcs.append(func) + break + else: + funcs.append(lambda x: 0.) + elif mt in nuc: - if yield_check: + if yields[i]: for prod in nuc[mt].products: if prod.particle == 'neutron' and \ - prod.emission_mode == 'total': + prod.emission_mode in ('total', 'prompt'): func = openmc.data.Combination( [nuc[mt].xs[nucT], prod.yield_], [np.multiply]) funcs.append(func) break else: - for prod in nuc[mt].products: - if prod.particle == 'neutron' and \ - prod.emission_mode == 'prompt': - func = openmc.data.Combination( - [nuc[mt].xs[nucT], - prod.yield_], [np.multiply]) - funcs.append(func) - break - else: - # Assume the yield is 1 - funcs.append(nuc[mt].xs[nucT]) + # Assume the yield is 1 + funcs.append(nuc[mt].xs[nucT]) else: funcs.append(nuc[mt].xs[nucT]) elif mt == UNITY_MT: @@ -545,7 +546,7 @@ def _calculate_xs_material(this, types, temperature=294., cross_sections=None): library = openmc.data.DataLibrary.from_xml(cross_sections) # Expand elements in to nuclides with atomic densities - nuclides = this.get_nuclide_atom_densities(cross_sections) + nuclides = this.get_nuclide_atom_densities() # For ease of processing split out nuc and nuc_density nuc_densities = [nuclide[1][1] for nuclide in nuclides.items()] From e764a0852fcc809de030eb84f82fcdc7ce10dbd7 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 19 Nov 2016 21:02:50 -0500 Subject: [PATCH 41/60] Fixed the stupid for n in range... --- openmc/plotter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openmc/plotter.py b/openmc/plotter.py index e20363ca4..72d4a43fa 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -304,8 +304,8 @@ def _calculate_xs_element(this, types, temperature=294., sab_name=None, # Condense the data for every nuclide # First create a union energy grid energy_grid = E[0] - for n in range(1, len(E)): - energy_grid = np.union1d(energy_grid, E[n]) + for grid in E[1:]: + energy_grid = np.union1d(energy_grid, grid) # Now we can combine all the nuclidic data data = np.zeros((len(types), len(energy_grid))) From 9afb0c8d68c01b513fbe5c1d9240e290f67104fe Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 19 Nov 2016 22:52:30 -0500 Subject: [PATCH 42/60] Made the _calculate_xs routines consistent in what they return to give us a little simplification --- openmc/plotter.py | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/openmc/plotter.py b/openmc/plotter.py index 72d4a43fa..97add26ff 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -149,13 +149,9 @@ def plot_xs(this, types, divisor_types=None, temperature=294., axis=None, plot_func = ax.loglog # Plot the data for i in range(len(data)): - if data_type == 'nuclide': - to_plot = data[i](E) - else: - to_plot = data[i, :] - to_plot = np.nan_to_num(to_plot) - if np.sum(to_plot) > 0.: - plot_func(E, to_plot, label=types[i]) + data[i, :] = np.nan_to_num(data[i, :]) + if np.sum(data[i, :]) > 0.: + plot_func(E, data[i, :], label=types[i]) ax.set_xlabel('Energy [eV]') if divisor_types: @@ -223,11 +219,17 @@ def calculate_xs(this, types, temperature=294., sab_name=None, cv.check_type('enrichment', enrichment, Real) if isinstance(this, openmc.Nuclide): - energy_grid, data = _calculate_xs_nuclide(this, types, temperature, - sab_name, cross_sections) + energy_grid, xs = _calculate_xs_nuclide(this, types, temperature, + sab_name, cross_sections) + # Convert xs (Iterable of Callable) to a grid of cross section values + # calculated on @ the points in energy_grid for consistency with the + # element and material functions. + data = np.zeros((len(types), len(energy_grid))) + for line in range(len(types)): + data[line, :] = xs[line](energy_grid) elif isinstance(this, openmc.Element): energy_grid, data = _calculate_xs_element(this, types, temperature, - sab_name, cross_sections, + cross_sections, sab_name, enrichment) elif isinstance(this, openmc.Material): energy_grid, data = _calculate_xs_material(this, types, temperature, @@ -299,7 +301,10 @@ def _calculate_xs_element(this, types, temperature=294., sab_name=None, temp_E, temp_xs = calculate_xs(nuclide[0], types, temperature, sab_tab, cross_sections) E.append(temp_E) - xs.append(temp_xs) + # Since the energy grids are different, store the cross sections as + # a tabulated function so they can be calculated on any grid needed. + xs.append([openmc.data.Tabulated1D(temp_E, temp_xs[line]) + for line in range(len(types))]) # Condense the data for every nuclide # First create a union energy grid @@ -345,9 +350,8 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, ------- energy_grid : numpy.ndarray Energies at which cross sections are calculated, in units of eV - data : numpy.ndarray - Cross sections calculated at the energy grid described by - energy_grid + data : Iterable of Callable + Requested cross section functions """ @@ -569,7 +573,10 @@ def _calculate_xs_material(this, types, temperature=294., cross_sections=None): temp_E, temp_xs = calculate_xs(nuclide[0], types, T, sab_tab, cross_sections) E.append(temp_E) - xs.append(temp_xs) + # Since the energy grids are different, store the cross sections as + # a tabulated function so they can be calculated on any grid needed. + xs.append([openmc.data.Tabulated1D(temp_E, temp_xs[line]) + for line in range(len(types))]) # Condense the data for every nuclide # First create a union energy grid From 24798a0ecd6e51ad2e11f8cd5839ef2847282e3f Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 19 Nov 2016 23:29:59 -0500 Subject: [PATCH 43/60] Combined the elemental and material calculate_xs routines --- openmc/plotter.py | 178 ++++++++++++++++------------------------------ 1 file changed, 63 insertions(+), 115 deletions(-) diff --git a/openmc/plotter.py b/openmc/plotter.py index 97add26ff..cf2c97b92 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -228,11 +228,11 @@ def calculate_xs(this, types, temperature=294., sab_name=None, for line in range(len(types)): data[line, :] = xs[line](energy_grid) elif isinstance(this, openmc.Element): - energy_grid, data = _calculate_xs_element(this, types, temperature, - cross_sections, sab_name, - enrichment) + energy_grid, data = _calculate_xs_elem_mat(this, types, temperature, + cross_sections, sab_name, + enrichment) elif isinstance(this, openmc.Material): - energy_grid, data = _calculate_xs_material(this, types, temperature, + energy_grid, data = _calculate_xs_elem_mat(this, types, temperature, cross_sections) else: raise TypeError("Invalid type") @@ -240,90 +240,6 @@ def calculate_xs(this, types, temperature=294., sab_name=None, return energy_grid, data -def _calculate_xs_element(this, types, temperature=294., sab_name=None, - cross_sections=None, enrichment=None): - """Calculates continuous-energy cross sections of a requested type - - Parameters - ---------- - this : openmc.Element - Element object to source data from - types : Iterable of values of PLOT_TYPES - The type of cross sections to calculate - temperature : float, optional - Temperature in Kelvin to plot. If not specified, a default - temperature of 294K will be plotted. Note that the nearest - temperature in the library for each nuclide will be used as opposed - to using any interpolation. - sab_name : str, optional - Name of S(a,b) library to apply to MT=2 data when applicable. - cross_sections : str, optional - Location of cross_sections.xml file. Default is None. - enrichment : float, optional - Enrichment for U235 in weight percent. For example, input 4.95 for - 4.95 weight percent enriched U. Default is None - (natural composition). - - Returns - ------- - energy_grid : numpy.ndarray - Energies at which cross sections are calculated, in units of eV - data : numpy.ndarray - Macroscopic cross sections calculated at the energy grid described - by energy_grid - - """ - - # Load the library - library = openmc.data.DataLibrary.from_xml(cross_sections) - - # Expand elements in to nuclides with atomic densities - nuclides = this.expand(1., 'ao', enrichment=enrichment, - cross_sections=cross_sections) - - # For ease of processing split out nuc and nuc_density - nuc_fractions = [nuclide[1] for nuclide in nuclides] - - # Identify the nuclides which have S(a,b) data - sabs = {} - for nuclide in nuclides: - sabs[nuclide[0].name] = None - if sab_name: - sab = openmc.data.ThermalScattering.from_hdf5(sab_name) - for nuc in sab.nuclides: - sabs[nuc] = library.get_by_material(sab_name)['path'] - - # Now we can create the data sets to be plotted - xs = [] - E = [] - for nuclide in nuclides: - sab_tab = sabs[nuclide[0].name] - temp_E, temp_xs = calculate_xs(nuclide[0], types, temperature, sab_tab, - cross_sections) - E.append(temp_E) - # Since the energy grids are different, store the cross sections as - # a tabulated function so they can be calculated on any grid needed. - xs.append([openmc.data.Tabulated1D(temp_E, temp_xs[line]) - for line in range(len(types))]) - - # Condense the data for every nuclide - # First create a union energy grid - energy_grid = E[0] - for grid in E[1:]: - energy_grid = np.union1d(energy_grid, grid) - - # Now we can combine all the nuclidic data - data = np.zeros((len(types), len(energy_grid))) - for line in range(len(types)): - if types[line] == 'unity': - data[line, :] = 1. - else: - for n in range(len(nuclides)): - data[line, :] += nuc_fractions[n] * xs[n][line](energy_grid) - - return energy_grid, data - - def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, cross_sections=None): """Calculates continuous-energy cross sections of a requested type @@ -513,14 +429,14 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, return energy_grid, xs -def _calculate_xs_material(this, types, temperature=294., cross_sections=None): - """Calculates continuous-energy macroscopic cross sections of a - requested type +def _calculate_xs_elem_mat(this, types, temperature=294., cross_sections=None, + sab_name=None, enrichment=None): + """Calculates continuous-energy cross sections of a requested type Parameters ---------- - this : openmc.Material - Material object to source data from + this : {openmc.Material, openmc.Element} + Object to source data from types : Iterable of values of PLOT_TYPES The type of cross sections to calculate temperature : float, optional @@ -530,53 +446,83 @@ def _calculate_xs_material(this, types, temperature=294., cross_sections=None): to using any interpolation. cross_sections : str, optional Location of cross_sections.xml file. Default is None. + sab_name : str, optional + Name of S(a,b) library to apply to MT=2 data when applicable. + enrichment : float, optional + Enrichment for U235 in weight percent. For example, input 4.95 for + 4.95 weight percent enriched U. Default is None + (natural composition). Returns ------- energy_grid : numpy.ndarray Energies at which cross sections are calculated, in units of eV data : numpy.ndarray - Macroscopic cross sections calculated at the energy grid described - by energy_grid + Cross sections calculated at the energy grid described by energy_grid """ - if this.temperature is not None: - T = this.temperature + if isinstance(this, openmc.Material): + if this.temperature is not None: + T = this.temperature + else: + T = temperature else: T = temperature # Load the library library = openmc.data.DataLibrary.from_xml(cross_sections) - # Expand elements in to nuclides with atomic densities - nuclides = this.get_nuclide_atom_densities() + if isinstance(this, openmc.Material): + # Expand elements in to nuclides with atomic densities + nuclides = this.get_nuclide_atom_densities() - # For ease of processing split out nuc and nuc_density - nuc_densities = [nuclide[1][1] for nuclide in nuclides.items()] + # For ease of processing split out the nuclide and its fraction + nuc_fractions = {nuclide[1][0].name: nuclide[1][1] + for nuclide in nuclides.items()} + # Create a dict of [nuclide name] = nuclide object to carry forward + nuclides = {nuclide[1][0].name: nuclide[1][0] + for nuclide in nuclides.items()} + else: + # Expand elements in to nuclides with atomic densities + nuclides = this.expand(1., 'ao', enrichment=enrichment, + cross_sections=cross_sections) + + # For ease of processing split out the nuclide and its fraction + nuc_fractions = {nuclide[0].name: nuclide[1] for nuclide in nuclides} + # Create a dict of [nuclide name] = nuclide object to carry forward + nuclides = {nuclide[0].name: nuclide[0] for nuclide in nuclides} # Identify the nuclides which have S(a,b) data sabs = {} for nuclide in nuclides.items(): - sabs[nuclide[0].name] = None - for sab_name in this._sab: - sab = openmc.data.ThermalScattering.from_hdf5( - library.get_by_material(sab_name)['path']) - for nuc in sab.nuclides: - sabs[nuc] = library.get_by_material(sab_name)['path'] + sabs[nuclide[0]] = None + if isinstance(this, openmc.Material): + for sab_name in this._sab: + sab = openmc.data.ThermalScattering.from_hdf5( + library.get_by_material(sab_name)['path']) + for nuc in sab.nuclides: + sabs[nuc] = library.get_by_material(sab_name)['path'] + else: + if sab_name: + sab = openmc.data.ThermalScattering.from_hdf5(sab_name) + for nuc in sab.nuclides: + sabs[nuc] = library.get_by_material(sab_name)['path'] # Now we can create the data sets to be plotted - xs = [] + xs = {} E = [] + # for nuclide in nuclides: for nuclide in nuclides.items(): - sab_tab = sabs[nuclide[0].name] - temp_E, temp_xs = calculate_xs(nuclide[0], types, T, sab_tab, - cross_sections) + name = nuclide[0] + nuc = nuclide[1] + sab_tab = sabs[name] + temp_E, temp_xs = calculate_xs(nuc, types, T, sab_tab, cross_sections) E.append(temp_E) # Since the energy grids are different, store the cross sections as # a tabulated function so they can be calculated on any grid needed. - xs.append([openmc.data.Tabulated1D(temp_E, temp_xs[line]) - for line in range(len(types))]) + xs[name] = [openmc.data.Tabulated1D(temp_E, temp_xs[line]) + for line in range(len(types))] # Condense the data for every nuclide # First create a union energy grid @@ -590,7 +536,9 @@ def _calculate_xs_material(this, types, temperature=294., cross_sections=None): if types[line] == 'unity': data[line, :] = 1. else: - for n in range(len(nuclides)): - data[line, :] += nuc_densities[n] * xs[n][line](energy_grid) + for nuclide in nuclides.items(): + name = nuclide[0] + data[line, :] += (nuc_fractions[name] * + xs[name][line](energy_grid)) return energy_grid, data From 27c07b02d63b1f5b6bd0b7d4093af6c50055db6e Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 19 Nov 2016 23:32:49 -0500 Subject: [PATCH 44/60] cleaned up some comments --- openmc/plotter.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openmc/plotter.py b/openmc/plotter.py index cf2c97b92..45783d6cf 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -476,21 +476,23 @@ def _calculate_xs_elem_mat(this, types, temperature=294., cross_sections=None, if isinstance(this, openmc.Material): # Expand elements in to nuclides with atomic densities nuclides = this.get_nuclide_atom_densities() - # For ease of processing split out the nuclide and its fraction nuc_fractions = {nuclide[1][0].name: nuclide[1][1] for nuclide in nuclides.items()} # Create a dict of [nuclide name] = nuclide object to carry forward + # with a common nuclides format between openmc.Material and + # openmc.Element objects nuclides = {nuclide[1][0].name: nuclide[1][0] for nuclide in nuclides.items()} else: # Expand elements in to nuclides with atomic densities nuclides = this.expand(1., 'ao', enrichment=enrichment, cross_sections=cross_sections) - # For ease of processing split out the nuclide and its fraction nuc_fractions = {nuclide[0].name: nuclide[1] for nuclide in nuclides} # Create a dict of [nuclide name] = nuclide object to carry forward + # with a common nuclides format between openmc.Material and + # openmc.Element objects nuclides = {nuclide[0].name: nuclide[0] for nuclide in nuclides} # Identify the nuclides which have S(a,b) data @@ -512,7 +514,6 @@ def _calculate_xs_elem_mat(this, types, temperature=294., cross_sections=None, # Now we can create the data sets to be plotted xs = {} E = [] - # for nuclide in nuclides: for nuclide in nuclides.items(): name = nuclide[0] nuc = nuclide[1] From 14e3684a6a4013cb27900d474a60a18424bf0ed8 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 20 Nov 2016 06:05:36 -0500 Subject: [PATCH 45/60] Fixed issue with plotting nuclides with divisor types --- openmc/plotter.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/openmc/plotter.py b/openmc/plotter.py index 45783d6cf..d6c9527bd 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -116,20 +116,12 @@ def plot_xs(this, types, divisor_types=None, temperature=294., axis=None, # grid, and then do the actual division Enum = E[:] E = np.union1d(Enum, Ediv) - if data_type == 'nuclide': - data_new = [] - else: - data_new = np.zeros((len(types), len(E))) + data_new = np.zeros((len(types), len(E))) for line in range(len(types)): - if data_type == 'nuclide': - data_new.append(openmc.data.Combination([data[line], - data_div[line]], - [np.divide])) - else: - data_new[line, :] = \ - np.divide(np.interp(E, Enum, data[line, :]), - np.interp(E, Ediv, data_div[line, :])) + data_new[line, :] = \ + np.divide(np.interp(E, Enum, data[line, :]), + np.interp(E, Ediv, data_div[line, :])) if divisor_types[line] != 'unity': types[line] = types[line] + ' / ' + divisor_types[line] data = data_new From 91567fd9f4cf6590fae350bd74d761bc56949cff Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 21 Nov 2016 10:49:39 -0600 Subject: [PATCH 46/60] Fix broken links, update publications, list @samuelshaner as dev --- docs/source/developers.rst | 3 ++- docs/source/devguide/workflow.rst | 2 +- docs/source/methods/geometry.rst | 6 +++--- docs/source/publications.rst | 23 ++++++++++++++++++++++- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/docs/source/developers.rst b/docs/source/developers.rst index d82d89744..0bdae2416 100644 --- a/docs/source/developers.rst +++ b/docs/source/developers.rst @@ -13,6 +13,7 @@ Active development of the OpenMC Monte Carlo code is currently led by: * `Jon Walsh `_ * `Sterling Harper `_ * `Will Boyd `_ +* `Samuel Shaner `_ * `Benoit Forget `_ * `Kord Smith `_ -* `Andrew Siegel `_ +* `Andrew Siegel `_ diff --git a/docs/source/devguide/workflow.rst b/docs/source/devguide/workflow.rst index 2f36436ca..a53bd114b 100644 --- a/docs/source/devguide/workflow.rst +++ b/docs/source/devguide/workflow.rst @@ -238,4 +238,4 @@ from your private repository into a public fork. .. _paid plan: https://github.com/plans .. _Bitbucket: https://bitbucket.org .. _ctest: http://www.cmake.org/cmake/help/v2.8.12/ctest.html -.. _NNDC: http://http://www.nndc.bnl.gov/endf/b7.1/acefiles.html +.. _NNDC: http://www.nndc.bnl.gov/endf/b7.1/acefiles.html diff --git a/docs/source/methods/geometry.rst b/docs/source/methods/geometry.rst index c2e7270b6..36c252bb1 100644 --- a/docs/source/methods/geometry.rst +++ b/docs/source/methods/geometry.rst @@ -384,7 +384,7 @@ x - x_0`, :math:`\bar{y} = y - y_0`, and :math:`\bar{z} = z - z_0`. We then have Expanding equation :eq:`dist-xcone-1` and rearranging terms, we obtain .. math:: - :label: dist-xcylinder-2 + :label: dist-xcone-2 (v^2 + w^2 - R^2u^2) d^2 + 2 (\bar{y}v + \bar{z}w - R^2\bar{x}u) d + (\bar{y}^2 + \bar{z}^2 - R^2\bar{x}^2) = 0 @@ -392,7 +392,7 @@ Expanding equation :eq:`dist-xcone-1` and rearranging terms, we obtain Defining the terms .. math:: - :label: dist-quadric-terms + :label: dist-xcone-terms a = v^2 + w^2 - R^2u^2 @@ -896,4 +896,4 @@ Dxy + Eyz + Fxz + Gx + Hy + Jz + K = 0`. Thus, the gradient to the surface is .. _surfaces: http://en.wikipedia.org/wiki/Surface .. _MCNP: http://mcnp.lanl.gov .. _Serpent: http://montecarlo.vtt.fi -.. _Monte Carlo Performance benchmark: https://github.com/paulromano/benchmarks/tree/master/mc-performance/openmc +.. _Monte Carlo Performance benchmark: https://github.com/mit-crpg/benchmarks/tree/master/mc-performance/openmc diff --git a/docs/source/publications.rst b/docs/source/publications.rst index c5b29b194..7e79cf33f 100644 --- a/docs/source/publications.rst +++ b/docs/source/publications.rst @@ -82,6 +82,10 @@ Coupling and Multi-physics Geometry -------- +- Derek M. Lax, "Memory efficient indexing algorithm for physical properties in + OpenMC," S. M. Thesis, Massachusetts Institute of Technology + (2015). ``_ + - Derek Lax, William Boyd, Nicholas Horelik, Benoit Forget, and Kord Smith, "A memory efficient algorithm for classifying unique regions in constructive solid geometries," *Proc. PHYSOR*, Kyoto, Japan, Sep. 28--Oct. 3 (2014). @@ -106,6 +110,10 @@ Miscellaneous triggers for the OpenMC Monte Carlo code," *Trans. Am. Nucl. Soc.*, **112**, 637-640 (2015). +- Kyungkwan Noh and Deokjung Lee, "Whole Core Analysis using OpenMC Monte Carlo + Code," *Trans. Kor. Nucl. Soc. Autumn Meeting*, Gyeongju, Korea, + Oct. 24-25, 2013. + - Timothy P. Burke, Brian C. Kiedrowski, and William R. Martin, "Flux and Reaction Rate Kernel Density Estimators in OpenMC," *Trans. Am. Nucl. Soc.*, **109**, 683-686 (2013). @@ -139,7 +147,7 @@ Doppler Broadening - Colin Josey, Pablo Ducru, Benoit Forget, and Kord Smith, "Windowed multipole for cross section Doppler broadening," *J. Comput. Phys.*, **307**, 715-727 - (2016). ``_ + (2016). ``_ - Jonathan A. Walsh, Benoit Forget, Kord S. Smith, and Forrest B. Brown, "On-the-fly Doppler Broadening of Unresolved Resonance Region Cross Sections @@ -213,10 +221,19 @@ Parallelism memory subsystem on Monte Carlo code performance," *Proc. Joint Int. Conf. M&C+SNA+MC*, Nashville, Tennessee, Apr. 19--23 (2015). +- Hajime Fujita, Nan Dun, Aiman Fang, Zachary A. Rubinstein, Ziming Zheng, Kamil + Iskra, Jeff Hammonds, Anshu Dubey, Pavan Balaji, and Andrew A. Chien, "Using + Global View Resilience (GVR) to add Resilience to Exascale Applications," + *Proc. Supercomputing*, New Orleans, Louisiana, Nov. 16--21, 2014. + - Nicholas Horelik, Benoit Forget, Kord Smith, and Andrew Siegel, "Domain decomposition and terabyte tallies with the OpenMC Monte Carlo neutron transport code," *Proc. PHYSOR*, Kyoto Japan, Sep. 28--Oct. 3 (2014). +- John R. Tramm, Andrew R. Siegel, Tanzima Islam, and Martin Schulz, "XSBench -- + the development and verification of a performance abstraction for Monte Carlo + reactor analysis," *Proc. PHYSOR*, Kyoto, Japan, Sep 28--Oct. 3, 2014. + - Nicholas Horelik, Andrew Siegel, Benoit Forget, and Kord Smith, "Monte Carlo domain decomposition for robust nuclear reactor analysis," *Parallel Comput.*, **40**, 646--660 (2014). ``_ @@ -270,6 +287,10 @@ Parallelism Depletion --------- +- Anas Gul, K. S. Chaudri, R. Khan, and M. Azeen, "Development and verification + of LOOP: A Linkage of ORIGEN2.2 and OpenMC," *Ann. Nucl. Energy*, **99**, + 321--327 (2017). ``_ + - Kai Huang, Hongchun Wu, Yunzhao Li, and Liangzhi Cao, "Generalized depletion chain simplification based of significance analysis," *Proc. PHYSOR*, Sun Valley, Idaho, May 1-5, 2016. From 4e059a4d2b435fae41902a8cef1834b69cc5727c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 21 Nov 2016 14:10:40 -0600 Subject: [PATCH 47/60] Use isomeric state, not excited state, for fission products. After a discussion with Dave Brown from BNL, it was confirmed that FPS in the ENDF-6 format for fission product yields refers to the isomeric state, not the excited state. --- openmc/data/decay.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openmc/data/decay.py b/openmc/data/decay.py index 35bc11345..41929c034 100644 --- a/openmc/data/decay.py +++ b/openmc/data/decay.py @@ -114,10 +114,10 @@ class FissionProductYields(EqualityMixin): yields = {} for j in range(n_products): Z, A = divmod(int(values[4*j]), 1000) - excited_state = int(values[4*j + 1]) + isomeric_state = int(values[4*j + 1]) name = ATOMIC_SYMBOL[Z] + str(A) - if excited_state > 0: - name += '_e{}'.format(excited_state) + if isomeric_state > 0: + name += '_m{}'.format(isomeric_state) yield_j = ufloat(values[4*j + 2], values[4*j + 3]) yields[name] = yield_j From 20ce145e366a50240fbec7e552f6fb60ed46c3d7 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 21 Nov 2016 20:30:54 -0500 Subject: [PATCH 48/60] Read in total_nu as a derived product for MT=18 if it only exists as summed, and more correctly treated yields --- openmc/data/neutron.py | 3 +++ openmc/plotter.py | 50 +++++++++++++++++++++++------------------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index f478aafc7..581adc417 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -511,6 +511,9 @@ class IncidentNeutron(EqualityMixin): rxs = [data[mt] for mt in SUM_RULES[mt_sum] if mt in data] if len(rxs) > 0: data.summed_reactions[mt_sum] = rx = Reaction(mt_sum) + if rx.mt == 18 and 'total_nu' in group: + tgroup = group['total_nu'] + rx.derived_products.append(Product.from_hdf5(tgroup)) for T in data.temperatures: rx.xs[T] = Sum([rx_i.xs[T] for rx_i in rxs]) diff --git a/openmc/plotter.py b/openmc/plotter.py index d6c9527bd..f576dd8a6 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -1,5 +1,6 @@ from numbers import Integral, Real from six import string_types +from itertools import chain import numpy as np @@ -371,38 +372,41 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, funcs.append(pw_funcs) else: funcs.append(nuc[mt].xs[nucT]) - elif mt == 5 and mt in nuc: - # Only consider the (n,misc) products if neutrons are - # included in the outgoing channel since (n,misc) is only - # explicitly needed for scatter cross sections. - for prod in nuc[mt].products: - if prod.particle == 'neutron' and \ - prod.emission_mode in ('total', 'prompt'): - if yields[i]: - func = openmc.data.Combination( - [nuc[mt].xs[nucT], prod.yield_], - [np.multiply]) - else: - func = nuc[mt].xs[nucT] - - funcs.append(func) - break - else: - funcs.append(lambda x: 0.) - elif mt in nuc: if yields[i]: - for prod in nuc[mt].products: + for prod in chain(nuc[mt].products, + nuc[mt].derived_products): if prod.particle == 'neutron' and \ - prod.emission_mode in ('total', 'prompt'): + prod.emission_mode == 'total': func = openmc.data.Combination( [nuc[mt].xs[nucT], prod.yield_], [np.multiply]) funcs.append(func) break else: - # Assume the yield is 1 - funcs.append(nuc[mt].xs[nucT]) + # Total doesn't exist so we have to create from + # prompt and delayed + func = None + for prod in chain(nuc[mt].products, + nuc[mt].derived_products): + if prod.particle == 'neutron' and \ + prod.emission_mode != 'total': + if func: + func = openmc.data.Combination( + [nuc[mt].xs[nucT], prod.yield_, + func], [np.multiply, np.add]) + else: + func = openmc.data.Combination( + [nuc[mt].xs[nucT], prod.yield_], + [np.multiply]) + if func: + funcs.append(func) + else: + # If func is still None, then there were no + # products. In that case, assume the yield is + # one as its not provided for some summed + # reactions like MT=4 + funcs.append(nuc[mt].xs[nucT]) else: funcs.append(nuc[mt].xs[nucT]) elif mt == UNITY_MT: From 42baabd155152d6d343b6252baf86ff9aa054784 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 21 Nov 2016 20:35:06 -0500 Subject: [PATCH 49/60] Whoops, improperly weighted the data --- openmc/plotter.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/openmc/plotter.py b/openmc/plotter.py index f576dd8a6..aa4317d30 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -374,6 +374,8 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, funcs.append(nuc[mt].xs[nucT]) elif mt in nuc: if yields[i]: + # Get the total yield first if available. This will be + # used primarily for fission. for prod in chain(nuc[mt].products, nuc[mt].derived_products): if prod.particle == 'neutron' and \ @@ -385,7 +387,8 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, break else: # Total doesn't exist so we have to create from - # prompt and delayed + # prompt and delayed. This is used for scatter + # multiplication. func = None for prod in chain(nuc[mt].products, nuc[mt].derived_products): @@ -393,14 +396,12 @@ def _calculate_xs_nuclide(this, types, temperature=294., sab_name=None, prod.emission_mode != 'total': if func: func = openmc.data.Combination( - [nuc[mt].xs[nucT], prod.yield_, - func], [np.multiply, np.add]) + [prod.yield_, func], [np.add]) else: - func = openmc.data.Combination( - [nuc[mt].xs[nucT], prod.yield_], - [np.multiply]) + func = prod.yield_ if func: - funcs.append(func) + funcs.append(openmc.data.Combination( + [func, nuc[mt].xs[nucT]], [np.multiply])) else: # If func is still None, then there were no # products. In that case, assume the yield is From 6434886820d1225dfe57dcb4954fd7675148e19f Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 23 Nov 2016 18:51:05 -0600 Subject: [PATCH 50/60] Address @smharper comments on #761. Also add one publication in docs. --- docs/source/publications.rst | 5 +++++ openmc/data/decay.py | 25 +++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/docs/source/publications.rst b/docs/source/publications.rst index 7e79cf33f..097cd43d0 100644 --- a/docs/source/publications.rst +++ b/docs/source/publications.rst @@ -177,6 +177,11 @@ Nuclear Data - Paul K. Romano and Sterling M. Harper, "Nuclear data processing capabilities in OpenMC", *Proc. Nuclear Data*, Sep. 11-16, 2016. +- Jonathan A. Walsh, Benoit Froget, Kord S. Smith, and Forrest B. Brown, + "Neutron Cross Section Processing Methods for Improved Integral Benchmarking + of Unresolved Resonance Region Evaluations," *Eur. Phys. J. Web Conf.* + **111**, 06001 (2016). ``_ + - Jonathan A. Walsh, Paul K. Romano, Benoit Forget, and Kord S. Smith, "Optimizations of the energy grid search algorithm in continuous-energy Monte Carlo particle transport codes", *Comput. Phys. Commun.*, **196**, 134-142 diff --git a/openmc/data/decay.py b/openmc/data/decay.py index 41929c034..33d447973 100644 --- a/openmc/data/decay.py +++ b/openmc/data/decay.py @@ -80,16 +80,26 @@ class FissionProductYields(EqualityMixin): cumulative : list of dict Cumulative yields for each tabulated energy. Each item in the list is a dictionary whose keys are nuclide names and values are cumulative - yields. The i-th dictionary corresponds to the i-th energy. + yields. The i-th dictionary corresponds to the i-th incident neutron + energy. energies : Iterable of float or None Energies at which fission product yields are tabulated. independent : list of dict Independent yields for each tabulated energy. Each item in the list is a dictionary whose keys are nuclide names and values are independent - yields. The i-th dictionary corresponds to the i-th energy. + yields. The i-th dictionary corresponds to the i-th incident neutron + energy. nuclide : dict Properties of the fissioning nuclide. + Notes + ----- + Neutron fission yields are typically not measured with a monoenergetic + source of neutrons. As such, if the fission yields are given at, e.g., + 0.0253 eV, one should interpret this as meaning that they are derived from a + typical thermal reactor flux spectrum as opposed to a monoenergetic source + at 0.0253 eV. + """ def __init__(self, ev_or_filename): # Define function that can be used to read both independent and @@ -97,17 +107,13 @@ class FissionProductYields(EqualityMixin): def get_yields(file_obj): # Determine number of energies n_energy = get_head_record(file_obj)[2] - if n_energy > 1: - energies = np.zeros(n_energy) - else: - energies = None + energies = np.zeros(n_energy) data = [] for i in range(n_energy): # Determine i-th energy and number of products items, values = get_list_record(file_obj) - if n_energy > 1: - energies[i] = items[0] + energies[i] = items[0] n_products = items[5] # Get yields for i-th energy @@ -314,7 +320,6 @@ class Decay(EqualityMixin): ev = ev_or_filename else: ev = Evaluation(ev_or_filename) - #assert ev.info['sublibrary'] == 'Radioactive decay data' file_obj = StringIO(ev.section[8, 457]) @@ -332,7 +337,7 @@ class Decay(EqualityMixin): self.nuclide['isomeric_state'] = metastable if metastable > 0: self.nuclide['name'] = '{}{}_m{}'.format(ATOMIC_SYMBOL[Z], A, - metastable) + metastable) else: self.nuclide['name'] = '{}{}'.format(ATOMIC_SYMBOL[Z], A) self.nuclide['mass'] = items[1] # AWR From 6ba1f046311aef9ef9b67985b494fbd00fe0caff Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sun, 27 Nov 2016 06:34:47 -0500 Subject: [PATCH 51/60] Resolving @paulromano comments --- .../python/pincell_multigroup/build-xml.py | 4 +-- openmc/filter.py | 11 +++++--- openmc/mgxs/library.py | 2 +- openmc/mgxs/mgxs.py | 25 +++++++++++++------ openmc/mgxs_library.py | 10 ++++++-- tests/test_tallies/test_tallies.py | 3 ++- 6 files changed, 38 insertions(+), 17 deletions(-) diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index cc57b61e2..9cc23300d 100644 --- a/examples/python/pincell_multigroup/build-xml.py +++ b/examples/python/pincell_multigroup/build-xml.py @@ -36,7 +36,7 @@ scatter_matrix = np.array( [0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000], [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090], [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]]) -scatter_matrix = np.swapaxes(np.swapaxes(scatter_matrix, 0, 1), 1, 2) +scatter_matrix = np.rollaxis(scatter_matrix, 0, 3) uo2_xsdata.set_scatter_matrix(scatter_matrix) uo2_xsdata.set_fission([7.21206E-03, 8.19301E-04, 6.45320E-03, 1.85648E-02, 1.78084E-02, 8.30348E-02, @@ -62,7 +62,7 @@ scatter_matrix = np.array( [0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290], [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200], [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]]) -scatter_matrix = np.swapaxes(np.swapaxes(scatter_matrix, 0, 1), 1, 2) +scatter_matrix = np.rollaxis(scatter_matrix, 0, 3) h2o_xsdata.set_scatter_matrix(scatter_matrix) mg_cross_sections_file = openmc.MGXSLibrary(groups) diff --git a/openmc/filter.py b/openmc/filter.py index 61818f89f..a7a8b934a 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -100,10 +100,13 @@ class Filter(object): @classmethod def _recursive_subclasses(cls): """Return all subclasses and their subclasses, etc.""" - subs = cls.__subclasses__() - subsubs = [grand for s in subs for grand in s.__subclasses__()] - subsubsubs = [grand for s in subsubs for grand in s.__subclasses__()] - return subs + subsubs + subsubsubs + all_subclasses = [] + + for subclass in cls.__subclasses__(): + all_subclasses.append(subclass) + all_subclasses.extend(subclass._recursive_subclasses()) + + return all_subclasses @classmethod def from_hdf5(cls, group, **kwargs): diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 2e2b7f908..7e0289064 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -59,7 +59,7 @@ class Library(object): The spatial domain(s) for which MGXS in the Library are computed correction : {'P0', None} Apply the P0 correction to scattering matrices if set to 'P0' - scatter_format : {'legendre', or 'histogram'} + scatter_format : {'legendre', 'histogram'} Representation of the angular scattering distribution (default is 'legendre') legendre_order : int diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index db31e2f32..58b8a32c2 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -1529,9 +1529,19 @@ class MGXS(object): else: df = df.drop('score', axis=1) + # Determine if change-in-angle bins are included in the MGXS to + # properly tile the group boundaries + if 'mu low' in df: + # Find the length of the mu filters indirectly from the number + # of times the mu bins repeats. + num_mu = int(df.shape[0] / + df[df['mu low'] == df['mu low'][0]].shape[0]) + else: + num_mu = 1 + # Override energy groups bounds with indices all_groups = np.arange(self.num_groups, 0, -1, dtype=np.int) - all_groups = np.repeat(all_groups, len(query_nuclides)) + all_groups = np.repeat(all_groups, len(query_nuclides) * num_mu) if 'energy low [eV]' in df and 'energyout low [eV]' in df: df.rename(columns={'energy low [eV]': 'group in'}, inplace=True) @@ -3791,10 +3801,8 @@ class ScatterMatrixXS(MatrixMGXS): # than 1, so try each axis in axes one at a time, catching the # ValueError as needed. for axis in axes: - try: + if xs.shape[axis] == 1: xs = np.squeeze(xs, axis=axis) - except ValueError: - pass return xs @@ -3874,9 +3882,12 @@ class ScatterMatrixXS(MatrixMGXS): df = df[df['moment'] == 'P{}'.format(moment)] elif self.scatter_format == 'histogram': - # Add a change-in-angle (mu) column to dataframe - ###TODO NOT SURE I NEED TO DO THIS - pass + # Replace the mu low and mu high columns with a single mu bin + del df['mu high'] + df.rename(columns={'mu low': 'mu bins'}, inplace=True) + bins = [i + 1 for i in range(self.histogram_bins)] + bins = np.tile(bins, int(df.shape[0] / len(bins))) + df['mu bins'] = bins return df diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 25452bdb4..347c015e7 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1773,8 +1773,14 @@ class XSdata(object): np.sum(self._scatter_matrix[i][p, a, g_in, :, :], axis=1) 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] + # It is possible that there only zeros in matrix + # and therefore nz will be empty, in that case set + # g_out_bounds to 0s + if len(nz[0]) == 0: + g_out_bounds[p, a, g_in, :] = 0 + else: + 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 = [] diff --git a/tests/test_tallies/test_tallies.py b/tests/test_tallies/test_tallies.py index 9e525d2cf..033c7b812 100644 --- a/tests/test_tallies/test_tallies.py +++ b/tests/test_tallies/test_tallies.py @@ -3,13 +3,14 @@ import os import sys sys.path.insert(0, os.pardir) -import numpy as np + from testing_harness import PyAPITestHarness from openmc.filter import * from openmc import Mesh, Tally, Tallies from openmc.source import Source from openmc.stats import Box + class TalliesTestHarness(PyAPITestHarness): def _build_inputs(self): # Build default materials/geometry From 0e029771e70cdf8ebdbf3fcd5b220c65f836ad26 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 27 Nov 2016 16:04:40 -0600 Subject: [PATCH 52/60] Fix decay_constant attribute, add Decay.from_endf classmethod --- openmc/data/decay.py | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/openmc/data/decay.py b/openmc/data/decay.py index 33d447973..4327b2fc3 100644 --- a/openmc/data/decay.py +++ b/openmc/data/decay.py @@ -157,7 +157,7 @@ class FissionProductYields(EqualityMixin): assert np.all(energies == self.energies) @classmethod - def from_endf(cls, filename): + def from_endf(cls, ev_or_filename): """Generate fission product yield data from an ENDF evaluation Parameters @@ -172,7 +172,7 @@ class FissionProductYields(EqualityMixin): Fission product yield data """ - return cls(filename) + return cls(ev_or_filename) class DecayMode(EqualityMixin): @@ -460,4 +460,26 @@ class Decay(EqualityMixin): @property def decay_constant(self): - return log(2.)/self.half_life + if hasattr(self.half_life, 'n'): + return log(2.)/self.half_life + else: + mu, sigma = self.half_life + return ufloat(log(2.)/mu, log(2.)/mu**2*sigma) + + @classmethod + def from_endf(cls, ev_or_filename): + """Generate radioactive decay data from an ENDF evaluation + + Parameters + ---------- + ev_or_filename : str or openmc.data.endf.Evaluation + ENDF radioactive decay data evaluation to read from. If given as a + string, it is assumed to be the filename for the ENDF file. + + Returns + ------- + openmc.data.Decay + Radioactive decay data + + """ + return cls(ev_or_filename) From 0a0b50de2f630c35264ac007da18d929ede8d7fe Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Mon, 28 Nov 2016 10:22:47 -0500 Subject: [PATCH 53/60] Removed use of Filter.type property --- .../pythonapi/examples/mgxs-part-ii.ipynb | 1049 ++++++++++------- openmc/filter.py | 15 +- 2 files changed, 627 insertions(+), 437 deletions(-) diff --git a/docs/source/pythonapi/examples/mgxs-part-ii.ipynb b/docs/source/pythonapi/examples/mgxs-part-ii.ipynb index c43fab6ff..e35c205c3 100644 --- a/docs/source/pythonapi/examples/mgxs-part-ii.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-ii.ipynb @@ -34,7 +34,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/romano/miniconda3/envs/default/lib/python3.5/site-packages/matplotlib/__init__.py:1350: UserWarning: This call to matplotlib.use() has no effect\n", + "/home/wbinventor/miniconda3/lib/python3.5/site-packages/IPython/html.py:14: ShimWarning: The `IPython.html` package has been deprecated. You should import from `notebook` instead. `IPython.html.widgets` has moved to `ipywidgets`.\n", + " \"`IPython.html.widgets` has moved to `ipywidgets`.\", ShimWarning)\n", + "/home/wbinventor/miniconda3/lib/python3.5/site-packages/matplotlib/__init__.py:1350: UserWarning: This call to matplotlib.use() has no effect\n", "because the backend has already been chosen;\n", "matplotlib.use() must be called *before* pylab, matplotlib.pyplot,\n", "or matplotlib.backends is imported for the first time.\n", @@ -453,8 +455,8 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | da5563eddb5f2c2d6b2c9839d518de40962b78f2\n", - " Date/Time | 2016-10-31 12:29:16\n", + " Git SHA1 | 2c25ec97653482825b529215b8a61b54d468d34e\n", + " Date/Time | 2016-11-28 09:10:24\n", " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", @@ -465,11 +467,16 @@ " Reading geometry XML file...\n", " Reading materials XML file...\n", " Reading cross sections XML file...\n", - " Reading U235 from /home/romano/openmc/scripts/nndc_hdf5/U235.h5\n", - " Reading U238 from /home/romano/openmc/scripts/nndc_hdf5/U238.h5\n", - " Reading O16 from /home/romano/openmc/scripts/nndc_hdf5/O16.h5\n", - " Reading H1 from /home/romano/openmc/scripts/nndc_hdf5/H1.h5\n", - " Reading Zr90 from /home/romano/openmc/scripts/nndc_hdf5/Zr90.h5\n", + " Reading U235 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/U235.h5\n", + " Reading U238 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/U238.h5\n", + " Reading O16 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/O16.h5\n", + " Reading H1 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/H1.h5\n", + " Reading Zr90 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/Zr90.h5\n", " Maximum neutron transport energy: 2.00000E+07 eV for U235\n", " Reading tallies XML file...\n", " Building neighboring cells lists for each surface...\n", @@ -531,7 +538,7 @@ " 48/1 1.21610 1.22612 +/- 0.00251\n", " 49/1 1.22199 1.22602 +/- 0.00245\n", " 50/1 1.20860 1.22558 +/- 0.00243\n", - " Triggers unsatisfied, max unc./thresh. is 1.25496 for flux in tally 10050\n", + " Triggers unsatisfied, max unc./thresh. is 1.25496 for flux in tally 10057\n", " The estimated number of batches is 73\n", " Creating state point statepoint.050.h5...\n", " 51/1 1.21850 1.22541 +/- 0.00237\n", @@ -557,7 +564,7 @@ " 71/1 1.19720 1.22444 +/- 0.00195\n", " 72/1 1.23770 1.22465 +/- 0.00193\n", " 73/1 1.23894 1.22488 +/- 0.00191\n", - " Triggers unsatisfied, max unc./thresh. is 1.00243 for flux in tally 10050\n", + " Triggers unsatisfied, max unc./thresh. is 1.00243 for flux in tally 10057\n", " The estimated number of batches is 74\n", " 74/1 1.22437 1.22487 +/- 0.00188\n", " Triggers satisfied for batch 74\n", @@ -570,20 +577,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 5.0262E-01 seconds\n", - " Reading cross sections = 3.4207E-01 seconds\n", - " Total time in simulation = 1.2843E+02 seconds\n", - " Time in transport only = 1.2831E+02 seconds\n", - " Time in inactive batches = 8.1328E+00 seconds\n", - " Time in active batches = 1.2030E+02 seconds\n", - " Time synchronizing fission bank = 2.9797E-02 seconds\n", - " Sampling source sites = 2.1385E-02 seconds\n", - " SEND/RECV source sites = 8.2632E-03 seconds\n", - " Time accumulating tallies = 1.4577E-03 seconds\n", - " Total time for finalization = 1.3462E-02 seconds\n", - " Total time elapsed = 1.2901E+02 seconds\n", - " Calculation Rate (inactive) = 12295.9 neutrons/second\n", - " Calculation Rate (active) = 3325.12 neutrons/second\n", + " Total time for initialization = 3.1270E-01 seconds\n", + " Reading cross sections = 1.8695E-01 seconds\n", + " Total time in simulation = 1.1922E+02 seconds\n", + " Time in transport only = 1.1903E+02 seconds\n", + " Time in inactive batches = 8.5633E+00 seconds\n", + " Time in active batches = 1.1066E+02 seconds\n", + " Time synchronizing fission bank = 2.4702E-02 seconds\n", + " Sampling source sites = 1.8297E-02 seconds\n", + " SEND/RECV source sites = 6.2794E-03 seconds\n", + " Time accumulating tallies = 2.6114E-03 seconds\n", + " Total time for finalization = 1.6967E-02 seconds\n", + " Total time elapsed = 1.1961E+02 seconds\n", + " Calculation Rate (inactive) = 11677.8 neutrons/second\n", + " Calculation Rate (active) = 3614.65 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -1172,169 +1179,239 @@ "text": [ "[ NORMAL ] Importing ray tracing data from file...\n", "[ NORMAL ] Computing the eigenvalue...\n", - "[ NORMAL ] Iteration 0:\tk_eff = 0.574672\tres = 0.000E+00\n", - "[ NORMAL ] Iteration 1:\tk_eff = 0.679815\tres = 4.253E-01\n", - "[ NORMAL ] Iteration 2:\tk_eff = 0.660826\tres = 1.830E-01\n", - "[ NORMAL ] Iteration 3:\tk_eff = 0.658941\tres = 2.793E-02\n", - "[ NORMAL ] Iteration 4:\tk_eff = 0.643012\tres = 2.852E-03\n", - "[ NORMAL ] Iteration 5:\tk_eff = 0.625810\tres = 2.417E-02\n", - "[ NORMAL ] Iteration 6:\tk_eff = 0.606678\tres = 2.675E-02\n", - "[ NORMAL ] Iteration 7:\tk_eff = 0.587485\tres = 3.057E-02\n", - "[ NORMAL ] Iteration 8:\tk_eff = 0.569029\tres = 3.164E-02\n", - "[ NORMAL ] Iteration 9:\tk_eff = 0.551707\tres = 3.142E-02\n", - "[ NORMAL ] Iteration 10:\tk_eff = 0.536035\tres = 3.044E-02\n", - "[ NORMAL ] Iteration 11:\tk_eff = 0.522274\tres = 2.841E-02\n", - "[ NORMAL ] Iteration 12:\tk_eff = 0.510609\tres = 2.567E-02\n", - "[ NORMAL ] Iteration 13:\tk_eff = 0.501106\tres = 2.234E-02\n", - "[ NORMAL ] Iteration 14:\tk_eff = 0.493831\tres = 1.861E-02\n", - "[ NORMAL ] Iteration 15:\tk_eff = 0.488780\tres = 1.452E-02\n", - "[ NORMAL ] Iteration 16:\tk_eff = 0.485923\tres = 1.023E-02\n", - "[ NORMAL ] Iteration 17:\tk_eff = 0.485210\tres = 5.846E-03\n", - "[ NORMAL ] Iteration 18:\tk_eff = 0.486569\tres = 1.467E-03\n", - "[ NORMAL ] Iteration 19:\tk_eff = 0.489903\tres = 2.801E-03\n", - "[ NORMAL ] Iteration 20:\tk_eff = 0.495103\tres = 6.852E-03\n", - "[ NORMAL ] Iteration 21:\tk_eff = 0.502053\tres = 1.061E-02\n", - "[ NORMAL ] Iteration 22:\tk_eff = 0.510627\tres = 1.404E-02\n", - "[ NORMAL ] Iteration 23:\tk_eff = 0.520693\tres = 1.708E-02\n", - "[ NORMAL ] Iteration 24:\tk_eff = 0.532117\tres = 1.971E-02\n", - "[ NORMAL ] Iteration 25:\tk_eff = 0.544764\tres = 2.194E-02\n", - "[ NORMAL ] Iteration 26:\tk_eff = 0.558501\tres = 2.377E-02\n", - "[ NORMAL ] Iteration 27:\tk_eff = 0.573195\tres = 2.522E-02\n", - "[ NORMAL ] Iteration 28:\tk_eff = 0.588718\tres = 2.631E-02\n", - "[ NORMAL ] Iteration 29:\tk_eff = 0.604946\tres = 2.708E-02\n", - "[ NORMAL ] Iteration 30:\tk_eff = 0.621759\tres = 2.756E-02\n", - "[ NORMAL ] Iteration 31:\tk_eff = 0.639047\tres = 2.779E-02\n", - "[ NORMAL ] Iteration 32:\tk_eff = 0.656702\tres = 2.780E-02\n", - "[ NORMAL ] Iteration 33:\tk_eff = 0.674624\tres = 2.763E-02\n", - "[ NORMAL ] Iteration 34:\tk_eff = 0.692722\tres = 2.729E-02\n", - "[ NORMAL ] Iteration 35:\tk_eff = 0.710910\tres = 2.683E-02\n", - "[ NORMAL ] Iteration 36:\tk_eff = 0.729109\tres = 2.625E-02\n", - "[ NORMAL ] Iteration 37:\tk_eff = 0.747248\tres = 2.560E-02\n", - "[ NORMAL ] Iteration 38:\tk_eff = 0.765263\tres = 2.488E-02\n", - "[ NORMAL ] Iteration 39:\tk_eff = 0.783094\tres = 2.411E-02\n", - "[ NORMAL ] Iteration 40:\tk_eff = 0.800690\tres = 2.330E-02\n", - "[ NORMAL ] Iteration 41:\tk_eff = 0.818005\tres = 2.247E-02\n", - "[ NORMAL ] Iteration 42:\tk_eff = 0.834999\tres = 2.163E-02\n", - "[ NORMAL ] Iteration 43:\tk_eff = 0.851638\tres = 2.078E-02\n", - "[ NORMAL ] Iteration 44:\tk_eff = 0.867892\tres = 1.993E-02\n", - "[ NORMAL ] Iteration 45:\tk_eff = 0.883736\tres = 1.909E-02\n", - "[ NORMAL ] Iteration 46:\tk_eff = 0.899149\tres = 1.826E-02\n", - "[ NORMAL ] Iteration 47:\tk_eff = 0.914115\tres = 1.744E-02\n", - "[ NORMAL ] Iteration 48:\tk_eff = 0.928622\tres = 1.664E-02\n", - "[ NORMAL ] Iteration 49:\tk_eff = 0.942659\tres = 1.587E-02\n", - "[ NORMAL ] Iteration 50:\tk_eff = 0.956221\tres = 1.512E-02\n", - "[ NORMAL ] Iteration 51:\tk_eff = 0.969305\tres = 1.439E-02\n", - "[ NORMAL ] Iteration 52:\tk_eff = 0.981909\tres = 1.368E-02\n", - "[ NORMAL ] Iteration 53:\tk_eff = 0.994035\tres = 1.300E-02\n", - "[ NORMAL ] Iteration 54:\tk_eff = 1.005685\tres = 1.235E-02\n", - "[ NORMAL ] Iteration 55:\tk_eff = 1.016866\tres = 1.172E-02\n", - "[ NORMAL ] Iteration 56:\tk_eff = 1.027584\tres = 1.112E-02\n", - "[ NORMAL ] Iteration 57:\tk_eff = 1.037846\tres = 1.054E-02\n", - "[ NORMAL ] Iteration 58:\tk_eff = 1.047661\tres = 9.986E-03\n", - "[ NORMAL ] Iteration 59:\tk_eff = 1.057040\tres = 9.457E-03\n", - "[ NORMAL ] Iteration 60:\tk_eff = 1.065994\tres = 8.953E-03\n", - "[ NORMAL ] Iteration 61:\tk_eff = 1.074533\tres = 8.470E-03\n", - "[ NORMAL ] Iteration 62:\tk_eff = 1.082671\tres = 8.011E-03\n", - "[ NORMAL ] Iteration 63:\tk_eff = 1.090418\tres = 7.573E-03\n", - "[ NORMAL ] Iteration 64:\tk_eff = 1.097790\tres = 7.156E-03\n", - "[ NORMAL ] Iteration 65:\tk_eff = 1.104797\tres = 6.760E-03\n", - "[ NORMAL ] Iteration 66:\tk_eff = 1.111453\tres = 6.383E-03\n", - "[ NORMAL ] Iteration 67:\tk_eff = 1.117770\tres = 6.025E-03\n", - "[ NORMAL ] Iteration 68:\tk_eff = 1.123764\tres = 5.684E-03\n", - "[ NORMAL ] Iteration 69:\tk_eff = 1.129446\tres = 5.362E-03\n", - "[ NORMAL ] Iteration 70:\tk_eff = 1.134828\tres = 5.056E-03\n", - "[ NORMAL ] Iteration 71:\tk_eff = 1.139924\tres = 4.765E-03\n", - "[ NORMAL ] Iteration 72:\tk_eff = 1.144746\tres = 4.491E-03\n", - "[ NORMAL ] Iteration 73:\tk_eff = 1.149306\tres = 4.230E-03\n", - "[ NORMAL ] Iteration 74:\tk_eff = 1.153617\tres = 3.983E-03\n", - "[ NORMAL ] Iteration 75:\tk_eff = 1.157688\tres = 3.751E-03\n", - "[ NORMAL ] Iteration 76:\tk_eff = 1.161534\tres = 3.530E-03\n", - "[ NORMAL ] Iteration 77:\tk_eff = 1.165163\tres = 3.322E-03\n", - "[ NORMAL ] Iteration 78:\tk_eff = 1.168586\tres = 3.124E-03\n", - "[ NORMAL ] Iteration 79:\tk_eff = 1.171813\tres = 2.938E-03\n", - "[ NORMAL ] Iteration 80:\tk_eff = 1.174855\tres = 2.762E-03\n", - "[ NORMAL ] Iteration 81:\tk_eff = 1.177721\tres = 2.596E-03\n", - "[ NORMAL ] Iteration 82:\tk_eff = 1.180419\tres = 2.439E-03\n", - "[ NORMAL ] Iteration 83:\tk_eff = 1.182960\tres = 2.291E-03\n", - "[ NORMAL ] Iteration 84:\tk_eff = 1.185350\tres = 2.152E-03\n", - "[ NORMAL ] Iteration 85:\tk_eff = 1.187599\tres = 2.021E-03\n", - "[ NORMAL ] Iteration 86:\tk_eff = 1.189713\tres = 1.897E-03\n", - "[ NORMAL ] Iteration 87:\tk_eff = 1.191700\tres = 1.780E-03\n", - "[ NORMAL ] Iteration 88:\tk_eff = 1.193567\tres = 1.670E-03\n", - "[ NORMAL ] Iteration 89:\tk_eff = 1.195321\tres = 1.567E-03\n", - "[ NORMAL ] Iteration 90:\tk_eff = 1.196967\tres = 1.469E-03\n", - "[ NORMAL ] Iteration 91:\tk_eff = 1.198513\tres = 1.378E-03\n", - "[ NORMAL ] Iteration 92:\tk_eff = 1.199964\tres = 1.291E-03\n", - "[ NORMAL ] Iteration 93:\tk_eff = 1.201326\tres = 1.211E-03\n", - "[ NORMAL ] Iteration 94:\tk_eff = 1.202602\tres = 1.135E-03\n", - "[ NORMAL ] Iteration 95:\tk_eff = 1.203800\tres = 1.062E-03\n", - "[ NORMAL ] Iteration 96:\tk_eff = 1.204922\tres = 9.959E-04\n", - "[ NORMAL ] Iteration 97:\tk_eff = 1.205974\tres = 9.321E-04\n", - "[ NORMAL ] Iteration 98:\tk_eff = 1.206961\tres = 8.732E-04\n", - "[ NORMAL ] Iteration 99:\tk_eff = 1.207884\tres = 8.175E-04\n", - "[ NORMAL ] Iteration 100:\tk_eff = 1.208748\tres = 7.646E-04\n", - "[ NORMAL ] Iteration 101:\tk_eff = 1.209558\tres = 7.159E-04\n", - "[ NORMAL ] Iteration 102:\tk_eff = 1.210316\tres = 6.699E-04\n", - "[ NORMAL ] Iteration 103:\tk_eff = 1.211025\tres = 6.262E-04\n", - "[ NORMAL ] Iteration 104:\tk_eff = 1.211689\tres = 5.864E-04\n", - "[ NORMAL ] Iteration 105:\tk_eff = 1.212310\tres = 5.481E-04\n", - "[ NORMAL ] Iteration 106:\tk_eff = 1.212891\tres = 5.124E-04\n", - "[ NORMAL ] Iteration 107:\tk_eff = 1.213434\tres = 4.792E-04\n", - "[ NORMAL ] Iteration 108:\tk_eff = 1.213942\tres = 4.477E-04\n", - "[ NORMAL ] Iteration 109:\tk_eff = 1.214416\tres = 4.189E-04\n", - "[ NORMAL ] Iteration 110:\tk_eff = 1.214861\tres = 3.907E-04\n", - "[ NORMAL ] Iteration 111:\tk_eff = 1.215275\tres = 3.660E-04\n", - "[ NORMAL ] Iteration 112:\tk_eff = 1.215663\tres = 3.414E-04\n", - "[ NORMAL ] Iteration 113:\tk_eff = 1.216025\tres = 3.188E-04\n", - "[ NORMAL ] Iteration 114:\tk_eff = 1.216363\tres = 2.981E-04\n", - "[ NORMAL ] Iteration 115:\tk_eff = 1.216679\tres = 2.776E-04\n", - "[ NORMAL ] Iteration 116:\tk_eff = 1.216974\tres = 2.599E-04\n", - "[ NORMAL ] Iteration 117:\tk_eff = 1.217250\tres = 2.427E-04\n", - "[ NORMAL ] Iteration 118:\tk_eff = 1.217507\tres = 2.263E-04\n", - "[ NORMAL ] Iteration 119:\tk_eff = 1.217747\tres = 2.115E-04\n", - "[ NORMAL ] Iteration 120:\tk_eff = 1.217970\tres = 1.970E-04\n", - "[ NORMAL ] Iteration 121:\tk_eff = 1.218180\tres = 1.834E-04\n", - "[ NORMAL ] Iteration 122:\tk_eff = 1.218375\tres = 1.718E-04\n", - "[ NORMAL ] Iteration 123:\tk_eff = 1.218557\tres = 1.602E-04\n", - "[ NORMAL ] Iteration 124:\tk_eff = 1.218726\tres = 1.496E-04\n", - "[ NORMAL ] Iteration 125:\tk_eff = 1.218885\tres = 1.387E-04\n", - "[ NORMAL ] Iteration 126:\tk_eff = 1.219032\tres = 1.301E-04\n", - "[ NORMAL ] Iteration 127:\tk_eff = 1.219169\tres = 1.211E-04\n", - "[ NORMAL ] Iteration 128:\tk_eff = 1.219298\tres = 1.127E-04\n", - "[ NORMAL ] Iteration 129:\tk_eff = 1.219418\tres = 1.058E-04\n", - "[ NORMAL ] Iteration 130:\tk_eff = 1.219529\tres = 9.828E-05\n", - "[ NORMAL ] Iteration 131:\tk_eff = 1.219633\tres = 9.100E-05\n", - "[ NORMAL ] Iteration 132:\tk_eff = 1.219730\tres = 8.530E-05\n", - "[ NORMAL ] Iteration 133:\tk_eff = 1.219820\tres = 7.940E-05\n", - "[ NORMAL ] Iteration 134:\tk_eff = 1.219904\tres = 7.409E-05\n", - "[ NORMAL ] Iteration 135:\tk_eff = 1.219983\tres = 6.876E-05\n", - "[ NORMAL ] Iteration 136:\tk_eff = 1.220056\tres = 6.455E-05\n", - "[ NORMAL ] Iteration 137:\tk_eff = 1.220124\tres = 5.969E-05\n", - "[ NORMAL ] Iteration 138:\tk_eff = 1.220187\tres = 5.603E-05\n", - "[ NORMAL ] Iteration 139:\tk_eff = 1.220246\tres = 5.166E-05\n", - "[ NORMAL ] Iteration 140:\tk_eff = 1.220301\tres = 4.829E-05\n", - "[ NORMAL ] Iteration 141:\tk_eff = 1.220352\tres = 4.510E-05\n", - "[ NORMAL ] Iteration 142:\tk_eff = 1.220400\tres = 4.199E-05\n", - "[ NORMAL ] Iteration 143:\tk_eff = 1.220445\tres = 3.939E-05\n", - "[ NORMAL ] Iteration 144:\tk_eff = 1.220486\tres = 3.630E-05\n", - "[ NORMAL ] Iteration 145:\tk_eff = 1.220525\tres = 3.362E-05\n", - "[ NORMAL ] Iteration 146:\tk_eff = 1.220561\tres = 3.181E-05\n", - "[ NORMAL ] Iteration 147:\tk_eff = 1.220594\tres = 2.977E-05\n", - "[ NORMAL ] Iteration 148:\tk_eff = 1.220626\tres = 2.745E-05\n", - "[ NORMAL ] Iteration 149:\tk_eff = 1.220655\tres = 2.569E-05\n", - "[ NORMAL ] Iteration 150:\tk_eff = 1.220682\tres = 2.376E-05\n", - "[ NORMAL ] Iteration 151:\tk_eff = 1.220707\tres = 2.201E-05\n", - "[ NORMAL ] Iteration 152:\tk_eff = 1.220730\tres = 2.071E-05\n", - "[ NORMAL ] Iteration 153:\tk_eff = 1.220752\tres = 1.925E-05\n", - "[ NORMAL ] Iteration 154:\tk_eff = 1.220772\tres = 1.793E-05\n", - "[ NORMAL ] Iteration 155:\tk_eff = 1.220791\tres = 1.669E-05\n", - "[ NORMAL ] Iteration 156:\tk_eff = 1.220809\tres = 1.554E-05\n", - "[ NORMAL ] Iteration 157:\tk_eff = 1.220826\tres = 1.457E-05\n", - "[ NORMAL ] Iteration 158:\tk_eff = 1.220841\tres = 1.372E-05\n", - "[ NORMAL ] Iteration 159:\tk_eff = 1.220855\tres = 1.249E-05\n", - "[ NORMAL ] Iteration 160:\tk_eff = 1.220868\tres = 1.138E-05\n", - "[ NORMAL ] Iteration 161:\tk_eff = 1.220881\tres = 1.104E-05\n", - "[ NORMAL ] Iteration 162:\tk_eff = 1.220892\tres = 1.028E-05\n" + "[ NORMAL ] Iteration 0:\tk_eff = 0.423123\tres = 0.000E+00\n", + "[ NORMAL ] Iteration 1:\tk_eff = 0.475921\tres = 5.769E-01\n", + "[ NORMAL ] Iteration 2:\tk_eff = 0.491443\tres = 1.248E-01\n", + "[ NORMAL ] Iteration 3:\tk_eff = 0.487441\tres = 3.261E-02\n", + "[ NORMAL ] Iteration 4:\tk_eff = 0.483949\tres = 8.144E-03\n", + "[ NORMAL ] Iteration 5:\tk_eff = 0.477326\tres = 7.164E-03\n", + "[ NORMAL ] Iteration 6:\tk_eff = 0.469012\tres = 1.369E-02\n", + "[ NORMAL ] Iteration 7:\tk_eff = 0.460422\tres = 1.742E-02\n", + "[ NORMAL ] Iteration 8:\tk_eff = 0.450721\tres = 1.832E-02\n", + "[ NORMAL ] Iteration 9:\tk_eff = 0.441532\tres = 2.107E-02\n", + "[ NORMAL ] Iteration 10:\tk_eff = 0.432168\tres = 2.039E-02\n", + "[ NORMAL ] Iteration 11:\tk_eff = 0.423131\tres = 2.121E-02\n", + "[ NORMAL ] Iteration 12:\tk_eff = 0.414705\tres = 2.091E-02\n", + "[ NORMAL ] Iteration 13:\tk_eff = 0.406942\tres = 1.991E-02\n", + "[ NORMAL ] Iteration 14:\tk_eff = 0.399627\tres = 1.872E-02\n", + "[ NORMAL ] Iteration 15:\tk_eff = 0.393329\tres = 1.798E-02\n", + "[ NORMAL ] Iteration 16:\tk_eff = 0.387699\tres = 1.576E-02\n", + "[ NORMAL ] Iteration 17:\tk_eff = 0.382948\tres = 1.431E-02\n", + "[ NORMAL ] Iteration 18:\tk_eff = 0.379028\tres = 1.225E-02\n", + "[ NORMAL ] Iteration 19:\tk_eff = 0.375934\tres = 1.024E-02\n", + "[ NORMAL ] Iteration 20:\tk_eff = 0.373784\tres = 8.161E-03\n", + "[ NORMAL ] Iteration 21:\tk_eff = 0.372654\tres = 5.719E-03\n", + "[ NORMAL ] Iteration 22:\tk_eff = 0.372273\tres = 3.023E-03\n", + "[ NORMAL ] Iteration 23:\tk_eff = 0.372879\tres = 1.024E-03\n", + "[ NORMAL ] Iteration 24:\tk_eff = 0.374353\tres = 1.629E-03\n", + "[ NORMAL ] Iteration 25:\tk_eff = 0.376678\tres = 3.951E-03\n", + "[ NORMAL ] Iteration 26:\tk_eff = 0.379854\tres = 6.212E-03\n", + "[ NORMAL ] Iteration 27:\tk_eff = 0.383870\tres = 8.432E-03\n", + "[ NORMAL ] Iteration 28:\tk_eff = 0.388663\tres = 1.057E-02\n", + "[ NORMAL ] Iteration 29:\tk_eff = 0.394216\tres = 1.249E-02\n", + "[ NORMAL ] Iteration 30:\tk_eff = 0.400506\tres = 1.429E-02\n", + "[ NORMAL ] Iteration 31:\tk_eff = 0.407501\tres = 1.596E-02\n", + "[ NORMAL ] Iteration 32:\tk_eff = 0.415145\tres = 1.747E-02\n", + "[ NORMAL ] Iteration 33:\tk_eff = 0.423426\tres = 1.876E-02\n", + "[ NORMAL ] Iteration 34:\tk_eff = 0.432299\tres = 1.995E-02\n", + "[ NORMAL ] Iteration 35:\tk_eff = 0.441713\tres = 2.095E-02\n", + "[ NORMAL ] Iteration 36:\tk_eff = 0.451665\tres = 2.178E-02\n", + "[ NORMAL ] Iteration 37:\tk_eff = 0.462081\tres = 2.253E-02\n", + "[ NORMAL ] Iteration 38:\tk_eff = 0.472951\tres = 2.306E-02\n", + "[ NORMAL ] Iteration 39:\tk_eff = 0.484220\tres = 2.352E-02\n", + "[ NORMAL ] Iteration 40:\tk_eff = 0.495861\tres = 2.383E-02\n", + "[ NORMAL ] Iteration 41:\tk_eff = 0.507836\tres = 2.404E-02\n", + "[ NORMAL ] Iteration 42:\tk_eff = 0.520110\tres = 2.415E-02\n", + "[ NORMAL ] Iteration 43:\tk_eff = 0.532648\tres = 2.417E-02\n", + "[ NORMAL ] Iteration 44:\tk_eff = 0.545418\tres = 2.411E-02\n", + "[ NORMAL ] Iteration 45:\tk_eff = 0.558388\tres = 2.398E-02\n", + "[ NORMAL ] Iteration 46:\tk_eff = 0.571526\tres = 2.378E-02\n", + "[ NORMAL ] Iteration 47:\tk_eff = 0.584802\tres = 2.353E-02\n", + "[ NORMAL ] Iteration 48:\tk_eff = 0.598189\tres = 2.323E-02\n", + "[ NORMAL ] Iteration 49:\tk_eff = 0.611657\tres = 2.289E-02\n", + "[ NORMAL ] Iteration 50:\tk_eff = 0.625182\tres = 2.252E-02\n", + "[ NORMAL ] Iteration 51:\tk_eff = 0.638738\tres = 2.211E-02\n", + "[ NORMAL ] Iteration 52:\tk_eff = 0.652302\tres = 2.168E-02\n", + "[ NORMAL ] Iteration 53:\tk_eff = 0.665851\tres = 2.124E-02\n", + "[ NORMAL ] Iteration 54:\tk_eff = 0.679364\tres = 2.077E-02\n", + "[ NORMAL ] Iteration 55:\tk_eff = 0.692821\tres = 2.029E-02\n", + "[ NORMAL ] Iteration 56:\tk_eff = 0.706204\tres = 1.981E-02\n", + "[ NORMAL ] Iteration 57:\tk_eff = 0.719496\tres = 1.932E-02\n", + "[ NORMAL ] Iteration 58:\tk_eff = 0.732679\tres = 1.882E-02\n", + "[ NORMAL ] Iteration 59:\tk_eff = 0.745740\tres = 1.832E-02\n", + "[ NORMAL ] Iteration 60:\tk_eff = 0.758664\tres = 1.783E-02\n", + "[ NORMAL ] Iteration 61:\tk_eff = 0.771439\tres = 1.733E-02\n", + "[ NORMAL ] Iteration 62:\tk_eff = 0.784053\tres = 1.684E-02\n", + "[ NORMAL ] Iteration 63:\tk_eff = 0.796495\tres = 1.635E-02\n", + "[ NORMAL ] Iteration 64:\tk_eff = 0.808756\tres = 1.587E-02\n", + "[ NORMAL ] Iteration 65:\tk_eff = 0.820827\tres = 1.539E-02\n", + "[ NORMAL ] Iteration 66:\tk_eff = 0.832700\tres = 1.493E-02\n", + "[ NORMAL ] Iteration 67:\tk_eff = 0.844370\tres = 1.447E-02\n", + "[ NORMAL ] Iteration 68:\tk_eff = 0.855828\tres = 1.401E-02\n", + "[ NORMAL ] Iteration 69:\tk_eff = 0.867071\tres = 1.357E-02\n", + "[ NORMAL ] Iteration 70:\tk_eff = 0.878094\tres = 1.314E-02\n", + "[ NORMAL ] Iteration 71:\tk_eff = 0.888893\tres = 1.271E-02\n", + "[ NORMAL ] Iteration 72:\tk_eff = 0.899465\tres = 1.230E-02\n", + "[ NORMAL ] Iteration 73:\tk_eff = 0.909807\tres = 1.189E-02\n", + "[ NORMAL ] Iteration 74:\tk_eff = 0.919919\tres = 1.150E-02\n", + "[ NORMAL ] Iteration 75:\tk_eff = 0.929798\tres = 1.111E-02\n", + "[ NORMAL ] Iteration 76:\tk_eff = 0.939444\tres = 1.074E-02\n", + "[ NORMAL ] Iteration 77:\tk_eff = 0.948856\tres = 1.037E-02\n", + "[ NORMAL ] Iteration 78:\tk_eff = 0.958036\tres = 1.002E-02\n", + "[ NORMAL ] Iteration 79:\tk_eff = 0.966983\tres = 9.674E-03\n", + "[ NORMAL ] Iteration 80:\tk_eff = 0.975698\tres = 9.339E-03\n", + "[ NORMAL ] Iteration 81:\tk_eff = 0.984184\tres = 9.013E-03\n", + "[ NORMAL ] Iteration 82:\tk_eff = 0.992441\tres = 8.697E-03\n", + "[ NORMAL ] Iteration 83:\tk_eff = 1.000472\tres = 8.390E-03\n", + "[ NORMAL ] Iteration 84:\tk_eff = 1.008280\tres = 8.092E-03\n", + "[ NORMAL ] Iteration 85:\tk_eff = 1.015866\tres = 7.804E-03\n", + "[ NORMAL ] Iteration 86:\tk_eff = 1.023234\tres = 7.524E-03\n", + "[ NORMAL ] Iteration 87:\tk_eff = 1.030386\tres = 7.253E-03\n", + "[ NORMAL ] Iteration 88:\tk_eff = 1.037327\tres = 6.990E-03\n", + "[ NORMAL ] Iteration 89:\tk_eff = 1.044059\tres = 6.736E-03\n", + "[ NORMAL ] Iteration 90:\tk_eff = 1.050585\tres = 6.490E-03\n", + "[ NORMAL ] Iteration 91:\tk_eff = 1.056911\tres = 6.251E-03\n", + "[ NORMAL ] Iteration 92:\tk_eff = 1.063038\tres = 6.021E-03\n", + "[ NORMAL ] Iteration 93:\tk_eff = 1.068972\tres = 5.798E-03\n", + "[ NORMAL ] Iteration 94:\tk_eff = 1.074716\tres = 5.582E-03\n", + "[ NORMAL ] Iteration 95:\tk_eff = 1.080275\tres = 5.373E-03\n", + "[ NORMAL ] Iteration 96:\tk_eff = 1.085651\tres = 5.172E-03\n", + "[ NORMAL ] Iteration 97:\tk_eff = 1.090850\tres = 4.977E-03\n", + "[ NORMAL ] Iteration 98:\tk_eff = 1.095876\tres = 4.789E-03\n", + "[ NORMAL ] Iteration 99:\tk_eff = 1.100733\tres = 4.607E-03\n", + "[ NORMAL ] Iteration 100:\tk_eff = 1.105424\tres = 4.432E-03\n", + "[ NORMAL ] Iteration 101:\tk_eff = 1.109955\tres = 4.262E-03\n", + "[ NORMAL ] Iteration 102:\tk_eff = 1.114328\tres = 4.099E-03\n", + "[ NORMAL ] Iteration 103:\tk_eff = 1.118550\tres = 3.941E-03\n", + "[ NORMAL ] Iteration 104:\tk_eff = 1.122623\tres = 3.788E-03\n", + "[ NORMAL ] Iteration 105:\tk_eff = 1.126551\tres = 3.641E-03\n", + "[ NORMAL ] Iteration 106:\tk_eff = 1.130339\tres = 3.499E-03\n", + "[ NORMAL ] Iteration 107:\tk_eff = 1.133991\tres = 3.363E-03\n", + "[ NORMAL ] Iteration 108:\tk_eff = 1.137511\tres = 3.231E-03\n", + "[ NORMAL ] Iteration 109:\tk_eff = 1.140902\tres = 3.104E-03\n", + "[ NORMAL ] Iteration 110:\tk_eff = 1.144168\tres = 2.981E-03\n", + "[ NORMAL ] Iteration 111:\tk_eff = 1.147313\tres = 2.863E-03\n", + "[ NORMAL ] Iteration 112:\tk_eff = 1.150342\tres = 2.749E-03\n", + "[ NORMAL ] Iteration 113:\tk_eff = 1.153257\tres = 2.640E-03\n", + "[ NORMAL ] Iteration 114:\tk_eff = 1.156062\tres = 2.534E-03\n", + "[ NORMAL ] Iteration 115:\tk_eff = 1.158761\tres = 2.432E-03\n", + "[ NORMAL ] Iteration 116:\tk_eff = 1.161356\tres = 2.334E-03\n", + "[ NORMAL ] Iteration 117:\tk_eff = 1.163852\tres = 2.240E-03\n", + "[ NORMAL ] Iteration 118:\tk_eff = 1.166252\tres = 2.149E-03\n", + "[ NORMAL ] Iteration 119:\tk_eff = 1.168559\tres = 2.062E-03\n", + "[ NORMAL ] Iteration 120:\tk_eff = 1.170776\tres = 1.978E-03\n", + "[ NORMAL ] Iteration 121:\tk_eff = 1.172906\tres = 1.897E-03\n", + "[ NORMAL ] Iteration 122:\tk_eff = 1.174952\tres = 1.819E-03\n", + "[ NORMAL ] Iteration 123:\tk_eff = 1.176918\tres = 1.745E-03\n", + "[ NORMAL ] Iteration 124:\tk_eff = 1.178805\tres = 1.673E-03\n", + "[ NORMAL ] Iteration 125:\tk_eff = 1.180617\tres = 1.603E-03\n", + "[ NORMAL ] Iteration 126:\tk_eff = 1.182356\tres = 1.537E-03\n", + "[ NORMAL ] Iteration 127:\tk_eff = 1.184025\tres = 1.473E-03\n", + "[ NORMAL ] Iteration 128:\tk_eff = 1.185626\tres = 1.412E-03\n", + "[ NORMAL ] Iteration 129:\tk_eff = 1.187163\tres = 1.353E-03\n", + "[ NORMAL ] Iteration 130:\tk_eff = 1.188637\tres = 1.296E-03\n", + "[ NORMAL ] Iteration 131:\tk_eff = 1.190050\tres = 1.241E-03\n", + "[ NORMAL ] Iteration 132:\tk_eff = 1.191405\tres = 1.189E-03\n", + "[ NORMAL ] Iteration 133:\tk_eff = 1.192704\tres = 1.139E-03\n", + "[ NORMAL ] Iteration 134:\tk_eff = 1.193950\tres = 1.091E-03\n", + "[ NORMAL ] Iteration 135:\tk_eff = 1.195144\tres = 1.044E-03\n", + "[ NORMAL ] Iteration 136:\tk_eff = 1.196287\tres = 9.997E-04\n", + "[ NORMAL ] Iteration 137:\tk_eff = 1.197383\tres = 9.571E-04\n", + "[ NORMAL ] Iteration 138:\tk_eff = 1.198433\tres = 9.161E-04\n", + "[ NORMAL ] Iteration 139:\tk_eff = 1.199439\tres = 8.768E-04\n", + "[ NORMAL ] Iteration 140:\tk_eff = 1.200402\tres = 8.391E-04\n", + "[ NORMAL ] Iteration 141:\tk_eff = 1.201324\tres = 8.029E-04\n", + "[ NORMAL ] Iteration 142:\tk_eff = 1.202207\tres = 7.682E-04\n", + "[ NORMAL ] Iteration 143:\tk_eff = 1.203052\tres = 7.349E-04\n", + "[ NORMAL ] Iteration 144:\tk_eff = 1.203861\tres = 7.030E-04\n", + "[ NORMAL ] Iteration 145:\tk_eff = 1.204635\tres = 6.724E-04\n", + "[ NORMAL ] Iteration 146:\tk_eff = 1.205376\tres = 6.431E-04\n", + "[ NORMAL ] Iteration 147:\tk_eff = 1.206084\tres = 6.149E-04\n", + "[ NORMAL ] Iteration 148:\tk_eff = 1.206762\tres = 5.880E-04\n", + "[ NORMAL ] Iteration 149:\tk_eff = 1.207411\tres = 5.622E-04\n", + "[ NORMAL ] Iteration 150:\tk_eff = 1.208031\tres = 5.374E-04\n", + "[ NORMAL ] Iteration 151:\tk_eff = 1.208624\tres = 5.137E-04\n", + "[ NORMAL ] Iteration 152:\tk_eff = 1.209192\tres = 4.910E-04\n", + "[ NORMAL ] Iteration 153:\tk_eff = 1.209734\tres = 4.693E-04\n", + "[ NORMAL ] Iteration 154:\tk_eff = 1.210252\tres = 4.484E-04\n", + "[ NORMAL ] Iteration 155:\tk_eff = 1.210748\tres = 4.285E-04\n", + "[ NORMAL ] Iteration 156:\tk_eff = 1.211221\tres = 4.094E-04\n", + "[ NORMAL ] Iteration 157:\tk_eff = 1.211674\tres = 3.911E-04\n", + "[ NORMAL ] Iteration 158:\tk_eff = 1.212106\tres = 3.736E-04\n", + "[ NORMAL ] Iteration 159:\tk_eff = 1.212519\tres = 3.569E-04\n", + "[ NORMAL ] Iteration 160:\tk_eff = 1.212914\tres = 3.408E-04\n", + "[ NORMAL ] Iteration 161:\tk_eff = 1.213291\tres = 3.255E-04\n", + "[ NORMAL ] Iteration 162:\tk_eff = 1.213651\tres = 3.108E-04\n", + "[ NORMAL ] Iteration 163:\tk_eff = 1.213995\tres = 2.968E-04\n", + "[ NORMAL ] Iteration 164:\tk_eff = 1.214323\tres = 2.834E-04\n", + "[ NORMAL ] Iteration 165:\tk_eff = 1.214637\tres = 2.705E-04\n", + "[ NORMAL ] Iteration 166:\tk_eff = 1.214936\tres = 2.582E-04\n", + "[ NORMAL ] Iteration 167:\tk_eff = 1.215222\tres = 2.465E-04\n", + "[ NORMAL ] Iteration 168:\tk_eff = 1.215495\tres = 2.353E-04\n", + "[ NORMAL ] Iteration 169:\tk_eff = 1.215755\tres = 2.245E-04\n", + "[ NORMAL ] Iteration 170:\tk_eff = 1.216004\tres = 2.142E-04\n", + "[ NORMAL ] Iteration 171:\tk_eff = 1.216241\tres = 2.044E-04\n", + "[ NORMAL ] Iteration 172:\tk_eff = 1.216468\tres = 1.951E-04\n", + "[ NORMAL ] Iteration 173:\tk_eff = 1.216683\tres = 1.861E-04\n", + "[ NORMAL ] Iteration 174:\tk_eff = 1.216889\tres = 1.775E-04\n", + "[ NORMAL ] Iteration 175:\tk_eff = 1.217086\tres = 1.693E-04\n", + "[ NORMAL ] Iteration 176:\tk_eff = 1.217274\tres = 1.615E-04\n", + "[ NORMAL ] Iteration 177:\tk_eff = 1.217452\tres = 1.540E-04\n", + "[ NORMAL ] Iteration 178:\tk_eff = 1.217623\tres = 1.469E-04\n", + "[ NORMAL ] Iteration 179:\tk_eff = 1.217786\tres = 1.401E-04\n", + "[ NORMAL ] Iteration 180:\tk_eff = 1.217941\tres = 1.336E-04\n", + "[ NORMAL ] Iteration 181:\tk_eff = 1.218089\tres = 1.274E-04\n", + "[ NORMAL ] Iteration 182:\tk_eff = 1.218230\tres = 1.214E-04\n", + "[ NORMAL ] Iteration 183:\tk_eff = 1.218364\tres = 1.158E-04\n", + "[ NORMAL ] Iteration 184:\tk_eff = 1.218492\tres = 1.104E-04\n", + "[ NORMAL ] Iteration 185:\tk_eff = 1.218614\tres = 1.052E-04\n", + "[ NORMAL ] Iteration 186:\tk_eff = 1.218731\tres = 1.003E-04\n", + "[ NORMAL ] Iteration 187:\tk_eff = 1.218842\tres = 9.556E-05\n", + "[ NORMAL ] Iteration 188:\tk_eff = 1.218948\tres = 9.107E-05\n", + "[ NORMAL ] Iteration 189:\tk_eff = 1.219048\tres = 8.679E-05\n", + "[ NORMAL ] Iteration 190:\tk_eff = 1.219144\tres = 8.270E-05\n", + "[ NORMAL ] Iteration 191:\tk_eff = 1.219236\tres = 7.880E-05\n", + "[ NORMAL ] Iteration 192:\tk_eff = 1.219323\tres = 7.508E-05\n", + "[ NORMAL ] Iteration 193:\tk_eff = 1.219406\tres = 7.152E-05\n", + "[ NORMAL ] Iteration 194:\tk_eff = 1.219485\tres = 6.814E-05\n", + "[ NORMAL ] Iteration 195:\tk_eff = 1.219561\tres = 6.491E-05\n", + "[ NORMAL ] Iteration 196:\tk_eff = 1.219633\tres = 6.183E-05\n", + "[ NORMAL ] Iteration 197:\tk_eff = 1.219701\tres = 5.889E-05\n", + "[ NORMAL ] Iteration 198:\tk_eff = 1.219766\tres = 5.609E-05\n", + "[ NORMAL ] Iteration 199:\tk_eff = 1.219828\tres = 5.341E-05\n", + "[ NORMAL ] Iteration 200:\tk_eff = 1.219887\tres = 5.087E-05\n", + "[ NORMAL ] Iteration 201:\tk_eff = 1.219944\tres = 4.844E-05\n", + "[ NORMAL ] Iteration 202:\tk_eff = 1.219997\tres = 4.612E-05\n", + "[ NORMAL ] Iteration 203:\tk_eff = 1.220048\tres = 4.391E-05\n", + "[ NORMAL ] Iteration 204:\tk_eff = 1.220097\tres = 4.181E-05\n", + "[ NORMAL ] Iteration 205:\tk_eff = 1.220143\tres = 3.981E-05\n", + "[ NORMAL ] Iteration 206:\tk_eff = 1.220187\tres = 3.789E-05\n", + "[ NORMAL ] Iteration 207:\tk_eff = 1.220229\tres = 3.607E-05\n", + "[ NORMAL ] Iteration 208:\tk_eff = 1.220269\tres = 3.434E-05\n", + "[ NORMAL ] Iteration 209:\tk_eff = 1.220307\tres = 3.268E-05\n", + "[ NORMAL ] Iteration 210:\tk_eff = 1.220343\tres = 3.111E-05\n", + "[ NORMAL ] Iteration 211:\tk_eff = 1.220377\tres = 2.961E-05\n", + "[ NORMAL ] Iteration 212:\tk_eff = 1.220410\tres = 2.818E-05\n", + "[ NORMAL ] Iteration 213:\tk_eff = 1.220441\tres = 2.681E-05\n", + "[ NORMAL ] Iteration 214:\tk_eff = 1.220471\tres = 2.552E-05\n", + "[ NORMAL ] Iteration 215:\tk_eff = 1.220499\tres = 2.428E-05\n", + "[ NORMAL ] Iteration 216:\tk_eff = 1.220526\tres = 2.310E-05\n", + "[ NORMAL ] Iteration 217:\tk_eff = 1.220551\tres = 2.198E-05\n", + "[ NORMAL ] Iteration 218:\tk_eff = 1.220576\tres = 2.091E-05\n", + "[ NORMAL ] Iteration 219:\tk_eff = 1.220599\tres = 1.990E-05\n", + "[ NORMAL ] Iteration 220:\tk_eff = 1.220621\tres = 1.893E-05\n", + "[ NORMAL ] Iteration 221:\tk_eff = 1.220642\tres = 1.801E-05\n", + "[ NORMAL ] Iteration 222:\tk_eff = 1.220661\tres = 1.713E-05\n", + "[ NORMAL ] Iteration 223:\tk_eff = 1.220680\tres = 1.629E-05\n", + "[ NORMAL ] Iteration 224:\tk_eff = 1.220698\tres = 1.550E-05\n", + "[ NORMAL ] Iteration 225:\tk_eff = 1.220715\tres = 1.474E-05\n", + "[ NORMAL ] Iteration 226:\tk_eff = 1.220732\tres = 1.402E-05\n", + "[ NORMAL ] Iteration 227:\tk_eff = 1.220747\tres = 1.333E-05\n", + "[ NORMAL ] Iteration 228:\tk_eff = 1.220762\tres = 1.268E-05\n", + "[ NORMAL ] Iteration 229:\tk_eff = 1.220776\tres = 1.206E-05\n", + "[ NORMAL ] Iteration 230:\tk_eff = 1.220789\tres = 1.146E-05\n", + "[ NORMAL ] Iteration 231:\tk_eff = 1.220802\tres = 1.090E-05\n", + "[ NORMAL ] Iteration 232:\tk_eff = 1.220814\tres = 1.036E-05\n" ] } ], @@ -1367,8 +1444,8 @@ "output_type": "stream", "text": [ "openmc keff = 1.223474\n", - "openmoc keff = 1.220892\n", - "bias [pcm]: -258.1\n" + "openmoc keff = 1.220814\n", + "bias [pcm]: -266.0\n" ] } ], @@ -1443,237 +1520,346 @@ "text": [ "[ NORMAL ] Importing ray tracing data from file...\n", "[ NORMAL ] Computing the eigenvalue...\n", - "[ NORMAL ] Iteration 0:\tk_eff = 0.495816\tres = 0.000E+00\n", - "[ NORMAL ] Iteration 1:\tk_eff = 0.557477\tres = 5.042E-01\n", - "[ NORMAL ] Iteration 2:\tk_eff = 0.518301\tres = 1.244E-01\n", - "[ NORMAL ] Iteration 3:\tk_eff = 0.509212\tres = 7.027E-02\n", - "[ NORMAL ] Iteration 4:\tk_eff = 0.496490\tres = 1.754E-02\n", - "[ NORMAL ] Iteration 5:\tk_eff = 0.488581\tres = 2.498E-02\n", - "[ NORMAL ] Iteration 6:\tk_eff = 0.482897\tres = 1.593E-02\n", - "[ NORMAL ] Iteration 7:\tk_eff = 0.479775\tres = 1.163E-02\n", - "[ NORMAL ] Iteration 8:\tk_eff = 0.478834\tres = 6.465E-03\n", - "[ NORMAL ] Iteration 9:\tk_eff = 0.479871\tres = 1.960E-03\n", - "[ NORMAL ] Iteration 10:\tk_eff = 0.482684\tres = 2.165E-03\n", - "[ NORMAL ] Iteration 11:\tk_eff = 0.487084\tres = 5.860E-03\n", - "[ NORMAL ] Iteration 12:\tk_eff = 0.492900\tres = 9.116E-03\n", - "[ NORMAL ] Iteration 13:\tk_eff = 0.499971\tres = 1.194E-02\n", - "[ NORMAL ] Iteration 14:\tk_eff = 0.508153\tres = 1.435E-02\n", - "[ NORMAL ] Iteration 15:\tk_eff = 0.517312\tres = 1.637E-02\n", - "[ NORMAL ] Iteration 16:\tk_eff = 0.527325\tres = 1.802E-02\n", - "[ NORMAL ] Iteration 17:\tk_eff = 0.538079\tres = 1.936E-02\n", - "[ NORMAL ] Iteration 18:\tk_eff = 0.549472\tres = 2.039E-02\n", - "[ NORMAL ] Iteration 19:\tk_eff = 0.561410\tres = 2.117E-02\n", - "[ NORMAL ] Iteration 20:\tk_eff = 0.573807\tres = 2.173E-02\n", - "[ NORMAL ] Iteration 21:\tk_eff = 0.586585\tres = 2.208E-02\n", - "[ NORMAL ] Iteration 22:\tk_eff = 0.599674\tres = 2.227E-02\n", - "[ NORMAL ] Iteration 23:\tk_eff = 0.613007\tres = 2.231E-02\n", - "[ NORMAL ] Iteration 24:\tk_eff = 0.626528\tres = 2.223E-02\n", - "[ NORMAL ] Iteration 25:\tk_eff = 0.640181\tres = 2.206E-02\n", - "[ NORMAL ] Iteration 26:\tk_eff = 0.653920\tres = 2.179E-02\n", - "[ NORMAL ] Iteration 27:\tk_eff = 0.667700\tres = 2.146E-02\n", - "[ NORMAL ] Iteration 28:\tk_eff = 0.681483\tres = 2.107E-02\n", - "[ NORMAL ] Iteration 29:\tk_eff = 0.695234\tres = 2.064E-02\n", - "[ NORMAL ] Iteration 30:\tk_eff = 0.708921\tres = 2.018E-02\n", - "[ NORMAL ] Iteration 31:\tk_eff = 0.722515\tres = 1.969E-02\n", - "[ NORMAL ] Iteration 32:\tk_eff = 0.735993\tres = 1.918E-02\n", - "[ NORMAL ] Iteration 33:\tk_eff = 0.749331\tres = 1.865E-02\n", - "[ NORMAL ] Iteration 34:\tk_eff = 0.762510\tres = 1.812E-02\n", - "[ NORMAL ] Iteration 35:\tk_eff = 0.775514\tres = 1.759E-02\n", - "[ NORMAL ] Iteration 36:\tk_eff = 0.788326\tres = 1.705E-02\n", - "[ NORMAL ] Iteration 37:\tk_eff = 0.800935\tres = 1.652E-02\n", - "[ NORMAL ] Iteration 38:\tk_eff = 0.813328\tres = 1.599E-02\n", - "[ NORMAL ] Iteration 39:\tk_eff = 0.825497\tres = 1.547E-02\n", - "[ NORMAL ] Iteration 40:\tk_eff = 0.837433\tres = 1.496E-02\n", - "[ NORMAL ] Iteration 41:\tk_eff = 0.849130\tres = 1.446E-02\n", - "[ NORMAL ] Iteration 42:\tk_eff = 0.860583\tres = 1.397E-02\n", - "[ NORMAL ] Iteration 43:\tk_eff = 0.871788\tres = 1.349E-02\n", - "[ NORMAL ] Iteration 44:\tk_eff = 0.882742\tres = 1.302E-02\n", - "[ NORMAL ] Iteration 45:\tk_eff = 0.893442\tres = 1.256E-02\n", - "[ NORMAL ] Iteration 46:\tk_eff = 0.903887\tres = 1.212E-02\n", - "[ NORMAL ] Iteration 47:\tk_eff = 0.914077\tres = 1.169E-02\n", - "[ NORMAL ] Iteration 48:\tk_eff = 0.924012\tres = 1.127E-02\n", - "[ NORMAL ] Iteration 49:\tk_eff = 0.933693\tres = 1.087E-02\n", - "[ NORMAL ] Iteration 50:\tk_eff = 0.943122\tres = 1.048E-02\n", - "[ NORMAL ] Iteration 51:\tk_eff = 0.952299\tres = 1.010E-02\n", - "[ NORMAL ] Iteration 52:\tk_eff = 0.961228\tres = 9.730E-03\n", - "[ NORMAL ] Iteration 53:\tk_eff = 0.969911\tres = 9.377E-03\n", - "[ NORMAL ] Iteration 54:\tk_eff = 0.978351\tres = 9.033E-03\n", - "[ NORMAL ] Iteration 55:\tk_eff = 0.986552\tres = 8.702E-03\n", - "[ NORMAL ] Iteration 56:\tk_eff = 0.994517\tres = 8.382E-03\n", - "[ NORMAL ] Iteration 57:\tk_eff = 1.002250\tres = 8.074E-03\n", - "[ NORMAL ] Iteration 58:\tk_eff = 1.009755\tres = 7.776E-03\n", - "[ NORMAL ] Iteration 59:\tk_eff = 1.017037\tres = 7.488E-03\n", - "[ NORMAL ] Iteration 60:\tk_eff = 1.024099\tres = 7.211E-03\n", - "[ NORMAL ] Iteration 61:\tk_eff = 1.030947\tres = 6.944E-03\n", - "[ NORMAL ] Iteration 62:\tk_eff = 1.037584\tres = 6.687E-03\n", - "[ NORMAL ] Iteration 63:\tk_eff = 1.044016\tres = 6.438E-03\n", - "[ NORMAL ] Iteration 64:\tk_eff = 1.050247\tres = 6.199E-03\n", - "[ NORMAL ] Iteration 65:\tk_eff = 1.056282\tres = 5.969E-03\n", - "[ NORMAL ] Iteration 66:\tk_eff = 1.062125\tres = 5.746E-03\n", - "[ NORMAL ] Iteration 67:\tk_eff = 1.067781\tres = 5.531E-03\n", - "[ NORMAL ] Iteration 68:\tk_eff = 1.073255\tres = 5.326E-03\n", - "[ NORMAL ] Iteration 69:\tk_eff = 1.078552\tres = 5.126E-03\n", - "[ NORMAL ] Iteration 70:\tk_eff = 1.083676\tres = 4.936E-03\n", - "[ NORMAL ] Iteration 71:\tk_eff = 1.088632\tres = 4.751E-03\n", - "[ NORMAL ] Iteration 72:\tk_eff = 1.093425\tres = 4.573E-03\n", - "[ NORMAL ] Iteration 73:\tk_eff = 1.098058\tres = 4.403E-03\n", - "[ NORMAL ] Iteration 74:\tk_eff = 1.102537\tres = 4.237E-03\n", - "[ NORMAL ] Iteration 75:\tk_eff = 1.106866\tres = 4.079E-03\n", - "[ NORMAL ] Iteration 76:\tk_eff = 1.111049\tres = 3.926E-03\n", - "[ NORMAL ] Iteration 77:\tk_eff = 1.115090\tres = 3.779E-03\n", - "[ NORMAL ] Iteration 78:\tk_eff = 1.118995\tres = 3.638E-03\n", - "[ NORMAL ] Iteration 79:\tk_eff = 1.122766\tres = 3.501E-03\n", - "[ NORMAL ] Iteration 80:\tk_eff = 1.126408\tres = 3.370E-03\n", - "[ NORMAL ] Iteration 81:\tk_eff = 1.129925\tres = 3.244E-03\n", - "[ NORMAL ] Iteration 82:\tk_eff = 1.133320\tres = 3.122E-03\n", - "[ NORMAL ] Iteration 83:\tk_eff = 1.136597\tres = 3.005E-03\n", - "[ NORMAL ] Iteration 84:\tk_eff = 1.139761\tres = 2.892E-03\n", - "[ NORMAL ] Iteration 85:\tk_eff = 1.142815\tres = 2.783E-03\n", - "[ NORMAL ] Iteration 86:\tk_eff = 1.145761\tres = 2.679E-03\n", - "[ NORMAL ] Iteration 87:\tk_eff = 1.148605\tres = 2.579E-03\n", - "[ NORMAL ] Iteration 88:\tk_eff = 1.151348\tres = 2.482E-03\n", - "[ NORMAL ] Iteration 89:\tk_eff = 1.153994\tres = 2.388E-03\n", - "[ NORMAL ] Iteration 90:\tk_eff = 1.156547\tres = 2.299E-03\n", - "[ NORMAL ] Iteration 91:\tk_eff = 1.159009\tres = 2.212E-03\n", - "[ NORMAL ] Iteration 92:\tk_eff = 1.161384\tres = 2.129E-03\n", - "[ NORMAL ] Iteration 93:\tk_eff = 1.163674\tres = 2.049E-03\n", - "[ NORMAL ] Iteration 94:\tk_eff = 1.165882\tres = 1.972E-03\n", - "[ NORMAL ] Iteration 95:\tk_eff = 1.168012\tres = 1.898E-03\n", - "[ NORMAL ] Iteration 96:\tk_eff = 1.170064\tres = 1.827E-03\n", - "[ NORMAL ] Iteration 97:\tk_eff = 1.172043\tres = 1.757E-03\n", - "[ NORMAL ] Iteration 98:\tk_eff = 1.173951\tres = 1.692E-03\n", - "[ NORMAL ] Iteration 99:\tk_eff = 1.175790\tres = 1.628E-03\n", - "[ NORMAL ] Iteration 100:\tk_eff = 1.177562\tres = 1.566E-03\n", - "[ NORMAL ] Iteration 101:\tk_eff = 1.179269\tres = 1.507E-03\n", - "[ NORMAL ] Iteration 102:\tk_eff = 1.180916\tres = 1.450E-03\n", - "[ NORMAL ] Iteration 103:\tk_eff = 1.182502\tres = 1.396E-03\n", - "[ NORMAL ] Iteration 104:\tk_eff = 1.184030\tres = 1.343E-03\n", - "[ NORMAL ] Iteration 105:\tk_eff = 1.185503\tres = 1.292E-03\n", - "[ NORMAL ] Iteration 106:\tk_eff = 1.186922\tres = 1.244E-03\n", - "[ NORMAL ] Iteration 107:\tk_eff = 1.188288\tres = 1.197E-03\n", - "[ NORMAL ] Iteration 108:\tk_eff = 1.189606\tres = 1.151E-03\n", - "[ NORMAL ] Iteration 109:\tk_eff = 1.190874\tres = 1.108E-03\n", - "[ NORMAL ] Iteration 110:\tk_eff = 1.192096\tres = 1.066E-03\n", - "[ NORMAL ] Iteration 111:\tk_eff = 1.193273\tres = 1.026E-03\n", - "[ NORMAL ] Iteration 112:\tk_eff = 1.194407\tres = 9.870E-04\n", - "[ NORMAL ] Iteration 113:\tk_eff = 1.195499\tres = 9.504E-04\n", - "[ NORMAL ] Iteration 114:\tk_eff = 1.196550\tres = 9.140E-04\n", - "[ NORMAL ] Iteration 115:\tk_eff = 1.197563\tres = 8.792E-04\n", - "[ NORMAL ] Iteration 116:\tk_eff = 1.198538\tres = 8.468E-04\n", - "[ NORMAL ] Iteration 117:\tk_eff = 1.199477\tres = 8.140E-04\n", - "[ NORMAL ] Iteration 118:\tk_eff = 1.200382\tres = 7.837E-04\n", - "[ NORMAL ] Iteration 119:\tk_eff = 1.201253\tres = 7.539E-04\n", - "[ NORMAL ] Iteration 120:\tk_eff = 1.202091\tres = 7.257E-04\n", - "[ NORMAL ] Iteration 121:\tk_eff = 1.202898\tres = 6.979E-04\n", - "[ NORMAL ] Iteration 122:\tk_eff = 1.203676\tres = 6.716E-04\n", - "[ NORMAL ] Iteration 123:\tk_eff = 1.204424\tres = 6.465E-04\n", - "[ NORMAL ] Iteration 124:\tk_eff = 1.205144\tres = 6.217E-04\n", - "[ NORMAL ] Iteration 125:\tk_eff = 1.205838\tres = 5.979E-04\n", - "[ NORMAL ] Iteration 126:\tk_eff = 1.206505\tres = 5.760E-04\n", - "[ NORMAL ] Iteration 127:\tk_eff = 1.207148\tres = 5.532E-04\n", - "[ NORMAL ] Iteration 128:\tk_eff = 1.207767\tres = 5.325E-04\n", - "[ NORMAL ] Iteration 129:\tk_eff = 1.208363\tres = 5.125E-04\n", - "[ NORMAL ] Iteration 130:\tk_eff = 1.208936\tres = 4.935E-04\n", - "[ NORMAL ] Iteration 131:\tk_eff = 1.209487\tres = 4.744E-04\n", - "[ NORMAL ] Iteration 132:\tk_eff = 1.210018\tres = 4.559E-04\n", - "[ NORMAL ] Iteration 133:\tk_eff = 1.210529\tres = 4.392E-04\n", - "[ NORMAL ] Iteration 134:\tk_eff = 1.211021\tres = 4.223E-04\n", - "[ NORMAL ] Iteration 135:\tk_eff = 1.211495\tres = 4.060E-04\n", - "[ NORMAL ] Iteration 136:\tk_eff = 1.211951\tres = 3.914E-04\n", - "[ NORMAL ] Iteration 137:\tk_eff = 1.212390\tres = 3.763E-04\n", - "[ NORMAL ] Iteration 138:\tk_eff = 1.212812\tres = 3.623E-04\n", - "[ NORMAL ] Iteration 139:\tk_eff = 1.213217\tres = 3.480E-04\n", - "[ NORMAL ] Iteration 140:\tk_eff = 1.213608\tres = 3.344E-04\n", - "[ NORMAL ] Iteration 141:\tk_eff = 1.213984\tres = 3.223E-04\n", - "[ NORMAL ] Iteration 142:\tk_eff = 1.214347\tres = 3.097E-04\n", - "[ NORMAL ] Iteration 143:\tk_eff = 1.214695\tres = 2.985E-04\n", - "[ NORMAL ] Iteration 144:\tk_eff = 1.215031\tres = 2.869E-04\n", - "[ NORMAL ] Iteration 145:\tk_eff = 1.215352\tres = 2.763E-04\n", - "[ NORMAL ] Iteration 146:\tk_eff = 1.215663\tres = 2.648E-04\n", - "[ NORMAL ] Iteration 147:\tk_eff = 1.215962\tres = 2.552E-04\n", - "[ NORMAL ] Iteration 148:\tk_eff = 1.216249\tres = 2.460E-04\n", - "[ NORMAL ] Iteration 149:\tk_eff = 1.216526\tres = 2.362E-04\n", - "[ NORMAL ] Iteration 150:\tk_eff = 1.216792\tres = 2.279E-04\n", - "[ NORMAL ] Iteration 151:\tk_eff = 1.217048\tres = 2.188E-04\n", - "[ NORMAL ] Iteration 152:\tk_eff = 1.217294\tres = 2.100E-04\n", - "[ NORMAL ] Iteration 153:\tk_eff = 1.217531\tres = 2.024E-04\n", - "[ NORMAL ] Iteration 154:\tk_eff = 1.217759\tres = 1.948E-04\n", - "[ NORMAL ] Iteration 155:\tk_eff = 1.217978\tres = 1.872E-04\n", - "[ NORMAL ] Iteration 156:\tk_eff = 1.218189\tres = 1.799E-04\n", - "[ NORMAL ] Iteration 157:\tk_eff = 1.218393\tres = 1.733E-04\n", - "[ NORMAL ] Iteration 158:\tk_eff = 1.218588\tres = 1.668E-04\n", - "[ NORMAL ] Iteration 159:\tk_eff = 1.218776\tres = 1.600E-04\n", - "[ NORMAL ] Iteration 160:\tk_eff = 1.218957\tres = 1.544E-04\n", - "[ NORMAL ] Iteration 161:\tk_eff = 1.219131\tres = 1.485E-04\n", - "[ NORMAL ] Iteration 162:\tk_eff = 1.219298\tres = 1.428E-04\n", - "[ NORMAL ] Iteration 163:\tk_eff = 1.219459\tres = 1.374E-04\n", - "[ NORMAL ] Iteration 164:\tk_eff = 1.219614\tres = 1.321E-04\n", - "[ NORMAL ] Iteration 165:\tk_eff = 1.219763\tres = 1.270E-04\n", - "[ NORMAL ] Iteration 166:\tk_eff = 1.219906\tres = 1.221E-04\n", - "[ NORMAL ] Iteration 167:\tk_eff = 1.220044\tres = 1.175E-04\n", - "[ NORMAL ] Iteration 168:\tk_eff = 1.220177\tres = 1.130E-04\n", - "[ NORMAL ] Iteration 169:\tk_eff = 1.220304\tres = 1.084E-04\n", - "[ NORMAL ] Iteration 170:\tk_eff = 1.220427\tres = 1.045E-04\n", - "[ NORMAL ] Iteration 171:\tk_eff = 1.220545\tres = 1.007E-04\n", - "[ NORMAL ] Iteration 172:\tk_eff = 1.220659\tres = 9.678E-05\n", - "[ NORMAL ] Iteration 173:\tk_eff = 1.220768\tres = 9.304E-05\n", - "[ NORMAL ] Iteration 174:\tk_eff = 1.220874\tres = 8.984E-05\n", - "[ NORMAL ] Iteration 175:\tk_eff = 1.220975\tres = 8.640E-05\n", - "[ NORMAL ] Iteration 176:\tk_eff = 1.221073\tres = 8.326E-05\n", - "[ NORMAL ] Iteration 177:\tk_eff = 1.221166\tres = 7.985E-05\n", - "[ NORMAL ] Iteration 178:\tk_eff = 1.221256\tres = 7.662E-05\n", - "[ NORMAL ] Iteration 179:\tk_eff = 1.221343\tres = 7.371E-05\n", - "[ NORMAL ] Iteration 180:\tk_eff = 1.221426\tres = 7.091E-05\n", - "[ NORMAL ] Iteration 181:\tk_eff = 1.221506\tres = 6.827E-05\n", - "[ NORMAL ] Iteration 182:\tk_eff = 1.221583\tres = 6.560E-05\n", - "[ NORMAL ] Iteration 183:\tk_eff = 1.221657\tres = 6.320E-05\n", - "[ NORMAL ] Iteration 184:\tk_eff = 1.221729\tres = 6.067E-05\n", - "[ NORMAL ] Iteration 185:\tk_eff = 1.221797\tres = 5.829E-05\n", - "[ NORMAL ] Iteration 186:\tk_eff = 1.221863\tres = 5.641E-05\n", - "[ NORMAL ] Iteration 187:\tk_eff = 1.221927\tres = 5.382E-05\n", - "[ NORMAL ] Iteration 188:\tk_eff = 1.221987\tres = 5.196E-05\n", - "[ NORMAL ] Iteration 189:\tk_eff = 1.222046\tres = 4.968E-05\n", - "[ NORMAL ] Iteration 190:\tk_eff = 1.222102\tres = 4.810E-05\n", - "[ NORMAL ] Iteration 191:\tk_eff = 1.222157\tres = 4.617E-05\n", - "[ NORMAL ] Iteration 192:\tk_eff = 1.222209\tres = 4.456E-05\n", - "[ NORMAL ] Iteration 193:\tk_eff = 1.222260\tres = 4.287E-05\n", - "[ NORMAL ] Iteration 194:\tk_eff = 1.222308\tres = 4.122E-05\n", - "[ NORMAL ] Iteration 195:\tk_eff = 1.222355\tres = 3.971E-05\n", - "[ NORMAL ] Iteration 196:\tk_eff = 1.222399\tres = 3.805E-05\n", - "[ NORMAL ] Iteration 197:\tk_eff = 1.222442\tres = 3.657E-05\n", - "[ NORMAL ] Iteration 198:\tk_eff = 1.222484\tres = 3.521E-05\n", - "[ NORMAL ] Iteration 199:\tk_eff = 1.222523\tres = 3.381E-05\n", - "[ NORMAL ] Iteration 200:\tk_eff = 1.222561\tres = 3.262E-05\n", - "[ NORMAL ] Iteration 201:\tk_eff = 1.222598\tres = 3.107E-05\n", - "[ NORMAL ] Iteration 202:\tk_eff = 1.222634\tres = 2.985E-05\n", - "[ NORMAL ] Iteration 203:\tk_eff = 1.222668\tres = 2.902E-05\n", - "[ NORMAL ] Iteration 204:\tk_eff = 1.222700\tres = 2.804E-05\n", - "[ NORMAL ] Iteration 205:\tk_eff = 1.222732\tres = 2.639E-05\n", - "[ NORMAL ] Iteration 206:\tk_eff = 1.222762\tres = 2.577E-05\n", - "[ NORMAL ] Iteration 207:\tk_eff = 1.222792\tres = 2.487E-05\n", - "[ NORMAL ] Iteration 208:\tk_eff = 1.222820\tres = 2.400E-05\n", - "[ NORMAL ] Iteration 209:\tk_eff = 1.222847\tres = 2.291E-05\n", - "[ NORMAL ] Iteration 210:\tk_eff = 1.222872\tres = 2.200E-05\n", - "[ NORMAL ] Iteration 211:\tk_eff = 1.222897\tres = 2.121E-05\n", - "[ NORMAL ] Iteration 212:\tk_eff = 1.222921\tres = 2.040E-05\n", - "[ NORMAL ] Iteration 213:\tk_eff = 1.222944\tres = 1.964E-05\n", - "[ NORMAL ] Iteration 214:\tk_eff = 1.222967\tres = 1.882E-05\n", - "[ NORMAL ] Iteration 215:\tk_eff = 1.222988\tres = 1.821E-05\n", - "[ NORMAL ] Iteration 216:\tk_eff = 1.223009\tres = 1.763E-05\n", - "[ NORMAL ] Iteration 217:\tk_eff = 1.223029\tres = 1.690E-05\n", - "[ NORMAL ] Iteration 218:\tk_eff = 1.223048\tres = 1.630E-05\n", - "[ NORMAL ] Iteration 219:\tk_eff = 1.223067\tres = 1.572E-05\n", - "[ NORMAL ] Iteration 220:\tk_eff = 1.223084\tres = 1.507E-05\n", - "[ NORMAL ] Iteration 221:\tk_eff = 1.223101\tres = 1.427E-05\n", - "[ NORMAL ] Iteration 222:\tk_eff = 1.223117\tres = 1.394E-05\n", - "[ NORMAL ] Iteration 223:\tk_eff = 1.223133\tres = 1.330E-05\n", - "[ NORMAL ] Iteration 224:\tk_eff = 1.223148\tres = 1.298E-05\n", - "[ NORMAL ] Iteration 225:\tk_eff = 1.223163\tres = 1.241E-05\n", - "[ NORMAL ] Iteration 226:\tk_eff = 1.223177\tres = 1.167E-05\n", - "[ NORMAL ] Iteration 227:\tk_eff = 1.223190\tres = 1.151E-05\n", - "[ NORMAL ] Iteration 228:\tk_eff = 1.223203\tres = 1.073E-05\n", - "[ NORMAL ] Iteration 229:\tk_eff = 1.223215\tres = 1.050E-05\n", - "[ NORMAL ] Iteration 230:\tk_eff = 1.223227\tres = 1.000E-05\n" + "[ NORMAL ] Iteration 0:\tk_eff = 0.366907\tres = 0.000E+00\n", + "[ NORMAL ] Iteration 1:\tk_eff = 0.391217\tres = 6.331E-01\n", + "[ NORMAL ] Iteration 2:\tk_eff = 0.393027\tres = 6.626E-02\n", + "[ NORMAL ] Iteration 3:\tk_eff = 0.381142\tres = 4.627E-03\n", + "[ NORMAL ] Iteration 4:\tk_eff = 0.375065\tres = 3.024E-02\n", + "[ NORMAL ] Iteration 5:\tk_eff = 0.369645\tres = 1.594E-02\n", + "[ NORMAL ] Iteration 6:\tk_eff = 0.365597\tres = 1.445E-02\n", + "[ NORMAL ] Iteration 7:\tk_eff = 0.363111\tres = 1.095E-02\n", + "[ NORMAL ] Iteration 8:\tk_eff = 0.361532\tres = 6.802E-03\n", + "[ NORMAL ] Iteration 9:\tk_eff = 0.361339\tres = 4.349E-03\n", + "[ NORMAL ] Iteration 10:\tk_eff = 0.362062\tres = 5.322E-04\n", + "[ NORMAL ] Iteration 11:\tk_eff = 0.363777\tres = 2.001E-03\n", + "[ NORMAL ] Iteration 12:\tk_eff = 0.366395\tres = 4.735E-03\n", + "[ NORMAL ] Iteration 13:\tk_eff = 0.369859\tres = 7.198E-03\n", + "[ NORMAL ] Iteration 14:\tk_eff = 0.374042\tres = 9.454E-03\n", + "[ NORMAL ] Iteration 15:\tk_eff = 0.378972\tres = 1.131E-02\n", + "[ NORMAL ] Iteration 16:\tk_eff = 0.384524\tres = 1.318E-02\n", + "[ NORMAL ] Iteration 17:\tk_eff = 0.390678\tres = 1.465E-02\n", + "[ NORMAL ] Iteration 18:\tk_eff = 0.397373\tres = 1.600E-02\n", + "[ NORMAL ] Iteration 19:\tk_eff = 0.404563\tres = 1.714E-02\n", + "[ NORMAL ] Iteration 20:\tk_eff = 0.412207\tres = 1.809E-02\n", + "[ NORMAL ] Iteration 21:\tk_eff = 0.420270\tres = 1.890E-02\n", + "[ NORMAL ] Iteration 22:\tk_eff = 0.428695\tres = 1.956E-02\n", + "[ NORMAL ] Iteration 23:\tk_eff = 0.437463\tres = 2.005E-02\n", + "[ NORMAL ] Iteration 24:\tk_eff = 0.446530\tres = 2.045E-02\n", + "[ NORMAL ] Iteration 25:\tk_eff = 0.455867\tres = 2.073E-02\n", + "[ NORMAL ] Iteration 26:\tk_eff = 0.465442\tres = 2.091E-02\n", + "[ NORMAL ] Iteration 27:\tk_eff = 0.475229\tres = 2.101E-02\n", + "[ NORMAL ] Iteration 28:\tk_eff = 0.485198\tres = 2.103E-02\n", + "[ NORMAL ] Iteration 29:\tk_eff = 0.495327\tres = 2.098E-02\n", + "[ NORMAL ] Iteration 30:\tk_eff = 0.505591\tres = 2.088E-02\n", + "[ NORMAL ] Iteration 31:\tk_eff = 0.515969\tres = 2.072E-02\n", + "[ NORMAL ] Iteration 32:\tk_eff = 0.526440\tres = 2.053E-02\n", + "[ NORMAL ] Iteration 33:\tk_eff = 0.536985\tres = 2.029E-02\n", + "[ NORMAL ] Iteration 34:\tk_eff = 0.547587\tres = 2.003E-02\n", + "[ NORMAL ] Iteration 35:\tk_eff = 0.558228\tres = 1.974E-02\n", + "[ NORMAL ] Iteration 36:\tk_eff = 0.568893\tres = 1.943E-02\n", + "[ NORMAL ] Iteration 37:\tk_eff = 0.579569\tres = 1.911E-02\n", + "[ NORMAL ] Iteration 38:\tk_eff = 0.590241\tres = 1.877E-02\n", + "[ NORMAL ] Iteration 39:\tk_eff = 0.600898\tres = 1.841E-02\n", + "[ NORMAL ] Iteration 40:\tk_eff = 0.611527\tres = 1.805E-02\n", + "[ NORMAL ] Iteration 41:\tk_eff = 0.622118\tres = 1.769E-02\n", + "[ NORMAL ] Iteration 42:\tk_eff = 0.632662\tres = 1.732E-02\n", + "[ NORMAL ] Iteration 43:\tk_eff = 0.643149\tres = 1.695E-02\n", + "[ NORMAL ] Iteration 44:\tk_eff = 0.653571\tres = 1.658E-02\n", + "[ NORMAL ] Iteration 45:\tk_eff = 0.663920\tres = 1.620E-02\n", + "[ NORMAL ] Iteration 46:\tk_eff = 0.674189\tres = 1.583E-02\n", + "[ NORMAL ] Iteration 47:\tk_eff = 0.684372\tres = 1.547E-02\n", + "[ NORMAL ] Iteration 48:\tk_eff = 0.694464\tres = 1.510E-02\n", + "[ NORMAL ] Iteration 49:\tk_eff = 0.704457\tres = 1.475E-02\n", + "[ NORMAL ] Iteration 50:\tk_eff = 0.714349\tres = 1.439E-02\n", + "[ NORMAL ] Iteration 51:\tk_eff = 0.724134\tres = 1.404E-02\n", + "[ NORMAL ] Iteration 52:\tk_eff = 0.733808\tres = 1.370E-02\n", + "[ NORMAL ] Iteration 53:\tk_eff = 0.743369\tres = 1.336E-02\n", + "[ NORMAL ] Iteration 54:\tk_eff = 0.752812\tres = 1.303E-02\n", + "[ NORMAL ] Iteration 55:\tk_eff = 0.762135\tres = 1.270E-02\n", + "[ NORMAL ] Iteration 56:\tk_eff = 0.771336\tres = 1.238E-02\n", + "[ NORMAL ] Iteration 57:\tk_eff = 0.780412\tres = 1.207E-02\n", + "[ NORMAL ] Iteration 58:\tk_eff = 0.789362\tres = 1.177E-02\n", + "[ NORMAL ] Iteration 59:\tk_eff = 0.798184\tres = 1.147E-02\n", + "[ NORMAL ] Iteration 60:\tk_eff = 0.806877\tres = 1.118E-02\n", + "[ NORMAL ] Iteration 61:\tk_eff = 0.815440\tres = 1.089E-02\n", + "[ NORMAL ] Iteration 62:\tk_eff = 0.823872\tres = 1.061E-02\n", + "[ NORMAL ] Iteration 63:\tk_eff = 0.832172\tres = 1.034E-02\n", + "[ NORMAL ] Iteration 64:\tk_eff = 0.840340\tres = 1.007E-02\n", + "[ NORMAL ] Iteration 65:\tk_eff = 0.848377\tres = 9.816E-03\n", + "[ NORMAL ] Iteration 66:\tk_eff = 0.856281\tres = 9.563E-03\n", + "[ NORMAL ] Iteration 67:\tk_eff = 0.864053\tres = 9.317E-03\n", + "[ NORMAL ] Iteration 68:\tk_eff = 0.871693\tres = 9.076E-03\n", + "[ NORMAL ] Iteration 69:\tk_eff = 0.879202\tres = 8.842E-03\n", + "[ NORMAL ] Iteration 70:\tk_eff = 0.886580\tres = 8.614E-03\n", + "[ NORMAL ] Iteration 71:\tk_eff = 0.893828\tres = 8.392E-03\n", + "[ NORMAL ] Iteration 72:\tk_eff = 0.900946\tres = 8.175E-03\n", + "[ NORMAL ] Iteration 73:\tk_eff = 0.907936\tres = 7.964E-03\n", + "[ NORMAL ] Iteration 74:\tk_eff = 0.914798\tres = 7.758E-03\n", + "[ NORMAL ] Iteration 75:\tk_eff = 0.921534\tres = 7.558E-03\n", + "[ NORMAL ] Iteration 76:\tk_eff = 0.928144\tres = 7.363E-03\n", + "[ NORMAL ] Iteration 77:\tk_eff = 0.934629\tres = 7.173E-03\n", + "[ NORMAL ] Iteration 78:\tk_eff = 0.940992\tres = 6.988E-03\n", + "[ NORMAL ] Iteration 79:\tk_eff = 0.947233\tres = 6.808E-03\n", + "[ NORMAL ] Iteration 80:\tk_eff = 0.953353\tres = 6.632E-03\n", + "[ NORMAL ] Iteration 81:\tk_eff = 0.959355\tres = 6.461E-03\n", + "[ NORMAL ] Iteration 82:\tk_eff = 0.965238\tres = 6.295E-03\n", + "[ NORMAL ] Iteration 83:\tk_eff = 0.971006\tres = 6.133E-03\n", + "[ NORMAL ] Iteration 84:\tk_eff = 0.976659\tres = 5.975E-03\n", + "[ NORMAL ] Iteration 85:\tk_eff = 0.982199\tres = 5.822E-03\n", + "[ NORMAL ] Iteration 86:\tk_eff = 0.987627\tres = 5.672E-03\n", + "[ NORMAL ] Iteration 87:\tk_eff = 0.992945\tres = 5.527E-03\n", + "[ NORMAL ] Iteration 88:\tk_eff = 0.998155\tres = 5.385E-03\n", + "[ NORMAL ] Iteration 89:\tk_eff = 1.003258\tres = 5.247E-03\n", + "[ NORMAL ] Iteration 90:\tk_eff = 1.008256\tres = 5.113E-03\n", + "[ NORMAL ] Iteration 91:\tk_eff = 1.013151\tres = 4.982E-03\n", + "[ NORMAL ] Iteration 92:\tk_eff = 1.017943\tres = 4.854E-03\n", + "[ NORMAL ] Iteration 93:\tk_eff = 1.022635\tres = 4.730E-03\n", + "[ NORMAL ] Iteration 94:\tk_eff = 1.027229\tres = 4.609E-03\n", + "[ NORMAL ] Iteration 95:\tk_eff = 1.031726\tres = 4.492E-03\n", + "[ NORMAL ] Iteration 96:\tk_eff = 1.036127\tres = 4.377E-03\n", + "[ NORMAL ] Iteration 97:\tk_eff = 1.040434\tres = 4.266E-03\n", + "[ NORMAL ] Iteration 98:\tk_eff = 1.044649\tres = 4.157E-03\n", + "[ NORMAL ] Iteration 99:\tk_eff = 1.048774\tres = 4.051E-03\n", + "[ NORMAL ] Iteration 100:\tk_eff = 1.052810\tres = 3.948E-03\n", + "[ NORMAL ] Iteration 101:\tk_eff = 1.056759\tres = 3.848E-03\n", + "[ NORMAL ] Iteration 102:\tk_eff = 1.060622\tres = 3.751E-03\n", + "[ NORMAL ] Iteration 103:\tk_eff = 1.064400\tres = 3.655E-03\n", + "[ NORMAL ] Iteration 104:\tk_eff = 1.068096\tres = 3.563E-03\n", + "[ NORMAL ] Iteration 105:\tk_eff = 1.071711\tres = 3.473E-03\n", + "[ NORMAL ] Iteration 106:\tk_eff = 1.075247\tres = 3.385E-03\n", + "[ NORMAL ] Iteration 107:\tk_eff = 1.078705\tres = 3.299E-03\n", + "[ NORMAL ] Iteration 108:\tk_eff = 1.082086\tres = 3.216E-03\n", + "[ NORMAL ] Iteration 109:\tk_eff = 1.085392\tres = 3.134E-03\n", + "[ NORMAL ] Iteration 110:\tk_eff = 1.088624\tres = 3.055E-03\n", + "[ NORMAL ] Iteration 111:\tk_eff = 1.091785\tres = 2.978E-03\n", + "[ NORMAL ] Iteration 112:\tk_eff = 1.094875\tres = 2.903E-03\n", + "[ NORMAL ] Iteration 113:\tk_eff = 1.097895\tres = 2.830E-03\n", + "[ NORMAL ] Iteration 114:\tk_eff = 1.100848\tres = 2.759E-03\n", + "[ NORMAL ] Iteration 115:\tk_eff = 1.103734\tres = 2.689E-03\n", + "[ NORMAL ] Iteration 116:\tk_eff = 1.106555\tres = 2.622E-03\n", + "[ NORMAL ] Iteration 117:\tk_eff = 1.109312\tres = 2.556E-03\n", + "[ NORMAL ] Iteration 118:\tk_eff = 1.112007\tres = 2.492E-03\n", + "[ NORMAL ] Iteration 119:\tk_eff = 1.114641\tres = 2.429E-03\n", + "[ NORMAL ] Iteration 120:\tk_eff = 1.117214\tres = 2.368E-03\n", + "[ NORMAL ] Iteration 121:\tk_eff = 1.119729\tres = 2.309E-03\n", + "[ NORMAL ] Iteration 122:\tk_eff = 1.122187\tres = 2.251E-03\n", + "[ NORMAL ] Iteration 123:\tk_eff = 1.124588\tres = 2.195E-03\n", + "[ NORMAL ] Iteration 124:\tk_eff = 1.126934\tres = 2.140E-03\n", + "[ NORMAL ] Iteration 125:\tk_eff = 1.129226\tres = 2.086E-03\n", + "[ NORMAL ] Iteration 126:\tk_eff = 1.131466\tres = 2.034E-03\n", + "[ NORMAL ] Iteration 127:\tk_eff = 1.133654\tres = 1.983E-03\n", + "[ NORMAL ] Iteration 128:\tk_eff = 1.135791\tres = 1.934E-03\n", + "[ NORMAL ] Iteration 129:\tk_eff = 1.137879\tres = 1.885E-03\n", + "[ NORMAL ] Iteration 130:\tk_eff = 1.139919\tres = 1.838E-03\n", + "[ NORMAL ] Iteration 131:\tk_eff = 1.141911\tres = 1.793E-03\n", + "[ NORMAL ] Iteration 132:\tk_eff = 1.143857\tres = 1.748E-03\n", + "[ NORMAL ] Iteration 133:\tk_eff = 1.145758\tres = 1.704E-03\n", + "[ NORMAL ] Iteration 134:\tk_eff = 1.147615\tres = 1.662E-03\n", + "[ NORMAL ] Iteration 135:\tk_eff = 1.149428\tres = 1.620E-03\n", + "[ NORMAL ] Iteration 136:\tk_eff = 1.151200\tres = 1.580E-03\n", + "[ NORMAL ] Iteration 137:\tk_eff = 1.152929\tres = 1.541E-03\n", + "[ NORMAL ] Iteration 138:\tk_eff = 1.154619\tres = 1.503E-03\n", + "[ NORMAL ] Iteration 139:\tk_eff = 1.156268\tres = 1.465E-03\n", + "[ NORMAL ] Iteration 140:\tk_eff = 1.157879\tres = 1.429E-03\n", + "[ NORMAL ] Iteration 141:\tk_eff = 1.159453\tres = 1.393E-03\n", + "[ NORMAL ] Iteration 142:\tk_eff = 1.160989\tres = 1.359E-03\n", + "[ NORMAL ] Iteration 143:\tk_eff = 1.162489\tres = 1.325E-03\n", + "[ NORMAL ] Iteration 144:\tk_eff = 1.163954\tres = 1.292E-03\n", + "[ NORMAL ] Iteration 145:\tk_eff = 1.165384\tres = 1.260E-03\n", + "[ NORMAL ] Iteration 146:\tk_eff = 1.166781\tres = 1.229E-03\n", + "[ NORMAL ] Iteration 147:\tk_eff = 1.168144\tres = 1.198E-03\n", + "[ NORMAL ] Iteration 148:\tk_eff = 1.169476\tres = 1.169E-03\n", + "[ NORMAL ] Iteration 149:\tk_eff = 1.170776\tres = 1.140E-03\n", + "[ NORMAL ] Iteration 150:\tk_eff = 1.172045\tres = 1.112E-03\n", + "[ NORMAL ] Iteration 151:\tk_eff = 1.173284\tres = 1.084E-03\n", + "[ NORMAL ] Iteration 152:\tk_eff = 1.174494\tres = 1.057E-03\n", + "[ NORMAL ] Iteration 153:\tk_eff = 1.175675\tres = 1.031E-03\n", + "[ NORMAL ] Iteration 154:\tk_eff = 1.176828\tres = 1.006E-03\n", + "[ NORMAL ] Iteration 155:\tk_eff = 1.177953\tres = 9.807E-04\n", + "[ NORMAL ] Iteration 156:\tk_eff = 1.179052\tres = 9.565E-04\n", + "[ NORMAL ] Iteration 157:\tk_eff = 1.180125\tres = 9.328E-04\n", + "[ NORMAL ] Iteration 158:\tk_eff = 1.181172\tres = 9.098E-04\n", + "[ NORMAL ] Iteration 159:\tk_eff = 1.182194\tres = 8.873E-04\n", + "[ NORMAL ] Iteration 160:\tk_eff = 1.183192\tres = 8.654E-04\n", + "[ NORMAL ] Iteration 161:\tk_eff = 1.184166\tres = 8.441E-04\n", + "[ NORMAL ] Iteration 162:\tk_eff = 1.185117\tres = 8.232E-04\n", + "[ NORMAL ] Iteration 163:\tk_eff = 1.186045\tres = 8.029E-04\n", + "[ NORMAL ] Iteration 164:\tk_eff = 1.186951\tres = 7.831E-04\n", + "[ NORMAL ] Iteration 165:\tk_eff = 1.187835\tres = 7.638E-04\n", + "[ NORMAL ] Iteration 166:\tk_eff = 1.188698\tres = 7.450E-04\n", + "[ NORMAL ] Iteration 167:\tk_eff = 1.189541\tres = 7.266E-04\n", + "[ NORMAL ] Iteration 168:\tk_eff = 1.190363\tres = 7.087E-04\n", + "[ NORMAL ] Iteration 169:\tk_eff = 1.191166\tres = 6.912E-04\n", + "[ NORMAL ] Iteration 170:\tk_eff = 1.191949\tres = 6.742E-04\n", + "[ NORMAL ] Iteration 171:\tk_eff = 1.192713\tres = 6.576E-04\n", + "[ NORMAL ] Iteration 172:\tk_eff = 1.193460\tres = 6.414E-04\n", + "[ NORMAL ] Iteration 173:\tk_eff = 1.194188\tres = 6.256E-04\n", + "[ NORMAL ] Iteration 174:\tk_eff = 1.194899\tres = 6.102E-04\n", + "[ NORMAL ] Iteration 175:\tk_eff = 1.195592\tres = 5.952E-04\n", + "[ NORMAL ] Iteration 176:\tk_eff = 1.196269\tres = 5.806E-04\n", + "[ NORMAL ] Iteration 177:\tk_eff = 1.196930\tres = 5.663E-04\n", + "[ NORMAL ] Iteration 178:\tk_eff = 1.197575\tres = 5.524E-04\n", + "[ NORMAL ] Iteration 179:\tk_eff = 1.198204\tres = 5.388E-04\n", + "[ NORMAL ] Iteration 180:\tk_eff = 1.198819\tres = 5.255E-04\n", + "[ NORMAL ] Iteration 181:\tk_eff = 1.199418\tres = 5.126E-04\n", + "[ NORMAL ] Iteration 182:\tk_eff = 1.200003\tres = 5.000E-04\n", + "[ NORMAL ] Iteration 183:\tk_eff = 1.200574\tres = 4.877E-04\n", + "[ NORMAL ] Iteration 184:\tk_eff = 1.201131\tres = 4.757E-04\n", + "[ NORMAL ] Iteration 185:\tk_eff = 1.201675\tres = 4.640E-04\n", + "[ NORMAL ] Iteration 186:\tk_eff = 1.202205\tres = 4.526E-04\n", + "[ NORMAL ] Iteration 187:\tk_eff = 1.202723\tres = 4.415E-04\n", + "[ NORMAL ] Iteration 188:\tk_eff = 1.203228\tres = 4.307E-04\n", + "[ NORMAL ] Iteration 189:\tk_eff = 1.203721\tres = 4.201E-04\n", + "[ NORMAL ] Iteration 190:\tk_eff = 1.204202\tres = 4.098E-04\n", + "[ NORMAL ] Iteration 191:\tk_eff = 1.204672\tres = 3.997E-04\n", + "[ NORMAL ] Iteration 192:\tk_eff = 1.205130\tres = 3.899E-04\n", + "[ NORMAL ] Iteration 193:\tk_eff = 1.205577\tres = 3.803E-04\n", + "[ NORMAL ] Iteration 194:\tk_eff = 1.206014\tres = 3.710E-04\n", + "[ NORMAL ] Iteration 195:\tk_eff = 1.206439\tres = 3.619E-04\n", + "[ NORMAL ] Iteration 196:\tk_eff = 1.206855\tres = 3.530E-04\n", + "[ NORMAL ] Iteration 197:\tk_eff = 1.207260\tres = 3.444E-04\n", + "[ NORMAL ] Iteration 198:\tk_eff = 1.207656\tres = 3.359E-04\n", + "[ NORMAL ] Iteration 199:\tk_eff = 1.208042\tres = 3.277E-04\n", + "[ NORMAL ] Iteration 200:\tk_eff = 1.208418\tres = 3.196E-04\n", + "[ NORMAL ] Iteration 201:\tk_eff = 1.208786\tres = 3.118E-04\n", + "[ NORMAL ] Iteration 202:\tk_eff = 1.209144\tres = 3.041E-04\n", + "[ NORMAL ] Iteration 203:\tk_eff = 1.209494\tres = 2.967E-04\n", + "[ NORMAL ] Iteration 204:\tk_eff = 1.209836\tres = 2.894E-04\n", + "[ NORMAL ] Iteration 205:\tk_eff = 1.210169\tres = 2.823E-04\n", + "[ NORMAL ] Iteration 206:\tk_eff = 1.210494\tres = 2.754E-04\n", + "[ NORMAL ] Iteration 207:\tk_eff = 1.210811\tres = 2.686E-04\n", + "[ NORMAL ] Iteration 208:\tk_eff = 1.211121\tres = 2.621E-04\n", + "[ NORMAL ] Iteration 209:\tk_eff = 1.211423\tres = 2.556E-04\n", + "[ NORMAL ] Iteration 210:\tk_eff = 1.211718\tres = 2.494E-04\n", + "[ NORMAL ] Iteration 211:\tk_eff = 1.212005\tres = 2.433E-04\n", + "[ NORMAL ] Iteration 212:\tk_eff = 1.212286\tres = 2.373E-04\n", + "[ NORMAL ] Iteration 213:\tk_eff = 1.212559\tres = 2.315E-04\n", + "[ NORMAL ] Iteration 214:\tk_eff = 1.212827\tres = 2.258E-04\n", + "[ NORMAL ] Iteration 215:\tk_eff = 1.213087\tres = 2.203E-04\n", + "[ NORMAL ] Iteration 216:\tk_eff = 1.213341\tres = 2.149E-04\n", + "[ NORMAL ] Iteration 217:\tk_eff = 1.213590\tres = 2.096E-04\n", + "[ NORMAL ] Iteration 218:\tk_eff = 1.213832\tres = 2.045E-04\n", + "[ NORMAL ] Iteration 219:\tk_eff = 1.214068\tres = 1.995E-04\n", + "[ NORMAL ] Iteration 220:\tk_eff = 1.214298\tres = 1.946E-04\n", + "[ NORMAL ] Iteration 221:\tk_eff = 1.214523\tres = 1.898E-04\n", + "[ NORMAL ] Iteration 222:\tk_eff = 1.214743\tres = 1.852E-04\n", + "[ NORMAL ] Iteration 223:\tk_eff = 1.214957\tres = 1.806E-04\n", + "[ NORMAL ] Iteration 224:\tk_eff = 1.215165\tres = 1.762E-04\n", + "[ NORMAL ] Iteration 225:\tk_eff = 1.215369\tres = 1.719E-04\n", + "[ NORMAL ] Iteration 226:\tk_eff = 1.215568\tres = 1.677E-04\n", + "[ NORMAL ] Iteration 227:\tk_eff = 1.215762\tres = 1.636E-04\n", + "[ NORMAL ] Iteration 228:\tk_eff = 1.215951\tres = 1.596E-04\n", + "[ NORMAL ] Iteration 229:\tk_eff = 1.216136\tres = 1.557E-04\n", + "[ NORMAL ] Iteration 230:\tk_eff = 1.216316\tres = 1.519E-04\n", + "[ NORMAL ] Iteration 231:\tk_eff = 1.216492\tres = 1.482E-04\n", + "[ NORMAL ] Iteration 232:\tk_eff = 1.216663\tres = 1.445E-04\n", + "[ NORMAL ] Iteration 233:\tk_eff = 1.216831\tres = 1.410E-04\n", + "[ NORMAL ] Iteration 234:\tk_eff = 1.216994\tres = 1.375E-04\n", + "[ NORMAL ] Iteration 235:\tk_eff = 1.217153\tres = 1.342E-04\n", + "[ NORMAL ] Iteration 236:\tk_eff = 1.217309\tres = 1.309E-04\n", + "[ NORMAL ] Iteration 237:\tk_eff = 1.217460\tres = 1.277E-04\n", + "[ NORMAL ] Iteration 238:\tk_eff = 1.217608\tres = 1.246E-04\n", + "[ NORMAL ] Iteration 239:\tk_eff = 1.217753\tres = 1.215E-04\n", + "[ NORMAL ] Iteration 240:\tk_eff = 1.217894\tres = 1.185E-04\n", + "[ NORMAL ] Iteration 241:\tk_eff = 1.218031\tres = 1.156E-04\n", + "[ NORMAL ] Iteration 242:\tk_eff = 1.218165\tres = 1.128E-04\n", + "[ NORMAL ] Iteration 243:\tk_eff = 1.218296\tres = 1.101E-04\n", + "[ NORMAL ] Iteration 244:\tk_eff = 1.218423\tres = 1.074E-04\n", + "[ NORMAL ] Iteration 245:\tk_eff = 1.218548\tres = 1.047E-04\n", + "[ NORMAL ] Iteration 246:\tk_eff = 1.218669\tres = 1.022E-04\n", + "[ NORMAL ] Iteration 247:\tk_eff = 1.218788\tres = 9.967E-05\n", + "[ NORMAL ] Iteration 248:\tk_eff = 1.218903\tres = 9.723E-05\n", + "[ NORMAL ] Iteration 249:\tk_eff = 1.219016\tres = 9.486E-05\n", + "[ NORMAL ] Iteration 250:\tk_eff = 1.219126\tres = 9.254E-05\n", + "[ NORMAL ] Iteration 251:\tk_eff = 1.219234\tres = 9.027E-05\n", + "[ NORMAL ] Iteration 252:\tk_eff = 1.219338\tres = 8.806E-05\n", + "[ NORMAL ] Iteration 253:\tk_eff = 1.219441\tres = 8.591E-05\n", + "[ NORMAL ] Iteration 254:\tk_eff = 1.219540\tres = 8.381E-05\n", + "[ NORMAL ] Iteration 255:\tk_eff = 1.219637\tres = 8.176E-05\n", + "[ NORMAL ] Iteration 256:\tk_eff = 1.219732\tres = 7.976E-05\n", + "[ NORMAL ] Iteration 257:\tk_eff = 1.219825\tres = 7.781E-05\n", + "[ NORMAL ] Iteration 258:\tk_eff = 1.219915\tres = 7.591E-05\n", + "[ NORMAL ] Iteration 259:\tk_eff = 1.220003\tres = 7.405E-05\n", + "[ NORMAL ] Iteration 260:\tk_eff = 1.220089\tres = 7.224E-05\n", + "[ NORMAL ] Iteration 261:\tk_eff = 1.220173\tres = 7.047E-05\n", + "[ NORMAL ] Iteration 262:\tk_eff = 1.220255\tres = 6.875E-05\n", + "[ NORMAL ] Iteration 263:\tk_eff = 1.220335\tres = 6.707E-05\n", + "[ NORMAL ] Iteration 264:\tk_eff = 1.220413\tres = 6.543E-05\n", + "[ NORMAL ] Iteration 265:\tk_eff = 1.220489\tres = 6.383E-05\n", + "[ NORMAL ] Iteration 266:\tk_eff = 1.220563\tres = 6.227E-05\n", + "[ NORMAL ] Iteration 267:\tk_eff = 1.220635\tres = 6.075E-05\n", + "[ NORMAL ] Iteration 268:\tk_eff = 1.220706\tres = 5.926E-05\n", + "[ NORMAL ] Iteration 269:\tk_eff = 1.220775\tres = 5.781E-05\n", + "[ NORMAL ] Iteration 270:\tk_eff = 1.220842\tres = 5.640E-05\n", + "[ NORMAL ] Iteration 271:\tk_eff = 1.220907\tres = 5.502E-05\n", + "[ NORMAL ] Iteration 272:\tk_eff = 1.220971\tres = 5.368E-05\n", + "[ NORMAL ] Iteration 273:\tk_eff = 1.221034\tres = 5.236E-05\n", + "[ NORMAL ] Iteration 274:\tk_eff = 1.221095\tres = 5.108E-05\n", + "[ NORMAL ] Iteration 275:\tk_eff = 1.221154\tres = 4.984E-05\n", + "[ NORMAL ] Iteration 276:\tk_eff = 1.221212\tres = 4.862E-05\n", + "[ NORMAL ] Iteration 277:\tk_eff = 1.221268\tres = 4.743E-05\n", + "[ NORMAL ] Iteration 278:\tk_eff = 1.221324\tres = 4.627E-05\n", + "[ NORMAL ] Iteration 279:\tk_eff = 1.221377\tres = 4.514E-05\n", + "[ NORMAL ] Iteration 280:\tk_eff = 1.221430\tres = 4.403E-05\n", + "[ NORMAL ] Iteration 281:\tk_eff = 1.221481\tres = 4.296E-05\n", + "[ NORMAL ] Iteration 282:\tk_eff = 1.221531\tres = 4.191E-05\n", + "[ NORMAL ] Iteration 283:\tk_eff = 1.221580\tres = 4.088E-05\n", + "[ NORMAL ] Iteration 284:\tk_eff = 1.221627\tres = 3.988E-05\n", + "[ NORMAL ] Iteration 285:\tk_eff = 1.221674\tres = 3.891E-05\n", + "[ NORMAL ] Iteration 286:\tk_eff = 1.221719\tres = 3.796E-05\n", + "[ NORMAL ] Iteration 287:\tk_eff = 1.221763\tres = 3.703E-05\n", + "[ NORMAL ] Iteration 288:\tk_eff = 1.221806\tres = 3.613E-05\n", + "[ NORMAL ] Iteration 289:\tk_eff = 1.221848\tres = 3.524E-05\n", + "[ NORMAL ] Iteration 290:\tk_eff = 1.221889\tres = 3.438E-05\n", + "[ NORMAL ] Iteration 291:\tk_eff = 1.221929\tres = 3.354E-05\n", + "[ NORMAL ] Iteration 292:\tk_eff = 1.221968\tres = 3.272E-05\n", + "[ NORMAL ] Iteration 293:\tk_eff = 1.222006\tres = 3.192E-05\n", + "[ NORMAL ] Iteration 294:\tk_eff = 1.222043\tres = 3.114E-05\n", + "[ NORMAL ] Iteration 295:\tk_eff = 1.222079\tres = 3.038E-05\n", + "[ NORMAL ] Iteration 296:\tk_eff = 1.222115\tres = 2.964E-05\n", + "[ NORMAL ] Iteration 297:\tk_eff = 1.222149\tres = 2.891E-05\n", + "[ NORMAL ] Iteration 298:\tk_eff = 1.222183\tres = 2.821E-05\n", + "[ NORMAL ] Iteration 299:\tk_eff = 1.222216\tres = 2.752E-05\n", + "[ NORMAL ] Iteration 300:\tk_eff = 1.222248\tres = 2.685E-05\n", + "[ NORMAL ] Iteration 301:\tk_eff = 1.222279\tres = 2.619E-05\n", + "[ NORMAL ] Iteration 302:\tk_eff = 1.222309\tres = 2.555E-05\n", + "[ NORMAL ] Iteration 303:\tk_eff = 1.222339\tres = 2.492E-05\n", + "[ NORMAL ] Iteration 304:\tk_eff = 1.222368\tres = 2.432E-05\n", + "[ NORMAL ] Iteration 305:\tk_eff = 1.222396\tres = 2.372E-05\n", + "[ NORMAL ] Iteration 306:\tk_eff = 1.222424\tres = 2.314E-05\n", + "[ NORMAL ] Iteration 307:\tk_eff = 1.222451\tres = 2.258E-05\n", + "[ NORMAL ] Iteration 308:\tk_eff = 1.222477\tres = 2.202E-05\n", + "[ NORMAL ] Iteration 309:\tk_eff = 1.222503\tres = 2.149E-05\n", + "[ NORMAL ] Iteration 310:\tk_eff = 1.222528\tres = 2.096E-05\n", + "[ NORMAL ] Iteration 311:\tk_eff = 1.222552\tres = 2.045E-05\n", + "[ NORMAL ] Iteration 312:\tk_eff = 1.222576\tres = 1.995E-05\n", + "[ NORMAL ] Iteration 313:\tk_eff = 1.222599\tres = 1.946E-05\n", + "[ NORMAL ] Iteration 314:\tk_eff = 1.222622\tres = 1.899E-05\n", + "[ NORMAL ] Iteration 315:\tk_eff = 1.222644\tres = 1.852E-05\n", + "[ NORMAL ] Iteration 316:\tk_eff = 1.222665\tres = 1.807E-05\n", + "[ NORMAL ] Iteration 317:\tk_eff = 1.222686\tres = 1.763E-05\n", + "[ NORMAL ] Iteration 318:\tk_eff = 1.222707\tres = 1.720E-05\n", + "[ NORMAL ] Iteration 319:\tk_eff = 1.222727\tres = 1.678E-05\n", + "[ NORMAL ] Iteration 320:\tk_eff = 1.222746\tres = 1.637E-05\n", + "[ NORMAL ] Iteration 321:\tk_eff = 1.222766\tres = 1.597E-05\n", + "[ NORMAL ] Iteration 322:\tk_eff = 1.222784\tres = 1.558E-05\n", + "[ NORMAL ] Iteration 323:\tk_eff = 1.222802\tres = 1.520E-05\n", + "[ NORMAL ] Iteration 324:\tk_eff = 1.222820\tres = 1.483E-05\n", + "[ NORMAL ] Iteration 325:\tk_eff = 1.222837\tres = 1.446E-05\n", + "[ NORMAL ] Iteration 326:\tk_eff = 1.222854\tres = 1.411E-05\n", + "[ NORMAL ] Iteration 327:\tk_eff = 1.222870\tres = 1.377E-05\n", + "[ NORMAL ] Iteration 328:\tk_eff = 1.222886\tres = 1.343E-05\n", + "[ NORMAL ] Iteration 329:\tk_eff = 1.222902\tres = 1.310E-05\n", + "[ NORMAL ] Iteration 330:\tk_eff = 1.222917\tres = 1.278E-05\n", + "[ NORMAL ] Iteration 331:\tk_eff = 1.222932\tres = 1.247E-05\n", + "[ NORMAL ] Iteration 332:\tk_eff = 1.222947\tres = 1.216E-05\n", + "[ NORMAL ] Iteration 333:\tk_eff = 1.222961\tres = 1.187E-05\n", + "[ NORMAL ] Iteration 334:\tk_eff = 1.222975\tres = 1.158E-05\n", + "[ NORMAL ] Iteration 335:\tk_eff = 1.222988\tres = 1.129E-05\n", + "[ NORMAL ] Iteration 336:\tk_eff = 1.223001\tres = 1.102E-05\n", + "[ NORMAL ] Iteration 337:\tk_eff = 1.223014\tres = 1.075E-05\n", + "[ NORMAL ] Iteration 338:\tk_eff = 1.223027\tres = 1.049E-05\n", + "[ NORMAL ] Iteration 339:\tk_eff = 1.223039\tres = 1.023E-05\n" ] } ], @@ -1699,8 +1885,8 @@ "output_type": "stream", "text": [ "openmc keff = 1.223474\n", - "openmoc keff = 1.223227\n", - "bias [pcm]: -24.7\n" + "openmoc keff = 1.223039\n", + "bias [pcm]: -43.5\n" ] } ], @@ -1753,7 +1939,7 @@ "outputs": [], "source": [ "# Parse ACE data into memory\n", - "u235 = openmc.data.IncidentNeutron.from_ace('../../../../scripts/nndc/293.6K/U_235_293.6K.ace')\n", + "u235 = openmc.data.IncidentNeutron.from_hdf5('../../../../data/nndc_hdf5/U235.h5')\n", "\n", "# Extract the continuous-energy U-235 fission cross section data\n", "fission = u235[18]" @@ -1785,9 +1971,9 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1869,9 +2055,9 @@ "outputs": [ { "data": { - "image/png": "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\nfn35+EIOpHUAAAAASUVORK5CYII=\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1898,6 +2084,15 @@ "# Show the plot on screen\n", "plt.show()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/openmc/filter.py b/openmc/filter.py index 88a88f99d..0320cdeca 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -1,8 +1,7 @@ -from abc import ABCMeta, abstractproperty +from abc import ABCMeta from collections import Iterable, OrderedDict import copy from numbers import Real, Integral -import sys from xml.etree import ElementTree as ET from six import add_metaclass @@ -829,7 +828,7 @@ class EnergyFilter(Filter): if bins[index] < bins[index-1]: msg = 'Unable to add bin edges "{0}" to a "{1}" Filter ' \ 'since they are not monotonically ' \ - 'increasing'.format(bins, self.type) + 'increasing'.format(bins, type(self)) raise ValueError(msg) def can_merge(self, other): @@ -848,7 +847,7 @@ class EnergyFilter(Filter): def merge(self, other): if not self.can_merge(other): msg = 'Unable to merge "{0}" with "{1}" ' \ - 'filters'.format(self.type, other.type) + 'filters'.format(type(self), other.type) raise ValueError(msg) # Merge unique filter bins @@ -1324,13 +1323,11 @@ class PolarFilter(Filter): # Extract the lower and upper angle bounds, then repeat and tile # them as necessary to account for other filters. lo_bins = np.repeat(self.bins[:-1], self.stride) - hi_bins = np.repeat(self.bins[1:], self.stride) tile_factor = data_size / len(lo_bins) lo_bins = np.tile(lo_bins, tile_factor) - hi_bins = np.tile(hi_bins, tile_factor) # Add the new angle columns to the DataFrame. - df.loc[:, self.type + ' low'] = lo_bins + df.loc[:, 'polar low'] = lo_bins return df @@ -1402,13 +1399,11 @@ class AzimuthalFilter(Filter): # Extract the lower and upper angle bounds, then repeat and tile # them as necessary to account for other filters. lo_bins = np.repeat(self.bins[:-1], self.stride) - hi_bins = np.repeat(self.bins[1:], self.stride) tile_factor = data_size / len(lo_bins) lo_bins = np.tile(lo_bins, tile_factor) - hi_bins = np.tile(hi_bins, tile_factor) # Add the new angle columns to the DataFrame. - df.loc[:, self.type + ' low'] = lo_bins + df.loc[:, 'azimuthal low'] = lo_bins return df From b94d1bf6617526854ea6eb6dcb8afd40891b6992 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Mon, 28 Nov 2016 14:18:19 -0500 Subject: [PATCH 54/60] Now using list comprehensions for filter bin indices in tallies.py --- openmc/cmfd.py | 6 +++--- openmc/summary.py | 2 +- openmc/tallies.py | 18 +++++++++--------- tests/test_asymmetric_lattice/results_true.dat | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/openmc/cmfd.py b/openmc/cmfd.py index 4e1fccb8b..c3df3f104 100644 --- a/openmc/cmfd.py +++ b/openmc/cmfd.py @@ -368,7 +368,7 @@ class CMFD(object): @cmfd_mesh.setter def cmfd_mesh(self, mesh): check_type('CMFD mesh', mesh, CMFDMesh) - self._mesh = mesh + self._cmfd_mesh = mesh @norm.setter def norm(self, norm): @@ -446,8 +446,8 @@ class CMFD(object): element.text = str(self._ktol) def _create_mesh_subelement(self): - if self._mesh is not None: - xml_element = self._mesh._get_xml_element() + if self._cmfd_mesh is not None: + xml_element = self._cmfd_mesh._get_xml_element() self._cmfd_file.append(xml_element) def _create_norm_subelement(self): diff --git a/openmc/summary.py b/openmc/summary.py index 37509ec37..b283ed502 100644 --- a/openmc/summary.py +++ b/openmc/summary.py @@ -387,7 +387,7 @@ class Summary(object): # Set the distribcell offsets for the lattice if offsets is not None: - lattice.offsets = offsets[:, ::-1, :] + lattice.offsets = offsets # Add the Lattice to the global dictionary of all Lattices self.lattices[index] = lattice diff --git a/openmc/tallies.py b/openmc/tallies.py index d5d6df03f..d59237718 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1327,7 +1327,7 @@ class Tally(object): # Create list of cell instance IDs for distribcell Filters elif isinstance(self_filter, openmc.DistribcellFilter): - bins = np.arange(self_filter.num_bins) + bins = [i for i in range(self_filter.num_bins)] # Create list of IDs for bins for all other filter types else: @@ -2258,12 +2258,12 @@ class Tally(object): # Construct lists of tuples for the bins in each of the two filters filters = [type(filter1), type(filter2)] if isinstance(filter1, openmc.DistribcellFilter): - filter1_bins = np.arange(filter1.num_bins) + filter1_bins = [i for i in range(filter1.num_bins)] else: filter1_bins = [filter1.get_bin(i) for i in range(filter1.num_bins)] if isinstance(filter2, openmc.DistribcellFilter): - filter2_bins = np.arange(filter2.num_bins) + filter2_bins = [i for i in range(filter2.num_bins)] else: filter2_bins = [filter2.get_bin(i) for i in range(filter2.num_bins)] @@ -3257,8 +3257,8 @@ class Tally(object): if isinstance(self_filter, filter_type): mean = np.take(mean, indices=bin_indices, axis=i) std_dev = np.take(std_dev, indices=bin_indices, axis=i) - mean = np.mean(mean, axis=i, keepdims=True) - std_dev = np.mean(std_dev**2, axis=i, keepdims=True) + mean = np.nanmean(mean, axis=i, keepdims=True) + std_dev = np.nanmean(std_dev**2, axis=i, keepdims=True) std_dev /= len(bin_indices) std_dev = np.sqrt(std_dev) @@ -3282,8 +3282,8 @@ class Tally(object): axis_index = self.num_filters mean = np.take(mean, indices=nuclide_bins, axis=axis_index) std_dev = np.take(std_dev, indices=nuclide_bins, axis=axis_index) - mean = np.mean(mean, axis=axis_index, keepdims=True) - std_dev = np.mean(std_dev**2, axis=axis_index, keepdims=True) + mean = np.nanmean(mean, axis=axis_index, keepdims=True) + std_dev = np.nanmean(std_dev**2, axis=axis_index, keepdims=True) std_dev /= len(nuclide_bins) std_dev = np.sqrt(std_dev) @@ -3301,8 +3301,8 @@ class Tally(object): axis_index = self.num_filters + 1 mean = np.take(mean, indices=score_bins, axis=axis_index) std_dev = np.take(std_dev, indices=score_bins, axis=axis_index) - mean = np.sum(mean, axis=axis_index, keepdims=True) - std_dev = np.sum(std_dev**2, axis=axis_index, keepdims=True) + mean = np.nanmean(mean, axis=axis_index, keepdims=True) + std_dev = np.nanmean(std_dev**2, axis=axis_index, keepdims=True) std_dev /= len(score_bins) std_dev = np.sqrt(std_dev) diff --git a/tests/test_asymmetric_lattice/results_true.dat b/tests/test_asymmetric_lattice/results_true.dat index dda6f953f..34c8faa64 100644 --- a/tests/test_asymmetric_lattice/results_true.dat +++ b/tests/test_asymmetric_lattice/results_true.dat @@ -1 +1 @@ -e18c2318bab6c42a263e5079fd796b1bee609e4274884fbc7bfd8b33e59aeb5e5a167da8e093f339f766815e007bd606c002939e3f730af523cbc9cf75c53faa \ No newline at end of file +b70886031e22db9e3f0332eac703a7356504750c1e90d7083ffd16b8884d00661d0e20c6d8bead3c93369b2e7c105ca3280c7858ca6a147fa6669a5d3d530461 \ No newline at end of file From 0faa406ceae2c6bd7f51b4a4005d239bdda0a87b Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Mon, 28 Nov 2016 17:52:38 -0500 Subject: [PATCH 55/60] Fixed MGXS.get_subdomain_avg_xs(...) to use track density-weighted averaging --- openmc/mgxs/mgxs.py | 89 ++++++---- openmc/tallies.py | 22 ++- .../results_true.dat | 158 +++++++++--------- 3 files changed, 151 insertions(+), 118 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 1936697ee..c7548c4dd 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -192,7 +192,9 @@ class MGXS(object): clone._rxn_rate_tally = copy.deepcopy(self._rxn_rate_tally, memo) clone._xs_tally = copy.deepcopy(self._xs_tally, memo) clone._sparse = self.sparse + clone._loaded_sp = self._loaded_sp clone._derived = self.derived + clone._hdf5_key = self._hdf5_key clone._tallies = OrderedDict() for tally_type, tally in self.tallies.items(): @@ -325,7 +327,7 @@ class MGXS(object): @property def num_subdomains(self): - if self.domain_type.startswith('avg('): + if self.domain_type.startswith('sum('): domain_type = self.domain_type[4:-1] else: domain_type = self.domain_type @@ -789,16 +791,22 @@ class MGXS(object): if not isinstance(subdomains, string_types): cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) + + filters.append(_DOMAIN_TO_FILTER[self.domain_type]) + subdomain_bins = [] for subdomain in subdomains: - filters.append(_DOMAIN_TO_FILTER[self.domain_type]) - filter_bins.append((subdomain,)) + subdomain_bins.append(subdomain) + filter_bins.append(tuple(subdomain_bins)) # Construct list of energy group bounds tuples for all requested groups if not isinstance(groups, string_types): cv.check_iterable_type('groups', groups, Integral) + filters.append(openmc.EnergyFilter) + energy_bins = [] for group in groups: - filters.append(openmc.EnergyFilter) - filter_bins.append((self.energy_groups.get_group_bounds(group),)) + energy_bins.append( + (self.energy_groups.get_group_bounds(group),)) + filter_bins.append(tuple(energy_bins)) # Construct a collection of the nuclides to retrieve from the xs tally if self.by_nuclide: @@ -958,30 +966,27 @@ class MGXS(object): # Construct a collection of the subdomain filter bins to average across if not isinstance(subdomains, string_types): cv.check_iterable_type('subdomains', subdomains, Integral) + subdomains = [(subdomain,) for subdomain in subdomains] + subdomains = [tuple(subdomains)] elif self.domain_type == 'distribcell': - subdomains = np.arange(self.num_subdomains) + subdomains = [i for i in range(self.num_subdomains)] + subdomains = [tuple(subdomains)] else: subdomains = None # Clone this MGXS to initialize the subdomain-averaged version avg_xs = copy.deepcopy(self) + avg_xs._rxn_rate_tally = None + avg_xs._xs_tally = None - if self.derived: - avg_xs._rxn_rate_tally = avg_xs.rxn_rate_tally.average( - filter_type=_DOMAIN_TO_FILTER[self.domain_type], - filter_bins=subdomains) - else: - avg_xs._rxn_rate_tally = None - avg_xs._xs_tally = None + # Average each of the tallies across subdomains + for tally_type, tally in avg_xs.tallies.items(): + filt_type = _DOMAIN_TO_FILTER[self.domain_type] + tally_avg = tally.summation(filter_type=filt_type, + filter_bins=subdomains) + avg_xs.tallies[tally_type] = tally_avg - # Average each of the tallies across subdomains - for tally_type, tally in avg_xs.tallies.items(): - filt_type = _DOMAIN_TO_FILTER[self.domain_type] - tally_avg = tally.average(filter_type=filt_type, - filter_bins=subdomains) - avg_xs.tallies[tally_type] = tally_avg - - avg_xs._domain_type = 'avg({0})'.format(self.domain_type) + avg_xs._domain_type = 'sum({0})'.format(self.domain_type) avg_xs.sparse = self.sparse return avg_xs @@ -1304,8 +1309,8 @@ class MGXS(object): cv.check_iterable_type('subdomains', subdomains, Integral) elif self.domain_type == 'distribcell': subdomains = np.arange(self.num_subdomains, dtype=np.int) - elif self.domain_type == 'avg(distribcell)': - domain_filter = self.xs_tally.find_filter('avg(distribcell)') + elif self.domain_type == 'sum(distribcell)': + domain_filter = self.xs_tally.find_filter('sum(distribcell)') subdomains = domain_filter.bins elif self.domain_type == 'mesh': xyz = [range(1, x+1) for x in self.domain.dimension] @@ -1784,17 +1789,19 @@ class MatrixMGXS(MGXS): if not isinstance(subdomains, string_types): cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) + filters.append(_DOMAIN_TO_FILTER[self.domain_type]) + subdomain_bins = [] for subdomain in subdomains: - filters.append(_DOMAIN_TO_FILTER[self.domain_type]) - filter_bins.append((subdomain,)) + subdomain_bins.append(subdomain) + filter_bins.append(tuple(subdomain_bins)) # Construct list of energy group bounds tuples for all requested groups if not isinstance(in_groups, string_types): cv.check_iterable_type('groups', in_groups, Integral) + filters.append(openmc.EnergyFilter) for group in in_groups: - filters.append(openmc.EnergyFilter) - filter_bins.append(( - self.energy_groups.get_group_bounds(group),)) + energy_bins.append((self.energy_groups.get_group_bounds(group),)) + filter_bins.append(tuple(energy_bins)) # Construct list of energy group bounds tuples for all requested groups if not isinstance(out_groups, string_types): @@ -3618,16 +3625,21 @@ class ScatterMatrixXS(MatrixMGXS): # Construct a collection of the domain filter bins if not isinstance(subdomains, string_types): cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) + filters.append(_DOMAIN_TO_FILTER[self.domain_type]) + subdomain_bins = [] for subdomain in subdomains: - filters.append(_DOMAIN_TO_FILTER[self.domain_type]) - filter_bins.append((subdomain,)) + subdomain_bins.append(subdomain) + filter_bins.append(tuple(subdomain_bins)) # Construct list of energy group bounds tuples for all requested groups if not isinstance(in_groups, string_types): cv.check_iterable_type('groups', in_groups, Integral) + filters.append(openmc.EnergyFilter) + energy_bins = [] for group in in_groups: - filters.append(openmc.EnergyFilter) - filter_bins.append((self.energy_groups.get_group_bounds(group),)) + energy_bins.append( + (self.energy_groups.get_group_bounds(group),)) + filter_bins.append(tuple(energy_bins)) # Construct list of energy group bounds tuples for all requested groups if not isinstance(out_groups, string_types): @@ -4606,16 +4618,21 @@ class Chi(MGXS): # Construct a collection of the domain filter bins if not isinstance(subdomains, string_types): cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) + filters.append(_DOMAIN_TO_FILTER[self.domain_type]) + subdomain_bins = [] for subdomain in subdomains: - filters.append(_DOMAIN_TO_FILTER[self.domain_type]) - filter_bins.append((subdomain,)) + subdomain_bins.append(subdomain) + filter_bins.append(tuple(subdomain_bins)) # Construct list of energy group bounds tuples for all requested groups if not isinstance(groups, string_types): cv.check_iterable_type('groups', groups, Integral) + filters.append(openmc.EnergyoutFilter) + energy_bins = [] for group in groups: - filters.append(openmc.EnergyoutFilter) - filter_bins.append((self.energy_groups.get_group_bounds(group),)) + energy_bins.append( + (self.energy_groups.get_group_bounds(group),)) + filter_bins.append(tuple(energy_bins)) # If chi was computed for each nuclide in the domain if self.by_nuclide: diff --git a/openmc/tallies.py b/openmc/tallies.py index d59237718..ff55e2354 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1327,7 +1327,7 @@ class Tally(object): # Create list of cell instance IDs for distribcell Filters elif isinstance(self_filter, openmc.DistribcellFilter): - bins = [i for i in range(self_filter.num_bins)] + bins = [b for b in range(self_filter.num_bins)] # Create list of IDs for bins for all other filter types else: @@ -2258,12 +2258,12 @@ class Tally(object): # Construct lists of tuples for the bins in each of the two filters filters = [type(filter1), type(filter2)] if isinstance(filter1, openmc.DistribcellFilter): - filter1_bins = [i for i in range(filter1.num_bins)] + filter1_bins = [b for b in range(filter1.num_bins)] else: filter1_bins = [filter1.get_bin(i) for i in range(filter1.num_bins)] if isinstance(filter2, openmc.DistribcellFilter): - filter2_bins = [i for i in range(filter2.num_bins)] + filter2_bins = [b for b in range(filter2.num_bins)] else: filter2_bins = [filter2.get_bin(i) for i in range(filter2.num_bins)] @@ -3108,8 +3108,16 @@ class Tally(object): # Sum across the bins in the user-specified filter for i, self_filter in enumerate(self.filters): if isinstance(self_filter, filter_type): + shape = mean.shape mean = np.take(mean, indices=bin_indices, axis=i) std_dev = np.take(std_dev, indices=bin_indices, axis=i) + + # NumPy take introduces a new dimension in output array + # for some special cases that must be removed + if len(mean.shape) > len(shape): + mean = np.squeeze(mean, axis=i) + std_dev = np.squeeze(std_dev, axis=i) + mean = np.sum(mean, axis=i, keepdims=True) std_dev = np.sum(std_dev**2, axis=i, keepdims=True) std_dev = np.sqrt(std_dev) @@ -3255,8 +3263,16 @@ class Tally(object): # Average across the bins in the user-specified filter for i, self_filter in enumerate(self.filters): if isinstance(self_filter, filter_type): + shape = mean.shape mean = np.take(mean, indices=bin_indices, axis=i) std_dev = np.take(std_dev, indices=bin_indices, axis=i) + + # NumPy take introduces a new dimension in output array + # for some special cases that must be removed + if len(mean.shape) > len(shape): + mean = np.squeeze(mean, axis=i) + std_dev = np.squeeze(std_dev, axis=i) + mean = np.nanmean(mean, axis=i, keepdims=True) std_dev = np.nanmean(std_dev**2, axis=i, keepdims=True) std_dev /= len(bin_indices) diff --git a/tests/test_mgxs_library_distribcell/results_true.dat b/tests/test_mgxs_library_distribcell/results_true.dat index 2b43005aa..905a55815 100644 --- a/tests/test_mgxs_library_distribcell/results_true.dat +++ b/tests/test_mgxs_library_distribcell/results_true.dat @@ -1,79 +1,79 @@ - avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.457353 0.010474 - avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.405649 0.015784 - avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.405641 0.015787 - avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.066556 0.00251 - avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.028979 0.002712 - avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.037577 0.001487 - avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.092377 0.003628 - avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 7.276707e+06 287579.26286 - avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.390797 0.008717 - avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.387332 0.014241 - avg(distribcell) group in group out nuclide moment mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total P0 0.387009 0.014230 -1 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total P1 0.047179 0.004923 -2 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total P2 0.015713 0.003654 -3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total P3 0.005378 0.003137 - avg(distribcell) group in group out nuclide moment mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total P0 0.387332 0.014241 -1 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total P1 0.047187 0.004933 -2 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total P2 0.015727 0.003654 -3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total P3 0.005387 0.003141 - avg(distribcell) group in group out nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 1.000834 0.037242 - avg(distribcell) group in group out nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 0.094516 0.0059 - avg(distribcell) group out nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 1.0 0.080455 - avg(distribcell) group out nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 1.0 0.080541 - avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 5.139437e-07 2.133314e-08 - avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.091725 0.003604 - avg(distribcell) group in group out nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 0.093985 0.005872 - avg(distribcell) delayedgroup group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 0.000021 8.253907e-07 -1 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 2 1 total 0.000112 4.284000e-06 -2 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 3 1 total 0.000109 4.105197e-06 -3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 4 1 total 0.000252 9.271420e-06 -4 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 5 1 total 0.000112 3.888625e-06 -5 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 6 1 total 0.000047 1.625563e-06 - avg(distribcell) delayedgroup group out nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 0.0 0.000000 -1 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 2 1 total 1.0 1.414214 -2 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 3 1 total 1.0 1.414214 -3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 4 1 total 0.0 0.000000 -4 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 5 1 total 0.0 0.000000 -5 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 6 1 total 1.0 1.414214 - avg(distribcell) delayedgroup group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 0.000227 0.000012 -1 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 2 1 total 0.001209 0.000061 -2 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 3 1 total 0.001177 0.000059 -3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 4 1 total 0.002727 0.000135 -4 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 5 1 total 0.001210 0.000058 -5 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 6 1 total 0.000504 0.000024 - avg(distribcell) delayedgroup group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 0.000000 0.000000 -1 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 2 1 total 0.032739 0.046300 -2 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 3 1 total 0.120780 0.170809 -3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 4 1 total 0.000000 0.000000 -4 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 5 1 total 0.000000 0.000000 -5 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 6 1 total 2.853000 4.034751 - avg(distribcell) delayedgroup group in group out nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 1 total 0.000000 0.000000 -1 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 2 1 1 total 0.000175 0.000175 -2 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 3 1 1 total 0.000178 0.000178 -3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 4 1 1 total 0.000000 0.000000 -4 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 5 1 1 total 0.000000 0.000000 -5 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 6 1 1 total 0.000178 0.000178 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.457353 0.010474 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.405649 0.015784 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.405641 0.015787 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.066556 0.00251 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.028979 0.002712 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.037577 0.001487 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.092377 0.003628 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 7.276707e+06 287579.26286 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.390797 0.008717 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.387332 0.014241 + sum(distribcell) group in group out nuclide moment mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total P0 0.387009 0.014230 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total P1 0.047179 0.004923 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total P2 0.015713 0.003654 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total P3 0.005378 0.003137 + sum(distribcell) group in group out nuclide moment mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total P0 0.387332 0.014241 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total P1 0.047187 0.004933 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total P2 0.015727 0.003654 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total P3 0.005387 0.003141 + sum(distribcell) group in group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 1.000834 0.037242 + sum(distribcell) group in group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.094516 0.0059 + sum(distribcell) group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 1.0 0.080455 + sum(distribcell) group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 1.0 0.080541 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 5.139437e-07 2.133314e-08 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.091725 0.003604 + sum(distribcell) group in group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.093985 0.005872 + sum(distribcell) delayedgroup group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.000021 8.253907e-07 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 total 0.000112 4.284000e-06 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 total 0.000109 4.105197e-06 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 total 0.000252 9.271420e-06 +4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 total 0.000112 3.888625e-06 +5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 total 0.000047 1.625563e-06 + sum(distribcell) delayedgroup group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.0 0.000000 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 total 1.0 1.414214 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 total 1.0 1.414214 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 total 0.0 0.000000 +4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 total 0.0 0.000000 +5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 total 1.0 1.414214 + sum(distribcell) delayedgroup group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.000227 0.000012 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 total 0.001209 0.000061 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 total 0.001177 0.000059 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 total 0.002727 0.000135 +4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 total 0.001210 0.000058 +5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 total 0.000504 0.000024 + sum(distribcell) delayedgroup group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.000000 0.000000 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 total 0.032739 0.046300 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 total 0.120780 0.170809 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 total 0.000000 0.000000 +4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 total 0.000000 0.000000 +5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 total 2.853000 4.034751 + sum(distribcell) delayedgroup group in group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 1 total 0.000000 0.000000 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 1 total 0.000175 0.000175 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 1 total 0.000178 0.000178 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 1 total 0.000000 0.000000 +4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 1 total 0.000000 0.000000 +5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 1 total 0.000178 0.000178 From cdbcdd52348bee444211c50fbfcd969db52d8cd2 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Mon, 28 Nov 2016 18:18:03 -0500 Subject: [PATCH 56/60] Reverted changes to MGXS Part II notebook per suggestion by @nelsonag --- .../pythonapi/examples/mgxs-part-ii.ipynb | 1049 +++++++---------- 1 file changed, 427 insertions(+), 622 deletions(-) diff --git a/docs/source/pythonapi/examples/mgxs-part-ii.ipynb b/docs/source/pythonapi/examples/mgxs-part-ii.ipynb index e35c205c3..c43fab6ff 100644 --- a/docs/source/pythonapi/examples/mgxs-part-ii.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-ii.ipynb @@ -34,9 +34,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/wbinventor/miniconda3/lib/python3.5/site-packages/IPython/html.py:14: ShimWarning: The `IPython.html` package has been deprecated. You should import from `notebook` instead. `IPython.html.widgets` has moved to `ipywidgets`.\n", - " \"`IPython.html.widgets` has moved to `ipywidgets`.\", ShimWarning)\n", - "/home/wbinventor/miniconda3/lib/python3.5/site-packages/matplotlib/__init__.py:1350: UserWarning: This call to matplotlib.use() has no effect\n", + "/home/romano/miniconda3/envs/default/lib/python3.5/site-packages/matplotlib/__init__.py:1350: UserWarning: This call to matplotlib.use() has no effect\n", "because the backend has already been chosen;\n", "matplotlib.use() must be called *before* pylab, matplotlib.pyplot,\n", "or matplotlib.backends is imported for the first time.\n", @@ -455,8 +453,8 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 2c25ec97653482825b529215b8a61b54d468d34e\n", - " Date/Time | 2016-11-28 09:10:24\n", + " Git SHA1 | da5563eddb5f2c2d6b2c9839d518de40962b78f2\n", + " Date/Time | 2016-10-31 12:29:16\n", " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", @@ -467,16 +465,11 @@ " Reading geometry XML file...\n", " Reading materials XML file...\n", " Reading cross sections XML file...\n", - " Reading U235 from\n", - " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/U235.h5\n", - " Reading U238 from\n", - " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/U238.h5\n", - " Reading O16 from\n", - " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/O16.h5\n", - " Reading H1 from\n", - " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/H1.h5\n", - " Reading Zr90 from\n", - " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/Zr90.h5\n", + " Reading U235 from /home/romano/openmc/scripts/nndc_hdf5/U235.h5\n", + " Reading U238 from /home/romano/openmc/scripts/nndc_hdf5/U238.h5\n", + " Reading O16 from /home/romano/openmc/scripts/nndc_hdf5/O16.h5\n", + " Reading H1 from /home/romano/openmc/scripts/nndc_hdf5/H1.h5\n", + " Reading Zr90 from /home/romano/openmc/scripts/nndc_hdf5/Zr90.h5\n", " Maximum neutron transport energy: 2.00000E+07 eV for U235\n", " Reading tallies XML file...\n", " Building neighboring cells lists for each surface...\n", @@ -538,7 +531,7 @@ " 48/1 1.21610 1.22612 +/- 0.00251\n", " 49/1 1.22199 1.22602 +/- 0.00245\n", " 50/1 1.20860 1.22558 +/- 0.00243\n", - " Triggers unsatisfied, max unc./thresh. is 1.25496 for flux in tally 10057\n", + " Triggers unsatisfied, max unc./thresh. is 1.25496 for flux in tally 10050\n", " The estimated number of batches is 73\n", " Creating state point statepoint.050.h5...\n", " 51/1 1.21850 1.22541 +/- 0.00237\n", @@ -564,7 +557,7 @@ " 71/1 1.19720 1.22444 +/- 0.00195\n", " 72/1 1.23770 1.22465 +/- 0.00193\n", " 73/1 1.23894 1.22488 +/- 0.00191\n", - " Triggers unsatisfied, max unc./thresh. is 1.00243 for flux in tally 10057\n", + " Triggers unsatisfied, max unc./thresh. is 1.00243 for flux in tally 10050\n", " The estimated number of batches is 74\n", " 74/1 1.22437 1.22487 +/- 0.00188\n", " Triggers satisfied for batch 74\n", @@ -577,20 +570,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 3.1270E-01 seconds\n", - " Reading cross sections = 1.8695E-01 seconds\n", - " Total time in simulation = 1.1922E+02 seconds\n", - " Time in transport only = 1.1903E+02 seconds\n", - " Time in inactive batches = 8.5633E+00 seconds\n", - " Time in active batches = 1.1066E+02 seconds\n", - " Time synchronizing fission bank = 2.4702E-02 seconds\n", - " Sampling source sites = 1.8297E-02 seconds\n", - " SEND/RECV source sites = 6.2794E-03 seconds\n", - " Time accumulating tallies = 2.6114E-03 seconds\n", - " Total time for finalization = 1.6967E-02 seconds\n", - " Total time elapsed = 1.1961E+02 seconds\n", - " Calculation Rate (inactive) = 11677.8 neutrons/second\n", - " Calculation Rate (active) = 3614.65 neutrons/second\n", + " Total time for initialization = 5.0262E-01 seconds\n", + " Reading cross sections = 3.4207E-01 seconds\n", + " Total time in simulation = 1.2843E+02 seconds\n", + " Time in transport only = 1.2831E+02 seconds\n", + " Time in inactive batches = 8.1328E+00 seconds\n", + " Time in active batches = 1.2030E+02 seconds\n", + " Time synchronizing fission bank = 2.9797E-02 seconds\n", + " Sampling source sites = 2.1385E-02 seconds\n", + " SEND/RECV source sites = 8.2632E-03 seconds\n", + " Time accumulating tallies = 1.4577E-03 seconds\n", + " Total time for finalization = 1.3462E-02 seconds\n", + " Total time elapsed = 1.2901E+02 seconds\n", + " Calculation Rate (inactive) = 12295.9 neutrons/second\n", + " Calculation Rate (active) = 3325.12 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -1179,239 +1172,169 @@ "text": [ "[ NORMAL ] Importing ray tracing data from file...\n", "[ NORMAL ] Computing the eigenvalue...\n", - "[ NORMAL ] Iteration 0:\tk_eff = 0.423123\tres = 0.000E+00\n", - "[ NORMAL ] Iteration 1:\tk_eff = 0.475921\tres = 5.769E-01\n", - "[ NORMAL ] Iteration 2:\tk_eff = 0.491443\tres = 1.248E-01\n", - "[ NORMAL ] Iteration 3:\tk_eff = 0.487441\tres = 3.261E-02\n", - "[ NORMAL ] Iteration 4:\tk_eff = 0.483949\tres = 8.144E-03\n", - "[ NORMAL ] Iteration 5:\tk_eff = 0.477326\tres = 7.164E-03\n", - "[ NORMAL ] Iteration 6:\tk_eff = 0.469012\tres = 1.369E-02\n", - "[ NORMAL ] Iteration 7:\tk_eff = 0.460422\tres = 1.742E-02\n", - "[ NORMAL ] Iteration 8:\tk_eff = 0.450721\tres = 1.832E-02\n", - "[ NORMAL ] Iteration 9:\tk_eff = 0.441532\tres = 2.107E-02\n", - "[ NORMAL ] Iteration 10:\tk_eff = 0.432168\tres = 2.039E-02\n", - "[ NORMAL ] Iteration 11:\tk_eff = 0.423131\tres = 2.121E-02\n", - "[ NORMAL ] Iteration 12:\tk_eff = 0.414705\tres = 2.091E-02\n", - "[ NORMAL ] Iteration 13:\tk_eff = 0.406942\tres = 1.991E-02\n", - "[ NORMAL ] Iteration 14:\tk_eff = 0.399627\tres = 1.872E-02\n", - "[ NORMAL ] Iteration 15:\tk_eff = 0.393329\tres = 1.798E-02\n", - "[ NORMAL ] Iteration 16:\tk_eff = 0.387699\tres = 1.576E-02\n", - "[ NORMAL ] Iteration 17:\tk_eff = 0.382948\tres = 1.431E-02\n", - "[ NORMAL ] Iteration 18:\tk_eff = 0.379028\tres = 1.225E-02\n", - "[ NORMAL ] Iteration 19:\tk_eff = 0.375934\tres = 1.024E-02\n", - "[ NORMAL ] Iteration 20:\tk_eff = 0.373784\tres = 8.161E-03\n", - "[ NORMAL ] Iteration 21:\tk_eff = 0.372654\tres = 5.719E-03\n", - "[ NORMAL ] Iteration 22:\tk_eff = 0.372273\tres = 3.023E-03\n", - "[ NORMAL ] Iteration 23:\tk_eff = 0.372879\tres = 1.024E-03\n", - "[ NORMAL ] Iteration 24:\tk_eff = 0.374353\tres = 1.629E-03\n", - "[ NORMAL ] Iteration 25:\tk_eff = 0.376678\tres = 3.951E-03\n", - "[ NORMAL ] Iteration 26:\tk_eff = 0.379854\tres = 6.212E-03\n", - "[ NORMAL ] Iteration 27:\tk_eff = 0.383870\tres = 8.432E-03\n", - "[ NORMAL ] Iteration 28:\tk_eff = 0.388663\tres = 1.057E-02\n", - "[ NORMAL ] Iteration 29:\tk_eff = 0.394216\tres = 1.249E-02\n", - "[ NORMAL ] Iteration 30:\tk_eff = 0.400506\tres = 1.429E-02\n", - "[ NORMAL ] Iteration 31:\tk_eff = 0.407501\tres = 1.596E-02\n", - "[ NORMAL ] Iteration 32:\tk_eff = 0.415145\tres = 1.747E-02\n", - "[ NORMAL ] Iteration 33:\tk_eff = 0.423426\tres = 1.876E-02\n", - "[ NORMAL ] Iteration 34:\tk_eff = 0.432299\tres = 1.995E-02\n", - "[ NORMAL ] Iteration 35:\tk_eff = 0.441713\tres = 2.095E-02\n", - "[ NORMAL ] Iteration 36:\tk_eff = 0.451665\tres = 2.178E-02\n", - "[ NORMAL ] Iteration 37:\tk_eff = 0.462081\tres = 2.253E-02\n", - "[ NORMAL ] Iteration 38:\tk_eff = 0.472951\tres = 2.306E-02\n", - "[ NORMAL ] Iteration 39:\tk_eff = 0.484220\tres = 2.352E-02\n", - "[ NORMAL ] Iteration 40:\tk_eff = 0.495861\tres = 2.383E-02\n", - "[ NORMAL ] Iteration 41:\tk_eff = 0.507836\tres = 2.404E-02\n", - "[ NORMAL ] Iteration 42:\tk_eff = 0.520110\tres = 2.415E-02\n", - "[ NORMAL ] Iteration 43:\tk_eff = 0.532648\tres = 2.417E-02\n", - "[ NORMAL ] Iteration 44:\tk_eff = 0.545418\tres = 2.411E-02\n", - "[ NORMAL ] Iteration 45:\tk_eff = 0.558388\tres = 2.398E-02\n", - "[ NORMAL ] Iteration 46:\tk_eff = 0.571526\tres = 2.378E-02\n", - "[ NORMAL ] Iteration 47:\tk_eff = 0.584802\tres = 2.353E-02\n", - "[ NORMAL ] Iteration 48:\tk_eff = 0.598189\tres = 2.323E-02\n", - "[ NORMAL ] Iteration 49:\tk_eff = 0.611657\tres = 2.289E-02\n", - "[ NORMAL ] Iteration 50:\tk_eff = 0.625182\tres = 2.252E-02\n", - "[ NORMAL ] Iteration 51:\tk_eff = 0.638738\tres = 2.211E-02\n", - "[ NORMAL ] Iteration 52:\tk_eff = 0.652302\tres = 2.168E-02\n", - "[ NORMAL ] Iteration 53:\tk_eff = 0.665851\tres = 2.124E-02\n", - "[ NORMAL ] Iteration 54:\tk_eff = 0.679364\tres = 2.077E-02\n", - "[ NORMAL ] Iteration 55:\tk_eff = 0.692821\tres = 2.029E-02\n", - "[ NORMAL ] Iteration 56:\tk_eff = 0.706204\tres = 1.981E-02\n", - "[ NORMAL ] Iteration 57:\tk_eff = 0.719496\tres = 1.932E-02\n", - "[ NORMAL ] Iteration 58:\tk_eff = 0.732679\tres = 1.882E-02\n", - "[ NORMAL ] Iteration 59:\tk_eff = 0.745740\tres = 1.832E-02\n", - "[ NORMAL ] Iteration 60:\tk_eff = 0.758664\tres = 1.783E-02\n", - "[ NORMAL ] Iteration 61:\tk_eff = 0.771439\tres = 1.733E-02\n", - "[ NORMAL ] Iteration 62:\tk_eff = 0.784053\tres = 1.684E-02\n", - "[ NORMAL ] Iteration 63:\tk_eff = 0.796495\tres = 1.635E-02\n", - "[ NORMAL ] Iteration 64:\tk_eff = 0.808756\tres = 1.587E-02\n", - "[ NORMAL ] Iteration 65:\tk_eff = 0.820827\tres = 1.539E-02\n", - "[ NORMAL ] Iteration 66:\tk_eff = 0.832700\tres = 1.493E-02\n", - "[ NORMAL ] Iteration 67:\tk_eff = 0.844370\tres = 1.447E-02\n", - "[ NORMAL ] Iteration 68:\tk_eff = 0.855828\tres = 1.401E-02\n", - "[ NORMAL ] Iteration 69:\tk_eff = 0.867071\tres = 1.357E-02\n", - "[ NORMAL ] Iteration 70:\tk_eff = 0.878094\tres = 1.314E-02\n", - "[ NORMAL ] Iteration 71:\tk_eff = 0.888893\tres = 1.271E-02\n", - "[ NORMAL ] Iteration 72:\tk_eff = 0.899465\tres = 1.230E-02\n", - "[ NORMAL ] Iteration 73:\tk_eff = 0.909807\tres = 1.189E-02\n", - "[ NORMAL ] Iteration 74:\tk_eff = 0.919919\tres = 1.150E-02\n", - "[ NORMAL ] Iteration 75:\tk_eff = 0.929798\tres = 1.111E-02\n", - "[ NORMAL ] Iteration 76:\tk_eff = 0.939444\tres = 1.074E-02\n", - "[ NORMAL ] Iteration 77:\tk_eff = 0.948856\tres = 1.037E-02\n", - "[ NORMAL ] Iteration 78:\tk_eff = 0.958036\tres = 1.002E-02\n", - "[ NORMAL ] Iteration 79:\tk_eff = 0.966983\tres = 9.674E-03\n", - "[ NORMAL ] Iteration 80:\tk_eff = 0.975698\tres = 9.339E-03\n", - "[ NORMAL ] Iteration 81:\tk_eff = 0.984184\tres = 9.013E-03\n", - "[ NORMAL ] Iteration 82:\tk_eff = 0.992441\tres = 8.697E-03\n", - "[ NORMAL ] Iteration 83:\tk_eff = 1.000472\tres = 8.390E-03\n", - "[ NORMAL ] Iteration 84:\tk_eff = 1.008280\tres = 8.092E-03\n", - "[ NORMAL ] Iteration 85:\tk_eff = 1.015866\tres = 7.804E-03\n", - "[ NORMAL ] Iteration 86:\tk_eff = 1.023234\tres = 7.524E-03\n", - "[ NORMAL ] Iteration 87:\tk_eff = 1.030386\tres = 7.253E-03\n", - "[ NORMAL ] Iteration 88:\tk_eff = 1.037327\tres = 6.990E-03\n", - "[ NORMAL ] Iteration 89:\tk_eff = 1.044059\tres = 6.736E-03\n", - "[ NORMAL ] Iteration 90:\tk_eff = 1.050585\tres = 6.490E-03\n", - "[ NORMAL ] Iteration 91:\tk_eff = 1.056911\tres = 6.251E-03\n", - "[ NORMAL ] Iteration 92:\tk_eff = 1.063038\tres = 6.021E-03\n", - "[ NORMAL ] Iteration 93:\tk_eff = 1.068972\tres = 5.798E-03\n", - "[ NORMAL ] Iteration 94:\tk_eff = 1.074716\tres = 5.582E-03\n", - "[ NORMAL ] Iteration 95:\tk_eff = 1.080275\tres = 5.373E-03\n", - "[ NORMAL ] Iteration 96:\tk_eff = 1.085651\tres = 5.172E-03\n", - "[ NORMAL ] Iteration 97:\tk_eff = 1.090850\tres = 4.977E-03\n", - "[ NORMAL ] Iteration 98:\tk_eff = 1.095876\tres = 4.789E-03\n", - "[ NORMAL ] Iteration 99:\tk_eff = 1.100733\tres = 4.607E-03\n", - "[ NORMAL ] Iteration 100:\tk_eff = 1.105424\tres = 4.432E-03\n", - "[ NORMAL ] Iteration 101:\tk_eff = 1.109955\tres = 4.262E-03\n", - "[ NORMAL ] Iteration 102:\tk_eff = 1.114328\tres = 4.099E-03\n", - "[ NORMAL ] Iteration 103:\tk_eff = 1.118550\tres = 3.941E-03\n", - "[ NORMAL ] Iteration 104:\tk_eff = 1.122623\tres = 3.788E-03\n", - "[ NORMAL ] Iteration 105:\tk_eff = 1.126551\tres = 3.641E-03\n", - "[ NORMAL ] Iteration 106:\tk_eff = 1.130339\tres = 3.499E-03\n", - "[ NORMAL ] Iteration 107:\tk_eff = 1.133991\tres = 3.363E-03\n", - "[ NORMAL ] Iteration 108:\tk_eff = 1.137511\tres = 3.231E-03\n", - "[ NORMAL ] Iteration 109:\tk_eff = 1.140902\tres = 3.104E-03\n", - "[ NORMAL ] Iteration 110:\tk_eff = 1.144168\tres = 2.981E-03\n", - "[ NORMAL ] Iteration 111:\tk_eff = 1.147313\tres = 2.863E-03\n", - "[ NORMAL ] Iteration 112:\tk_eff = 1.150342\tres = 2.749E-03\n", - "[ NORMAL ] Iteration 113:\tk_eff = 1.153257\tres = 2.640E-03\n", - "[ NORMAL ] Iteration 114:\tk_eff = 1.156062\tres = 2.534E-03\n", - "[ NORMAL ] Iteration 115:\tk_eff = 1.158761\tres = 2.432E-03\n", - "[ NORMAL ] Iteration 116:\tk_eff = 1.161356\tres = 2.334E-03\n", - "[ NORMAL ] Iteration 117:\tk_eff = 1.163852\tres = 2.240E-03\n", - "[ NORMAL ] Iteration 118:\tk_eff = 1.166252\tres = 2.149E-03\n", - "[ NORMAL ] Iteration 119:\tk_eff = 1.168559\tres = 2.062E-03\n", - "[ NORMAL ] Iteration 120:\tk_eff = 1.170776\tres = 1.978E-03\n", - "[ NORMAL ] Iteration 121:\tk_eff = 1.172906\tres = 1.897E-03\n", - "[ NORMAL ] Iteration 122:\tk_eff = 1.174952\tres = 1.819E-03\n", - "[ NORMAL ] Iteration 123:\tk_eff = 1.176918\tres = 1.745E-03\n", - "[ NORMAL ] Iteration 124:\tk_eff = 1.178805\tres = 1.673E-03\n", - "[ NORMAL ] Iteration 125:\tk_eff = 1.180617\tres = 1.603E-03\n", - "[ NORMAL ] Iteration 126:\tk_eff = 1.182356\tres = 1.537E-03\n", - "[ NORMAL ] Iteration 127:\tk_eff = 1.184025\tres = 1.473E-03\n", - "[ NORMAL ] Iteration 128:\tk_eff = 1.185626\tres = 1.412E-03\n", - "[ NORMAL ] Iteration 129:\tk_eff = 1.187163\tres = 1.353E-03\n", - "[ NORMAL ] Iteration 130:\tk_eff = 1.188637\tres = 1.296E-03\n", - "[ NORMAL ] Iteration 131:\tk_eff = 1.190050\tres = 1.241E-03\n", - "[ NORMAL ] Iteration 132:\tk_eff = 1.191405\tres = 1.189E-03\n", - "[ NORMAL ] Iteration 133:\tk_eff = 1.192704\tres = 1.139E-03\n", - "[ NORMAL ] Iteration 134:\tk_eff = 1.193950\tres = 1.091E-03\n", - "[ NORMAL ] Iteration 135:\tk_eff = 1.195144\tres = 1.044E-03\n", - "[ NORMAL ] Iteration 136:\tk_eff = 1.196287\tres = 9.997E-04\n", - "[ NORMAL ] Iteration 137:\tk_eff = 1.197383\tres = 9.571E-04\n", - "[ NORMAL ] Iteration 138:\tk_eff = 1.198433\tres = 9.161E-04\n", - "[ NORMAL ] Iteration 139:\tk_eff = 1.199439\tres = 8.768E-04\n", - "[ NORMAL ] Iteration 140:\tk_eff = 1.200402\tres = 8.391E-04\n", - "[ NORMAL ] Iteration 141:\tk_eff = 1.201324\tres = 8.029E-04\n", - "[ NORMAL ] Iteration 142:\tk_eff = 1.202207\tres = 7.682E-04\n", - "[ NORMAL ] Iteration 143:\tk_eff = 1.203052\tres = 7.349E-04\n", - "[ NORMAL ] Iteration 144:\tk_eff = 1.203861\tres = 7.030E-04\n", - "[ NORMAL ] Iteration 145:\tk_eff = 1.204635\tres = 6.724E-04\n", - "[ NORMAL ] Iteration 146:\tk_eff = 1.205376\tres = 6.431E-04\n", - "[ NORMAL ] Iteration 147:\tk_eff = 1.206084\tres = 6.149E-04\n", - "[ NORMAL ] Iteration 148:\tk_eff = 1.206762\tres = 5.880E-04\n", - "[ NORMAL ] Iteration 149:\tk_eff = 1.207411\tres = 5.622E-04\n", - "[ NORMAL ] Iteration 150:\tk_eff = 1.208031\tres = 5.374E-04\n", - "[ NORMAL ] Iteration 151:\tk_eff = 1.208624\tres = 5.137E-04\n", - "[ NORMAL ] Iteration 152:\tk_eff = 1.209192\tres = 4.910E-04\n", - "[ NORMAL ] Iteration 153:\tk_eff = 1.209734\tres = 4.693E-04\n", - "[ NORMAL ] Iteration 154:\tk_eff = 1.210252\tres = 4.484E-04\n", - "[ NORMAL ] Iteration 155:\tk_eff = 1.210748\tres = 4.285E-04\n", - "[ NORMAL ] Iteration 156:\tk_eff = 1.211221\tres = 4.094E-04\n", - "[ NORMAL ] Iteration 157:\tk_eff = 1.211674\tres = 3.911E-04\n", - "[ NORMAL ] Iteration 158:\tk_eff = 1.212106\tres = 3.736E-04\n", - "[ NORMAL ] Iteration 159:\tk_eff = 1.212519\tres = 3.569E-04\n", - "[ NORMAL ] Iteration 160:\tk_eff = 1.212914\tres = 3.408E-04\n", - "[ NORMAL ] Iteration 161:\tk_eff = 1.213291\tres = 3.255E-04\n", - "[ NORMAL ] Iteration 162:\tk_eff = 1.213651\tres = 3.108E-04\n", - "[ NORMAL ] Iteration 163:\tk_eff = 1.213995\tres = 2.968E-04\n", - "[ NORMAL ] Iteration 164:\tk_eff = 1.214323\tres = 2.834E-04\n", - "[ NORMAL ] Iteration 165:\tk_eff = 1.214637\tres = 2.705E-04\n", - "[ NORMAL ] Iteration 166:\tk_eff = 1.214936\tres = 2.582E-04\n", - "[ NORMAL ] Iteration 167:\tk_eff = 1.215222\tres = 2.465E-04\n", - "[ NORMAL ] Iteration 168:\tk_eff = 1.215495\tres = 2.353E-04\n", - "[ NORMAL ] Iteration 169:\tk_eff = 1.215755\tres = 2.245E-04\n", - "[ NORMAL ] Iteration 170:\tk_eff = 1.216004\tres = 2.142E-04\n", - "[ NORMAL ] Iteration 171:\tk_eff = 1.216241\tres = 2.044E-04\n", - "[ NORMAL ] Iteration 172:\tk_eff = 1.216468\tres = 1.951E-04\n", - "[ NORMAL ] Iteration 173:\tk_eff = 1.216683\tres = 1.861E-04\n", - "[ NORMAL ] Iteration 174:\tk_eff = 1.216889\tres = 1.775E-04\n", - "[ NORMAL ] Iteration 175:\tk_eff = 1.217086\tres = 1.693E-04\n", - "[ NORMAL ] Iteration 176:\tk_eff = 1.217274\tres = 1.615E-04\n", - "[ NORMAL ] Iteration 177:\tk_eff = 1.217452\tres = 1.540E-04\n", - "[ NORMAL ] Iteration 178:\tk_eff = 1.217623\tres = 1.469E-04\n", - "[ NORMAL ] Iteration 179:\tk_eff = 1.217786\tres = 1.401E-04\n", - "[ NORMAL ] Iteration 180:\tk_eff = 1.217941\tres = 1.336E-04\n", - "[ NORMAL ] Iteration 181:\tk_eff = 1.218089\tres = 1.274E-04\n", - "[ NORMAL ] Iteration 182:\tk_eff = 1.218230\tres = 1.214E-04\n", - "[ NORMAL ] Iteration 183:\tk_eff = 1.218364\tres = 1.158E-04\n", - "[ NORMAL ] Iteration 184:\tk_eff = 1.218492\tres = 1.104E-04\n", - "[ NORMAL ] Iteration 185:\tk_eff = 1.218614\tres = 1.052E-04\n", - "[ NORMAL ] Iteration 186:\tk_eff = 1.218731\tres = 1.003E-04\n", - "[ NORMAL ] Iteration 187:\tk_eff = 1.218842\tres = 9.556E-05\n", - "[ NORMAL ] Iteration 188:\tk_eff = 1.218948\tres = 9.107E-05\n", - "[ NORMAL ] Iteration 189:\tk_eff = 1.219048\tres = 8.679E-05\n", - "[ NORMAL ] Iteration 190:\tk_eff = 1.219144\tres = 8.270E-05\n", - "[ NORMAL ] Iteration 191:\tk_eff = 1.219236\tres = 7.880E-05\n", - "[ NORMAL ] Iteration 192:\tk_eff = 1.219323\tres = 7.508E-05\n", - "[ NORMAL ] Iteration 193:\tk_eff = 1.219406\tres = 7.152E-05\n", - "[ NORMAL ] Iteration 194:\tk_eff = 1.219485\tres = 6.814E-05\n", - "[ NORMAL ] Iteration 195:\tk_eff = 1.219561\tres = 6.491E-05\n", - "[ NORMAL ] Iteration 196:\tk_eff = 1.219633\tres = 6.183E-05\n", - "[ NORMAL ] Iteration 197:\tk_eff = 1.219701\tres = 5.889E-05\n", - "[ NORMAL ] Iteration 198:\tk_eff = 1.219766\tres = 5.609E-05\n", - "[ NORMAL ] Iteration 199:\tk_eff = 1.219828\tres = 5.341E-05\n", - "[ NORMAL ] Iteration 200:\tk_eff = 1.219887\tres = 5.087E-05\n", - "[ NORMAL ] Iteration 201:\tk_eff = 1.219944\tres = 4.844E-05\n", - "[ NORMAL ] Iteration 202:\tk_eff = 1.219997\tres = 4.612E-05\n", - "[ NORMAL ] Iteration 203:\tk_eff = 1.220048\tres = 4.391E-05\n", - "[ NORMAL ] Iteration 204:\tk_eff = 1.220097\tres = 4.181E-05\n", - "[ NORMAL ] Iteration 205:\tk_eff = 1.220143\tres = 3.981E-05\n", - "[ NORMAL ] Iteration 206:\tk_eff = 1.220187\tres = 3.789E-05\n", - "[ NORMAL ] Iteration 207:\tk_eff = 1.220229\tres = 3.607E-05\n", - "[ NORMAL ] Iteration 208:\tk_eff = 1.220269\tres = 3.434E-05\n", - "[ NORMAL ] Iteration 209:\tk_eff = 1.220307\tres = 3.268E-05\n", - "[ NORMAL ] Iteration 210:\tk_eff = 1.220343\tres = 3.111E-05\n", - "[ NORMAL ] Iteration 211:\tk_eff = 1.220377\tres = 2.961E-05\n", - "[ NORMAL ] Iteration 212:\tk_eff = 1.220410\tres = 2.818E-05\n", - "[ NORMAL ] Iteration 213:\tk_eff = 1.220441\tres = 2.681E-05\n", - "[ NORMAL ] Iteration 214:\tk_eff = 1.220471\tres = 2.552E-05\n", - "[ NORMAL ] Iteration 215:\tk_eff = 1.220499\tres = 2.428E-05\n", - "[ NORMAL ] Iteration 216:\tk_eff = 1.220526\tres = 2.310E-05\n", - "[ NORMAL ] Iteration 217:\tk_eff = 1.220551\tres = 2.198E-05\n", - "[ NORMAL ] Iteration 218:\tk_eff = 1.220576\tres = 2.091E-05\n", - "[ NORMAL ] Iteration 219:\tk_eff = 1.220599\tres = 1.990E-05\n", - "[ NORMAL ] Iteration 220:\tk_eff = 1.220621\tres = 1.893E-05\n", - "[ NORMAL ] Iteration 221:\tk_eff = 1.220642\tres = 1.801E-05\n", - "[ NORMAL ] Iteration 222:\tk_eff = 1.220661\tres = 1.713E-05\n", - "[ NORMAL ] Iteration 223:\tk_eff = 1.220680\tres = 1.629E-05\n", - "[ NORMAL ] Iteration 224:\tk_eff = 1.220698\tres = 1.550E-05\n", - "[ NORMAL ] Iteration 225:\tk_eff = 1.220715\tres = 1.474E-05\n", - "[ NORMAL ] Iteration 226:\tk_eff = 1.220732\tres = 1.402E-05\n", - "[ NORMAL ] Iteration 227:\tk_eff = 1.220747\tres = 1.333E-05\n", - "[ NORMAL ] Iteration 228:\tk_eff = 1.220762\tres = 1.268E-05\n", - "[ NORMAL ] Iteration 229:\tk_eff = 1.220776\tres = 1.206E-05\n", - "[ NORMAL ] Iteration 230:\tk_eff = 1.220789\tres = 1.146E-05\n", - "[ NORMAL ] Iteration 231:\tk_eff = 1.220802\tres = 1.090E-05\n", - "[ NORMAL ] Iteration 232:\tk_eff = 1.220814\tres = 1.036E-05\n" + "[ NORMAL ] Iteration 0:\tk_eff = 0.574672\tres = 0.000E+00\n", + "[ NORMAL ] Iteration 1:\tk_eff = 0.679815\tres = 4.253E-01\n", + "[ NORMAL ] Iteration 2:\tk_eff = 0.660826\tres = 1.830E-01\n", + "[ NORMAL ] Iteration 3:\tk_eff = 0.658941\tres = 2.793E-02\n", + "[ NORMAL ] Iteration 4:\tk_eff = 0.643012\tres = 2.852E-03\n", + "[ NORMAL ] Iteration 5:\tk_eff = 0.625810\tres = 2.417E-02\n", + "[ NORMAL ] Iteration 6:\tk_eff = 0.606678\tres = 2.675E-02\n", + "[ NORMAL ] Iteration 7:\tk_eff = 0.587485\tres = 3.057E-02\n", + "[ NORMAL ] Iteration 8:\tk_eff = 0.569029\tres = 3.164E-02\n", + "[ NORMAL ] Iteration 9:\tk_eff = 0.551707\tres = 3.142E-02\n", + "[ NORMAL ] Iteration 10:\tk_eff = 0.536035\tres = 3.044E-02\n", + "[ NORMAL ] Iteration 11:\tk_eff = 0.522274\tres = 2.841E-02\n", + "[ NORMAL ] Iteration 12:\tk_eff = 0.510609\tres = 2.567E-02\n", + "[ NORMAL ] Iteration 13:\tk_eff = 0.501106\tres = 2.234E-02\n", + "[ NORMAL ] Iteration 14:\tk_eff = 0.493831\tres = 1.861E-02\n", + "[ NORMAL ] Iteration 15:\tk_eff = 0.488780\tres = 1.452E-02\n", + "[ NORMAL ] Iteration 16:\tk_eff = 0.485923\tres = 1.023E-02\n", + "[ NORMAL ] Iteration 17:\tk_eff = 0.485210\tres = 5.846E-03\n", + "[ NORMAL ] Iteration 18:\tk_eff = 0.486569\tres = 1.467E-03\n", + "[ NORMAL ] Iteration 19:\tk_eff = 0.489903\tres = 2.801E-03\n", + "[ NORMAL ] Iteration 20:\tk_eff = 0.495103\tres = 6.852E-03\n", + "[ NORMAL ] Iteration 21:\tk_eff = 0.502053\tres = 1.061E-02\n", + "[ NORMAL ] Iteration 22:\tk_eff = 0.510627\tres = 1.404E-02\n", + "[ NORMAL ] Iteration 23:\tk_eff = 0.520693\tres = 1.708E-02\n", + "[ NORMAL ] Iteration 24:\tk_eff = 0.532117\tres = 1.971E-02\n", + "[ NORMAL ] Iteration 25:\tk_eff = 0.544764\tres = 2.194E-02\n", + "[ NORMAL ] Iteration 26:\tk_eff = 0.558501\tres = 2.377E-02\n", + "[ NORMAL ] Iteration 27:\tk_eff = 0.573195\tres = 2.522E-02\n", + "[ NORMAL ] Iteration 28:\tk_eff = 0.588718\tres = 2.631E-02\n", + "[ NORMAL ] Iteration 29:\tk_eff = 0.604946\tres = 2.708E-02\n", + "[ NORMAL ] Iteration 30:\tk_eff = 0.621759\tres = 2.756E-02\n", + "[ NORMAL ] Iteration 31:\tk_eff = 0.639047\tres = 2.779E-02\n", + "[ NORMAL ] Iteration 32:\tk_eff = 0.656702\tres = 2.780E-02\n", + "[ NORMAL ] Iteration 33:\tk_eff = 0.674624\tres = 2.763E-02\n", + "[ NORMAL ] Iteration 34:\tk_eff = 0.692722\tres = 2.729E-02\n", + "[ NORMAL ] Iteration 35:\tk_eff = 0.710910\tres = 2.683E-02\n", + "[ NORMAL ] Iteration 36:\tk_eff = 0.729109\tres = 2.625E-02\n", + "[ NORMAL ] Iteration 37:\tk_eff = 0.747248\tres = 2.560E-02\n", + "[ NORMAL ] Iteration 38:\tk_eff = 0.765263\tres = 2.488E-02\n", + "[ NORMAL ] Iteration 39:\tk_eff = 0.783094\tres = 2.411E-02\n", + "[ NORMAL ] Iteration 40:\tk_eff = 0.800690\tres = 2.330E-02\n", + "[ NORMAL ] Iteration 41:\tk_eff = 0.818005\tres = 2.247E-02\n", + "[ NORMAL ] Iteration 42:\tk_eff = 0.834999\tres = 2.163E-02\n", + "[ NORMAL ] Iteration 43:\tk_eff = 0.851638\tres = 2.078E-02\n", + "[ NORMAL ] Iteration 44:\tk_eff = 0.867892\tres = 1.993E-02\n", + "[ NORMAL ] Iteration 45:\tk_eff = 0.883736\tres = 1.909E-02\n", + "[ NORMAL ] Iteration 46:\tk_eff = 0.899149\tres = 1.826E-02\n", + "[ NORMAL ] Iteration 47:\tk_eff = 0.914115\tres = 1.744E-02\n", + "[ NORMAL ] Iteration 48:\tk_eff = 0.928622\tres = 1.664E-02\n", + "[ NORMAL ] Iteration 49:\tk_eff = 0.942659\tres = 1.587E-02\n", + "[ NORMAL ] Iteration 50:\tk_eff = 0.956221\tres = 1.512E-02\n", + "[ NORMAL ] Iteration 51:\tk_eff = 0.969305\tres = 1.439E-02\n", + "[ NORMAL ] Iteration 52:\tk_eff = 0.981909\tres = 1.368E-02\n", + "[ NORMAL ] Iteration 53:\tk_eff = 0.994035\tres = 1.300E-02\n", + "[ NORMAL ] Iteration 54:\tk_eff = 1.005685\tres = 1.235E-02\n", + "[ NORMAL ] Iteration 55:\tk_eff = 1.016866\tres = 1.172E-02\n", + "[ NORMAL ] Iteration 56:\tk_eff = 1.027584\tres = 1.112E-02\n", + "[ NORMAL ] Iteration 57:\tk_eff = 1.037846\tres = 1.054E-02\n", + "[ NORMAL ] Iteration 58:\tk_eff = 1.047661\tres = 9.986E-03\n", + "[ NORMAL ] Iteration 59:\tk_eff = 1.057040\tres = 9.457E-03\n", + "[ NORMAL ] Iteration 60:\tk_eff = 1.065994\tres = 8.953E-03\n", + "[ NORMAL ] Iteration 61:\tk_eff = 1.074533\tres = 8.470E-03\n", + "[ NORMAL ] Iteration 62:\tk_eff = 1.082671\tres = 8.011E-03\n", + "[ NORMAL ] Iteration 63:\tk_eff = 1.090418\tres = 7.573E-03\n", + "[ NORMAL ] Iteration 64:\tk_eff = 1.097790\tres = 7.156E-03\n", + "[ NORMAL ] Iteration 65:\tk_eff = 1.104797\tres = 6.760E-03\n", + "[ NORMAL ] Iteration 66:\tk_eff = 1.111453\tres = 6.383E-03\n", + "[ NORMAL ] Iteration 67:\tk_eff = 1.117770\tres = 6.025E-03\n", + "[ NORMAL ] Iteration 68:\tk_eff = 1.123764\tres = 5.684E-03\n", + "[ NORMAL ] Iteration 69:\tk_eff = 1.129446\tres = 5.362E-03\n", + "[ NORMAL ] Iteration 70:\tk_eff = 1.134828\tres = 5.056E-03\n", + "[ NORMAL ] Iteration 71:\tk_eff = 1.139924\tres = 4.765E-03\n", + "[ NORMAL ] Iteration 72:\tk_eff = 1.144746\tres = 4.491E-03\n", + "[ NORMAL ] Iteration 73:\tk_eff = 1.149306\tres = 4.230E-03\n", + "[ NORMAL ] Iteration 74:\tk_eff = 1.153617\tres = 3.983E-03\n", + "[ NORMAL ] Iteration 75:\tk_eff = 1.157688\tres = 3.751E-03\n", + "[ NORMAL ] Iteration 76:\tk_eff = 1.161534\tres = 3.530E-03\n", + "[ NORMAL ] Iteration 77:\tk_eff = 1.165163\tres = 3.322E-03\n", + "[ NORMAL ] Iteration 78:\tk_eff = 1.168586\tres = 3.124E-03\n", + "[ NORMAL ] Iteration 79:\tk_eff = 1.171813\tres = 2.938E-03\n", + "[ NORMAL ] Iteration 80:\tk_eff = 1.174855\tres = 2.762E-03\n", + "[ NORMAL ] Iteration 81:\tk_eff = 1.177721\tres = 2.596E-03\n", + "[ NORMAL ] Iteration 82:\tk_eff = 1.180419\tres = 2.439E-03\n", + "[ NORMAL ] Iteration 83:\tk_eff = 1.182960\tres = 2.291E-03\n", + "[ NORMAL ] Iteration 84:\tk_eff = 1.185350\tres = 2.152E-03\n", + "[ NORMAL ] Iteration 85:\tk_eff = 1.187599\tres = 2.021E-03\n", + "[ NORMAL ] Iteration 86:\tk_eff = 1.189713\tres = 1.897E-03\n", + "[ NORMAL ] Iteration 87:\tk_eff = 1.191700\tres = 1.780E-03\n", + "[ NORMAL ] Iteration 88:\tk_eff = 1.193567\tres = 1.670E-03\n", + "[ NORMAL ] Iteration 89:\tk_eff = 1.195321\tres = 1.567E-03\n", + "[ NORMAL ] Iteration 90:\tk_eff = 1.196967\tres = 1.469E-03\n", + "[ NORMAL ] Iteration 91:\tk_eff = 1.198513\tres = 1.378E-03\n", + "[ NORMAL ] Iteration 92:\tk_eff = 1.199964\tres = 1.291E-03\n", + "[ NORMAL ] Iteration 93:\tk_eff = 1.201326\tres = 1.211E-03\n", + "[ NORMAL ] Iteration 94:\tk_eff = 1.202602\tres = 1.135E-03\n", + "[ NORMAL ] Iteration 95:\tk_eff = 1.203800\tres = 1.062E-03\n", + "[ NORMAL ] Iteration 96:\tk_eff = 1.204922\tres = 9.959E-04\n", + "[ NORMAL ] Iteration 97:\tk_eff = 1.205974\tres = 9.321E-04\n", + "[ NORMAL ] Iteration 98:\tk_eff = 1.206961\tres = 8.732E-04\n", + "[ NORMAL ] Iteration 99:\tk_eff = 1.207884\tres = 8.175E-04\n", + "[ NORMAL ] Iteration 100:\tk_eff = 1.208748\tres = 7.646E-04\n", + "[ NORMAL ] Iteration 101:\tk_eff = 1.209558\tres = 7.159E-04\n", + "[ NORMAL ] Iteration 102:\tk_eff = 1.210316\tres = 6.699E-04\n", + "[ NORMAL ] Iteration 103:\tk_eff = 1.211025\tres = 6.262E-04\n", + "[ NORMAL ] Iteration 104:\tk_eff = 1.211689\tres = 5.864E-04\n", + "[ NORMAL ] Iteration 105:\tk_eff = 1.212310\tres = 5.481E-04\n", + "[ NORMAL ] Iteration 106:\tk_eff = 1.212891\tres = 5.124E-04\n", + "[ NORMAL ] Iteration 107:\tk_eff = 1.213434\tres = 4.792E-04\n", + "[ NORMAL ] Iteration 108:\tk_eff = 1.213942\tres = 4.477E-04\n", + "[ NORMAL ] Iteration 109:\tk_eff = 1.214416\tres = 4.189E-04\n", + "[ NORMAL ] Iteration 110:\tk_eff = 1.214861\tres = 3.907E-04\n", + "[ NORMAL ] Iteration 111:\tk_eff = 1.215275\tres = 3.660E-04\n", + "[ NORMAL ] Iteration 112:\tk_eff = 1.215663\tres = 3.414E-04\n", + "[ NORMAL ] Iteration 113:\tk_eff = 1.216025\tres = 3.188E-04\n", + "[ NORMAL ] Iteration 114:\tk_eff = 1.216363\tres = 2.981E-04\n", + "[ NORMAL ] Iteration 115:\tk_eff = 1.216679\tres = 2.776E-04\n", + "[ NORMAL ] Iteration 116:\tk_eff = 1.216974\tres = 2.599E-04\n", + "[ NORMAL ] Iteration 117:\tk_eff = 1.217250\tres = 2.427E-04\n", + "[ NORMAL ] Iteration 118:\tk_eff = 1.217507\tres = 2.263E-04\n", + "[ NORMAL ] Iteration 119:\tk_eff = 1.217747\tres = 2.115E-04\n", + "[ NORMAL ] Iteration 120:\tk_eff = 1.217970\tres = 1.970E-04\n", + "[ NORMAL ] Iteration 121:\tk_eff = 1.218180\tres = 1.834E-04\n", + "[ NORMAL ] Iteration 122:\tk_eff = 1.218375\tres = 1.718E-04\n", + "[ NORMAL ] Iteration 123:\tk_eff = 1.218557\tres = 1.602E-04\n", + "[ NORMAL ] Iteration 124:\tk_eff = 1.218726\tres = 1.496E-04\n", + "[ NORMAL ] Iteration 125:\tk_eff = 1.218885\tres = 1.387E-04\n", + "[ NORMAL ] Iteration 126:\tk_eff = 1.219032\tres = 1.301E-04\n", + "[ NORMAL ] Iteration 127:\tk_eff = 1.219169\tres = 1.211E-04\n", + "[ NORMAL ] Iteration 128:\tk_eff = 1.219298\tres = 1.127E-04\n", + "[ NORMAL ] Iteration 129:\tk_eff = 1.219418\tres = 1.058E-04\n", + "[ NORMAL ] Iteration 130:\tk_eff = 1.219529\tres = 9.828E-05\n", + "[ NORMAL ] Iteration 131:\tk_eff = 1.219633\tres = 9.100E-05\n", + "[ NORMAL ] Iteration 132:\tk_eff = 1.219730\tres = 8.530E-05\n", + "[ NORMAL ] Iteration 133:\tk_eff = 1.219820\tres = 7.940E-05\n", + "[ NORMAL ] Iteration 134:\tk_eff = 1.219904\tres = 7.409E-05\n", + "[ NORMAL ] Iteration 135:\tk_eff = 1.219983\tres = 6.876E-05\n", + "[ NORMAL ] Iteration 136:\tk_eff = 1.220056\tres = 6.455E-05\n", + "[ NORMAL ] Iteration 137:\tk_eff = 1.220124\tres = 5.969E-05\n", + "[ NORMAL ] Iteration 138:\tk_eff = 1.220187\tres = 5.603E-05\n", + "[ NORMAL ] Iteration 139:\tk_eff = 1.220246\tres = 5.166E-05\n", + "[ NORMAL ] Iteration 140:\tk_eff = 1.220301\tres = 4.829E-05\n", + "[ NORMAL ] Iteration 141:\tk_eff = 1.220352\tres = 4.510E-05\n", + "[ NORMAL ] Iteration 142:\tk_eff = 1.220400\tres = 4.199E-05\n", + "[ NORMAL ] Iteration 143:\tk_eff = 1.220445\tres = 3.939E-05\n", + "[ NORMAL ] Iteration 144:\tk_eff = 1.220486\tres = 3.630E-05\n", + "[ NORMAL ] Iteration 145:\tk_eff = 1.220525\tres = 3.362E-05\n", + "[ NORMAL ] Iteration 146:\tk_eff = 1.220561\tres = 3.181E-05\n", + "[ NORMAL ] Iteration 147:\tk_eff = 1.220594\tres = 2.977E-05\n", + "[ NORMAL ] Iteration 148:\tk_eff = 1.220626\tres = 2.745E-05\n", + "[ NORMAL ] Iteration 149:\tk_eff = 1.220655\tres = 2.569E-05\n", + "[ NORMAL ] Iteration 150:\tk_eff = 1.220682\tres = 2.376E-05\n", + "[ NORMAL ] Iteration 151:\tk_eff = 1.220707\tres = 2.201E-05\n", + "[ NORMAL ] Iteration 152:\tk_eff = 1.220730\tres = 2.071E-05\n", + "[ NORMAL ] Iteration 153:\tk_eff = 1.220752\tres = 1.925E-05\n", + "[ NORMAL ] Iteration 154:\tk_eff = 1.220772\tres = 1.793E-05\n", + "[ NORMAL ] Iteration 155:\tk_eff = 1.220791\tres = 1.669E-05\n", + "[ NORMAL ] Iteration 156:\tk_eff = 1.220809\tres = 1.554E-05\n", + "[ NORMAL ] Iteration 157:\tk_eff = 1.220826\tres = 1.457E-05\n", + "[ NORMAL ] Iteration 158:\tk_eff = 1.220841\tres = 1.372E-05\n", + "[ NORMAL ] Iteration 159:\tk_eff = 1.220855\tres = 1.249E-05\n", + "[ NORMAL ] Iteration 160:\tk_eff = 1.220868\tres = 1.138E-05\n", + "[ NORMAL ] Iteration 161:\tk_eff = 1.220881\tres = 1.104E-05\n", + "[ NORMAL ] Iteration 162:\tk_eff = 1.220892\tres = 1.028E-05\n" ] } ], @@ -1444,8 +1367,8 @@ "output_type": "stream", "text": [ "openmc keff = 1.223474\n", - "openmoc keff = 1.220814\n", - "bias [pcm]: -266.0\n" + "openmoc keff = 1.220892\n", + "bias [pcm]: -258.1\n" ] } ], @@ -1520,346 +1443,237 @@ "text": [ "[ NORMAL ] Importing ray tracing data from file...\n", "[ NORMAL ] Computing the eigenvalue...\n", - "[ NORMAL ] Iteration 0:\tk_eff = 0.366907\tres = 0.000E+00\n", - "[ NORMAL ] Iteration 1:\tk_eff = 0.391217\tres = 6.331E-01\n", - "[ NORMAL ] Iteration 2:\tk_eff = 0.393027\tres = 6.626E-02\n", - "[ NORMAL ] Iteration 3:\tk_eff = 0.381142\tres = 4.627E-03\n", - "[ NORMAL ] Iteration 4:\tk_eff = 0.375065\tres = 3.024E-02\n", - "[ NORMAL ] Iteration 5:\tk_eff = 0.369645\tres = 1.594E-02\n", - "[ NORMAL ] Iteration 6:\tk_eff = 0.365597\tres = 1.445E-02\n", - "[ NORMAL ] Iteration 7:\tk_eff = 0.363111\tres = 1.095E-02\n", - "[ NORMAL ] Iteration 8:\tk_eff = 0.361532\tres = 6.802E-03\n", - "[ NORMAL ] Iteration 9:\tk_eff = 0.361339\tres = 4.349E-03\n", - "[ NORMAL ] Iteration 10:\tk_eff = 0.362062\tres = 5.322E-04\n", - "[ NORMAL ] Iteration 11:\tk_eff = 0.363777\tres = 2.001E-03\n", - "[ NORMAL ] Iteration 12:\tk_eff = 0.366395\tres = 4.735E-03\n", - "[ NORMAL ] Iteration 13:\tk_eff = 0.369859\tres = 7.198E-03\n", - "[ NORMAL ] Iteration 14:\tk_eff = 0.374042\tres = 9.454E-03\n", - "[ NORMAL ] Iteration 15:\tk_eff = 0.378972\tres = 1.131E-02\n", - "[ NORMAL ] Iteration 16:\tk_eff = 0.384524\tres = 1.318E-02\n", - "[ NORMAL ] Iteration 17:\tk_eff = 0.390678\tres = 1.465E-02\n", - "[ NORMAL ] Iteration 18:\tk_eff = 0.397373\tres = 1.600E-02\n", - "[ NORMAL ] Iteration 19:\tk_eff = 0.404563\tres = 1.714E-02\n", - "[ NORMAL ] Iteration 20:\tk_eff = 0.412207\tres = 1.809E-02\n", - "[ NORMAL ] Iteration 21:\tk_eff = 0.420270\tres = 1.890E-02\n", - "[ NORMAL ] Iteration 22:\tk_eff = 0.428695\tres = 1.956E-02\n", - "[ NORMAL ] Iteration 23:\tk_eff = 0.437463\tres = 2.005E-02\n", - "[ NORMAL ] Iteration 24:\tk_eff = 0.446530\tres = 2.045E-02\n", - "[ NORMAL ] Iteration 25:\tk_eff = 0.455867\tres = 2.073E-02\n", - "[ NORMAL ] Iteration 26:\tk_eff = 0.465442\tres = 2.091E-02\n", - "[ NORMAL ] Iteration 27:\tk_eff = 0.475229\tres = 2.101E-02\n", - "[ NORMAL ] Iteration 28:\tk_eff = 0.485198\tres = 2.103E-02\n", - "[ NORMAL ] Iteration 29:\tk_eff = 0.495327\tres = 2.098E-02\n", - "[ NORMAL ] Iteration 30:\tk_eff = 0.505591\tres = 2.088E-02\n", - "[ NORMAL ] Iteration 31:\tk_eff = 0.515969\tres = 2.072E-02\n", - "[ NORMAL ] Iteration 32:\tk_eff = 0.526440\tres = 2.053E-02\n", - "[ NORMAL ] Iteration 33:\tk_eff = 0.536985\tres = 2.029E-02\n", - "[ NORMAL ] Iteration 34:\tk_eff = 0.547587\tres = 2.003E-02\n", - "[ NORMAL ] Iteration 35:\tk_eff = 0.558228\tres = 1.974E-02\n", - "[ NORMAL ] Iteration 36:\tk_eff = 0.568893\tres = 1.943E-02\n", - "[ NORMAL ] Iteration 37:\tk_eff = 0.579569\tres = 1.911E-02\n", - "[ NORMAL ] Iteration 38:\tk_eff = 0.590241\tres = 1.877E-02\n", - "[ NORMAL ] Iteration 39:\tk_eff = 0.600898\tres = 1.841E-02\n", - "[ NORMAL ] Iteration 40:\tk_eff = 0.611527\tres = 1.805E-02\n", - "[ NORMAL ] Iteration 41:\tk_eff = 0.622118\tres = 1.769E-02\n", - "[ NORMAL ] Iteration 42:\tk_eff = 0.632662\tres = 1.732E-02\n", - "[ NORMAL ] Iteration 43:\tk_eff = 0.643149\tres = 1.695E-02\n", - "[ NORMAL ] Iteration 44:\tk_eff = 0.653571\tres = 1.658E-02\n", - "[ NORMAL ] Iteration 45:\tk_eff = 0.663920\tres = 1.620E-02\n", - "[ NORMAL ] Iteration 46:\tk_eff = 0.674189\tres = 1.583E-02\n", - "[ NORMAL ] Iteration 47:\tk_eff = 0.684372\tres = 1.547E-02\n", - "[ NORMAL ] Iteration 48:\tk_eff = 0.694464\tres = 1.510E-02\n", - "[ NORMAL ] Iteration 49:\tk_eff = 0.704457\tres = 1.475E-02\n", - "[ NORMAL ] Iteration 50:\tk_eff = 0.714349\tres = 1.439E-02\n", - "[ NORMAL ] Iteration 51:\tk_eff = 0.724134\tres = 1.404E-02\n", - "[ NORMAL ] Iteration 52:\tk_eff = 0.733808\tres = 1.370E-02\n", - "[ NORMAL ] Iteration 53:\tk_eff = 0.743369\tres = 1.336E-02\n", - "[ NORMAL ] Iteration 54:\tk_eff = 0.752812\tres = 1.303E-02\n", - "[ NORMAL ] Iteration 55:\tk_eff = 0.762135\tres = 1.270E-02\n", - "[ NORMAL ] Iteration 56:\tk_eff = 0.771336\tres = 1.238E-02\n", - "[ NORMAL ] Iteration 57:\tk_eff = 0.780412\tres = 1.207E-02\n", - "[ NORMAL ] Iteration 58:\tk_eff = 0.789362\tres = 1.177E-02\n", - "[ NORMAL ] Iteration 59:\tk_eff = 0.798184\tres = 1.147E-02\n", - "[ NORMAL ] Iteration 60:\tk_eff = 0.806877\tres = 1.118E-02\n", - "[ NORMAL ] Iteration 61:\tk_eff = 0.815440\tres = 1.089E-02\n", - "[ NORMAL ] Iteration 62:\tk_eff = 0.823872\tres = 1.061E-02\n", - "[ NORMAL ] Iteration 63:\tk_eff = 0.832172\tres = 1.034E-02\n", - "[ NORMAL ] Iteration 64:\tk_eff = 0.840340\tres = 1.007E-02\n", - "[ NORMAL ] Iteration 65:\tk_eff = 0.848377\tres = 9.816E-03\n", - "[ NORMAL ] Iteration 66:\tk_eff = 0.856281\tres = 9.563E-03\n", - "[ NORMAL ] Iteration 67:\tk_eff = 0.864053\tres = 9.317E-03\n", - "[ NORMAL ] Iteration 68:\tk_eff = 0.871693\tres = 9.076E-03\n", - "[ NORMAL ] Iteration 69:\tk_eff = 0.879202\tres = 8.842E-03\n", - "[ NORMAL ] Iteration 70:\tk_eff = 0.886580\tres = 8.614E-03\n", - "[ NORMAL ] Iteration 71:\tk_eff = 0.893828\tres = 8.392E-03\n", - "[ NORMAL ] Iteration 72:\tk_eff = 0.900946\tres = 8.175E-03\n", - "[ NORMAL ] Iteration 73:\tk_eff = 0.907936\tres = 7.964E-03\n", - "[ NORMAL ] Iteration 74:\tk_eff = 0.914798\tres = 7.758E-03\n", - "[ NORMAL ] Iteration 75:\tk_eff = 0.921534\tres = 7.558E-03\n", - "[ NORMAL ] Iteration 76:\tk_eff = 0.928144\tres = 7.363E-03\n", - "[ NORMAL ] Iteration 77:\tk_eff = 0.934629\tres = 7.173E-03\n", - "[ NORMAL ] Iteration 78:\tk_eff = 0.940992\tres = 6.988E-03\n", - "[ NORMAL ] Iteration 79:\tk_eff = 0.947233\tres = 6.808E-03\n", - "[ NORMAL ] Iteration 80:\tk_eff = 0.953353\tres = 6.632E-03\n", - "[ NORMAL ] Iteration 81:\tk_eff = 0.959355\tres = 6.461E-03\n", - "[ NORMAL ] Iteration 82:\tk_eff = 0.965238\tres = 6.295E-03\n", - "[ NORMAL ] Iteration 83:\tk_eff = 0.971006\tres = 6.133E-03\n", - "[ NORMAL ] Iteration 84:\tk_eff = 0.976659\tres = 5.975E-03\n", - "[ NORMAL ] Iteration 85:\tk_eff = 0.982199\tres = 5.822E-03\n", - "[ NORMAL ] Iteration 86:\tk_eff = 0.987627\tres = 5.672E-03\n", - "[ NORMAL ] Iteration 87:\tk_eff = 0.992945\tres = 5.527E-03\n", - "[ NORMAL ] Iteration 88:\tk_eff = 0.998155\tres = 5.385E-03\n", - "[ NORMAL ] Iteration 89:\tk_eff = 1.003258\tres = 5.247E-03\n", - "[ NORMAL ] Iteration 90:\tk_eff = 1.008256\tres = 5.113E-03\n", - "[ NORMAL ] Iteration 91:\tk_eff = 1.013151\tres = 4.982E-03\n", - "[ NORMAL ] Iteration 92:\tk_eff = 1.017943\tres = 4.854E-03\n", - "[ NORMAL ] Iteration 93:\tk_eff = 1.022635\tres = 4.730E-03\n", - "[ NORMAL ] Iteration 94:\tk_eff = 1.027229\tres = 4.609E-03\n", - "[ NORMAL ] Iteration 95:\tk_eff = 1.031726\tres = 4.492E-03\n", - "[ NORMAL ] Iteration 96:\tk_eff = 1.036127\tres = 4.377E-03\n", - "[ NORMAL ] Iteration 97:\tk_eff = 1.040434\tres = 4.266E-03\n", - "[ NORMAL ] Iteration 98:\tk_eff = 1.044649\tres = 4.157E-03\n", - "[ NORMAL ] Iteration 99:\tk_eff = 1.048774\tres = 4.051E-03\n", - "[ NORMAL ] Iteration 100:\tk_eff = 1.052810\tres = 3.948E-03\n", - "[ NORMAL ] Iteration 101:\tk_eff = 1.056759\tres = 3.848E-03\n", - "[ NORMAL ] Iteration 102:\tk_eff = 1.060622\tres = 3.751E-03\n", - "[ NORMAL ] Iteration 103:\tk_eff = 1.064400\tres = 3.655E-03\n", - "[ NORMAL ] Iteration 104:\tk_eff = 1.068096\tres = 3.563E-03\n", - "[ NORMAL ] Iteration 105:\tk_eff = 1.071711\tres = 3.473E-03\n", - "[ NORMAL ] Iteration 106:\tk_eff = 1.075247\tres = 3.385E-03\n", - "[ NORMAL ] Iteration 107:\tk_eff = 1.078705\tres = 3.299E-03\n", - "[ NORMAL ] Iteration 108:\tk_eff = 1.082086\tres = 3.216E-03\n", - "[ NORMAL ] Iteration 109:\tk_eff = 1.085392\tres = 3.134E-03\n", - "[ NORMAL ] Iteration 110:\tk_eff = 1.088624\tres = 3.055E-03\n", - "[ NORMAL ] Iteration 111:\tk_eff = 1.091785\tres = 2.978E-03\n", - "[ NORMAL ] Iteration 112:\tk_eff = 1.094875\tres = 2.903E-03\n", - "[ NORMAL ] Iteration 113:\tk_eff = 1.097895\tres = 2.830E-03\n", - "[ NORMAL ] Iteration 114:\tk_eff = 1.100848\tres = 2.759E-03\n", - "[ NORMAL ] Iteration 115:\tk_eff = 1.103734\tres = 2.689E-03\n", - "[ NORMAL ] Iteration 116:\tk_eff = 1.106555\tres = 2.622E-03\n", - "[ NORMAL ] Iteration 117:\tk_eff = 1.109312\tres = 2.556E-03\n", - "[ NORMAL ] Iteration 118:\tk_eff = 1.112007\tres = 2.492E-03\n", - "[ NORMAL ] Iteration 119:\tk_eff = 1.114641\tres = 2.429E-03\n", - "[ NORMAL ] Iteration 120:\tk_eff = 1.117214\tres = 2.368E-03\n", - "[ NORMAL ] Iteration 121:\tk_eff = 1.119729\tres = 2.309E-03\n", - "[ NORMAL ] Iteration 122:\tk_eff = 1.122187\tres = 2.251E-03\n", - "[ NORMAL ] Iteration 123:\tk_eff = 1.124588\tres = 2.195E-03\n", - "[ NORMAL ] Iteration 124:\tk_eff = 1.126934\tres = 2.140E-03\n", - "[ NORMAL ] Iteration 125:\tk_eff = 1.129226\tres = 2.086E-03\n", - "[ NORMAL ] Iteration 126:\tk_eff = 1.131466\tres = 2.034E-03\n", - "[ NORMAL ] Iteration 127:\tk_eff = 1.133654\tres = 1.983E-03\n", - "[ NORMAL ] Iteration 128:\tk_eff = 1.135791\tres = 1.934E-03\n", - "[ NORMAL ] Iteration 129:\tk_eff = 1.137879\tres = 1.885E-03\n", - "[ NORMAL ] Iteration 130:\tk_eff = 1.139919\tres = 1.838E-03\n", - "[ NORMAL ] Iteration 131:\tk_eff = 1.141911\tres = 1.793E-03\n", - "[ NORMAL ] Iteration 132:\tk_eff = 1.143857\tres = 1.748E-03\n", - "[ NORMAL ] Iteration 133:\tk_eff = 1.145758\tres = 1.704E-03\n", - "[ NORMAL ] Iteration 134:\tk_eff = 1.147615\tres = 1.662E-03\n", - "[ NORMAL ] Iteration 135:\tk_eff = 1.149428\tres = 1.620E-03\n", - "[ NORMAL ] Iteration 136:\tk_eff = 1.151200\tres = 1.580E-03\n", - "[ NORMAL ] Iteration 137:\tk_eff = 1.152929\tres = 1.541E-03\n", - "[ NORMAL ] Iteration 138:\tk_eff = 1.154619\tres = 1.503E-03\n", - "[ NORMAL ] Iteration 139:\tk_eff = 1.156268\tres = 1.465E-03\n", - "[ NORMAL ] Iteration 140:\tk_eff = 1.157879\tres = 1.429E-03\n", - "[ NORMAL ] Iteration 141:\tk_eff = 1.159453\tres = 1.393E-03\n", - "[ NORMAL ] Iteration 142:\tk_eff = 1.160989\tres = 1.359E-03\n", - "[ NORMAL ] Iteration 143:\tk_eff = 1.162489\tres = 1.325E-03\n", - "[ NORMAL ] Iteration 144:\tk_eff = 1.163954\tres = 1.292E-03\n", - "[ NORMAL ] Iteration 145:\tk_eff = 1.165384\tres = 1.260E-03\n", - "[ NORMAL ] Iteration 146:\tk_eff = 1.166781\tres = 1.229E-03\n", - "[ NORMAL ] Iteration 147:\tk_eff = 1.168144\tres = 1.198E-03\n", - "[ NORMAL ] Iteration 148:\tk_eff = 1.169476\tres = 1.169E-03\n", - "[ NORMAL ] Iteration 149:\tk_eff = 1.170776\tres = 1.140E-03\n", - "[ NORMAL ] Iteration 150:\tk_eff = 1.172045\tres = 1.112E-03\n", - "[ NORMAL ] Iteration 151:\tk_eff = 1.173284\tres = 1.084E-03\n", - "[ NORMAL ] Iteration 152:\tk_eff = 1.174494\tres = 1.057E-03\n", - "[ NORMAL ] Iteration 153:\tk_eff = 1.175675\tres = 1.031E-03\n", - "[ NORMAL ] Iteration 154:\tk_eff = 1.176828\tres = 1.006E-03\n", - "[ NORMAL ] Iteration 155:\tk_eff = 1.177953\tres = 9.807E-04\n", - "[ NORMAL ] Iteration 156:\tk_eff = 1.179052\tres = 9.565E-04\n", - "[ NORMAL ] Iteration 157:\tk_eff = 1.180125\tres = 9.328E-04\n", - "[ NORMAL ] Iteration 158:\tk_eff = 1.181172\tres = 9.098E-04\n", - "[ NORMAL ] Iteration 159:\tk_eff = 1.182194\tres = 8.873E-04\n", - "[ NORMAL ] Iteration 160:\tk_eff = 1.183192\tres = 8.654E-04\n", - "[ NORMAL ] Iteration 161:\tk_eff = 1.184166\tres = 8.441E-04\n", - "[ NORMAL ] Iteration 162:\tk_eff = 1.185117\tres = 8.232E-04\n", - "[ NORMAL ] Iteration 163:\tk_eff = 1.186045\tres = 8.029E-04\n", - "[ NORMAL ] Iteration 164:\tk_eff = 1.186951\tres = 7.831E-04\n", - "[ NORMAL ] Iteration 165:\tk_eff = 1.187835\tres = 7.638E-04\n", - "[ NORMAL ] Iteration 166:\tk_eff = 1.188698\tres = 7.450E-04\n", - "[ NORMAL ] Iteration 167:\tk_eff = 1.189541\tres = 7.266E-04\n", - "[ NORMAL ] Iteration 168:\tk_eff = 1.190363\tres = 7.087E-04\n", - "[ NORMAL ] Iteration 169:\tk_eff = 1.191166\tres = 6.912E-04\n", - "[ NORMAL ] Iteration 170:\tk_eff = 1.191949\tres = 6.742E-04\n", - "[ NORMAL ] Iteration 171:\tk_eff = 1.192713\tres = 6.576E-04\n", - "[ NORMAL ] Iteration 172:\tk_eff = 1.193460\tres = 6.414E-04\n", - "[ NORMAL ] Iteration 173:\tk_eff = 1.194188\tres = 6.256E-04\n", - "[ NORMAL ] Iteration 174:\tk_eff = 1.194899\tres = 6.102E-04\n", - "[ NORMAL ] Iteration 175:\tk_eff = 1.195592\tres = 5.952E-04\n", - "[ NORMAL ] Iteration 176:\tk_eff = 1.196269\tres = 5.806E-04\n", - "[ NORMAL ] Iteration 177:\tk_eff = 1.196930\tres = 5.663E-04\n", - "[ NORMAL ] Iteration 178:\tk_eff = 1.197575\tres = 5.524E-04\n", - "[ NORMAL ] Iteration 179:\tk_eff = 1.198204\tres = 5.388E-04\n", - "[ NORMAL ] Iteration 180:\tk_eff = 1.198819\tres = 5.255E-04\n", - "[ NORMAL ] Iteration 181:\tk_eff = 1.199418\tres = 5.126E-04\n", - "[ NORMAL ] Iteration 182:\tk_eff = 1.200003\tres = 5.000E-04\n", - "[ NORMAL ] Iteration 183:\tk_eff = 1.200574\tres = 4.877E-04\n", - "[ NORMAL ] Iteration 184:\tk_eff = 1.201131\tres = 4.757E-04\n", - "[ NORMAL ] Iteration 185:\tk_eff = 1.201675\tres = 4.640E-04\n", - "[ NORMAL ] Iteration 186:\tk_eff = 1.202205\tres = 4.526E-04\n", - "[ NORMAL ] Iteration 187:\tk_eff = 1.202723\tres = 4.415E-04\n", - "[ NORMAL ] Iteration 188:\tk_eff = 1.203228\tres = 4.307E-04\n", - "[ NORMAL ] Iteration 189:\tk_eff = 1.203721\tres = 4.201E-04\n", - "[ NORMAL ] Iteration 190:\tk_eff = 1.204202\tres = 4.098E-04\n", - "[ NORMAL ] Iteration 191:\tk_eff = 1.204672\tres = 3.997E-04\n", - "[ NORMAL ] Iteration 192:\tk_eff = 1.205130\tres = 3.899E-04\n", - "[ NORMAL ] Iteration 193:\tk_eff = 1.205577\tres = 3.803E-04\n", - "[ NORMAL ] Iteration 194:\tk_eff = 1.206014\tres = 3.710E-04\n", - "[ NORMAL ] Iteration 195:\tk_eff = 1.206439\tres = 3.619E-04\n", - "[ NORMAL ] Iteration 196:\tk_eff = 1.206855\tres = 3.530E-04\n", - "[ NORMAL ] Iteration 197:\tk_eff = 1.207260\tres = 3.444E-04\n", - "[ NORMAL ] Iteration 198:\tk_eff = 1.207656\tres = 3.359E-04\n", - "[ NORMAL ] Iteration 199:\tk_eff = 1.208042\tres = 3.277E-04\n", - "[ NORMAL ] Iteration 200:\tk_eff = 1.208418\tres = 3.196E-04\n", - "[ NORMAL ] Iteration 201:\tk_eff = 1.208786\tres = 3.118E-04\n", - "[ NORMAL ] Iteration 202:\tk_eff = 1.209144\tres = 3.041E-04\n", - "[ NORMAL ] Iteration 203:\tk_eff = 1.209494\tres = 2.967E-04\n", - "[ NORMAL ] Iteration 204:\tk_eff = 1.209836\tres = 2.894E-04\n", - "[ NORMAL ] Iteration 205:\tk_eff = 1.210169\tres = 2.823E-04\n", - "[ NORMAL ] Iteration 206:\tk_eff = 1.210494\tres = 2.754E-04\n", - "[ NORMAL ] Iteration 207:\tk_eff = 1.210811\tres = 2.686E-04\n", - "[ NORMAL ] Iteration 208:\tk_eff = 1.211121\tres = 2.621E-04\n", - "[ NORMAL ] Iteration 209:\tk_eff = 1.211423\tres = 2.556E-04\n", - "[ NORMAL ] Iteration 210:\tk_eff = 1.211718\tres = 2.494E-04\n", - "[ NORMAL ] Iteration 211:\tk_eff = 1.212005\tres = 2.433E-04\n", - "[ NORMAL ] Iteration 212:\tk_eff = 1.212286\tres = 2.373E-04\n", - "[ NORMAL ] Iteration 213:\tk_eff = 1.212559\tres = 2.315E-04\n", - "[ NORMAL ] Iteration 214:\tk_eff = 1.212827\tres = 2.258E-04\n", - "[ NORMAL ] Iteration 215:\tk_eff = 1.213087\tres = 2.203E-04\n", - "[ NORMAL ] Iteration 216:\tk_eff = 1.213341\tres = 2.149E-04\n", - "[ NORMAL ] Iteration 217:\tk_eff = 1.213590\tres = 2.096E-04\n", - "[ NORMAL ] Iteration 218:\tk_eff = 1.213832\tres = 2.045E-04\n", - "[ NORMAL ] Iteration 219:\tk_eff = 1.214068\tres = 1.995E-04\n", - "[ NORMAL ] Iteration 220:\tk_eff = 1.214298\tres = 1.946E-04\n", - "[ NORMAL ] Iteration 221:\tk_eff = 1.214523\tres = 1.898E-04\n", - "[ NORMAL ] Iteration 222:\tk_eff = 1.214743\tres = 1.852E-04\n", - "[ NORMAL ] Iteration 223:\tk_eff = 1.214957\tres = 1.806E-04\n", - "[ NORMAL ] Iteration 224:\tk_eff = 1.215165\tres = 1.762E-04\n", - "[ NORMAL ] Iteration 225:\tk_eff = 1.215369\tres = 1.719E-04\n", - "[ NORMAL ] Iteration 226:\tk_eff = 1.215568\tres = 1.677E-04\n", - "[ NORMAL ] Iteration 227:\tk_eff = 1.215762\tres = 1.636E-04\n", - "[ NORMAL ] Iteration 228:\tk_eff = 1.215951\tres = 1.596E-04\n", - "[ NORMAL ] Iteration 229:\tk_eff = 1.216136\tres = 1.557E-04\n", - "[ NORMAL ] Iteration 230:\tk_eff = 1.216316\tres = 1.519E-04\n", - "[ NORMAL ] Iteration 231:\tk_eff = 1.216492\tres = 1.482E-04\n", - "[ NORMAL ] Iteration 232:\tk_eff = 1.216663\tres = 1.445E-04\n", - "[ NORMAL ] Iteration 233:\tk_eff = 1.216831\tres = 1.410E-04\n", - "[ NORMAL ] Iteration 234:\tk_eff = 1.216994\tres = 1.375E-04\n", - "[ NORMAL ] Iteration 235:\tk_eff = 1.217153\tres = 1.342E-04\n", - "[ NORMAL ] Iteration 236:\tk_eff = 1.217309\tres = 1.309E-04\n", - "[ NORMAL ] Iteration 237:\tk_eff = 1.217460\tres = 1.277E-04\n", - "[ NORMAL ] Iteration 238:\tk_eff = 1.217608\tres = 1.246E-04\n", - "[ NORMAL ] Iteration 239:\tk_eff = 1.217753\tres = 1.215E-04\n", - "[ NORMAL ] Iteration 240:\tk_eff = 1.217894\tres = 1.185E-04\n", - "[ NORMAL ] Iteration 241:\tk_eff = 1.218031\tres = 1.156E-04\n", - "[ NORMAL ] Iteration 242:\tk_eff = 1.218165\tres = 1.128E-04\n", - "[ NORMAL ] Iteration 243:\tk_eff = 1.218296\tres = 1.101E-04\n", - "[ NORMAL ] Iteration 244:\tk_eff = 1.218423\tres = 1.074E-04\n", - "[ NORMAL ] Iteration 245:\tk_eff = 1.218548\tres = 1.047E-04\n", - "[ NORMAL ] Iteration 246:\tk_eff = 1.218669\tres = 1.022E-04\n", - "[ NORMAL ] Iteration 247:\tk_eff = 1.218788\tres = 9.967E-05\n", - "[ NORMAL ] Iteration 248:\tk_eff = 1.218903\tres = 9.723E-05\n", - "[ NORMAL ] Iteration 249:\tk_eff = 1.219016\tres = 9.486E-05\n", - "[ NORMAL ] Iteration 250:\tk_eff = 1.219126\tres = 9.254E-05\n", - "[ NORMAL ] Iteration 251:\tk_eff = 1.219234\tres = 9.027E-05\n", - "[ NORMAL ] Iteration 252:\tk_eff = 1.219338\tres = 8.806E-05\n", - "[ NORMAL ] Iteration 253:\tk_eff = 1.219441\tres = 8.591E-05\n", - "[ NORMAL ] Iteration 254:\tk_eff = 1.219540\tres = 8.381E-05\n", - "[ NORMAL ] Iteration 255:\tk_eff = 1.219637\tres = 8.176E-05\n", - "[ NORMAL ] Iteration 256:\tk_eff = 1.219732\tres = 7.976E-05\n", - "[ NORMAL ] Iteration 257:\tk_eff = 1.219825\tres = 7.781E-05\n", - "[ NORMAL ] Iteration 258:\tk_eff = 1.219915\tres = 7.591E-05\n", - "[ NORMAL ] Iteration 259:\tk_eff = 1.220003\tres = 7.405E-05\n", - "[ NORMAL ] Iteration 260:\tk_eff = 1.220089\tres = 7.224E-05\n", - "[ NORMAL ] Iteration 261:\tk_eff = 1.220173\tres = 7.047E-05\n", - "[ NORMAL ] Iteration 262:\tk_eff = 1.220255\tres = 6.875E-05\n", - "[ NORMAL ] Iteration 263:\tk_eff = 1.220335\tres = 6.707E-05\n", - "[ NORMAL ] Iteration 264:\tk_eff = 1.220413\tres = 6.543E-05\n", - "[ NORMAL ] Iteration 265:\tk_eff = 1.220489\tres = 6.383E-05\n", - "[ NORMAL ] Iteration 266:\tk_eff = 1.220563\tres = 6.227E-05\n", - "[ NORMAL ] Iteration 267:\tk_eff = 1.220635\tres = 6.075E-05\n", - "[ NORMAL ] Iteration 268:\tk_eff = 1.220706\tres = 5.926E-05\n", - "[ NORMAL ] Iteration 269:\tk_eff = 1.220775\tres = 5.781E-05\n", - "[ NORMAL ] Iteration 270:\tk_eff = 1.220842\tres = 5.640E-05\n", - "[ NORMAL ] Iteration 271:\tk_eff = 1.220907\tres = 5.502E-05\n", - "[ NORMAL ] Iteration 272:\tk_eff = 1.220971\tres = 5.368E-05\n", - "[ NORMAL ] Iteration 273:\tk_eff = 1.221034\tres = 5.236E-05\n", - "[ NORMAL ] Iteration 274:\tk_eff = 1.221095\tres = 5.108E-05\n", - "[ NORMAL ] Iteration 275:\tk_eff = 1.221154\tres = 4.984E-05\n", - "[ NORMAL ] Iteration 276:\tk_eff = 1.221212\tres = 4.862E-05\n", - "[ NORMAL ] Iteration 277:\tk_eff = 1.221268\tres = 4.743E-05\n", - "[ NORMAL ] Iteration 278:\tk_eff = 1.221324\tres = 4.627E-05\n", - "[ NORMAL ] Iteration 279:\tk_eff = 1.221377\tres = 4.514E-05\n", - "[ NORMAL ] Iteration 280:\tk_eff = 1.221430\tres = 4.403E-05\n", - "[ NORMAL ] Iteration 281:\tk_eff = 1.221481\tres = 4.296E-05\n", - "[ NORMAL ] Iteration 282:\tk_eff = 1.221531\tres = 4.191E-05\n", - "[ NORMAL ] Iteration 283:\tk_eff = 1.221580\tres = 4.088E-05\n", - "[ NORMAL ] Iteration 284:\tk_eff = 1.221627\tres = 3.988E-05\n", - "[ NORMAL ] Iteration 285:\tk_eff = 1.221674\tres = 3.891E-05\n", - "[ NORMAL ] Iteration 286:\tk_eff = 1.221719\tres = 3.796E-05\n", - "[ NORMAL ] Iteration 287:\tk_eff = 1.221763\tres = 3.703E-05\n", - "[ NORMAL ] Iteration 288:\tk_eff = 1.221806\tres = 3.613E-05\n", - "[ NORMAL ] Iteration 289:\tk_eff = 1.221848\tres = 3.524E-05\n", - "[ NORMAL ] Iteration 290:\tk_eff = 1.221889\tres = 3.438E-05\n", - "[ NORMAL ] Iteration 291:\tk_eff = 1.221929\tres = 3.354E-05\n", - "[ NORMAL ] Iteration 292:\tk_eff = 1.221968\tres = 3.272E-05\n", - "[ NORMAL ] Iteration 293:\tk_eff = 1.222006\tres = 3.192E-05\n", - "[ NORMAL ] Iteration 294:\tk_eff = 1.222043\tres = 3.114E-05\n", - "[ NORMAL ] Iteration 295:\tk_eff = 1.222079\tres = 3.038E-05\n", - "[ NORMAL ] Iteration 296:\tk_eff = 1.222115\tres = 2.964E-05\n", - "[ NORMAL ] Iteration 297:\tk_eff = 1.222149\tres = 2.891E-05\n", - "[ NORMAL ] Iteration 298:\tk_eff = 1.222183\tres = 2.821E-05\n", - "[ NORMAL ] Iteration 299:\tk_eff = 1.222216\tres = 2.752E-05\n", - "[ NORMAL ] Iteration 300:\tk_eff = 1.222248\tres = 2.685E-05\n", - "[ NORMAL ] Iteration 301:\tk_eff = 1.222279\tres = 2.619E-05\n", - "[ NORMAL ] Iteration 302:\tk_eff = 1.222309\tres = 2.555E-05\n", - "[ NORMAL ] Iteration 303:\tk_eff = 1.222339\tres = 2.492E-05\n", - "[ NORMAL ] Iteration 304:\tk_eff = 1.222368\tres = 2.432E-05\n", - "[ NORMAL ] Iteration 305:\tk_eff = 1.222396\tres = 2.372E-05\n", - "[ NORMAL ] Iteration 306:\tk_eff = 1.222424\tres = 2.314E-05\n", - "[ NORMAL ] Iteration 307:\tk_eff = 1.222451\tres = 2.258E-05\n", - "[ NORMAL ] Iteration 308:\tk_eff = 1.222477\tres = 2.202E-05\n", - "[ NORMAL ] Iteration 309:\tk_eff = 1.222503\tres = 2.149E-05\n", - "[ NORMAL ] Iteration 310:\tk_eff = 1.222528\tres = 2.096E-05\n", - "[ NORMAL ] Iteration 311:\tk_eff = 1.222552\tres = 2.045E-05\n", - "[ NORMAL ] Iteration 312:\tk_eff = 1.222576\tres = 1.995E-05\n", - "[ NORMAL ] Iteration 313:\tk_eff = 1.222599\tres = 1.946E-05\n", - "[ NORMAL ] Iteration 314:\tk_eff = 1.222622\tres = 1.899E-05\n", - "[ NORMAL ] Iteration 315:\tk_eff = 1.222644\tres = 1.852E-05\n", - "[ NORMAL ] Iteration 316:\tk_eff = 1.222665\tres = 1.807E-05\n", - "[ NORMAL ] Iteration 317:\tk_eff = 1.222686\tres = 1.763E-05\n", - "[ NORMAL ] Iteration 318:\tk_eff = 1.222707\tres = 1.720E-05\n", - "[ NORMAL ] Iteration 319:\tk_eff = 1.222727\tres = 1.678E-05\n", - "[ NORMAL ] Iteration 320:\tk_eff = 1.222746\tres = 1.637E-05\n", - "[ NORMAL ] Iteration 321:\tk_eff = 1.222766\tres = 1.597E-05\n", - "[ NORMAL ] Iteration 322:\tk_eff = 1.222784\tres = 1.558E-05\n", - "[ NORMAL ] Iteration 323:\tk_eff = 1.222802\tres = 1.520E-05\n", - "[ NORMAL ] Iteration 324:\tk_eff = 1.222820\tres = 1.483E-05\n", - "[ NORMAL ] Iteration 325:\tk_eff = 1.222837\tres = 1.446E-05\n", - "[ NORMAL ] Iteration 326:\tk_eff = 1.222854\tres = 1.411E-05\n", - "[ NORMAL ] Iteration 327:\tk_eff = 1.222870\tres = 1.377E-05\n", - "[ NORMAL ] Iteration 328:\tk_eff = 1.222886\tres = 1.343E-05\n", - "[ NORMAL ] Iteration 329:\tk_eff = 1.222902\tres = 1.310E-05\n", - "[ NORMAL ] Iteration 330:\tk_eff = 1.222917\tres = 1.278E-05\n", - "[ NORMAL ] Iteration 331:\tk_eff = 1.222932\tres = 1.247E-05\n", - "[ NORMAL ] Iteration 332:\tk_eff = 1.222947\tres = 1.216E-05\n", - "[ NORMAL ] Iteration 333:\tk_eff = 1.222961\tres = 1.187E-05\n", - "[ NORMAL ] Iteration 334:\tk_eff = 1.222975\tres = 1.158E-05\n", - "[ NORMAL ] Iteration 335:\tk_eff = 1.222988\tres = 1.129E-05\n", - "[ NORMAL ] Iteration 336:\tk_eff = 1.223001\tres = 1.102E-05\n", - "[ NORMAL ] Iteration 337:\tk_eff = 1.223014\tres = 1.075E-05\n", - "[ NORMAL ] Iteration 338:\tk_eff = 1.223027\tres = 1.049E-05\n", - "[ NORMAL ] Iteration 339:\tk_eff = 1.223039\tres = 1.023E-05\n" + "[ NORMAL ] Iteration 0:\tk_eff = 0.495816\tres = 0.000E+00\n", + "[ NORMAL ] Iteration 1:\tk_eff = 0.557477\tres = 5.042E-01\n", + "[ NORMAL ] Iteration 2:\tk_eff = 0.518301\tres = 1.244E-01\n", + "[ NORMAL ] Iteration 3:\tk_eff = 0.509212\tres = 7.027E-02\n", + "[ NORMAL ] Iteration 4:\tk_eff = 0.496490\tres = 1.754E-02\n", + "[ NORMAL ] Iteration 5:\tk_eff = 0.488581\tres = 2.498E-02\n", + "[ NORMAL ] Iteration 6:\tk_eff = 0.482897\tres = 1.593E-02\n", + "[ NORMAL ] Iteration 7:\tk_eff = 0.479775\tres = 1.163E-02\n", + "[ NORMAL ] Iteration 8:\tk_eff = 0.478834\tres = 6.465E-03\n", + "[ NORMAL ] Iteration 9:\tk_eff = 0.479871\tres = 1.960E-03\n", + "[ NORMAL ] Iteration 10:\tk_eff = 0.482684\tres = 2.165E-03\n", + "[ NORMAL ] Iteration 11:\tk_eff = 0.487084\tres = 5.860E-03\n", + "[ NORMAL ] Iteration 12:\tk_eff = 0.492900\tres = 9.116E-03\n", + "[ NORMAL ] Iteration 13:\tk_eff = 0.499971\tres = 1.194E-02\n", + "[ NORMAL ] Iteration 14:\tk_eff = 0.508153\tres = 1.435E-02\n", + "[ NORMAL ] Iteration 15:\tk_eff = 0.517312\tres = 1.637E-02\n", + "[ NORMAL ] Iteration 16:\tk_eff = 0.527325\tres = 1.802E-02\n", + "[ NORMAL ] Iteration 17:\tk_eff = 0.538079\tres = 1.936E-02\n", + "[ NORMAL ] Iteration 18:\tk_eff = 0.549472\tres = 2.039E-02\n", + "[ NORMAL ] Iteration 19:\tk_eff = 0.561410\tres = 2.117E-02\n", + "[ NORMAL ] Iteration 20:\tk_eff = 0.573807\tres = 2.173E-02\n", + "[ NORMAL ] Iteration 21:\tk_eff = 0.586585\tres = 2.208E-02\n", + "[ NORMAL ] Iteration 22:\tk_eff = 0.599674\tres = 2.227E-02\n", + "[ NORMAL ] Iteration 23:\tk_eff = 0.613007\tres = 2.231E-02\n", + "[ NORMAL ] Iteration 24:\tk_eff = 0.626528\tres = 2.223E-02\n", + "[ NORMAL ] Iteration 25:\tk_eff = 0.640181\tres = 2.206E-02\n", + "[ NORMAL ] Iteration 26:\tk_eff = 0.653920\tres = 2.179E-02\n", + "[ NORMAL ] Iteration 27:\tk_eff = 0.667700\tres = 2.146E-02\n", + "[ NORMAL ] Iteration 28:\tk_eff = 0.681483\tres = 2.107E-02\n", + "[ NORMAL ] Iteration 29:\tk_eff = 0.695234\tres = 2.064E-02\n", + "[ NORMAL ] Iteration 30:\tk_eff = 0.708921\tres = 2.018E-02\n", + "[ NORMAL ] Iteration 31:\tk_eff = 0.722515\tres = 1.969E-02\n", + "[ NORMAL ] Iteration 32:\tk_eff = 0.735993\tres = 1.918E-02\n", + "[ NORMAL ] Iteration 33:\tk_eff = 0.749331\tres = 1.865E-02\n", + "[ NORMAL ] Iteration 34:\tk_eff = 0.762510\tres = 1.812E-02\n", + "[ NORMAL ] Iteration 35:\tk_eff = 0.775514\tres = 1.759E-02\n", + "[ NORMAL ] Iteration 36:\tk_eff = 0.788326\tres = 1.705E-02\n", + "[ NORMAL ] Iteration 37:\tk_eff = 0.800935\tres = 1.652E-02\n", + "[ NORMAL ] Iteration 38:\tk_eff = 0.813328\tres = 1.599E-02\n", + "[ NORMAL ] Iteration 39:\tk_eff = 0.825497\tres = 1.547E-02\n", + "[ NORMAL ] Iteration 40:\tk_eff = 0.837433\tres = 1.496E-02\n", + "[ NORMAL ] Iteration 41:\tk_eff = 0.849130\tres = 1.446E-02\n", + "[ NORMAL ] Iteration 42:\tk_eff = 0.860583\tres = 1.397E-02\n", + "[ NORMAL ] Iteration 43:\tk_eff = 0.871788\tres = 1.349E-02\n", + "[ NORMAL ] Iteration 44:\tk_eff = 0.882742\tres = 1.302E-02\n", + "[ NORMAL ] Iteration 45:\tk_eff = 0.893442\tres = 1.256E-02\n", + "[ NORMAL ] Iteration 46:\tk_eff = 0.903887\tres = 1.212E-02\n", + "[ NORMAL ] Iteration 47:\tk_eff = 0.914077\tres = 1.169E-02\n", + "[ NORMAL ] Iteration 48:\tk_eff = 0.924012\tres = 1.127E-02\n", + "[ NORMAL ] Iteration 49:\tk_eff = 0.933693\tres = 1.087E-02\n", + "[ NORMAL ] Iteration 50:\tk_eff = 0.943122\tres = 1.048E-02\n", + "[ NORMAL ] Iteration 51:\tk_eff = 0.952299\tres = 1.010E-02\n", + "[ NORMAL ] Iteration 52:\tk_eff = 0.961228\tres = 9.730E-03\n", + "[ NORMAL ] Iteration 53:\tk_eff = 0.969911\tres = 9.377E-03\n", + "[ NORMAL ] Iteration 54:\tk_eff = 0.978351\tres = 9.033E-03\n", + "[ NORMAL ] Iteration 55:\tk_eff = 0.986552\tres = 8.702E-03\n", + "[ NORMAL ] Iteration 56:\tk_eff = 0.994517\tres = 8.382E-03\n", + "[ NORMAL ] Iteration 57:\tk_eff = 1.002250\tres = 8.074E-03\n", + "[ NORMAL ] Iteration 58:\tk_eff = 1.009755\tres = 7.776E-03\n", + "[ NORMAL ] Iteration 59:\tk_eff = 1.017037\tres = 7.488E-03\n", + "[ NORMAL ] Iteration 60:\tk_eff = 1.024099\tres = 7.211E-03\n", + "[ NORMAL ] Iteration 61:\tk_eff = 1.030947\tres = 6.944E-03\n", + "[ NORMAL ] Iteration 62:\tk_eff = 1.037584\tres = 6.687E-03\n", + "[ NORMAL ] Iteration 63:\tk_eff = 1.044016\tres = 6.438E-03\n", + "[ NORMAL ] Iteration 64:\tk_eff = 1.050247\tres = 6.199E-03\n", + "[ NORMAL ] Iteration 65:\tk_eff = 1.056282\tres = 5.969E-03\n", + "[ NORMAL ] Iteration 66:\tk_eff = 1.062125\tres = 5.746E-03\n", + "[ NORMAL ] Iteration 67:\tk_eff = 1.067781\tres = 5.531E-03\n", + "[ NORMAL ] Iteration 68:\tk_eff = 1.073255\tres = 5.326E-03\n", + "[ NORMAL ] Iteration 69:\tk_eff = 1.078552\tres = 5.126E-03\n", + "[ NORMAL ] Iteration 70:\tk_eff = 1.083676\tres = 4.936E-03\n", + "[ NORMAL ] Iteration 71:\tk_eff = 1.088632\tres = 4.751E-03\n", + "[ NORMAL ] Iteration 72:\tk_eff = 1.093425\tres = 4.573E-03\n", + "[ NORMAL ] Iteration 73:\tk_eff = 1.098058\tres = 4.403E-03\n", + "[ NORMAL ] Iteration 74:\tk_eff = 1.102537\tres = 4.237E-03\n", + "[ NORMAL ] Iteration 75:\tk_eff = 1.106866\tres = 4.079E-03\n", + "[ NORMAL ] Iteration 76:\tk_eff = 1.111049\tres = 3.926E-03\n", + "[ NORMAL ] Iteration 77:\tk_eff = 1.115090\tres = 3.779E-03\n", + "[ NORMAL ] Iteration 78:\tk_eff = 1.118995\tres = 3.638E-03\n", + "[ NORMAL ] Iteration 79:\tk_eff = 1.122766\tres = 3.501E-03\n", + "[ NORMAL ] Iteration 80:\tk_eff = 1.126408\tres = 3.370E-03\n", + "[ NORMAL ] Iteration 81:\tk_eff = 1.129925\tres = 3.244E-03\n", + "[ NORMAL ] Iteration 82:\tk_eff = 1.133320\tres = 3.122E-03\n", + "[ NORMAL ] Iteration 83:\tk_eff = 1.136597\tres = 3.005E-03\n", + "[ NORMAL ] Iteration 84:\tk_eff = 1.139761\tres = 2.892E-03\n", + "[ NORMAL ] Iteration 85:\tk_eff = 1.142815\tres = 2.783E-03\n", + "[ NORMAL ] Iteration 86:\tk_eff = 1.145761\tres = 2.679E-03\n", + "[ NORMAL ] Iteration 87:\tk_eff = 1.148605\tres = 2.579E-03\n", + "[ NORMAL ] Iteration 88:\tk_eff = 1.151348\tres = 2.482E-03\n", + "[ NORMAL ] Iteration 89:\tk_eff = 1.153994\tres = 2.388E-03\n", + "[ NORMAL ] Iteration 90:\tk_eff = 1.156547\tres = 2.299E-03\n", + "[ NORMAL ] Iteration 91:\tk_eff = 1.159009\tres = 2.212E-03\n", + "[ NORMAL ] Iteration 92:\tk_eff = 1.161384\tres = 2.129E-03\n", + "[ NORMAL ] Iteration 93:\tk_eff = 1.163674\tres = 2.049E-03\n", + "[ NORMAL ] Iteration 94:\tk_eff = 1.165882\tres = 1.972E-03\n", + "[ NORMAL ] Iteration 95:\tk_eff = 1.168012\tres = 1.898E-03\n", + "[ NORMAL ] Iteration 96:\tk_eff = 1.170064\tres = 1.827E-03\n", + "[ NORMAL ] Iteration 97:\tk_eff = 1.172043\tres = 1.757E-03\n", + "[ NORMAL ] Iteration 98:\tk_eff = 1.173951\tres = 1.692E-03\n", + "[ NORMAL ] Iteration 99:\tk_eff = 1.175790\tres = 1.628E-03\n", + "[ NORMAL ] Iteration 100:\tk_eff = 1.177562\tres = 1.566E-03\n", + "[ NORMAL ] Iteration 101:\tk_eff = 1.179269\tres = 1.507E-03\n", + "[ NORMAL ] Iteration 102:\tk_eff = 1.180916\tres = 1.450E-03\n", + "[ NORMAL ] Iteration 103:\tk_eff = 1.182502\tres = 1.396E-03\n", + "[ NORMAL ] Iteration 104:\tk_eff = 1.184030\tres = 1.343E-03\n", + "[ NORMAL ] Iteration 105:\tk_eff = 1.185503\tres = 1.292E-03\n", + "[ NORMAL ] Iteration 106:\tk_eff = 1.186922\tres = 1.244E-03\n", + "[ NORMAL ] Iteration 107:\tk_eff = 1.188288\tres = 1.197E-03\n", + "[ NORMAL ] Iteration 108:\tk_eff = 1.189606\tres = 1.151E-03\n", + "[ NORMAL ] Iteration 109:\tk_eff = 1.190874\tres = 1.108E-03\n", + "[ NORMAL ] Iteration 110:\tk_eff = 1.192096\tres = 1.066E-03\n", + "[ NORMAL ] Iteration 111:\tk_eff = 1.193273\tres = 1.026E-03\n", + "[ NORMAL ] Iteration 112:\tk_eff = 1.194407\tres = 9.870E-04\n", + "[ NORMAL ] Iteration 113:\tk_eff = 1.195499\tres = 9.504E-04\n", + "[ NORMAL ] Iteration 114:\tk_eff = 1.196550\tres = 9.140E-04\n", + "[ NORMAL ] Iteration 115:\tk_eff = 1.197563\tres = 8.792E-04\n", + "[ NORMAL ] Iteration 116:\tk_eff = 1.198538\tres = 8.468E-04\n", + "[ NORMAL ] Iteration 117:\tk_eff = 1.199477\tres = 8.140E-04\n", + "[ NORMAL ] Iteration 118:\tk_eff = 1.200382\tres = 7.837E-04\n", + "[ NORMAL ] Iteration 119:\tk_eff = 1.201253\tres = 7.539E-04\n", + "[ NORMAL ] Iteration 120:\tk_eff = 1.202091\tres = 7.257E-04\n", + "[ NORMAL ] Iteration 121:\tk_eff = 1.202898\tres = 6.979E-04\n", + "[ NORMAL ] Iteration 122:\tk_eff = 1.203676\tres = 6.716E-04\n", + "[ NORMAL ] Iteration 123:\tk_eff = 1.204424\tres = 6.465E-04\n", + "[ NORMAL ] Iteration 124:\tk_eff = 1.205144\tres = 6.217E-04\n", + "[ NORMAL ] Iteration 125:\tk_eff = 1.205838\tres = 5.979E-04\n", + "[ NORMAL ] Iteration 126:\tk_eff = 1.206505\tres = 5.760E-04\n", + "[ NORMAL ] Iteration 127:\tk_eff = 1.207148\tres = 5.532E-04\n", + "[ NORMAL ] Iteration 128:\tk_eff = 1.207767\tres = 5.325E-04\n", + "[ NORMAL ] Iteration 129:\tk_eff = 1.208363\tres = 5.125E-04\n", + "[ NORMAL ] Iteration 130:\tk_eff = 1.208936\tres = 4.935E-04\n", + "[ NORMAL ] Iteration 131:\tk_eff = 1.209487\tres = 4.744E-04\n", + "[ NORMAL ] Iteration 132:\tk_eff = 1.210018\tres = 4.559E-04\n", + "[ NORMAL ] Iteration 133:\tk_eff = 1.210529\tres = 4.392E-04\n", + "[ NORMAL ] Iteration 134:\tk_eff = 1.211021\tres = 4.223E-04\n", + "[ NORMAL ] Iteration 135:\tk_eff = 1.211495\tres = 4.060E-04\n", + "[ NORMAL ] Iteration 136:\tk_eff = 1.211951\tres = 3.914E-04\n", + "[ NORMAL ] Iteration 137:\tk_eff = 1.212390\tres = 3.763E-04\n", + "[ NORMAL ] Iteration 138:\tk_eff = 1.212812\tres = 3.623E-04\n", + "[ NORMAL ] Iteration 139:\tk_eff = 1.213217\tres = 3.480E-04\n", + "[ NORMAL ] Iteration 140:\tk_eff = 1.213608\tres = 3.344E-04\n", + "[ NORMAL ] Iteration 141:\tk_eff = 1.213984\tres = 3.223E-04\n", + "[ NORMAL ] Iteration 142:\tk_eff = 1.214347\tres = 3.097E-04\n", + "[ NORMAL ] Iteration 143:\tk_eff = 1.214695\tres = 2.985E-04\n", + "[ NORMAL ] Iteration 144:\tk_eff = 1.215031\tres = 2.869E-04\n", + "[ NORMAL ] Iteration 145:\tk_eff = 1.215352\tres = 2.763E-04\n", + "[ NORMAL ] Iteration 146:\tk_eff = 1.215663\tres = 2.648E-04\n", + "[ NORMAL ] Iteration 147:\tk_eff = 1.215962\tres = 2.552E-04\n", + "[ NORMAL ] Iteration 148:\tk_eff = 1.216249\tres = 2.460E-04\n", + "[ NORMAL ] Iteration 149:\tk_eff = 1.216526\tres = 2.362E-04\n", + "[ NORMAL ] Iteration 150:\tk_eff = 1.216792\tres = 2.279E-04\n", + "[ NORMAL ] Iteration 151:\tk_eff = 1.217048\tres = 2.188E-04\n", + "[ NORMAL ] Iteration 152:\tk_eff = 1.217294\tres = 2.100E-04\n", + "[ NORMAL ] Iteration 153:\tk_eff = 1.217531\tres = 2.024E-04\n", + "[ NORMAL ] Iteration 154:\tk_eff = 1.217759\tres = 1.948E-04\n", + "[ NORMAL ] Iteration 155:\tk_eff = 1.217978\tres = 1.872E-04\n", + "[ NORMAL ] Iteration 156:\tk_eff = 1.218189\tres = 1.799E-04\n", + "[ NORMAL ] Iteration 157:\tk_eff = 1.218393\tres = 1.733E-04\n", + "[ NORMAL ] Iteration 158:\tk_eff = 1.218588\tres = 1.668E-04\n", + "[ NORMAL ] Iteration 159:\tk_eff = 1.218776\tres = 1.600E-04\n", + "[ NORMAL ] Iteration 160:\tk_eff = 1.218957\tres = 1.544E-04\n", + "[ NORMAL ] Iteration 161:\tk_eff = 1.219131\tres = 1.485E-04\n", + "[ NORMAL ] Iteration 162:\tk_eff = 1.219298\tres = 1.428E-04\n", + "[ NORMAL ] Iteration 163:\tk_eff = 1.219459\tres = 1.374E-04\n", + "[ NORMAL ] Iteration 164:\tk_eff = 1.219614\tres = 1.321E-04\n", + "[ NORMAL ] Iteration 165:\tk_eff = 1.219763\tres = 1.270E-04\n", + "[ NORMAL ] Iteration 166:\tk_eff = 1.219906\tres = 1.221E-04\n", + "[ NORMAL ] Iteration 167:\tk_eff = 1.220044\tres = 1.175E-04\n", + "[ NORMAL ] Iteration 168:\tk_eff = 1.220177\tres = 1.130E-04\n", + "[ NORMAL ] Iteration 169:\tk_eff = 1.220304\tres = 1.084E-04\n", + "[ NORMAL ] Iteration 170:\tk_eff = 1.220427\tres = 1.045E-04\n", + "[ NORMAL ] Iteration 171:\tk_eff = 1.220545\tres = 1.007E-04\n", + "[ NORMAL ] Iteration 172:\tk_eff = 1.220659\tres = 9.678E-05\n", + "[ NORMAL ] Iteration 173:\tk_eff = 1.220768\tres = 9.304E-05\n", + "[ NORMAL ] Iteration 174:\tk_eff = 1.220874\tres = 8.984E-05\n", + "[ NORMAL ] Iteration 175:\tk_eff = 1.220975\tres = 8.640E-05\n", + "[ NORMAL ] Iteration 176:\tk_eff = 1.221073\tres = 8.326E-05\n", + "[ NORMAL ] Iteration 177:\tk_eff = 1.221166\tres = 7.985E-05\n", + "[ NORMAL ] Iteration 178:\tk_eff = 1.221256\tres = 7.662E-05\n", + "[ NORMAL ] Iteration 179:\tk_eff = 1.221343\tres = 7.371E-05\n", + "[ NORMAL ] Iteration 180:\tk_eff = 1.221426\tres = 7.091E-05\n", + "[ NORMAL ] Iteration 181:\tk_eff = 1.221506\tres = 6.827E-05\n", + "[ NORMAL ] Iteration 182:\tk_eff = 1.221583\tres = 6.560E-05\n", + "[ NORMAL ] Iteration 183:\tk_eff = 1.221657\tres = 6.320E-05\n", + "[ NORMAL ] Iteration 184:\tk_eff = 1.221729\tres = 6.067E-05\n", + "[ NORMAL ] Iteration 185:\tk_eff = 1.221797\tres = 5.829E-05\n", + "[ NORMAL ] Iteration 186:\tk_eff = 1.221863\tres = 5.641E-05\n", + "[ NORMAL ] Iteration 187:\tk_eff = 1.221927\tres = 5.382E-05\n", + "[ NORMAL ] Iteration 188:\tk_eff = 1.221987\tres = 5.196E-05\n", + "[ NORMAL ] Iteration 189:\tk_eff = 1.222046\tres = 4.968E-05\n", + "[ NORMAL ] Iteration 190:\tk_eff = 1.222102\tres = 4.810E-05\n", + "[ NORMAL ] Iteration 191:\tk_eff = 1.222157\tres = 4.617E-05\n", + "[ NORMAL ] Iteration 192:\tk_eff = 1.222209\tres = 4.456E-05\n", + "[ NORMAL ] Iteration 193:\tk_eff = 1.222260\tres = 4.287E-05\n", + "[ NORMAL ] Iteration 194:\tk_eff = 1.222308\tres = 4.122E-05\n", + "[ NORMAL ] Iteration 195:\tk_eff = 1.222355\tres = 3.971E-05\n", + "[ NORMAL ] Iteration 196:\tk_eff = 1.222399\tres = 3.805E-05\n", + "[ NORMAL ] Iteration 197:\tk_eff = 1.222442\tres = 3.657E-05\n", + "[ NORMAL ] Iteration 198:\tk_eff = 1.222484\tres = 3.521E-05\n", + "[ NORMAL ] Iteration 199:\tk_eff = 1.222523\tres = 3.381E-05\n", + "[ NORMAL ] Iteration 200:\tk_eff = 1.222561\tres = 3.262E-05\n", + "[ NORMAL ] Iteration 201:\tk_eff = 1.222598\tres = 3.107E-05\n", + "[ NORMAL ] Iteration 202:\tk_eff = 1.222634\tres = 2.985E-05\n", + "[ NORMAL ] Iteration 203:\tk_eff = 1.222668\tres = 2.902E-05\n", + "[ NORMAL ] Iteration 204:\tk_eff = 1.222700\tres = 2.804E-05\n", + "[ NORMAL ] Iteration 205:\tk_eff = 1.222732\tres = 2.639E-05\n", + "[ NORMAL ] Iteration 206:\tk_eff = 1.222762\tres = 2.577E-05\n", + "[ NORMAL ] Iteration 207:\tk_eff = 1.222792\tres = 2.487E-05\n", + "[ NORMAL ] Iteration 208:\tk_eff = 1.222820\tres = 2.400E-05\n", + "[ NORMAL ] Iteration 209:\tk_eff = 1.222847\tres = 2.291E-05\n", + "[ NORMAL ] Iteration 210:\tk_eff = 1.222872\tres = 2.200E-05\n", + "[ NORMAL ] Iteration 211:\tk_eff = 1.222897\tres = 2.121E-05\n", + "[ NORMAL ] Iteration 212:\tk_eff = 1.222921\tres = 2.040E-05\n", + "[ NORMAL ] Iteration 213:\tk_eff = 1.222944\tres = 1.964E-05\n", + "[ NORMAL ] Iteration 214:\tk_eff = 1.222967\tres = 1.882E-05\n", + "[ NORMAL ] Iteration 215:\tk_eff = 1.222988\tres = 1.821E-05\n", + "[ NORMAL ] Iteration 216:\tk_eff = 1.223009\tres = 1.763E-05\n", + "[ NORMAL ] Iteration 217:\tk_eff = 1.223029\tres = 1.690E-05\n", + "[ NORMAL ] Iteration 218:\tk_eff = 1.223048\tres = 1.630E-05\n", + "[ NORMAL ] Iteration 219:\tk_eff = 1.223067\tres = 1.572E-05\n", + "[ NORMAL ] Iteration 220:\tk_eff = 1.223084\tres = 1.507E-05\n", + "[ NORMAL ] Iteration 221:\tk_eff = 1.223101\tres = 1.427E-05\n", + "[ NORMAL ] Iteration 222:\tk_eff = 1.223117\tres = 1.394E-05\n", + "[ NORMAL ] Iteration 223:\tk_eff = 1.223133\tres = 1.330E-05\n", + "[ NORMAL ] Iteration 224:\tk_eff = 1.223148\tres = 1.298E-05\n", + "[ NORMAL ] Iteration 225:\tk_eff = 1.223163\tres = 1.241E-05\n", + "[ NORMAL ] Iteration 226:\tk_eff = 1.223177\tres = 1.167E-05\n", + "[ NORMAL ] Iteration 227:\tk_eff = 1.223190\tres = 1.151E-05\n", + "[ NORMAL ] Iteration 228:\tk_eff = 1.223203\tres = 1.073E-05\n", + "[ NORMAL ] Iteration 229:\tk_eff = 1.223215\tres = 1.050E-05\n", + "[ NORMAL ] Iteration 230:\tk_eff = 1.223227\tres = 1.000E-05\n" ] } ], @@ -1885,8 +1699,8 @@ "output_type": "stream", "text": [ "openmc keff = 1.223474\n", - "openmoc keff = 1.223039\n", - "bias [pcm]: -43.5\n" + "openmoc keff = 1.223227\n", + "bias [pcm]: -24.7\n" ] } ], @@ -1939,7 +1753,7 @@ "outputs": [], "source": [ "# Parse ACE data into memory\n", - "u235 = openmc.data.IncidentNeutron.from_hdf5('../../../../data/nndc_hdf5/U235.h5')\n", + "u235 = openmc.data.IncidentNeutron.from_ace('../../../../scripts/nndc/293.6K/U_235_293.6K.ace')\n", "\n", "# Extract the continuous-energy U-235 fission cross section data\n", "fission = u235[18]" @@ -1971,9 +1785,9 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -2055,9 +1869,9 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAADSCAYAAABAbduaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGuBJREFUeJzt3Xm4HFWZx/HvDfsScABRYDAIA6+yKGEnBBKQLY4wMDAw\nC7LL5riNIoGIBJRFFgcdZBmBSAAHUSbsQ1QIIWxxCCBg5BeQTSHIJjKKLEnu/HHOhc7lLp3bVZ1b\ndX+f58lDd3X1W6cvb7196lT1qY7Ozk7MzKx+hi3uBpiZWTlc4M3MasoF3sysplzgzcxqygXezKym\nXODNzGpqycXdgLJFxAJgNUmvNCw7CNhX0h59vG9t4B7gY43v7bbOscA/56dLAFOBEyS9PcC2ngg8\nKOmGiNgCOEzS0YsY40hgZUlnDqQN3WKNAJ4E7pA0tttrk4CD6Pa37SFGr58jIjYHjpO0X6ttHSoi\n4ijgKNK+2wncD3xN0m/7ed+uwLckjWxYtgnwXWBlYB5wlKT7e3jvNsBpwCqkPH8GOFbS7AF+hoVy\nIiKmAv/UVx71EGMN4MeSRg+kDT3Eux3YAVhX0lMNy8cA04CvSPp2PzF6/RwRcWOO8WgR7W3WUOjB\n93ahf68/AIiIA4E7gDX6WGdfYC9g67zTbAF8BDhp4E1lJ2Cp/HhjYK1FDSDpoiKKe4M3gA3yFx4A\nEbE8sB19/A0b9Po5JM1ycW9eRJwN7A18UtLGkjYBfg7cExFr9vKeZSPiG8CPSMW5a/lypA7JGZI2\nA74BXNHD+5cGbgC+JGnTvM0fAjdHRMcAP0r3nNhlUQNImltUcc86gaeBA7otPwh4vskYvX4OSZ9q\nd3GHIdCDBxYpCXPPYE9gHPCrPlZdg7TDrAC8JemtiPgssHqOswLwH6RC+DZwnaQJEbE+8L38vjWB\nB4H9gcNJXxJn5QJ6MrBSRFwi6bCI2AOYQPoCeJ3UG5gZEScB2wIfBB4CfgOsKunzEfEk8APgE8Da\nwNWSjsvtGw8cCrwGzAD2kvThHj7nfFJxOAA4PS/7e+A64N9yrA7gXGArYDjpb3448NvGzwFMBr4D\n/BlYHjgOOEfSJhHxc2CWpOMiYmdgErCZpBf7+H8wZETEWsCRwFqSXutaLunyiNgMOB74XA9v3Y30\ntz4EOKVh+a7A45Km5jg35HzpbnlSD394wzavjIg/kvJ/XkQcSsqFecBLpKL4HM3lRNf+OS0iPkkq\ntOeR8nUp4CpJZ+SjyRnAr4ERwMHAzyQNz/vAOqR9cgTwArC/pOcjYivS/rYU8ER+/UuS7ujhs14B\n/AvwTXjnS3A70pcoedmnSH/rpUj7+mWSToqISxs+x9/mts4ENiHtt/8O7EP6cjspL+8A/hc4TdJ7\nvlyLMBR68JD+6Pfnfw+wcKIvJPcM9s3ftn19OVwG/BF4PiLuzr2rEZLuy6+fAiwjKYCRwKiI2IGU\n5D+QtB2wPrAu8LeSzgfuIxXuK4CvAzNycf8b4FRgnKTNSTv6lJyAAB8CRko6sId2riBpB1Kifi4i\nRkTEbsCBwOaStiDtgH0d6Uxm4Z7NQaQC3GVr4IOStpW0cV5/vKTfNX6OvO5GpJ1vJPBmw3YPAD4d\nEXsClwL/6OK+kK2B2Y3FvcGtQI+9WUnXSfoy8IduL20A/D4iLo6I/42In/Lu0WPj+18FvgpMjYjH\nI2JyRBwC3CppXkR8DDgD2FXSpsD1pILWVE5IOjRvaqykZ4HLgUskbZlj7JKPlgH+GjhZ0keAuSyc\ns6OBfSR9FHgVODIilgB+AkzIbfsu8PGe/k7ZA8BbEbFlft7VkZnfsM6XgAMlbUXqWJ0QEat0+xy/\ny48flrSRpGsb/p6TgbuBs0idnellFXcYOgV+rKTN8r+RpARriaTXJO0GBPB94P3AjRHR1cvdGbgk\nr/u2pB1zr2E88FIev7+A1OtYsSF0T18qu5B66LfmL6grSb2lv8mv3yuptwJ9XW7Dc8DvSeOo40jj\nl/+X1/leP5/1AWBBRIyMiL8GVszjrx359XuBEyPiqIg4C9i322dq9NuGHaBxG88DRwBTgIsk3dVX\nm4ao9xTgbBmaGy7rHmsccGEupueRhl16KvLnknqrnyf1zI8D7o+I4aSjw1tyfiHpu5KOWcScAOjI\nR65jgG/kPL+X1JPfNK/zdl7Wk9sl/Tk/foCU55sAnZJ+mtt2O30flcPCnZmDSEfAjfYEtoiIrwNd\nY/IrNH6OhsczetnG0cDupC+wL/TTnpYMhSEa6KMnnhOpa+c4vKeTTL2871jgTkn3kHqzkyJiO+B/\nSIdw8xrikgvj66SiPgy4GriR1PvubxhpCVKP6Z+6xXuO1Mv4Ux/v/Uu35x25bY3bnE//Lgc+DbyY\nH78jH5KeC5wNXAs8SjrU7Ulfbd2YNN65VRPtGWruBdaPiNUlvdDttR2Bu/NJ64vzss48tt6b54BH\nu444JV0fEReTjijVtVJEjAJGSTobuJn0JXAC8Aip49E9z5clDYOsR+qhNpMT5Bhd5wi2lfRmjrcq\nKYffD7wpaUEv72/M807ezfPundj+cv2HwH0R8e/AcEmzI6Lrsy1PGlK9hlS8LyWdh2vclxq/aHvL\n9Q8CywJLk4Zpn+qnTQM2VHrwvZI0sqF331Rxz5YHTo+Iv2pY9lHSVQ2Qxu0OioiOiFiGdKg4hrRT\nnCLpx6TE2Jp3E3se7/bSGh/fBuwaOdPyWOUvST23gbgJ2CciVsrPD6f3HmBX8l4B/AOwH2knaLQz\ncL2ki4BZpKTv6TP1Ko+Vfo50HuJ9EfH55j7K0JB7yN8F/qvxhGoeLvl70hUys3I+j+ynuEPqiKwT\nESNznB2ABaSrphq9CEzIhb7LWqT8f5h0hcnOEfGB/NpRwLfoPyeWbog3D1g6H1HeC3wlt+l9wF3A\n3+X1FvWk7q+BN/IVRF05tgl9HO1Imps/16Wk3nyj9UlHIV+TdBMwNn+O3j7Xe0TEkqT950TSuYir\n8lBSKYZCgW9lusy+3nsKqYjfHRG/iohHSQW866qQk0mHlL8kJfiNkqYAJwDXRsQvgPOB23l3qOUG\n4OyI+DTpEs2PRsQ1eTjkCFIyPJBj7yGpe++8v/Z3AkiaRurp3Z3bMZx0dNFrjFxgZgNz8rhsY/wL\ngbER8SBph3wc6Dphew/wkYi4prdGRsSKpKT/17yDHUI6vO9rvHTIkTSB9EV7XUQ8FBEiXXm1rfq5\nTLKHWL8nFd0LIuJh4Bxgb0lvdVvvsbze6XkM/hHgKuAzkh6T9AhwLGmM/gHSydujgIvoOyeiISem\nAHdGxIaky463iYiH8npXSvqvvN4i7cuS5pOGhk6OiFmk8fO59JzrjbEnk8bXF9qupF+SOkeKiPuA\nT5H2ia79t+tzbNRDW7uenwbMlXSppItJJ6VPXZTPtSg6PF3w0JMP5UdJ+o/8/EvAVo1DQGZ1EBFn\nAmdJejEPaz5Iuta9p5PVtTNUxuBtYXOA4yLiCN69/veIxdsks1I8DdwWEV0/PjxsqBR3cA/ezKy2\nhsIYvJnZkOQCb2ZWU4NqDL5jVktXvCxk3c37+z1D856YvlFhsWzx6hyzyJfatWwstxSW19M7PlRU\nKNJPMawuOjsnvie33YM3M6spF3gzs5pygTczqykXeDOzmir1JGueJ/x80hSdb5Am83qizG2alc15\nbVVRdg9+L9Kc6KNIMyz2ecsrs4pwXlsllF3gRwO3AEiaSZop0KzqnNdWCWUX+JVIdz3qMi8iPO5v\nVee8tkooOylfo+FejsCwPibsN6sK57VVQtkF/i7gkwARsQ1pIn2zqnNeWyWUPVXBFNJNc7vur3lI\nydszawfntVVCqQU+3wj66DK3YdZuzmurCp8YMjOrKRd4M7OacoE3M6spF3gzs5pygTczq6lBdUcn\n/lRcqOV5vbBY2465rbBY90zfqbBYVg3TO+4tLNZJjCss1smcU1is5LWC41mr3IM3M6spF3gzs5py\ngTczqykXeDOzmnKBNzOrqdILfERsHRHTyt6OWbs5t22wK/uerMcCn6bQCyDNFj/ntlVB2T34x4G9\nS96G2eLg3LZBr9QCL2kKMK/MbZgtDs5tqwKfZDUzq6l2FfiONm3HrN2c2zZotavAd7ZpO2bt5ty2\nQav0ycYkPQ2MKns7Zu3m3LbBzmPwZmY15QJvZlZTLvBmZjXlAm9mVlMu8GZmNTW4btlXoEemb1lY\nrG+M+Uphsd4cs3Rhse6fObqwWECxv8v0bzxLcTInFRbrDL5cWCyA8YXeAtC3/yuCe/BmZjXlAm9m\nVlMu8GZmNeUCb2ZWUy7wZmY1VdpVNBGxJHApsA6wNHCqpBvK2p5Zuzi3rSrK7MEfALwkaQdgHHBe\nidsyayfntlVCmdfBXw38OD8eBrxd4rbM2sm5bZVQWoGX9DpARAwn7QwTytqWWTs5t60qSj3JGhFr\nA7cBl0n6UZnbMmsn57ZVQZknWT8ATAU+K2laWdsxazfntlVFmWPwxwPvA06MiK+Tbm02TtKbJW7T\nrB2c21YJZY7BfxH4YlnxzRYX57ZVhX/oZGZWUy7wZmY15QJvZlZTLvBmZjXlAm9mVlMdnZ2d/a4U\nESsBKwMdXcskPVN4Y6bTf2Oq7tziQl07ZbfiggGncGJhsZ6a/+HCYr3yu9ULi9U5YqmOxuftyO2O\njon1z2tgBicXFmt77i0sFvxPgbEGr87OiR3dl/V7mWREnACMB15ujAWsW1zTzNrPuW1118x18IcB\n60l6sezGmLWZc9tqrZkx+GeAV8puiNli4Ny2WmumB/8YcGdETAPe6Foo6ZTSWmXWHs5tq7VmCvyz\n+R80nIgyqwHnttVavwVe0oBPjUfEMOD7QAALgKMkzR5oPLMiDTS3nddWFb0W+HzY2uvlXZJ2aiL+\nHkCnpNERMQY4DdhrkVtpVqACctt5bZXQVw9+YqvBJV0XEV03I14H+EOrMc0KMLGVNzuvrSp6LfCS\nphexAUkLIuIHpB7OvkXENGtFEbntvLYqaMtUBZIOBjYALo6I5dqxTbOyOa9tsCv7nqwHRMT4/PQN\nYD7ppJRZZTmvrSqauqNTRKwOjAbmATMkNTvm+N/ApIiYnrf1Bd/WzAaTAea289oqoZm5aA4Azgbu\nBJYALoiIz0i6ub/3Snod2L/lVpqVYKC57by2qmimB/81YHNJzwJExAjgBqDfAm82yDm3rdaaGYN/\nDZjb9UTS08BbpbXIrH2c21ZrzfTgHwZujohJpHHK/YC5EXEggKTJJbbPrEzObau1Zgr8MFIvZ/f8\n/PX8b0fSrwG9E1hVObet1pqZi+aQdjTErN2c21Z3zVxF8yQ9zNshyXe9sUpzblvdNTNEM7bh8VLA\n3sAypbRmKPhicaH26ti2uGDAgpe3LyzWqat8ubBYU0cUee/ZXRqfjG147Nxu0facUViszl23KSxW\nx5wCb4n71MTiYrVBM0M0T3dbdFZE3Ad8s5wmmbWHc9vqrpkhmh0annYAGwGed8Mqz7ltddfMEE3j\nTRE6gZeAg8ppjllbObet1poZotkRICKGA0tIerX0Vpm1gXPb6q6ZIZp1gauA9YCOiHga2F/SnGY2\nkCdzug/Yudn3mLWDc9vqrpmpCi4CzpS0qqRVgNOB/2wmeEQsCVxI+vGI2WDj3LZaa6bArybpJ11P\nJF0NrNJk/LOBC4DnBtA2s7I5t63Wminwb0bEZl1PImJzmui1RMTBwAuSfka6QsFssHFuW601cxXN\nF4BrIuIVUjKvQnNzYR8CLIiIXYBNgckRsaekFwbcWrNiObet1pop8KuR7ju5AanHL0n9TqkqaUzX\n44iYBhzpHcAGGee21VozBf5MSTcBv2phOwX+VtisMM5tq7VmCvxvIuJSYCbwl66FizJXtqSdBtA2\ns7I5t63WminwL5PGJxtn//Fc2VYHzm2rNc8Hb0OWc9vqrs8CHxFHA89LmhIRM4H3A/OB3SX9ph0N\nNCuDc9uGgl6vg4+I44F9ePcE1HKkW5l9Bzih/KaZlcO5bUNFXz90OhDYq2GOjfl5/uzzWXjM0qxq\nnNs2JPRV4OdL+lPD828CSFoAvFlqq8zK5dy2IaGvMfhhETFc0v8BSLoGICJWbkvLrH/3TSw03LBV\nVyosVuf3i7tl34aHzy4sVr5ln3O7FH/pf5Umdfy0qTnfmtL5reJmk+h4suCfPVw4sdh43fTVg7+S\n9BPsd/b6iFgRuBS4otRWmZXLuW1DQl89+DPIs+VFxGzS9cEbApdL+nY7GmdWEue2DQm9FnhJ84Ej\nIuJkYKu8eJakZ9rSMrOSOLdtqGjmh07PAlPa0BaztnJuW901M1VBSyJiFvDH/PRJSYeVvU2zsjmv\nrQpKLfARsQx4QiarF+e1VUXZPfiPAytExFRgCWCCpJklb9OsbM5rq4RmbtnXiteBsyTtBhwNXBkR\nZW/TrGzOa6uEspNyDumaYyQ9RpqedY2St2lWNue1VULZBf5Q4ByAiFgTGA7MLXmbZmVzXlsllD0G\nfwkwKSJmAAuAQ/N8H2ZV5ry2Sii1wEt6GzigzG2YtZvz2qrCJ4bMzGrKBd7MrKZc4M3MasoF3sys\nplzgzcxqygXezKymSp9N0kr0p/5XWRTLvnpwYbE6zv23wmJ1frS4W67x6+JCWZmeLSxSx3E/KSxW\n51cLzEWgY+eCbwHYjXvwZmY15QJvZlZTLvBmZjXlAm9mVlPtuGXfeGBPYCngfEmTyt6mWdmc11YF\npfbgI2IMsK2kUcBYYO0yt2fWDs5rq4qye/C7AY9ExLWkObOPLXl7Zu3gvLZKKLvArwZ8CPgUsC5w\nPfCRkrdpVjbntVVC2SdZXwamSponaQ7wRkSsVvI2zcrmvLZKKLvA3wnsDu/c2mx50s5hVmXOa6uE\nUgu8pJuAByLiF8B1wDGSyv1trlnJnNdWFaVfJilpfNnbMGs357VVgX/oZGZWUy7wZmY15QJvZlZT\nLvBmZjXlAm9mVlMu8GZmNdXR2Tl4Lt/tmM7gacxQtGxxoW7delRhse7ouKewWBM7O4u951oTOjom\nOq9rY0Kh0W5m6cJijesht92DNzOrKRd4M7OacoE3M6spF3gzs5oqdS6aiDgIOBjoBJYDPg58UNJr\nZW7XrEzOa6uKUgu8pMuAywAi4jzgYu8EVnXOa6uKtgzRRMQWwIaSLmnH9szawXltg127xuCPB05u\n07bM2sV5bYNa6QU+IlYGNpA0vextmbWL89qqoB09+B2AW9uwHbN2cl7boNeOAh/AE23Yjlk7Oa9t\n0GvHLfvOLnsbZu3mvLYq8A+dzMxqygXezKymXODNzGrKBd7MrKZc4M3MasoF3syspgbVLfvMzKw4\n7sGbmdWUC7yZWU25wJuZ1ZQLvJlZTbnAm5nVlAu8mVlNlT6bZFEiogM4n3SD4zeAwyW1NF1rRGwN\nnCFpxxZiLAlcCqwDLA2cKumGAcYaBnyfNBXtAuAoSbMH2rYcc3XgPmBnSXNaiDML+GN++qSkw1qI\nNR7YE1gKOF/SpAHGqcXNr4vO7cGW1zleobldVF7nWLXN7Sr14PcClpE0inSrtG+3EiwijiUl3DIt\ntusA4CVJOwDjgPNaiLUH0ClpNHAicForDcs76YXA6y3GWQZA0k75Xys7wBhg2/z/cSyw9kBjSbpM\n0o6SdgJmAZ+rWnHPCsvtQZrXUGBuF5XXOVatc7tKBX40cAuApJnAFi3GexzYu9VGAVeTEhbS3/Pt\ngQaSdB1wRH66DvCHlloGZwMXAM+1GOfjwAoRMTUifp57iAO1G/BIRFwLXA/c2GLb6nDz6yJze9Dl\nNRSe20XlNdQ8t6tU4Ffi3cMogHn5sG9AJE0B5rXaKEmvS/pzRAwHfgxMaDHegoj4AfAd4MqBxomI\ng4EXJP0M6GilTaSe0lmSdgOOBq5s4W+/GrA5sG+O9cMW2wbVv/l1Ybk9WPM6x2w5twvOa6h5blep\nwL8GDG94PkzSgsXVmEYRsTZwG3CZpB+1Gk/SwcAGwMURsdwAwxwC7BIR04BNgcl53HIg5pB3SEmP\nAS8Dawww1svAVEnz8tjpGxGx2gBj1eXm14Myt4vOaygkt4vMa6h5blepwN8FfBIgIrYBHi4obku9\ngIj4ADAV+Kqky1qMdUA+SQPpZNt80gmpRSZpTB7D2xF4EDhQ0gsDbNqhwDm5jWuSitHcAca6E9i9\nIdbypB1joOpw8+sycnvQ5HWOV0huF5zXUPPcrsxVNMAU0jf3Xfn5IQXFbXW2teOB9wEnRsTXc7xx\nkt4cQKz/BiZFxHTS/5svDDBOd61+xktI7ZpB2ikPHWgPU9JNEbF9RPyCVISOkdRK++pw8+sycnsw\n5TWUk9tFzJRY69z2bJJmZjVVpSEaMzNbBC7wZmY15QJvZlZTLvBmZjXlAm9mVlMu8GZmNVWl6+Ar\nJSKWAMYD/0K6vnYJYLKk09vcjvWBs4ANST8wEXCspKf6ed9E4GeS7uprPRt6nNvV4R58eS4gTRq1\ntaSNgS2BT0TE0e1qQP4J923AVZI2kPQx4FrgrohYtZ+3jyHtuGbdObcrwj90KkFErEXqTazZOMVn\nRGwAbCRpSkRMAlYF1gO+CrxEmoRpmfz4SElP5Dk3TpJ0R0SMAG6X9OH8/gXAJqTJqr4p6Ypu7TgJ\nGCHp0G7LfwQ8JOnUiFggaVhefhBpmtPbSPOTzwX2lvSrQv9AVlnO7WpxD74cWwGzu8/fLGlOnu2v\ny0uSNgJ+ClxF+mnzSOCi/Lwnjd/IawHbAJ8Azu5h0qUtgV/0EOOO/Fr3eJDm7L6cdDOFw+q+A9gi\nc25XiAt8ed5JrojYJyIeiIiHImJmwzpdjzcAXpF0P4CknwDr5ala+zJJ0gJJz5ImOhrdQxt6Os+y\ndMPjvialKmI6Vqsf53ZFuMCXYxawYUSsCCDpmtx72QN4f8N6f8n/HcZ7E66DNE7Y2fDaUt3WaZz3\newneOw/4TGBUD+3blp57P93jm3Xn3K4QF/gSSHoGuBy4LM/p3HVPyj1I06S+5y3AKhGxeV53P+Bp\nSa+Sxiw3yut1v1PPfnn9EaRD5xndXj8f2C4i/rlrQUQcSNoxLsyLXoyIDfN9QfdseO88fJWVdePc\nrhYX+JJIOoY0z/e0iLifNMf3SPJ80TQc5kp6C9gf+F5EPAQck58DnAl8NiLu47332Vw+L78B+Iyk\nhW6DJukVYHtg74h4NCIeJSX66PwapMvdbsptfbTh7bcAF+b5yc3e4dyuDl9FU1H5SoNpkiYv7raY\nFcm5XRz34KvL38xWV87tgrgHb2ZWU+7Bm5nVlAu8mVlNucCbmdWUC7yZWU25wJuZ1ZQLvJlZTf0/\nfn35+EIOpHUAAAAASUVORK5CYII=\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -2084,15 +1898,6 @@ "# Show the plot on screen\n", "plt.show()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] } ], "metadata": { From b9ad56a038005aaf56f2a18d92fc40fcae50af48 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Mon, 28 Nov 2016 18:32:46 -0500 Subject: [PATCH 57/60] Added low and high filter bounds to Pandas DataFrames for Azimuthal and Polar filters --- openmc/filter.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openmc/filter.py b/openmc/filter.py index 0320cdeca..9da77c18e 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -1323,11 +1323,14 @@ class PolarFilter(Filter): # Extract the lower and upper angle bounds, then repeat and tile # them as necessary to account for other filters. lo_bins = np.repeat(self.bins[:-1], self.stride) + hi_bins = np.repeast(self.bins[1:], self.stride) tile_factor = data_size / len(lo_bins) lo_bins = np.tile(lo_bins, tile_factor) + hi_bins = np.tile(hi_bins, tile_factor) # Add the new angle columns to the DataFrame. df.loc[:, 'polar low'] = lo_bins + df.loc[:, 'polar high'] = hi_bins return df @@ -1399,11 +1402,14 @@ class AzimuthalFilter(Filter): # Extract the lower and upper angle bounds, then repeat and tile # them as necessary to account for other filters. lo_bins = np.repeat(self.bins[:-1], self.stride) + hi_bins = np.repeat(self.bins[1:], self.stride) tile_factor = data_size / len(lo_bins) lo_bins = np.tile(lo_bins, tile_factor) + hi_bins = np.tile(hi_bins, tile_factor) # Add the new angle columns to the DataFrame. df.loc[:, 'azimuthal low'] = lo_bins + df.loc[:, 'azimuthal high'] = hi_bins return df From 81e3230adde9acc211615ae03337fe095eab1dde Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Mon, 28 Nov 2016 19:25:02 -0500 Subject: [PATCH 58/60] Fixed typo in filter.py --- openmc/filter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/filter.py b/openmc/filter.py index 9da77c18e..bf59e8238 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -1323,7 +1323,7 @@ class PolarFilter(Filter): # Extract the lower and upper angle bounds, then repeat and tile # them as necessary to account for other filters. lo_bins = np.repeat(self.bins[:-1], self.stride) - hi_bins = np.repeast(self.bins[1:], self.stride) + hi_bins = np.repeat(self.bins[1:], self.stride) tile_factor = data_size / len(lo_bins) lo_bins = np.tile(lo_bins, tile_factor) hi_bins = np.tile(hi_bins, tile_factor) From 2a594cc7041c89ed9dc45858816b22d329faae86 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 29 Nov 2016 18:46:09 -0500 Subject: [PATCH 59/60] Added from_hdf5 for MGXSLibrary class and some miscellaneous fixes' --- openmc/data/reaction.py | 2 +- openmc/macroscopic.py | 4 +- openmc/mgxs/mgxs.py | 6 +- openmc/mgxs_library.py | 239 +++++++++++++++++++++++++++++++++++++--- 4 files changed, 231 insertions(+), 20 deletions(-) diff --git a/openmc/data/reaction.py b/openmc/data/reaction.py index 08930fa65..bb976f9fa 100644 --- a/openmc/data/reaction.py +++ b/openmc/data/reaction.py @@ -818,7 +818,7 @@ class Reaction(EqualityMixin): Parameters ---------- group : h5py.Group - HDF5 group to write to + HDF5 group to read from energy : dict Dictionary whose keys are temperatures (e.g., '300K') and values are arrays of energies at which cross sections are tabulated at. diff --git a/openmc/macroscopic.py b/openmc/macroscopic.py index 4d3589141..f2521c4ac 100644 --- a/openmc/macroscopic.py +++ b/openmc/macroscopic.py @@ -1,5 +1,3 @@ -import sys - from six import string_types from openmc.checkvalue import check_type @@ -45,7 +43,7 @@ class Macroscopic(object): return hash((self._name)) def __repr__(self): - string = 'Nuclide - {0}\n'.format(self._name) + string = 'Macroscopic - {0}\n'.format(self._name) return string @property diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 58b8a32c2..6f8abefd1 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -62,6 +62,9 @@ _DOMAINS = (openmc.Cell, # Supported ScatterMatrixXS and NuScatterMatrixXS angular distribution types MU_TREATMENTS = ('legendre', 'histogram') +# Maximum Legendre order supported by OpenMC +MAX_LEGENDRE = 10 + @add_metaclass(ABCMeta) class MGXS(object): @@ -3475,7 +3478,8 @@ class ScatterMatrixXS(MatrixMGXS): cv.check_type('legendre_order', legendre_order, Integral) cv.check_greater_than('legendre_order', legendre_order, 0, equality=True) - cv.check_less_than('legendre_order', legendre_order, 10, equality=True) + cv.check_less_than('legendre_order', legendre_order, MAX_LEGENDRE, + equality=True) if self.scatter_format == 'legendre': if self.correction == 'P0' and legendre_order > 0: diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 347c015e7..70ff7a91b 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1,6 +1,6 @@ from collections import Iterable from numbers import Real, Integral -import sys +import os from six import string_types import numpy as np @@ -16,7 +16,7 @@ from openmc.checkvalue import check_type, check_value, check_greater_than, \ _REPRESENTATIONS = ['isotropic', 'angle'] _SCATTER_TYPES = ['tabular', 'legendre', 'histogram'] _XS_SHAPES = ["[G][G'][Order]", "[G]", "[G']", "[G][G']", "[DG]", "[G][DG]", - "[G'][DG]"] + "[G'][DG]", "[G][G'][DG]"] class XSdata(object): @@ -42,7 +42,7 @@ class XSdata(object): ---------- name : str Unique identifier for the xsdata object - aromic_weight_ratio : float + atomic_weight_ratio : float Atomic weight ratio of an isotope. That is, the ratio of the mass of the isotope to the mass of a single neutron. temperatures : numpy.ndarray @@ -303,13 +303,14 @@ class XSdata(object): self._xs_shapes["[G][G'][DG]"] = (self.energy_groups.num_groups, self.energy_groups.num_groups, self.num_delayed_groups) + self._xs_shapes["[G][G'][Order]"] \ = (self.energy_groups.num_groups, self.energy_groups.num_groups, self.num_orders) # If representation is by angle prepend num polar and num azim if self.representation == 'angle': - for key,shapes in self._xs_shapes.items(): + for key, shapes in self._xs_shapes.items(): self._xs_shapes[key] \ = (self.num_polar, self.num_azimuthal) + shapes @@ -337,7 +338,7 @@ class XSdata(object): def num_delayed_groups(self, num_delayed_groups): # Check validity of num_delayed_groups - check_type('num_delayed_groups', num_delayed_groups, int) + check_type('num_delayed_groups', num_delayed_groups, Integral) 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, @@ -359,6 +360,13 @@ class XSdata(object): check_greater_than('atomic_weight_ratio', atomic_weight_ratio, 0.0) self._atomic_weight_ratio = atomic_weight_ratio + @fissionable.setter + def fissionable(self, fissionable): + + # Check validity of type + check_type('fissionable', fissionable, bool) + self._fissionable = fissionable + @temperatures.setter def temperatures(self, temperatures): @@ -1652,6 +1660,7 @@ class XSdata(object): HDF5 File (a root Group) to write to """ + grp = file.create_group(self.name) if self.atomic_weight_ratio is not None: grp.attrs['atomic_weight_ratio'] = self.atomic_weight_ratio @@ -1719,11 +1728,12 @@ class XSdata(object): (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') + '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]) + 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", @@ -1737,7 +1747,8 @@ class XSdata(object): 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]) + 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 ' @@ -1836,6 +1847,143 @@ class XSdata(object): xs_grp.create_dataset("inverse-velocity", data=self._inverse_velocity[i]) + @classmethod + def from_hdf5(cls, group, name, energy_groups, num_delayed_groups): + """Generate XSdata object from an HDF5 group + + Parameters + ---------- + group : h5py.Group + HDF5 group to read from + name : str + Name of the mgxs data set. + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure + num_delayed_groups : int + Number of delayed groups + + Returns + ------- + openmc.XSdata + Multi-group cross section data + + """ + + # Get a list of all the subgroups which will contain our temperature + # strings + subgroups = group.keys() + temperatures = [] + for subgroup in subgroups: + if subgroup != 'kTs': + temperatures.append(subgroup) + + # To ensure the actual floating point temperature used when creating + # the new library is consistent with that used when originally creating + # the file, get the floating point temperatures straight from the kTs + # group. + kTs_group = group['kTs'] + float_temperatures = [] + for temperature in temperatures: + kT = kTs_group[temperature].value + float_temperatures.append(kT / openmc.data.K_BOLTZMANN) + + attrs = group.attrs.keys() + if 'representation' in attrs: + representation = group.attrs['representation'].decode() + else: + representation = 'isotropic' + + data = cls(name, energy_groups, float_temperatures, representation, + num_delayed_groups) + + if 'scatter_format' in attrs: + data.scatter_format = group.attrs['scatter_format'].decode() + + # Get the remaining optional attributes + if 'atomic_weight_ratio' in attrs: + data.atomic_weight_ratio = group.attrs['atomic_weight_ratio'] + if 'order' in attrs: + data.order = group.attrs['order'] + if data.representation == 'angle': + data.num_azimuthal = group.attrs['num_azimuthal'] + data.num_polar = group.attrs['num_polar'] + + # Read the temperature-dependent datasets + for temp, float_temp in zip(temperatures, float_temperatures): + xs_types = ['total', 'absorption', 'fission', 'kappa-fission', + 'chi', 'chi-prompt', 'chi-delayed', 'nu-fission', + 'prompt-nu-fission', 'delayed-nu-fission', 'beta', + 'decay rate', 'inverse-velocity'] + + temperature_group = group[temp] + + for xs_type in xs_types: + set_func = 'set_' + xs_type.replace(' ', '_').replace('-', '_') + if xs_type in temperature_group: + getattr(data, set_func)(temperature_group[xs_type].value, + float_temp) + + scatt_group = temperature_group['scatter_data'] + + # Get scatter matrix and 'un-flatten' it + g_max = scatt_group['g_max'] + g_min = scatt_group['g_min'] + flat_scatter = scatt_group['scatter_matrix'].value + scatter_matrix = np.zeros(data.xs_shapes["[G][G'][Order]"]) + G = data.energy_groups.num_groups + if data.representation == 'isotropic': + Np = 1 + Na = 1 + elif data.representation == 'angle': + Np = data.num_polar + Na = data.num_azimuthal + flat_index = 0 + for p in range(Np): + for a in range(Na): + for g_in in range(G): + if data.representation == 'isotropic': + g_mins = g_min[g_in] + g_maxs = g_max[g_in] + elif data.representation == 'angle': + g_mins = g_min[p, a, g_in] + g_maxs = g_max[p, a, g_in] + for g_out in range(g_mins - 1, g_maxs): + for ang in range(data.num_orders): + if data.representation == 'isotropic': + scatter_matrix[g_in, g_out, ang] = \ + flat_scatter[flat_index] + elif data.representation == 'angle': + scatter_matrix[p, a, g_in, g_out, ang] = \ + flat_scatter[flat_index] + flat_index += 1 + data.set_scatter_matrix(scatter_matrix, float_temp) + + # Repeat for multiplicity + if 'multiplicity_matrix' in scatt_group: + flat_mult = scatt_group['multiplicity_matrix'].value + mult_matrix = np.zeros(data.xs_shapes["[G][G']"]) + flat_index = 0 + for p in range(Np): + for a in range(Na): + for g_in in range(G): + if data.representation == 'isotropic': + g_mins = g_min[g_in] + g_maxs = g_max[g_in] + elif data.representation == 'angle': + g_mins = g_min[p, a, g_in] + g_maxs = g_max[p, a, g_in] + for g_out in range(g_mins - 1, g_maxs): + if data.representation == 'isotropic': + mult_matrix[g_in, g_out] = \ + flat_mult[flat_index] + elif data.representation == 'angle': + mult_matrix[p, a, g_in, g_out] = \ + flat_mult[flat_index] + flat_index += 1 + data.set_multiplicity_matrix(mult_matrix, float_temp) + + return data + class MGXSLibrary(object): """Multi-Group Cross Sections file used for an OpenMC simulation. @@ -1872,14 +2020,14 @@ class MGXSLibrary(object): def num_delayed_groups(self): return self._num_delayed_groups - @property - def temperatures(self): - return self._temperatures - @property def xsdatas(self): return self._xsdatas + @property + def names(self): + return [xsdata.name for xsdata in self.xsdatas] + @energy_groups.setter def energy_groups(self, energy_groups): check_type('energy groups', energy_groups, openmc.mgxs.EnergyGroups) @@ -1887,7 +2035,7 @@ 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_type('num_delayed_groups', num_delayed_groups, Integral) check_greater_than('num_delayed_groups', num_delayed_groups, 0, equality=True) check_less_than('num_delayed_groups', num_delayed_groups, @@ -1916,7 +2064,7 @@ class MGXSLibrary(object): self._xsdatas.append(xsdata) def add_xsdatas(self, xsdatas): - """Add multiple xsdatas to the file. + """Add multiple XSdatas to the file. Parameters ---------- @@ -1947,6 +2095,27 @@ class MGXSLibrary(object): self._xsdatas.remove(xsdata) + def get_by_name(self, name): + """Access the XSdata objects by name + + Parameters + ---------- + name : str + Name of openmc.XSdata object to obtain + + Returns + ------- + result : openmc.XSdata or None + Provides the matching XSdata object or None, if not found + + """ + check_type("name", name, str) + result = None + for xsdata in self.xsdatas: + if name == xsdata.name: + result = xsdata + return result + def export_to_hdf5(self, filename='mgxs.h5'): """Create an hdf5 file that can be used for a simulation. @@ -1969,3 +2138,43 @@ class MGXSLibrary(object): xsdata.to_hdf5(file) file.close() + + @classmethod + def from_hdf5(cls, filename=None): + """Generate an MGXS Library from an HDF5 group or file + Parameters + ---------- + filename : str, optional + Name of HDF5 file containing MGXS data. Default is None. + If not provided, the value of the OPENMC_MG_CROSS_SECTIONS + environmental variable will be used + Returns + ------- + openmc.MGXSLibrary + Multi-group cross section data object. + """ + + # If filename is None, get the cross sections from the + # OPENMC_CROSS_SECTIONS environment variable + if filename is None: + filename = os.environ.get('OPENMC_MG_CROSS_SECTIONS') + + # Check to make sure there was an environmental variable. + if filename is None: + raise ValueError("Either path or OPENMC_MG_CROSS_SECTIONS " + "environmental variable must be set") + + check_type('filename', filename, str) + file = h5py.File(filename, 'r') + + group_structure = file.attrs['group structure'] + num_delayed_groups = file.attrs['delayed_groups'] + energy_groups = openmc.mgxs.EnergyGroups(group_structure) + data = cls(energy_groups, num_delayed_groups) + + for group_name, group in file.items(): + data.add_xsdata(openmc.XSdata.from_hdf5(group, group_name, + energy_groups, + num_delayed_groups)) + + return data From c423975189d897925f7e316b822649b49812a9f0 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 30 Nov 2016 19:48:30 -0500 Subject: [PATCH 60/60] Modified XSData docstring, removed XSData.fissionable setter and made openmc.mgxs.MAX_LEGENDRE private. --- openmc/mgxs/mgxs.py | 4 ++-- openmc/mgxs_library.py | 37 +++++++++++++++---------------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 6f8abefd1..ce7511193 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -63,7 +63,7 @@ _DOMAINS = (openmc.Cell, MU_TREATMENTS = ('legendre', 'histogram') # Maximum Legendre order supported by OpenMC -MAX_LEGENDRE = 10 +_MAX_LEGENDRE = 10 @add_metaclass(ABCMeta) @@ -3478,7 +3478,7 @@ class ScatterMatrixXS(MatrixMGXS): cv.check_type('legendre_order', legendre_order, Integral) cv.check_greater_than('legendre_order', legendre_order, 0, equality=True) - cv.check_less_than('legendre_order', legendre_order, MAX_LEGENDRE, + cv.check_less_than('legendre_order', legendre_order, _MAX_LEGENDRE, equality=True) if self.scatter_format == 'legendre': diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 70ff7a91b..10fda4593 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -71,50 +71,50 @@ class XSdata(object): Number of equal width angular bins that the polar angular domain is subdivided into. This only applies when :attr:`XSdata.representation` is "angle". - total : dict of numpy.ndarray + total : list of numpy.ndarray Group-wise total cross section. - absorption : dict of numpy.ndarray + absorption : list of numpy.ndarray Group-wise absorption cross section. - scatter_matrix : dict of numpy.ndarray + scatter_matrix : list of numpy.ndarray Scattering moment matrices presented with the columns representing incoming group and rows representing the outgoing group. That is, down-scatter will be above the diagonal of the resultant matrix. - multiplicity_matrix : dict of numpy.ndarray + multiplicity_matrix : list of numpy.ndarray Ratio of neutrons produced in scattering collisions to the neutrons which undergo scattering collisions; that is, the multiplicity provides the code with a scaling factor to account for neutrons produced in (n,xn) reactions. - fission : dict of numpy.ndarray + fission : list of numpy.ndarray Group-wise fission cross section. - kappa_fission : dict of numpy.ndarray + kappa_fission : list of numpy.ndarray Group-wise kappa_fission cross section. - chi : dict of numpy.ndarray + chi : list of numpy.ndarray Group-wise fission spectra ordered by increasing group index (i.e., fast to thermal). This attribute should be used if making the common 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 :attr:`XSdata.nu_fission` attribute instead. - chi_prompt : dict of numpy.ndarray + chi_prompt : list 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 + chi_delayed : list 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 + nu_fission : list of numpy.ndarray Group-wise fission production cross section vector (i.e., if ``chi`` is provided), or is the group-wise fission production matrix. - prompt_nu_fission : dict of numpy.ndarray + prompt_nu_fission : list of numpy.ndarray Group-wise prompt fission production cross section vector. - delayed_nu_fission : dict of numpy.ndarray + delayed_nu_fission : list of numpy.ndarray Group-wise delayed fission production cross section vector. - beta : dict of numpy.ndarray + beta : list of numpy.ndarray Delayed-group-wise delayed neutron fraction cross section vector. - decay_rate : dict of numpy.ndarray + decay_rate : list of numpy.ndarray Delayed-group-wise decay rate vector. - inverse_velocity : dict of numpy.ndarray + inverse_velocity : list 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 @@ -360,13 +360,6 @@ class XSdata(object): check_greater_than('atomic_weight_ratio', atomic_weight_ratio, 0.0) self._atomic_weight_ratio = atomic_weight_ratio - @fissionable.setter - def fissionable(self, fissionable): - - # Check validity of type - check_type('fissionable', fissionable, bool) - self._fissionable = fissionable - @temperatures.setter def temperatures(self, temperatures):