From b0a5be1c1ce9dc3eebbcad803237ccf918f2028f Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Mon, 24 Oct 2016 09:12:57 -0400 Subject: [PATCH] updated documentation and comments in Python API --- docs/source/usersguide/input.rst | 117 ++++++-------------------- openmc/element.py | 37 +++++--- openmc/material.py | 4 + openmc/nuclide.py | 6 +- src/input_xml.F90 | 86 +++++-------------- tests/test_element_wo/inputs_true.dat | 2 +- tests/test_enrichment/inputs_true.dat | 2 +- 7 files changed, 80 insertions(+), 174 deletions(-) diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index 6327d4106a..74de4caa41 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -105,19 +105,6 @@ standard deviation. *Default*: false -.. _cross_sections: - -```` Element ----------------------------- - -The ```` element has no attributes and simply indicates the path -to an XML cross section listing file (usually named cross_sections.xml). If this -element is absent from the settings.xml file, the -:envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used to find the -path to the XML cross section listing when in continuous-energy mode, and the -:envvar:`OPENMC_MG_CROSS_SECTIONS` environment variable will be used in -multi-group mode. - ```` Element -------------------- @@ -289,20 +276,6 @@ based on the recommended value in LA-UR-14-24530_. .. note:: This element is not used in the multi-group :ref:`energy_mode`. -.. _multipole_library: - -```` Element -------------------------------- - -The ```` element indicates the directory containing a -windowed multipole library. If a windowed multipole library is available, -OpenMC can use it for on-the-fly Doppler-broadening of resolved resonance range -cross sections. If this element is absent from the settings.xml file, the -:envvar:`OPENMC_MULTIPOLE_LIBRARY` environment variable will be used. - - .. note:: The element must also be set to "true" for - windowed multipole functionality. - ```` Element --------------------------- @@ -316,29 +289,6 @@ then, OpenMC will only use up to the :math:`P_1` data. .. note:: This element is not used in the continuous-energy :ref:`energy_mode`. -.. _natural_elements: - -```` Element ------------------------------- - -The ```` element indicates to OpenMC what nuclides are -available in the cross section library when expanding an ```` into -separate isotopes (see :ref:`material`). The accepted values are: - - - ENDF/B-VII.0 - - ENDF/B-VII.1 - - JEFF-3.1.1 - - JEFF-3.1.2 - - JEFF-3.2 - - JENDL-3.2 - - JENDL-3.3 - - JENDL-4.0 - -Note that the value is case-insensitive, so "ENDF/B-VII.1" is equivalent to -"endf/b-vii.1". - - *Default*: ENDF/B-VII.1 - ```` Element ----------------------- @@ -1368,6 +1318,33 @@ Here is an example of a properly defined 2d hexagonal lattice: Materials Specification -- materials.xml ---------------------------------------- +.. _cross_sections: + +```` Element +---------------------------- + +The ```` element has no attributes and simply indicates the path +to an XML cross section listing file (usually named cross_sections.xml). If this +element is absent from the settings.xml file, the +:envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used to find the +path to the XML cross section listing when in continuous-energy mode, and the +:envvar:`OPENMC_MG_CROSS_SECTIONS` environment variable will be used in +multi-group mode. + +.. _multipole_library: + +```` Element +------------------------------- + +The ```` element indicates the directory containing a +windowed multipole library. If a windowed multipole library is available, +OpenMC can use it for on-the-fly Doppler-broadening of resolved resonance range +cross sections. If this element is absent from the settings.xml file, the +:envvar:`OPENMC_MULTIPOLE_LIBRARY` environment variable will be used. + + .. note:: The element must also be set to "true" for + windowed multipole functionality. + .. _material: ```` Element @@ -1440,43 +1417,6 @@ Each ``material`` element can have the following attributes or sub-elements: .. note:: The ``scattering`` attribute/sub-element is not used in the multi-group :ref:`energy_mode`. - :element: - - 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``, 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 - - - - - - - In some cross section libraries, certain naturally occurring isotopes do not - have cross sections. The :ref:`natural_elements` option determines how a - natural element is split into isotopes in these cases. - - *Default*: None - - An optional attribute/sub-element for each element is ``scattering``. This - attribute may be set to "data" to use the scattering laws specified by the - cross section library (default). Alternatively, when set to "iso-in-lab", - the scattering laws are used to sample the outgoing energy but an - isotropic-in-lab distribution is used to sample the outgoing angle at each - scattering interaction. The ``scattering`` attribute may be most useful - when using OpenMC to compute multi-group cross-sections for deterministic - transport codes and to quantify the effects of anisotropic scattering. - - *Default*: None - - .. note:: The ``scattering`` attribute/sub-element is not used in the - multi-group :ref:`energy_mode`. - :sab: Associates an S(a,b) table with the material. This element has one attribute/sub-element called ``name``. The ``name`` attribute @@ -1503,9 +1443,6 @@ Each ``material`` element can have the following attributes or sub-elements: *Default*: None -.. _IUPAC Isotopic Compositions of the Elements 2009: - http://pac.iupac.org/publications/pac/pdf/2011/pdf/8302x0397.pdf - ------------------------------------ Tallies Specification -- tallies.xml ------------------------------------ diff --git a/openmc/element.py b/openmc/element.py index ecea2b8c3f..d3d3ac95da 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -84,9 +84,9 @@ class Element(object): @scattering.setter def scattering(self, scattering): - if not scattering in ['data', 'iso-in-lab']: - msg = 'Unable to set scattering for Element to {0} ' \ - 'which is not "data" or "iso-in-lab"'.format(scattering) + if not scattering in ['data', 'iso-in-lab', None]: + msg = 'Unable to set scattering for Element to {0} which ' \ + 'is not "data", "iso-in-lab", or None'.format(scattering) raise ValueError(msg) self._scattering = scattering @@ -123,11 +123,14 @@ class Element(object): """ + # Get the length of this elements atomic symbol + name_len = len(self.name) + # Get the nuclides present in nature natural_nuclides = set() for nuclide in sorted(NATURAL_ABUNDANCE.keys()): if re.match(r'{}\d+'.format(self.name), nuclide): - natural_nuclides.add(int(nuclide[len(self.name):])) + natural_nuclides.add(int(nuclide[name_len:])) # Create lists to store the expanded nuclides and abundances nuclides = [] @@ -149,7 +152,7 @@ class Element(object): nuclide = child.attrib['materials'] if re.match(r'{}\d+'.format(self.name), nuclide) and \ '_m' not in nuclide: - library_nuclides.add(int(nuclide[len(self.name):])) + library_nuclides.add(int(nuclide[name_len:])) # Get a set of the mutual and absent nuclides mutual_nuclides = natural_nuclides.intersection(library_nuclides) @@ -162,7 +165,9 @@ class Element(object): if len(absent_nuclides) == 0: for nuclide, abundance in sorted(NATURAL_ABUNDANCE.items()): if re.match(r'{}\d+'.format(self.name), nuclide): - nuclides.append(openmc.Nuclide(nuclide)) + nuc = openmc.Nuclide(nuclide) + nuc.scattering = self.scattering + nuclides.append(nuc) abundances.append(abundance) # If no natural elements are present in the library, check if the @@ -170,7 +175,9 @@ class Element(object): # nuclide. Else, raise an error. elif len(mutual_nuclides) == 0: if 0 in library_nuclides: - nuclides.append(openmc.Nuclide(self.name + '0')) + nuc = openmc.Nuclide(self.name + '0') + nuc.scattering = self.scattering + nuclides.append(nuc) abundances.append(1.0) else: msg = 'Unable to expand element {0} because the cross '\ @@ -188,18 +195,20 @@ class Element(object): nuclides_a = [] for nuclide, abundance in sorted(NATURAL_ABUNDANCE.items()): if re.match(r'{}\d+'.format(self.name), nuclide) and \ - int(nuclide[len(self.name):]) in mutual_nuclides: - nuclides.append(openmc.Nuclide(nuclide)) - nuclides_a.append(int(nuclide[len(self.name):])) + int(nuclide[name_len:]) in mutual_nuclides: + nuc = openmc.Nuclide(nuclide) + nuc.scattering = self.scattering + nuclides.append(nuc) + nuclides_a.append(int(nuclide[name_len:])) abundances.append(abundance) # Adjust the abundances for the absent nuclides for nuclide, abundance in sorted(NATURAL_ABUNDANCE.items()): if re.match(r'{}\d+'.format(self.name), nuclide) and \ - int(nuclide[len(self.name):]) in absent_nuclides: + int(nuclide[name_len:]) in absent_nuclides: # Get index to the nearest nuclide - a = int(nuclide[len(self.name):]) + a = int(nuclide[name_len:]) i = min(list(range(len(nuclides_a))), key=lambda j: \ abs(nuclides_a[j] - a)) @@ -264,9 +273,9 @@ class Element(object): for i in range(n_nuclides): abundances[i] /= sum_abundances + # Create a list of the isotopes in this element isotopes = [] for nuclide, abundance in zip(nuclides, abundances): - pct = float('{:2.10f}'.format(percent*abundance)) - isotopes.append((nuclide, pct, percent_type)) + isotopes.append((nuclide, percent*abundance, percent_type)) return isotopes diff --git a/openmc/material.py b/openmc/material.py index cfd098c345..7b63ec8004 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -461,6 +461,10 @@ class Material(object): self._id) raise ValueError(msg) + # Check that the enrichment is in the valid range + cv.check_less_than('enrichment', enrichment, 1/1.008, equality=True) + cv.check_greater_than('enrichment', enrichment, 0., equality=True) + if enrichment > 0.05: msg = 'A uranium enrichment of {0} was given for Material ID='\ '"{1}". OpenMC assumes the U234/U235 mass ratio is '\ diff --git a/openmc/nuclide.py b/openmc/nuclide.py index 03616a313f..79b51e68a2 100644 --- a/openmc/nuclide.py +++ b/openmc/nuclide.py @@ -89,9 +89,9 @@ class Nuclide(object): @scattering.setter def scattering(self, scattering): - if not scattering in ['data', 'iso-in-lab']: - msg = 'Unable to set scattering for Nuclide to {0} ' \ - 'which is not "data" or "iso-in-lab"'.format(scattering) + if not scattering in ['data', 'iso-in-lab', None]: + msg = 'Unable to set scattering for Nuclide to {0} which ' \ + 'is not "data", "iso-in-lab", or None'.format(scattering) raise ValueError(msg) self._scattering = scattering diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 8973d8fdaa..3eb2cf2d4e 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -139,10 +139,10 @@ contains ! Look for deprecated cross_sections.xml file in settings.xml if (check_for_node(doc, "cross_sections")) then - call warning("Setting cross_sections in settings.xml has been deprecated. & - &The cross_sections are now set in materials.xml and the & - &cross_sections input to materials.xml and OPENMC_CROSS_SECTIONS & - &environment variable will take precendent over setting & + call warning("Setting cross_sections in settings.xml has been deprecated.& + & The cross_sections are now set in materials.xml and the & + &cross_sections input to materials.xml and the OPENMC_CROSS_SECTIONS& + & environment variable will take precendent over setting & &cross_sections in settings.xml.") call get_node_value(doc, "cross_sections", path_cross_sections) end if @@ -152,7 +152,7 @@ contains if (check_for_node(doc, "multipole_library")) then call warning("Setting multipole_library in settings.xml has been & &deprecated. The multipole_library is now set in materials.xml and& - & the multipole_library input to materials.xml and & + & the multipole_library input to materials.xml and the & &OPENMC_MULTIPOLE_LIBRARY environment variable will take & &precendent over setting multipole_library in settings.xml.") call get_node_value(doc, "multipole_library", path_multipole) @@ -1033,17 +1033,9 @@ contains ! Get temperature settings if (check_for_node(doc, "temperature_default")) then - call warning("Setting temperature_default in settings.xml has been & - &deprecated. temperature_default is now set in materials.xml and & - &its input to materials.xml will take precendent & - &over setting it in settings.xml.") call get_node_value(doc, "temperature_default", temperature_default) end if if (check_for_node(doc, "temperature_method")) then - call warning("Setting temperature_method in settings.xml has been & - &deprecated. temperature_method is now set in materials.xml and & - &its input to materials.xml will take precendent & - &over setting it in settings.xml.") call get_node_value(doc, "temperature_method", temp_str) select case (to_lower(temp_str)) case ('nearest') @@ -1055,17 +1047,9 @@ contains end select end if if (check_for_node(doc, "temperature_tolerance")) then - call warning("Setting temperature_tolerance in settings.xml has been & - &deprecated. temperature_tolerance is now set in materials.xml and & - &its input to materials.xml will take precendent & - &over setting it in settings.xml.") call get_node_value(doc, "temperature_tolerance", temperature_tolerance) end if if (check_for_node(doc, "temperature_multipole")) then - call warning("Setting temperature_multipole in settings.xml has been & - &deprecated. temperature_multipole is now set in materials.xml and & - &its input to materials.xml will take precendent & - &over setting it in settings.xml.") call get_node_value(doc, "temperature_multipole", temp_str) select case (to_lower(temp_str)) case ('true', '1') @@ -2076,7 +2060,7 @@ contains ! Find cross_sections.xml file -- the first place to look is the ! materials.xml file. If no file is found there, then we check the - ! CROSS_SECTIONS environment variable + ! OPENMC_CROSS_SECTIONS environment variable if (.not. check_for_node(doc, "cross_sections")) then ! No cross_sections.xml file specified in settings.xml, check ! environment variable @@ -2084,6 +2068,8 @@ contains call get_environment_variable("OPENMC_CROSS_SECTIONS", env_variable) if (len_trim(env_variable) == 0) then call get_environment_variable("CROSS_SECTIONS", env_variable) + ! FIXME: When deprecated option of setting the cross sections in + ! settings.xml is removed, remove ".and. path_cross_sections == ''" if (len_trim(env_variable) == 0 .and. path_cross_sections == '') then call fatal_error("No cross_sections.xml file was specified in & &materials.xml, settings.xml, or in the OPENMC_CROSS_SECTIONS& @@ -2100,13 +2086,15 @@ contains path_cross_sections = trim(env_variable) else call get_environment_variable("OPENMC_MG_CROSS_SECTIONS", env_variable) + ! FIXME: When deprecated option of setting the mg cross sections in + ! settings.xml is removed, remove ".and. path_cross_sections == ''" if (len_trim(env_variable) == 0 .and. path_cross_sections == '') then - call fatal_error("No mgxs.xml file was specified in & + call fatal_error("No mgxs.h5 file was specified in & &materials.xml or in the OPENMC_MG_CROSS_SECTIONS environment & &variable. OpenMC needs such a file to identify where to & - &find ACE cross section libraries. Please consult the user's & + &find MG cross section libraries. Please consult the user's & &guide at http://mit-crpg.github.io/openmc for information on & - &how to set up ACE cross section libraries.") + &how to set up MG cross section libraries.") else path_cross_sections = trim(env_variable) end if @@ -2129,40 +2117,10 @@ contains path_multipole = trim(path_multipole) // "/" end if - ! Get temperature settings - if (check_for_node(doc, "temperature_default")) then - call get_node_value(doc, "temperature_default", temperature_default) - end if - if (check_for_node(doc, "temperature_method")) then - call get_node_value(doc, "temperature_method", temp_str) - select case (to_lower(temp_str)) - case ('nearest') - temperature_method = TEMPERATURE_NEAREST - case ('interpolation') - temperature_method = TEMPERATURE_INTERPOLATION - case default - call fatal_error("Unknown temperature method: " // trim(temp_str)) - end select - end if - if (check_for_node(doc, "temperature_tolerance")) then - call get_node_value(doc, "temperature_tolerance", temperature_tolerance) - end if - if (check_for_node(doc, "temperature_multipole")) then - call get_node_value(doc, "temperature_multipole", temp_str) - select case (to_lower(temp_str)) - case ('true', '1') - temperature_multipole = .true. - case ('false', '0') - temperature_multipole = .false. - case default - call fatal_error("Unrecognized value for in & - &materials.xml") - end select - end if - ! Close materials XML file call close_xmldoc(doc) + ! Now that the cross_sections.xml or mgxs.h5 has been located, read it in if (run_CE) then call read_ce_cross_sections_xml(libraries) else @@ -2225,12 +2183,12 @@ contains integer :: index_nuclide ! index in nuclides integer :: index_sab ! index in sab_tables logical :: file_exists ! does materials.xml exist? - character(20) :: name ! name of nuclide, e.g. 92235.03c + character(20) :: name ! name of nuclide, e.g. 92235.03c character(MAX_LINE_LEN) :: filename ! absolute path to materials.xml character(MAX_LINE_LEN) :: temp_str ! temporary string when reading type(VectorChar) :: names ! temporary list of nuclide names type(VectorInt) :: list_iso_lab ! temporary list of isotropic lab scatterers - type(Material), pointer :: mat => null() + type(Material), pointer :: mat => null() type(Node), pointer :: doc => null() type(Node), pointer :: node_mat => null() type(Node), pointer :: node_nuc => null() @@ -4674,7 +4632,8 @@ contains end subroutine generate_rpn !=============================================================================== -! ASSIGN_NUCLIDE_DENSITIES Assign and normalize nuclide densities +! ASSIGN_NUCLIDE_DENSITIES Read in the nuclide densities from materials.xml +! and assign to the corresponding nuclides. !=============================================================================== subroutine assign_nuclide_densities() @@ -4731,16 +4690,13 @@ contains ! Copy units call get_node_value(node_dens, "units", units) + ! If the units is 'sum', then the total density of the material is taken + ! to be the sum of the atom fractions listed on the nuclides if (units == 'sum') then - ! If the user gave the units as 'sum', then the total density of the - ! material is taken to be the sum of the atom fractions listed on the - ! nuclides - sum_density = .true. else if (units == 'macro') then if (check_for_node(node_dens, "value")) then - ! Copy value call get_node_value(node_dens, "value", val) else val = ONE @@ -4752,7 +4708,6 @@ contains sum_density = .false. else - ! Copy value call get_node_value(node_dens, "value", val) ! Check for erroneous density @@ -4761,6 +4716,7 @@ contains call fatal_error("Need to specify a positive density on material " & // trim(to_str(mat % id)) // ".") end if + ! Adjust material density based on specified units select case(to_lower(units)) case ('g/cc', 'g/cm3') diff --git a/tests/test_element_wo/inputs_true.dat b/tests/test_element_wo/inputs_true.dat index 9f59e56f22..da97abc339 100644 --- a/tests/test_element_wo/inputs_true.dat +++ b/tests/test_element_wo/inputs_true.dat @@ -1 +1 @@ -c472877dd96f51dcfd7b45ec1c230c3847b26eb1f0a97751bb175b70eafff2ad8ee97e3ed8691a3bc8bf8f27c074a9d34021322988185bb04c3e55958f40589b \ No newline at end of file +f270ae43a29c53065678b419629ad713f5a4cc23c75825fee4da049d4159756f463fec86263a8dea6ce10fff6d60b24ebf100e8f5cc80e6d4fc31297ae1709ed \ No newline at end of file diff --git a/tests/test_enrichment/inputs_true.dat b/tests/test_enrichment/inputs_true.dat index 86c8f82f05..49acd2945a 100644 --- a/tests/test_enrichment/inputs_true.dat +++ b/tests/test_enrichment/inputs_true.dat @@ -1 +1 @@ -6f8d495cd7537f8ca29355664b31d429fe13f656a868852769b27ef9566e7bb683973322e41a92bab65beb1ba6cf477698b30a7ae6bc17d2e34cb44751e8c81d \ No newline at end of file +835357f7b3c10f1153bb5842978075d9bb788d639759f143dfe58064865712fdf4e17ce50747949411e7c5215f33371e883e48b670509e222fa338bbfe613b80 \ No newline at end of file