Updated pyapi and docs to support new default_temperature/temperature and lack of default_xs/xs

This commit is contained in:
Adam Nelson 2016-08-21 14:36:58 -04:00
parent 2f8afd291b
commit dfe2420b4a
7 changed files with 93 additions and 122 deletions

View file

@ -1295,6 +1295,13 @@ Each ``material`` element can have the following attributes or sub-elements:
*Default*: ""
:temperature:
An element with no attributes which is used to set the temperature of the
material. This element accepts a maximum 6-character string that indicates
the default temperature rounded to the nearest integer in units of Kelvin,
e.g. "294K".
:density:
An element with attributes/sub-elements called ``value`` and ``units``. The
``value`` attribute is the numeric value of the density while the ``units``
@ -1315,17 +1322,16 @@ Each ``material`` element can have the following attributes or sub-elements:
``nuclide``, ``element``, or ``sab`` quantity.
:nuclide:
An element with attributes/sub-elements called ``name``, ``xs``, and ``ao``
An element with attributes/sub-elements called ``name``, and ``ao``
or ``wo``. The ``name`` attribute is the name of the cross-section for a
desired nuclide while the ``xs`` attribute is the cross-section
identifier. Finally, the ``ao`` and ``wo`` attributes specify the atom or
desired nuclide. Finally, the ``ao`` and ``wo`` attributes specify the atom or
weight percent of that nuclide within the material, respectively. One
example would be as follows:
.. code-block:: xml
<nuclide name="H-1" xs="70c" ao="2.0" />
<nuclide name="O-16" xs="70c" ao="1.0" />
<nuclide name="H1" ao="2.0" />
<nuclide name="O16" ao="1.0" />
.. note:: If one nuclide is specified in atom percent, all others must also
be given in atom percent. The same applies for weight percentages.
@ -1349,11 +1355,10 @@ Each ``material`` element can have the following attributes or sub-elements:
Specifies that a natural element is present in the material. The natural
element is split up into individual isotopes based on `IUPAC Isotopic
Compositions of the Elements 2009`_. This element has
attributes/sub-elements called ``name``, ``xs``, and ``ao``. The ``name``
attribute is the atomic symbol of the element while the ``xs`` attribute is
the cross-section identifier. Finally, the ``ao`` attribute specifies the
atom percent of the element within the material, respectively. One example
would be as follows:
attributes/sub-elements called ``name``, and ``ao``. The ``name``
attribute is the atomic symbol of the element. Finally, the ``ao``
attribute specifies the atom percent of the element within the material,
respectively. One example would be as follows:
.. code-block:: xml
@ -1383,10 +1388,9 @@ Each ``material`` element can have the following attributes or sub-elements:
multi-group :ref:`energy_mode`.
:sab:
Associates an S(a,b) table with the material. This element has
attributes/sub-elements called ``name`` and ``xs``. The ``name`` attribute
is the name of the S(a,b) table that should be associated with the material,
and ``xs`` is the cross-section identifier for the table.
Associates an S(a,b) table with the material. This element has one
attribute/sub-element called ``name``. The ``name`` attribute
is the name of the S(a,b) table that should be associated with the material.
*Default*: None
@ -1397,14 +1401,13 @@ Each ``material`` element can have the following attributes or sub-elements:
recognizes that some multi-group libraries may be providing material
specific macroscopic cross sections instead of always providing nuclide
specific data like in the continuous-energy case. To that end, the
macroscopic element has attributes/sub-elements called ``name``, and ``xs``.
macroscopic element has one attribute/sub-element called ``name``.
The ``name`` attribute is the name of the cross-section for a
desired nuclide while the ``xs`` attribute is the cross-section
identifier. One example would be as follows:
desired nuclide. One example would be as follows:
.. code-block:: xml
<macroscopic name="UO2" xs="71c" />
<macroscopic name="UO2" />
.. note:: This element is only used in the multi-group :ref:`energy_mode`.
@ -1413,15 +1416,16 @@ Each ``material`` element can have the following attributes or sub-elements:
.. _IUPAC Isotopic Compositions of the Elements 2009:
http://pac.iupac.org/publications/pac/pdf/2011/pdf/8302x0397.pdf
``<default_xs>`` Element
``<default_temperature>`` Element
------------------------
In some circumstances, the cross-section identifier may be the same for many or
all nuclides in a given problem. In this case, rather than specifying the
``xs=...`` attribute on every nuclide, a ``<default_xs>`` element can be used to
set the default cross-section identifier for any nuclide without an identifier
explicitly listed. This element has no attributes and accepts a 3-letter string
that indicates the default cross-section identifier, e.g. "70c".
In some circumstances, the temperature may be the same for many or
all materials in a given problem. In this case, rather than specifying the
``<temperature>`` element on every material, a ``<default_temperature>``
element can be used to set the default material temperature for any material
without an explicitly provided temperature. This element has no attributes and
accepts a maximum 6-character string that indicates the default temperature
rounded to the nearest integer in units of Kelvin, e.g. "294K".
*Default*: None

View file

@ -25,7 +25,7 @@ moderator = openmc.Material(material_id=41, name='moderator')
moderator.set_density('g/cc', 1.0)
moderator.add_nuclide(h1, 2.)
moderator.add_nuclide(o16, 1.)
moderator.add_s_alpha_beta('c_H_in_H2O', '71t')
moderator.add_s_alpha_beta('c_H_in_H2O')
fuel = openmc.Material(material_id=40, name='fuel')
fuel.set_density('g/cc', 4.5)
@ -33,7 +33,7 @@ fuel.add_nuclide(u235, 1.)
# Instantiate a Materials collection and export to XML
materials_file = openmc.Materials([moderator, fuel])
materials_file.default_xs = '71c'
materials_file.default_temperature = '294K'
materials_file.export_to_xml()

View file

@ -19,38 +19,28 @@ class Element(object):
----------
name : str
Chemical symbol of the element, e.g. Pu
xs : str
Cross section identifier, e.g. 71c
Attributes
----------
name : str
Chemical symbol of the element, e.g. Pu
xs : str
Cross section identifier, e.g. 71c
scattering : {'data', 'iso-in-lab', None}
The type of angular scattering distribution to use
"""
def __init__(self, name='', xs=None):
def __init__(self, name=''):
# Initialize class attributes
self._name = ''
self._xs = None
self._scattering = None
# Set class attributes
self.name = name
if xs is not None:
self.xs = xs
def __eq__(self, other):
if isinstance(other, Element):
if self.name != other.name:
return False
elif self.xs != other.xs:
return False
else:
return True
elif isinstance(other, basestring) and other == self.name:
@ -72,17 +62,12 @@ class Element(object):
def __repr__(self):
string = 'Element - {0}\n'.format(self._name)
string += '{0: <16}{1}{2}\n'.format('\tXS', '=\t', self._xs)
if self.scattering is not None:
string += '{0: <16}{1}{2}\n'.format('\tscattering', '=\t',
self.scattering)
return string
@property
def xs(self):
return self._xs
@property
def name(self):
return self._name
@ -91,11 +76,6 @@ class Element(object):
def scattering(self):
return self._scattering
@xs.setter
def xs(self, xs):
check_type('cross section identifier', xs, basestring)
self._xs = xs
@name.setter
def name(self, name):
check_type('element name', name, basestring)
@ -127,6 +107,6 @@ class Element(object):
isotopes = []
for isotope, abundance in sorted(NATURAL_ABUNDANCE.items()):
if re.match(r'{}\d+'.format(self.name), isotope):
nuc = openmc.Nuclide(isotope, self.xs)
nuc = openmc.Nuclide(isotope)
isotopes.append((nuc, abundance))
return isotopes

View file

@ -13,29 +13,21 @@ class Macroscopic(object):
----------
name : str
Name of the macroscopic data, e.g. UO2
xs : str
Cross section identifier, e.g. 71c
Attributes
----------
name : str
Name of the nuclide, e.g. UO2
xs : str
Cross section identifier, e.g. 71c
"""
def __init__(self, name='', xs=None):
def __init__(self, name=''):
# Initialize class attributes
self._name = ''
self._xs = None
# Set the Macroscopic class attributes
self.name = name
if xs is not None:
self.xs = xs
def __eq__(self, other):
if isinstance(other, Macroscopic):
if self.name != other.name:
@ -57,23 +49,13 @@ class Macroscopic(object):
def __repr__(self):
string = 'Nuclide - {0}\n'.format(self._name)
string += '{0: <16}{1}{2}\n'.format('\tXS', '=\t', self._xs)
return string
@property
def name(self):
return self._name
@property
def xs(self):
return self._xs
@name.setter
def name(self, name):
check_type('name', name, basestring)
self._name = name
@xs.setter
def xs(self, xs):
check_type('cross-section identifier', xs, basestring)
self._xs = xs

View file

@ -41,11 +41,19 @@ class Material(object):
name : str, optional
Name of the material. If not specified, the name will be the empty
string.
temperature : str, optional
The temperature identifier applied to this material. The units are
in Kelvin and the temperature rounded to the nearest integer.
For example, a tempreature of 293.6K would be provided as '294K'
Attributes
----------
id : int
Unique identifier for the material
temperature : str
The temperature identifier applied to this material. The units are
in Kelvin and the temperature rounded to the nearest integer.
For example, a tempreature of 293.6K would be provided as '294K'
density : float
Density of the material (units defined separately)
density_units : str
@ -63,10 +71,11 @@ class Material(object):
"""
def __init__(self, material_id=None, name=''):
def __init__(self, material_id=None, name='', temperature=None):
# Initialize class attributes
self.id = material_id
self.name = name
self.temperature = temperature
self._density = None
self._density_units = ''
@ -133,7 +142,7 @@ class Material(object):
string += '{0: <16}\n'.format('\tNuclides')
for nuclide, percent, percent_type in self._nuclides:
string += '{0: <16}'.format('\t{0.name}.{0.xs}'.format(nuclide))
string += '{0: <16}'.format('\t{0.name}'.format(nuclide))
string += '=\t{0: <12} [{1}]\n'.format(percent, percent_type)
if self._macroscopic is not None:
@ -143,7 +152,7 @@ class Material(object):
string += '{0: <16}\n'.format('\tElements')
for element, percent, percent_type in self._elements:
string += '{0: <16}'.format('\t{0.name}.{0.xs}'.format(element))
string += '{0: <16}'.format('\t{0.name}'.format(element))
string += '=\t{0: <12} [{1}]\n'.format(percent, percent_type)
return string
@ -156,6 +165,10 @@ class Material(object):
def name(self):
return self._name
@property
def temperature(self):
return self._temperature
@property
def density(self):
return self._density
@ -201,6 +214,15 @@ class Material(object):
else:
self._name = ''
@temperature.setter
def temperature(self, temperature):
if temperature is not None:
cv.check_type('Temperature for Material ID="{0}"'.format(self._id),
temperature, basestring)
self._temperature = temperature
else:
self._temperature = ''
def set_density(self, units, density=None):
"""Set the density of the material
@ -458,15 +480,13 @@ class Material(object):
if element == elm:
self._nuclides.remove(elm)
def add_s_alpha_beta(self, name, xs):
def add_s_alpha_beta(self, name):
r"""Add an :math:`S(\alpha,\beta)` table to the material
Parameters
----------
name : str
Name of the :math:`S(\alpha,\beta)` table
xs : str
Cross section identifier, e.g. '71t'
"""
@ -480,18 +500,14 @@ class Material(object):
'non-string table name "{1}"'.format(self._id, name)
raise ValueError(msg)
if not isinstance(xs, basestring):
msg = 'Unable to add an S(a,b) table to Material ID="{0}" with a ' \
'non-string cross-section identifier "{1}"'.format(self._id, xs)
raise ValueError(msg)
new_name = openmc.data.get_thermal_name(name)
if new_name != name:
msg = 'OpenMC S(a,b) tables follow the GND naming convention. ' \
'Table "{}" is being renamed as "{}".'.format(name, new_name)
warnings.warn(msg)
self._sab.append((new_name, xs))
self._sab.append((new_name))
def make_isotropic_in_lab(self):
for nuclide, percent, percent_type in self._nuclides:
@ -554,9 +570,6 @@ class Material(object):
else:
xml_element.set("wo", str(nuclide[1]))
if nuclide[0].xs is not None:
xml_element.set("xs", nuclide[0].xs)
if not nuclide[0].scattering is None:
xml_element.set("scattering", nuclide[0].scattering)
@ -581,9 +594,6 @@ class Material(object):
else:
xml_element.set("wo", str(element[1]))
if element[0].xs is not None:
xml_element.set("xs", element[0].xs)
if not element[0].scattering is None:
xml_element.set("scattering", element[0].scattering)
@ -686,8 +696,7 @@ class Material(object):
if len(self._sab) > 0:
for sab in self._sab:
subelement = ET.SubElement(element, "sab")
subelement.set("name", sab[0])
subelement.set("xs", sab[1])
subelement.set("name", sab)
return element
@ -714,27 +723,29 @@ class Materials(cv.CheckedList):
Attributes
----------
default_xs : str
The default cross section identifier applied to a nuclide when none is
specified
default_temperature : str
The default temperature identifier applied to a material when none is
specified. The units are in Kelvin and the temperature rounded to the
nearest integer. For example, a tempreature of 293.6K would be
provided as '294K'
"""
def __init__(self, materials=None):
super(Materials, self).__init__(Material, 'materials collection')
self._default_xs = None
self._default_temperature = None
self._materials_file = ET.Element("materials")
if materials is not None:
self += materials
@property
def default_xs(self):
return self._default_xs
def default_temperature(self):
return self._default_temperature
@default_xs.setter
def default_xs(self, xs):
cv.check_type('default xs', xs, basestring)
self._default_xs = xs
@default_temperature.setter
def default_temperature(self, temperature):
cv.check_type('default_temperature', temperature, basestring)
self._default_temperature = temperature
def add_material(self, material):
"""Append material to collection
@ -817,9 +828,10 @@ class Materials(cv.CheckedList):
material.make_isotropic_in_lab()
def _create_material_subelements(self):
if self._default_xs is not None:
subelement = ET.SubElement(self._materials_file, "default_xs")
subelement.text = self._default_xs
if self._default_temperature is not None:
subelement = ET.SubElement(self._materials_file,
"default_temperature")
subelement.text = self._default_temperature
for material in self:
xml_element = material.get_material_xml()

View file

@ -15,15 +15,11 @@ class Nuclide(object):
----------
name : str
Name of the nuclide, e.g. U235
xs : str
Cross section identifier, e.g. 71c
Attributes
----------
name : str
Name of the nuclide, e.g. U235
xs : str
Cross section identifier, e.g. 71c
zaid : int
1000*(atomic number) + mass number. As an example, the zaid of U235
would be 92235.
@ -32,25 +28,19 @@ class Nuclide(object):
"""
def __init__(self, name='', xs=None):
def __init__(self, name=''):
# Initialize class attributes
self._name = ''
self._xs = None
self._zaid = None
self._scattering = None
# Set the Material class attributes
self.name = name
if xs is not None:
self.xs = xs
def __eq__(self, other):
if isinstance(other, Nuclide):
if self.name != other.name:
return False
elif self.xs != other.xs:
return False
else:
return True
elif isinstance(other, basestring) and other == self.name:
@ -72,7 +62,6 @@ class Nuclide(object):
def __repr__(self):
string = 'Nuclide - {0}\n'.format(self._name)
string += '{0: <16}{1}{2}\n'.format('\tXS', '=\t', self.xs)
if self.zaid is not None:
string += '{0: <16}{1}{2}\n'.format('\tZAID', '=\t', self.zaid)
if self.scattering is not None:
@ -84,10 +73,6 @@ class Nuclide(object):
def name(self):
return self._name
@property
def xs(self):
return self._xs
@property
def zaid(self):
return self._zaid
@ -111,11 +96,6 @@ class Nuclide(object):
'"{}" is being renamed as "{}".'.format(name, self._name)
warnings.warn(msg)
@xs.setter
def xs(self, xs):
check_type('cross-section identifier', xs, basestring)
self._xs = xs
@zaid.setter
def zaid(self, zaid):
check_type('zaid', zaid, Integral)

View file

@ -2129,6 +2129,7 @@ contains
logical :: file_exists ! does materials.xml exist?
logical :: sum_density ! density is taken to be sum of nuclide densities
character(20) :: name ! name of isotope, e.g. 92235.03c
character(6) :: default_temperature ! Default temperature, e.g., '300K'
character(MAX_WORD_LEN) :: units ! units on density
character(MAX_LINE_LEN) :: filename ! absolute path to materials.xml
character(MAX_LINE_LEN) :: temp_str ! temporary string when reading
@ -2162,6 +2163,13 @@ contains
! Parse materials.xml file
call open_xmldoc(doc, filename)
! Copy default temperature
if (check_for_node(doc, "default_temperature")) then
call get_node_value(doc, "default_temperature", default_temperature)
else
default_temperature = ''
end if
! Get pointer to list of XML <material>
call get_node_list(doc, "material", node_mat_list)
@ -2200,6 +2208,11 @@ contains
! Copy material temperature
if (check_for_node(node_mat, "temperature")) then
call get_node_value(node_mat, "temperature", mat % temperature)
else if (default_temperature /= '') then
mat % temperature = default_temperature
else
call fatal_error("Must specify eithe a material temperature or a &
&default temperature")
end if
! =======================================================================