mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 06:05:58 -04:00
Merge pull request #754 from nelsonag/function
Additions to openmc.data.Function1D and openmc.data.DataLibrary
This commit is contained in:
commit
13531aa35e
2 changed files with 168 additions and 0 deletions
|
|
@ -397,6 +397,67 @@ 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 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
|
||||
combinations of Combination objects. The operations parameter must have
|
||||
a length one less than the number of functions.
|
||||
|
||||
|
||||
Attributes
|
||||
----------
|
||||
functions : Iterable of Callable
|
||||
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
|
||||
combinations of Combination objects. The operations parameter must have
|
||||
a length one less than the number of functions.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, functions, operations):
|
||||
self.functions = functions
|
||||
self.operations = operations
|
||||
|
||||
def __call__(self, x):
|
||||
ans = self.functions[0](x)
|
||||
for i, operation in enumerate(self.operations):
|
||||
ans = operation(ans, self.functions[i + 1](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) - 1
|
||||
cv.check_length('operations', operations, length, length_max=length)
|
||||
self._operations = operations
|
||||
|
||||
|
||||
class Sum(EqualityMixin):
|
||||
"""Sum of multiple functions.
|
||||
|
||||
|
|
@ -432,6 +493,63 @@ class Sum(EqualityMixin):
|
|||
self._functions = functions
|
||||
|
||||
|
||||
class Regions1D(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 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
|
||||
----------
|
||||
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.
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,21 @@ class DataLibrary(EqualityMixin):
|
|||
def __init__(self):
|
||||
self.libraries = []
|
||||
|
||||
def get_by_material(self, value):
|
||||
"""Return the library dictionary containing a given material.
|
||||
|
||||
Returns
|
||||
-------
|
||||
library : dict or None
|
||||
Dictionary summarizing cross section data from a single file;
|
||||
the dictionary has keys 'path', 'type', and 'materials'.
|
||||
|
||||
"""
|
||||
for library in self.libraries:
|
||||
if value in library['materials']:
|
||||
return library
|
||||
return None
|
||||
|
||||
def register_file(self, filename):
|
||||
"""Register a file with the data library.
|
||||
|
||||
|
|
@ -78,3 +93,38 @@ 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.
|
||||
|
||||
Returns
|
||||
-------
|
||||
data : openmc.data.DataLibrary
|
||||
Data library object initialized from the provided XML
|
||||
|
||||
"""
|
||||
|
||||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue