diff --git a/openmc/settings.py b/openmc/settings.py index 1ae1597024..18d1fa4d9a 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -1247,6 +1247,12 @@ class Settings: for elem in root.findall('source'): self.source.append(Source.from_xml_element(elem)) + def _volume_calcs_from_xml_element(self, root): + volume_elems = root.findall("volume_calc") + if volume_elems: + self.volume_calculations = [VolumeCalculation.from_xml_element(elem) + for elem in volume_elems] + def _output_from_xml_element(self, root): elem = root.find('output') if elem is not None: @@ -1585,6 +1591,7 @@ class Settings: settings._generations_per_batch_from_xml_element(root) settings._keff_trigger_from_xml_element(root) settings._source_from_xml_element(root) + settings._volume_calcs_from_xml_element(root) settings._output_from_xml_element(root) settings._statepoint_from_xml_element(root) settings._sourcepoint_from_xml_element(root) diff --git a/openmc/volume.py b/openmc/volume.py index 9acf58ca3b..67f4b7abe5 100644 --- a/openmc/volume.py +++ b/openmc/volume.py @@ -11,6 +11,7 @@ from uncertainties import ufloat import openmc import openmc.checkvalue as cv +from openmc._xml import get_text _VERSION_VOLUME = 1 @@ -352,3 +353,49 @@ class VolumeCalculation: trigger_elem.set("type", self.trigger_type) trigger_elem.set("threshold", str(self.threshold)) return element + + @classmethod + def from_xml_element(cls, elem): + """Generate volume calculation object from an XML element + + Parameters + ---------- + elem : xml.etree.ElementTree.Element + XML element + + Returns + ------- + openmc.VolumeCalculation + Volume calculation object + + """ + domain_type = get_text(elem, "domain_type") + domain_ids = get_text(elem, "domain_ids").split() + ids = [int(x) for x in domain_ids] + samples = int(get_text(elem, "samples")) + lower_left = get_text(elem, "lower_left").split() + lower_left = tuple([float(x) for x in lower_left]) + upper_right = get_text(elem, "upper_right").split() + upper_right = tuple([float(x) for x in upper_right]) + + # Instantiate some throw-away domains that are used by the constructor + # to assign IDs + with warnings.catch_warnings(): + warnings.simplefilter('ignore', openmc.IDWarning) + if domain_type == 'cell': + domains = [openmc.Cell(uid) for uid in ids] + elif domain_type == 'material': + domains = [openmc.Material(uid) for uid in ids] + elif domain_type == 'universe': + domains = [openmc.Universe(uid) for uid in ids] + + vol = cls(domains, samples, lower_left, upper_right) + + # Check for trigger + trigger_elem = elem.find("threshold") + if trigger_elem is not None: + trigger_type = get_text(trigger_elem, "type") + threshold = float(get_text(trigger_elem, "threshold")) + vol.set_trigger(threshold, trigger_type) + + return vol diff --git a/tests/unit_tests/test_settings.py b/tests/unit_tests/test_settings.py index 832dc93989..e2c7259e75 100644 --- a/tests/unit_tests/test_settings.py +++ b/tests/unit_tests/test_settings.py @@ -112,3 +112,10 @@ def test_export_to_xml(run_in_tmpdir): assert not s.photon_transport assert s.electron_treatment == 'led' assert s.write_initial_source == True + assert len(s.volume_calculations) == 1 + vol = s.volume_calculations[0] + assert vol.domain_type == 'cell' + assert len(vol.ids) == 1 + assert vol.samples == 1000 + assert vol.lower_left == (-10., -10., -10.) + assert vol.upper_right == (10., 10., 10.)