From fc39abeea5385f84ee5bcf28cd474d36ad44555b Mon Sep 17 00:00:00 2001 From: Nick Horelik Date: Tue, 18 Nov 2014 23:37:18 -0500 Subject: [PATCH 1/4] Added support for distributed compositions in materials --- src/utils/openmc/material.py | 109 ++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 22 deletions(-) diff --git a/src/utils/openmc/material.py b/src/utils/openmc/material.py index bb841fbe82..dc3611e5df 100644 --- a/src/utils/openmc/material.py +++ b/src/utils/openmc/material.py @@ -57,6 +57,12 @@ class Material(object): # If specified, a list of tuples of (table name, xs identifier) self._sab = list() + # If true, the material will be initialized as distributed + self._convert_to_distrib_comps = False + + # If specified, this file will be used instead of composition values + self._distrib_otf_file = None + # Set the Material class attributes self.set_id(material_id) self.set_name(name) @@ -210,6 +216,21 @@ class Material(object): self._sab.append((name, xs)) + def set_otf_mat_file(self, name): + + if not is_string(name): + msg = 'Unable to add OTF material file to Material ID={0} with a ' \ + 'non-string name {1}'.format(self._id, name) + raise ValueError(msg) + + self._distrib_otf_file = name + + + def set_as_distrib_comp(self): + + self._convert_to_distrib_comps = True + + def get_all_nuclides(self): nuclides = dict() @@ -256,15 +277,16 @@ class Material(object): return string - def get_nuclide_xml(self, nuclide): + def get_nuclide_xml(self, nuclide, distrib=False): xml_element = ET.Element("nuclide") xml_element.set("name", nuclide[0]._name) - if nuclide[2] is 'ao': - xml_element.set("ao", str(nuclide[1])) - else: - xml_element.set("wo", str(nuclide[1])) + if not distrib: + if nuclide[2] is 'ao': + xml_element.set("ao", str(nuclide[1])) + else: + xml_element.set("wo", str(nuclide[1])) if not nuclide[0]._xs is None: xml_element.set("xs", nuclide[0]._xs) @@ -272,35 +294,36 @@ class Material(object): return xml_element - def get_element_xml(self, element): + def get_element_xml(self, element, distrib=False): xml_element = ET.Element("element") xml_element.set("name", str(element[0]._name)) - if element[2] is 'ao': - xml_element.set("ao", str(element[1])) - else: - xml_element.set("wo", str(element[1])) + if not distrib: + if element[2] is 'ao': + xml_element.set("ao", str(element[1])) + else: + xml_element.set("wo", str(element[1])) return xml_element - def get_nuclides_xml(self, nuclides): + def get_nuclides_xml(self, nuclides, distrib=False): xml_elements = list() for nuclide in nuclides.values(): - xml_elements.append(self.get_nuclide_xml(nuclide)) + xml_elements.append(self.get_nuclide_xml(nuclide, distrib)) return xml_elements - def get_elements_xml(self, elements): + def get_elements_xml(self, elements, distrib=False): xml_elements = list() for element in elements.values(): - xml_elements.append(self.get_element_xml(element)) + xml_elements.append(self.get_element_xml(element, distrib)) return xml_elements @@ -317,15 +340,57 @@ class Material(object): subelement.set("value", str(self._density)) subelement.set("units", self._density_units) - # Create nuclide XML subelements - subelements = self.get_nuclides_xml(self._nuclides) - for subelement in subelements: - element.append(subelement) + if not self._convert_to_distrib_comps: - # Create element XML subelements - subelements = self.get_elements_xml(self._elements) - for subelement in subelements: - element.append(subelement) + # Create nuclide XML subelements + subelements = self.get_nuclides_xml(self._nuclides) + for subelement in subelements: + element.append(subelement) + + # Create element XML subelements + subelements = self.get_elements_xml(self._elements) + for subelement in subelements: + element.append(subelement) + + else: + + subelement = ET.SubElement(element, "compositions") + + comps = [] + allnucs = self._nuclides.values() + self._elements.values() + dist_per_type = allnucs[0][2] + for nuc, per, typ in allnucs: + if not typ == dist_per_type: + msg = 'All nuclides and elements in a distributed ' \ + 'material must have the same type, either ao or wo' + raise ValueError(msg) + comps.append(per) + + + if self._distrib_otf_file is None: + + # Create values and units subelements + subsubelement = ET.SubElement(subelement, "values") + subsubelement.text = ' '.join([str(c) for c in comps]) + subsubelement = ET.SubElement(subelement, "units") + subsubelement.text = dist_per_type + + else: + + # Specify the materials file + subsubelement = ET.SubElement(subelement, "otf_file_path") + subsubelement.text = self._distrib_otf_file + + + # Create nuclide XML subelements + subelements = self.get_nuclides_xml(self._nuclides, distrib=True) + for subelement_nuc in subelements: + subelement.append(subelement_nuc) + + # Create element XML subelements + subelements = self.get_elements_xml(self._elements, distrib=True) + for subelement_ele in subelements: + subelement.append(subelement_ele) if len(self._sab) > 0: for sab in self._sab: From 4ddfc23897088590039f11a49fd1c6dd1b60ea8a Mon Sep 17 00:00:00 2001 From: Nick Horelik Date: Wed, 19 Nov 2014 13:54:35 -0500 Subject: [PATCH 2/4] Added domain decomp allow_leakage flag to python api --- src/utils/openmc/settings.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/utils/openmc/settings.py b/src/utils/openmc/settings.py index 6e996dc46e..4d4e672c1a 100644 --- a/src/utils/openmc/settings.py +++ b/src/utils/openmc/settings.py @@ -74,6 +74,7 @@ class SettingsFile(object): self._dd_mesh_lower_left = None self._dd_mesh_upper_right = None self._dd_nodemap = None + self._dd_allow_leakage = False self._settings_file = ET.Element("settings") self._eigenvalue_element = None @@ -780,6 +781,14 @@ class SettingsFile(object): self._dd_mesh_dimension = dimension + def set_dd_allow_leakage(self, allow): + + if not type(allow) == bool: + msg = 'Unable to set DD allow_leakage {0} which is ' \ + 'not a Python bool'.format(dimension) + raise ValueError(msg) + + self._dd_allow_leakage = allow def create_eigenvalue_subelement(self): @@ -1151,6 +1160,12 @@ class SettingsFile(object): if not self._dd_nodemap is None: subelement = ET.SubElement(element, "nodemap") subsubelement.text = ' '.join([str(n) for n in self._dd_nodemap]) + + subelement = ET.SubElement(element, "allow_leakage") + if self._dd_allow_leakage: + subelement.text = 'true' + else: + subelement.text = 'false' def export_to_xml(self): From 5378a9d8bf054c055e1e941ed778b614a24b0ea6 Mon Sep 17 00:00:00 2001 From: Nick Horelik Date: Wed, 19 Nov 2014 14:50:07 -0500 Subject: [PATCH 3/4] Added warnings for features not in a release version of openmc --- src/utils/openmc/material.py | 10 ++++++++++ src/utils/openmc/settings.py | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/utils/openmc/material.py b/src/utils/openmc/material.py index dc3611e5df..7034feb6ea 100644 --- a/src/utils/openmc/material.py +++ b/src/utils/openmc/material.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +import warnings + import openmc from openmc.checkvalue import * from openmc.clean_xml import * @@ -218,6 +220,10 @@ class Material(object): def set_otf_mat_file(self, name): + # TODO: remove this when distributed materials are merged + warnings.warn('This feature is not yet implemented in a release ' \ + 'version of openmc') + if not is_string(name): msg = 'Unable to add OTF material file to Material ID={0} with a ' \ 'non-string name {1}'.format(self._id, name) @@ -228,6 +234,10 @@ class Material(object): def set_as_distrib_comp(self): + # TODO: remove this when distributed materials are merged + warnings.warn('This feature is not yet implemented in a release ' \ + 'version of openmc') + self._convert_to_distrib_comps = True diff --git a/src/utils/openmc/settings.py b/src/utils/openmc/settings.py index 4d4e672c1a..972c91ea4a 100644 --- a/src/utils/openmc/settings.py +++ b/src/utils/openmc/settings.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +import warnings + from openmc.checkvalue import * from openmc.clean_xml import * from xml.etree import ElementTree as ET @@ -712,6 +714,10 @@ class SettingsFile(object): def set_dd_mesh_dimension(self, dimension): + # TODO: remove this when domain decomposition is merged + warnings.warn('This feature is not yet implemented in a release ' \ + 'version of openmc') + if not isinstance(dimension, tuple) and \ not isinstance(dimension, list): msg = 'Unable to set DD mesh upper right corner to {0} which is ' \ @@ -728,6 +734,10 @@ class SettingsFile(object): def set_dd_mesh_lower_left(self, lower_left): + # TODO: remove this when domain decomposition is merged + warnings.warn('This feature is not yet implemented in a release ' \ + 'version of openmc') + if not isinstance(lower_left, (tuple, list, np.ndarray)): msg = 'Unable to set DD mesh lower left corner to {0} which is ' \ 'not a Python tuple or list'.format(lower_left) @@ -743,6 +753,10 @@ class SettingsFile(object): def set_dd_mesh_upper_right(self, upper_right): + # TODO: remove this when domain decomposition is merged + warnings.warn('This feature is not yet implemented in a release ' \ + 'version of openmc') + if not isinstance(upper_right, tuple) and \ not isinstance(upper_right, list): msg = 'Unable to set DD mesh upper right corner to {0} which is ' \ @@ -759,6 +773,10 @@ class SettingsFile(object): def set_dd_nodemap(self, nodemap): + # TODO: remove this when domain decomposition is merged + warnings.warn('This feature is not yet implemented in a release ' \ + 'version of openmc') + if not isinstance(nodemap, tuple) and \ not isinstance(nodemap, list): msg = 'Unable to set DD nodemap {0} which is ' \ @@ -783,6 +801,10 @@ class SettingsFile(object): def set_dd_allow_leakage(self, allow): + # TODO: remove this when domain decomposition is merged + warnings.warn('This feature is not yet implemented in a release ' \ + 'version of openmc') + if not type(allow) == bool: msg = 'Unable to set DD allow_leakage {0} which is ' \ 'not a Python bool'.format(dimension) From 6a03bc1b88e2dc333abb1443defe6ec5f00f6d85 Mon Sep 17 00:00:00 2001 From: Nick Horelik Date: Thu, 20 Nov 2014 10:07:41 -0500 Subject: [PATCH 4/4] Added distribmats flag to output setting --- src/utils/openmc/settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/openmc/settings.py b/src/utils/openmc/settings.py index 972c91ea4a..6acb720cbe 100644 --- a/src/utils/openmc/settings.py +++ b/src/utils/openmc/settings.py @@ -281,7 +281,8 @@ class SettingsFile(object): for element in output: - if not element in ['summary', 'cross_sections', 'tallies']: + keys = ['summary', 'cross_sections', 'tallies', 'distribmats'] + if not element in keys: msg = 'Unable to set output to {0} which is unsupported by ' \ 'OpenMC'.format(element) raise ValueError(msg)