From 11040fb5f94cee76f551ef3681e0d2839c6d450a Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 7 Nov 2016 18:59:50 -0500 Subject: [PATCH 1/6] Added piecewise and combination functions --- openmc/data/function.py | 113 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/openmc/data/function.py b/openmc/data/function.py index e9ecf82c58..e87f0a9c42 100644 --- a/openmc/data/function.py +++ b/openmc/data/function.py @@ -397,6 +397,62 @@ 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 series of user-defined + operators connecting each of the callable objects. + + 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. @@ -432,6 +488,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 multiple other callable objects, each applying to a specific interval + + 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 intervals. + + 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. From fb512fb1ef1aee744b778c2247ba817f254d674e Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Mon, 7 Nov 2016 19:01:35 -0500 Subject: [PATCH 2/6] Added DataLibrary from_xml function --- openmc/data/library.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/openmc/data/library.py b/openmc/data/library.py index 0485af0641..3e01c24643 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 From cdae8f70f76f49c90792927170d11e2abd339010 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 8 Nov 2016 18:45:17 -0500 Subject: [PATCH 3/6] resolved @paulromano comments --- openmc/data/function.py | 12 ++++++------ openmc/data/library.py | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/openmc/data/function.py b/openmc/data/function.py index e87f0a9c42..4a1f9d7a38 100644 --- a/openmc/data/function.py +++ b/openmc/data/function.py @@ -428,8 +428,8 @@ class Combination(EqualityMixin): def __call__(self, x): ans = np.zeros_like(x) - for i, operation in enumerate(self.operations): - ans = operation(ans, self.functions[i](x)) + for op, func in zip(self.operations, self.functions): + ans = op(ans, func(x)) return ans @property @@ -488,7 +488,7 @@ class Sum(EqualityMixin): self._functions = functions -class Piecewise(EqualityMixin): +class Regions1D(EqualityMixin): """Piecewise composition of multiple functions. This class allows you to create a callable object which is composed @@ -499,9 +499,9 @@ class Piecewise(EqualityMixin): 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 intervals. + The values of the dependent variable that define the domain of + each function. The *i*th and *(i+1)*th values are the limits of the + domain of the *i*th function. Values must be monotonically increasing. Attributes ---------- diff --git a/openmc/data/library.py b/openmc/data/library.py index 3e01c24643..0363de4fc5 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -22,9 +22,19 @@ class DataLibrary(EqualityMixin): def __init__(self): self.libraries = [] - def __getitem__(self, material): + def get_by_materials(self, value): + """Access a library entry by passing a value of the 'materials' + attribute of the library entry. + + Returns + ------- + library : dict + Dictionary summarizing cross section data from a single file; + the dictionary has keys 'path', 'type', and 'materials'. + + """ for library in self.libraries: - if material in library['materials']: + if value in library['materials']: return library return None @@ -94,6 +104,11 @@ class DataLibrary(EqualityMixin): path : str Path to XML file to read. + Returns + ------- + data : openmc.data.DataLibrary + openmc.data.DataLibrary object initialized from the provided XML + """ data = cls() From deb4de90a25928ff59985e12f5006dc172708dbf Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 8 Nov 2016 18:52:39 -0500 Subject: [PATCH 4/6] Whoops, missed one --- openmc/data/function.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openmc/data/function.py b/openmc/data/function.py index 4a1f9d7a38..b1cdb09de0 100644 --- a/openmc/data/function.py +++ b/openmc/data/function.py @@ -427,9 +427,9 @@ class Combination(EqualityMixin): self.operations = operations def __call__(self, x): - ans = np.zeros_like(x) - for op, func in zip(self.operations, self.functions): - ans = op(ans, func(x)) + ans = self.functions[0](x) + for i, operation in enumerate(self.operations): + ans = operation(ans, self.functions[i + 1](x)) return ans @property @@ -448,7 +448,7 @@ class Combination(EqualityMixin): @operations.setter def operations(self, operations): cv.check_type('operations', operations, Iterable, np.ufunc) - length = len(self.functions) + length = len(self.functions) - 1 cv.check_length('operations', operations, length, length_max=length) self._operations = operations From ac8909fa29ad8507ef99dcca38a22eea91422426 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 8 Nov 2016 20:15:19 -0500 Subject: [PATCH 5/6] minor comment change --- openmc/data/function.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openmc/data/function.py b/openmc/data/function.py index b1cdb09de0..c8fa15b768 100644 --- a/openmc/data/function.py +++ b/openmc/data/function.py @@ -410,7 +410,9 @@ 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 will not be followed, but can be simulated by + combinations of Combination objects. The operations parameter must have + a length one less than the number of functions. Attributes From 93597752f27d3b4e0255b911fe6e8423ceb54957 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Wed, 9 Nov 2016 18:19:13 -0500 Subject: [PATCH 6/6] Resolved @paulromano comments --- openmc/data/function.py | 9 ++++++--- openmc/data/library.py | 9 ++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/openmc/data/function.py b/openmc/data/function.py index c8fa15b768..0515a57c0c 100644 --- a/openmc/data/function.py +++ b/openmc/data/function.py @@ -407,7 +407,7 @@ class Combination(EqualityMixin): Parameters ---------- functions : Iterable of Callable - Functions which are to be added together + Functions to combine according to operations operations : Iterable of numpy.ufunc Operations to perform between functions; note that the standard order of operations will not be followed, but can be simulated by @@ -418,9 +418,12 @@ class Combination(EqualityMixin): Attributes ---------- functions : Iterable of Callable - Functions which are to be added together + Functions to combine according to operations operations : Iterable of numpy.ufunc - Operations to perform between functions + Operations to perform between functions; note that the standard order + of operations will not be followed, but can be simulated by + combinations of Combination objects. The operations parameter must have + a length one less than the number of functions. """ diff --git a/openmc/data/library.py b/openmc/data/library.py index 0363de4fc5..9f6d931467 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -22,13 +22,12 @@ class DataLibrary(EqualityMixin): def __init__(self): self.libraries = [] - def get_by_materials(self, value): - """Access a library entry by passing a value of the 'materials' - attribute of the library entry. + def get_by_material(self, value): + """Return the library dictionary containing a given material. Returns ------- - library : dict + library : dict or None Dictionary summarizing cross section data from a single file; the dictionary has keys 'path', 'type', and 'materials'. @@ -107,7 +106,7 @@ class DataLibrary(EqualityMixin): Returns ------- data : openmc.data.DataLibrary - openmc.data.DataLibrary object initialized from the provided XML + Data library object initialized from the provided XML """