From a074e0a5cf985ce3a2763133aaa04e73c38d482b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 31 Aug 2022 22:13:54 -0500 Subject: [PATCH] Use openmc.config['cross_sections'] instead of OPENMC_CROSS_SECTIONS --- openmc/data/library.py | 17 ++++++++------- openmc/deplete/chain.py | 23 ++------------------- openmc/deplete/coupled_operator.py | 15 +++++--------- openmc/deplete/openmc_operator.py | 16 +++++++++++---- openmc/deplete/results.py | 4 ++-- openmc/element.py | 33 +++++++++++++++--------------- openmc/material.py | 10 ++++----- openmc/mgxs_library.py | 2 +- 8 files changed, 51 insertions(+), 69 deletions(-) diff --git a/openmc/data/library.py b/openmc/data/library.py index bf937e57a..ad6c65fb6 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -4,6 +4,7 @@ import pathlib import h5py +import openmc from openmc.mixin import EqualityMixin from openmc._xml import clean_indentation, reorder_attributes @@ -124,8 +125,8 @@ class DataLibrary(EqualityMixin): Parameters ---------- path : str, optional - Path to XML file to read. If not provided, the - :envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used. + Path to XML file to read. If not provided, + openmc.config['cross_sections'] will be used. Returns ------- @@ -136,15 +137,14 @@ class DataLibrary(EqualityMixin): data = cls() - # If path is None, get the cross sections from the - # OPENMC_CROSS_SECTIONS environment variable + # If path is None, get the cross sections from the global configuration if path is None: - path = os.environ.get('OPENMC_CROSS_SECTIONS') + path = openmc.config.get('cross_sections') - # Check to make sure there was an environmental variable. + # Check to make sure we picked up cross sections if path is None: - raise ValueError("Either path or OPENMC_CROSS_SECTIONS " - "environmental variable must be set") + raise ValueError("Either path or openmc.config['cross_sections'] " + "must be set") tree = ET.parse(path) root = tree.getroot() @@ -162,7 +162,6 @@ class DataLibrary(EqualityMixin): data.libraries.append(library) # get depletion chain data - dep_node = root.find("depletion_chain") if dep_node is not None: filename = os.path.join(directory, dep_node.attrib['path']) diff --git a/openmc/deplete/chain.py b/openmc/deplete/chain.py index d63bc6bfb..217c9cac0 100644 --- a/openmc/deplete/chain.py +++ b/openmc/deplete/chain.py @@ -239,24 +239,6 @@ def replace_missing_fpy(actinide, fpy_data, decay_data): return 'U235' -def _find_chain_file(cross_sections=None): - # First check deprecated OPENMC_DEPLETE_CHAIN environment variable - chain_file = os.environ.get("OPENMC_DEPLETE_CHAIN") - if chain_file is not None: - warn("Use of OPENMC_DEPLETE_CHAIN is deprecated in favor of adding " - "depletion_chain to OPENMC_CROSS_SECTIONS", FutureWarning) - return chain_file - - # Check for depletion chain in cross_sections.xml - data = DataLibrary.from_xml(cross_sections) - for lib in reversed(data.libraries): - if lib['type'] == 'depletion_chain': - return lib['path'] - - raise DataError("No depletion chain specified and could not find depletion " - f"chain in {cross_sections}") - - class Chain: """Full representation of a depletion chain. @@ -265,9 +247,8 @@ class Chain: yield sublibrary files. The depletion chain used during a depletion simulation is indicated by either an argument to :class:`openmc.deplete.CoupledOperator` or - :class:`openmc.deplete.IndependentOperator`, or through the - ``depletion_chain`` item in the :envvar:`OPENMC_CROSS_SECTIONS` - environment variable. + :class:`openmc.deplete.IndependentOperator`, or through + openmc.config['chain_file']. Attributes ---------- diff --git a/openmc/deplete/coupled_operator.py b/openmc/deplete/coupled_operator.py index dd14f282f..4a7c5c56f 100644 --- a/openmc/deplete/coupled_operator.py +++ b/openmc/deplete/coupled_operator.py @@ -9,7 +9,6 @@ filesystem. """ import copy -import os from warnings import warn import numpy as np @@ -22,7 +21,6 @@ from openmc.exceptions import DataError import openmc.lib from openmc.mpi import comm from .abc import OperatorResult -from .chain import _find_chain_file from .openmc_operator import OpenMCOperator, _distribute from .results import Results from .helpers import ( @@ -48,11 +46,11 @@ def _find_cross_sections(model): return model.materials.cross_sections # otherwise fallback to environment variable - cross_sections = os.environ.get("OPENMC_CROSS_SECTIONS") + cross_sections = openmc.config.get("cross_sections") if cross_sections is None: raise DataError( "Cross sections were not specified in Model.materials and " - "the OPENMC_CROSS_SECTIONS environment variable is not set." + "openmc.config['cross_sections'] is not set." ) return cross_sections @@ -103,9 +101,8 @@ class CoupledOperator(OpenMCOperator): model : openmc.model.Model OpenMC model object chain_file : str, optional - Path to the depletion chain XML file. Defaults to the file - listed under ``depletion_chain`` in - :envvar:`OPENMC_CROSS_SECTIONS` environment variable. + Path to the depletion chain XML file. Defaults to + ``openmc.config['chain_file']``. prev_results : Results, optional Results from a previous depletion calculation. If this argument is specified, the depletion calculation will start from the latest state @@ -231,10 +228,8 @@ class CoupledOperator(OpenMCOperator): " model with which to generate the transport Operator." raise TypeError(msg) - # Determine cross sections / depletion chain + # Determine cross sections cross_sections = _find_cross_sections(model) - if chain_file is None: - chain_file = _find_chain_file(cross_sections) check_value('fission yield mode', fission_yield_mode, self._fission_helpers.keys()) diff --git a/openmc/deplete/openmc_operator.py b/openmc/deplete/openmc_operator.py index ee569bf71..91dc49b54 100644 --- a/openmc/deplete/openmc_operator.py +++ b/openmc/deplete/openmc_operator.py @@ -11,6 +11,7 @@ from collections import OrderedDict import numpy as np import openmc +from openmc.exceptions import DataError from openmc.mpi import comm from .abc import TransportOperator, OperatorResult from .atom_number import AtomNumber @@ -57,9 +58,8 @@ class OpenMCOperator(TransportOperator): Path to continuous energy cross section library, or object containing one-group cross-sections. chain_file : str, optional - Path to the depletion chain XML file. Defaults to the file - listed under ``depletion_chain`` in - :envvar:`OPENMC_CROSS_SECTIONS` environment variable. + Path to the depletion chain XML file. Defaults to + openmc.config['chain_file']. prev_results : Results, optional Results from a previous depletion calculation. If this argument is specified, the depletion calculation will start from the latest state @@ -83,7 +83,6 @@ class OpenMCOperator(TransportOperator): if ``reduce_chain`` evaluates to true. The default value of ``None`` implies no limit on the depth. - Attributes ---------- materials : openmc.Materials @@ -133,6 +132,15 @@ class OpenMCOperator(TransportOperator): reduce_chain=False, reduce_chain_level=None): + # If chain file was not specified, try to get it from global config + if chain_file is None: + chain_file = openmc.config.get('chain_file') + if chain_file is None: + raise DataError( + "No depletion chain specified and could not find depletion " + "chain in openmc.config['chain_file']" + ) + super().__init__(chain_file, fission_q, dilute_initial, prev_results) self.round_number = False self.materials = materials diff --git a/openmc/deplete/results.py b/openmc/deplete/results.py index 15a65e98a..b2c8e7733 100644 --- a/openmc/deplete/results.py +++ b/openmc/deplete/results.py @@ -392,7 +392,7 @@ class Results(list): as such cannot be used in subsequent transport calculations. If not provided, nuclides from the cross_sections element of materials.xml will be used. If that element is not present, - nuclides from OPENMC_CROSS_SECTIONS will be used. + nuclides from openmc.config['cross_sections'] will be used. Returns ------- @@ -412,7 +412,7 @@ class Results(list): # the new materials XML file. The precedence of nuclides to select # is first ones provided as a kwarg here, then ones specified # in the materials.xml file if provided, then finally from - # the environment variable OPENMC_CROSS_SECTIONS. + # openmc.config['cross_sections']. if nuc_with_data: cv.check_iterable_type('nuclide names', nuc_with_data, str) available_cross_sections = nuc_with_data diff --git a/openmc/element.py b/openmc/element.py index 1473bd63e..49aeaf464 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -1,9 +1,9 @@ from collections import OrderedDict -import os import re from xml.etree import ElementTree as ET import openmc.checkvalue as cv +import openmc from openmc.data import NATURAL_ABUNDANCE, atomic_mass, \ isotopes as natural_isotopes @@ -40,10 +40,10 @@ class Element(str): cross_sections=None): """Expand natural element into its naturally-occurring isotopes. - An optional cross_sections argument or the :envvar:`OPENMC_CROSS_SECTIONS` - environment variable is used to specify a cross_sections.xml file. - If the cross_sections.xml file is found, the element is expanded only - into the isotopes/nuclides present in cross_sections.xml. If no + An optional cross_sections argument or the ``cross_sections`` + configuration value is used to specify a cross_sections.xml file. If the + cross_sections.xml file is found, the element is expanded only into the + isotopes/nuclides present in cross_sections.xml. If no cross_sections.xml file is found, the element is expanded based on its naturally occurring isotopes. @@ -54,12 +54,13 @@ class Element(str): percent_type : {'ao', 'wo'} 'ao' for atom percent and 'wo' for weight percent enrichment : float, optional - Enrichment of an enrichment_target nuclide in percent (ao or wo). - If enrichment_target is not supplied then it is enrichment for U235 - in weight percent. For example, input 4.95 for 4.95 weight percent + Enrichment of an enrichment_target nuclide in percent (ao or wo). If + enrichment_target is not supplied then it is enrichment for U235 in + weight percent. For example, input 4.95 for 4.95 weight percent enriched U. Default is None (natural composition). enrichment_target: str, optional - Single nuclide name to enrich from a natural composition (e.g., 'O16') + Single nuclide name to enrich from a natural composition (e.g., + 'O16') .. versionadded:: 0.12 enrichment_type: {'ao', 'wo'}, optional @@ -82,8 +83,8 @@ class Element(str): ValueError No data is available for any of natural isotopes of the element ValueError - If only some natural isotopes are available in the cross-section data - library and the element is not O, W, or Ta + If only some natural isotopes are available in the cross-section + data library and the element is not O, W, or Ta ValueError If a non-naturally-occurring isotope is requested ValueError @@ -101,8 +102,8 @@ class Element(str): `ORNL/CSD/TM-244 `_ is used to calculate the weight fractions of U234, U235, U236, and U238. Namely, the weight fraction of U234 and U236 are taken to be 0.89% and 0.46%, - respectively, of the U235 weight fraction. The remainder of the - isotopic weight is assigned to U238. + respectively, of the U235 weight fraction. The remainder of the isotopic + weight is assigned to U238. When the `enrichment` argument is specified with `enrichment_target`, a general enrichment procedure is used for elements composed of exactly @@ -125,10 +126,10 @@ class Element(str): # Create dict to store the expanded nuclides and abundances abundances = OrderedDict() - # If cross_sections is None, get the cross sections from the - # OPENMC_CROSS_SECTIONS environment variable + # If cross_sections is None, get the cross sections from the global + # configuration if cross_sections is None: - cross_sections = os.environ.get('OPENMC_CROSS_SECTIONS') + cross_sections = openmc.config.get('cross_sections') # If a cross_sections library is present, check natural nuclides # against the nuclides in the library diff --git a/openmc/material.py b/openmc/material.py index ece70df88..96a660b8b 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -1310,9 +1310,8 @@ class Materials(cv.CheckedList): """Collection of Materials used for an OpenMC simulation. This class corresponds directly to the materials.xml input file. It can be - thought of as a normal Python list where each member is a - :class:`Material`. It behaves like a list as the following example - demonstrates: + thought of as a normal Python list where each member is a :class:`Material`. + It behaves like a list as the following example demonstrates: >>> fuel = openmc.Material() >>> clad = openmc.Material() @@ -1330,9 +1329,8 @@ class Materials(cv.CheckedList): ---------- cross_sections : str or path-like Indicates the path to an XML cross section listing file (usually named - cross_sections.xml). If it is not set, the - :envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used for - continuous-energy calculations and + cross_sections.xml). If it is not set, openmc.config['cross_sections'] + will be used for continuous-energy calculations and :envvar:`OPENMC_MG_CROSS_SECTIONS` will be used for multi-group calculations to find the path to the HDF5 cross section file. diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 67ad151cc..8d6e4bec9 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -2546,7 +2546,7 @@ class MGXSLibrary: """ # If filename is None, get the cross sections from the - # OPENMC_CROSS_SECTIONS environment variable + # OPENMC_MG_CROSS_SECTIONS environment variable if filename is None: filename = os.environ.get('OPENMC_MG_CROSS_SECTIONS')