Merge pull request #5 from nhorelik/python-api-dd-distrib

Distributed compositions, OTF file handling, and another DD parameters
This commit is contained in:
Will Boyd 2014-11-20 10:20:54 -05:00
commit 859d71e85e
2 changed files with 136 additions and 23 deletions

View file

@ -1,5 +1,7 @@
#!/usr/bin/env python
import warnings
import openmc
from openmc.checkvalue import *
from openmc.clean_xml import *
@ -57,6 +59,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 +218,29 @@ class Material(object):
self._sab.append((name, xs))
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)
raise ValueError(msg)
self._distrib_otf_file = name
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
def get_all_nuclides(self):
nuclides = dict()
@ -256,15 +287,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 +304,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 +350,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:

View file

@ -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
@ -74,6 +76,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
@ -278,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)
@ -711,6 +715,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 ' \
@ -727,6 +735,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)
@ -742,6 +754,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 ' \
@ -758,6 +774,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 ' \
@ -780,6 +800,18 @@ class SettingsFile(object):
self._dd_mesh_dimension = dimension
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)
raise ValueError(msg)
self._dd_allow_leakage = allow
def create_eigenvalue_subelement(self):
@ -1151,6 +1183,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):