diff --git a/openmc/__init__.py b/openmc/__init__.py index a0492ee40..2aeacd689 100644 --- a/openmc/__init__.py +++ b/openmc/__init__.py @@ -22,6 +22,7 @@ from openmc.executor import * from openmc.statepoint import * from openmc.summary import * from openmc.particle_restart import * +from openmc.mixin import * try: from openmc.opencg_compatible import * diff --git a/openmc/data/ace.py b/openmc/data/ace.py index 4085b4222..831e40fc8 100644 --- a/openmc/data/ace.py +++ b/openmc/data/ace.py @@ -22,6 +22,8 @@ import sys import numpy as np +from openmc.mixin import EqualityMixin + if sys.version_info[0] >= 3: basestring = str @@ -131,7 +133,7 @@ def get_table(filename, name=None): .format(name)) -class Library(object): +class Library(EqualityMixin): """A Library objects represents an ACE-formatted file which may contain multiple tables with data. @@ -353,7 +355,7 @@ class Library(object): lines = [ace_file.readline() for i in range(13)] -class Table(object): +class Table(EqualityMixin): """ACE cross section table Parameters diff --git a/openmc/data/angle_distribution.py b/openmc/data/angle_distribution.py index 316559c50..80b6cdbdb 100644 --- a/openmc/data/angle_distribution.py +++ b/openmc/data/angle_distribution.py @@ -4,11 +4,12 @@ from numbers import Real import numpy as np import openmc.checkvalue as cv +from openmc.mixin import EqualityMixin from openmc.stats import Univariate, Tabular, Uniform from .function import INTERPOLATION_SCHEME -class AngleDistribution(object): +class AngleDistribution(EqualityMixin): """Angle distribution as a function of incoming energy Parameters diff --git a/openmc/data/angle_energy.py b/openmc/data/angle_energy.py index 00e049ebc..4a5e391e3 100644 --- a/openmc/data/angle_energy.py +++ b/openmc/data/angle_energy.py @@ -1,9 +1,10 @@ from abc import ABCMeta, abstractmethod import openmc.data +from openmc.mixin import EqualityMixin -class AngleEnergy(object): +class AngleEnergy(EqualityMixin): """Distribution in angle and energy of a secondary particle.""" __metaclass = ABCMeta diff --git a/openmc/data/correlated.py b/openmc/data/correlated.py index 97a96c17c..d6ce8ab47 100644 --- a/openmc/data/correlated.py +++ b/openmc/data/correlated.py @@ -56,6 +56,7 @@ class CorrelatedAngleEnergy(AngleEnergy): @property def interpolation(self): return self._interpolation + @property def energy(self): return self._energy diff --git a/openmc/data/energy_distribution.py b/openmc/data/energy_distribution.py index 2300081c1..a16090635 100644 --- a/openmc/data/energy_distribution.py +++ b/openmc/data/energy_distribution.py @@ -8,9 +8,10 @@ import numpy as np from .function import Tabulated1D, INTERPOLATION_SCHEME from openmc.stats.univariate import Univariate, Tabular, Discrete, Mixture import openmc.checkvalue as cv +from openmc.mixin import EqualityMixin -class EnergyDistribution(object): +class EnergyDistribution(EqualityMixin): """Abstract superclass for all energy distributions.""" __metaclass__ = ABCMeta diff --git a/openmc/data/fission_energy.py b/openmc/data/fission_energy.py index 03d3ed84e..6352915cc 100644 --- a/openmc/data/fission_energy.py +++ b/openmc/data/fission_energy.py @@ -9,6 +9,7 @@ from .data import ATOMIC_SYMBOL from .endf_utils import read_float, read_CONT_line, identify_nuclide from .function import Function1D, Tabulated1D, Polynomial, Sum import openmc.checkvalue as cv +from openmc.mixin import EqualityMixin if sys.version_info[0] >= 3: basestring = str @@ -189,7 +190,7 @@ def write_compact_458_library(endf_files, output_name='fission_Q_data.h5', out.close() -class FissionEnergyRelease(object): +class FissionEnergyRelease(EqualityMixin): """Energy relased by fission reactions. Energy is carried away from fission reactions by many different particles. @@ -560,7 +561,7 @@ class FissionEnergyRelease(object): self.delayed_photons.to_hdf5(group, 'delayed_photons') self.betas.to_hdf5(group, 'betas') self.neutrinos.to_hdf5(group, 'neutrinos') - + if isinstance(self.prompt_neutrons, Polynomial): # Add the polynomials for the relevant components together. Use a # Polynomial((0.0, -1.0)) to subtract incident energy. diff --git a/openmc/data/function.py b/openmc/data/function.py index a7397e785..94a2f0911 100644 --- a/openmc/data/function.py +++ b/openmc/data/function.py @@ -5,12 +5,13 @@ from numbers import Real, Integral import numpy as np import openmc.checkvalue as cv +from openmc.mixin import EqualityMixin INTERPOLATION_SCHEME = {1: 'histogram', 2: 'linear-linear', 3: 'linear-log', 4: 'log-linear', 5: 'log-log'} -class Function1D(object): +class Function1D(EqualityMixin): """A function of one independent variable with HDF5 support.""" __metaclass__ = ABCMeta @@ -389,7 +390,7 @@ class Polynomial(np.polynomial.Polynomial, Function1D): return cls(dataset.value) -class Sum(object): +class Sum(EqualityMixin): """Sum of multiple functions. This class allows you to create a callable object which represents the sum diff --git a/openmc/data/library.py b/openmc/data/library.py index dba5eabc1..49d1c78f6 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -3,9 +3,11 @@ import xml.etree.ElementTree as ET import h5py +from openmc.mixin import EqualityMixin from openmc.clean_xml import clean_xml_indentation -class DataLibrary(object): + +class DataLibrary(EqualityMixin): def __init__(self): self.libraries = [] diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index 95f840d64..c6621e1b8 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -15,12 +15,13 @@ from .product import Product from .reaction import Reaction, _get_photon_products from .urr import ProbabilityTables import openmc.checkvalue as cv +from openmc.mixin import EqualityMixin if sys.version_info[0] >= 3: basestring = str -class IncidentNeutron(object): +class IncidentNeutron(EqualityMixin): """Continuous-energy neutron interaction data. Instances of this class are not normally instantiated by the user but rather diff --git a/openmc/data/product.py b/openmc/data/product.py index eec47c956..753888f6d 100644 --- a/openmc/data/product.py +++ b/openmc/data/product.py @@ -5,6 +5,7 @@ import sys import numpy as np import openmc.checkvalue as cv +from openmc.mixin import EqualityMixin from .function import Tabulated1D, Polynomial, Function1D from .angle_energy import AngleEnergy @@ -12,7 +13,7 @@ if sys.version_info[0] >= 3: basestring = str -class Product(object): +class Product(EqualityMixin): """Secondary particle emitted in a nuclear reaction Parameters diff --git a/openmc/data/reaction.py b/openmc/data/reaction.py index d35599579..e7580ec47 100644 --- a/openmc/data/reaction.py +++ b/openmc/data/reaction.py @@ -7,6 +7,7 @@ from warnings import warn import numpy as np import openmc.checkvalue as cv +from openmc.mixin import EqualityMixin from openmc.stats import Uniform from .angle_distribution import AngleDistribution from .angle_energy import AngleEnergy @@ -250,7 +251,7 @@ def _get_photon_products(ace, rx): return photons -class Reaction(object): +class Reaction(EqualityMixin): """A nuclear reaction A Reaction object represents a single reaction channel for a nuclide with diff --git a/openmc/data/thermal.py b/openmc/data/thermal.py index be35da517..1551e8ac5 100644 --- a/openmc/data/thermal.py +++ b/openmc/data/thermal.py @@ -7,6 +7,7 @@ import numpy as np import h5py import openmc.checkvalue as cv +from openmc.mixin import EqualityMixin from .ace import Table, get_table from .angle_energy import AngleEnergy from .function import Tabulated1D @@ -61,7 +62,7 @@ def get_thermal_name(name): return 'c_' + name -class CoherentElastic(object): +class CoherentElastic(EqualityMixin): r"""Coherent elastic scattering data from a crystalline material Parameters @@ -90,6 +91,7 @@ class CoherentElastic(object): idx = np.searchsorted(self.bragg_edges, E) return self.factors[idx]/E + def __len__(self): return len(self.bragg_edges) @@ -147,7 +149,7 @@ class CoherentElastic(object): return cls(bragg_edges, factors) -class ThermalScattering(object): +class ThermalScattering(EqualityMixin): """A ThermalScattering object contains thermal scattering data as represented by an S(alpha, beta) table. @@ -237,13 +239,15 @@ class ThermalScattering(object): self.inelastic_dist.to_hdf5(inelastic_group) @classmethod - def from_hdf5(cls, group): + def from_hdf5(cls, group_or_filename): """Generate thermal scattering data from HDF5 group Parameters ---------- - group : h5py.Group - HDF5 group to read from + group_or_filename : h5py.Group or str + HDF5 group containing interaction data. If given as a string, it is + assumed to be the filename for the HDF5 file, and the first group + is used to read from. Returns ------- @@ -251,6 +255,12 @@ class ThermalScattering(object): Neutron thermal scattering data """ + if isinstance(group_or_filename, h5py.Group): + group = group_or_filename + else: + h5file = h5py.File(group_or_filename, 'r') + group = list(h5file.values())[0] + name = group.name[1:] atomic_weight_ratio = group.attrs['atomic_weight_ratio'] temperature = group.attrs['temperature'] diff --git a/openmc/data/urr.py b/openmc/data/urr.py index 052da6612..05f64e578 100644 --- a/openmc/data/urr.py +++ b/openmc/data/urr.py @@ -4,9 +4,10 @@ from numbers import Integral, Real import numpy as np import openmc.checkvalue as cv +from openmc.mixin import EqualityMixin -class ProbabilityTables(object): +class ProbabilityTables(EqualityMixin): r"""Unresolved resonance region probability tables. Parameters diff --git a/openmc/mixin.py b/openmc/mixin.py new file mode 100644 index 000000000..dd97e8924 --- /dev/null +++ b/openmc/mixin.py @@ -0,0 +1,20 @@ +import numpy as np + + +class EqualityMixin(object): + """A Class which provides generic __eq__ and __ne__ functionality which + can easily be inherited by downstream classes. + """ + + def __eq__(self, other): + if isinstance(other, type(self)): + for key, value in self.__dict__.items(): + if not np.array_equal(value, other.__dict__.get(key)): + return False + else: + return False + + return True + + def __ne__(self, other): + return not self.__eq__(other) diff --git a/openmc/stats/univariate.py b/openmc/stats/univariate.py index 3fdd5e4a2..ce0f0fae1 100644 --- a/openmc/stats/univariate.py +++ b/openmc/stats/univariate.py @@ -7,6 +7,7 @@ from xml.etree import ElementTree as ET import numpy as np import openmc.checkvalue as cv +from openmc.mixin import EqualityMixin if sys.version_info[0] >= 3: basestring = str @@ -15,7 +16,7 @@ _INTERPOLATION_SCHEMES = ['histogram', 'linear-linear', 'linear-log', 'log-linear', 'log-log'] -class Univariate(object): +class Univariate(EqualityMixin): """Probability distribution of a single random variable. The Univariate class is an abstract class that can be derived to implement a