from numbers import Integral
import lxml.etree as ET
import openmc.checkvalue as cv
from .mixin import EqualityMixin, IDManagerMixin
[docs]class TallyDerivative(EqualityMixin, IDManagerMixin):
"""A material perturbation derivative to apply to a tally.
Parameters
----------
derivative_id : int, optional
Unique identifier for the tally derivative. If none is specified, an
identifier will automatically be assigned
variable : str, optional
Accepted values are 'density', 'nuclide_density', and 'temperature'
material : int, optional
The perturbed material ID
nuclide : str, optional
The perturbed nuclide. Only needed for 'nuclide_density' derivatives.
Ex: 'Xe135'
Attributes
----------
id : int
Unique identifier for the tally derivative
variable : str
Accepted values are 'density', 'nuclide_density', and 'temperature'
material : int
The perturubed material ID
nuclide : str
The perturbed nuclide. Only needed for 'nuclide_density' derivatives.
Ex: 'Xe135'
"""
next_id = 1
used_ids = set()
def __init__(self, derivative_id=None, variable=None, material=None,
nuclide=None):
# Initialize Tally class attributes
self.id = derivative_id
self.variable = variable
self.material = material
self.nuclide = nuclide
def __repr__(self):
string = 'Tally Derivative\n'
string += '{: <16}=\t{}\n'.format('\tID', self.id)
string += '{: <16}=\t{}\n'.format('\tVariable', self.variable)
string += '{: <16}=\t{}\n'.format('\tMaterial', self.material)
if self.variable == 'nuclide_density':
string += '{: <16}=\t{}\n'.format('\tNuclide', self.nuclide)
return string
@property
def variable(self):
return self._variable
@property
def material(self):
return self._material
@property
def nuclide(self):
return self._nuclide
@variable.setter
def variable(self, var):
if var is not None:
cv.check_type('derivative variable', var, str)
cv.check_value('derivative variable', var,
('density', 'nuclide_density', 'temperature'))
self._variable = var
@material.setter
def material(self, mat):
if mat is not None:
cv.check_type('derivative material', mat, Integral)
self._material = mat
@nuclide.setter
def nuclide(self, nuc):
if nuc is not None:
cv.check_type('derivative nuclide', nuc, str)
self._nuclide = nuc
[docs] def to_xml_element(self):
"""Return XML representation of the tally derivative
Returns
-------
element : lxml.etree._Element
XML element containing derivative data
"""
element = ET.Element("derivative")
element.set("id", str(self.id))
element.set("variable", self.variable)
element.set("material", str(self.material))
if self.variable == 'nuclide_density':
element.set("nuclide", self.nuclide)
return element
[docs] @classmethod
def from_xml_element(cls, elem):
"""Generate tally derivative from an XML element
Parameters
----------
elem : lxml.etree._Element
XML element
Returns
-------
openmc.TallyDerivative
Tally derivative object
"""
derivative_id = int(elem.get("id"))
variable = elem.get("variable")
material = int(elem.get("material"))
nuclide = elem.get("nuclide") if variable == "nuclide_density" else None
return cls(derivative_id, variable, material, nuclide)