mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-26 21:25:36 -04:00
Updated pyapi and docs to support new default_temperature/temperature and lack of default_xs/xs
This commit is contained in:
parent
2f8afd291b
commit
dfe2420b4a
7 changed files with 93 additions and 122 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
! =======================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue