diff --git a/docs/source/conf.py b/docs/source/conf.py index ebda1bdad3..222b95c9f5 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -255,6 +255,7 @@ napoleon_use_ivar = True intersphinx_mapping = { 'python': ('https://docs.python.org/3', None), 'numpy': ('https://docs.scipy.org/doc/numpy/', None), + 'scipy': ('https://docs.scipy.org/doc/scipy/reference', None), 'pandas': ('https://pandas.pydata.org/pandas-docs/stable/', None), 'matplotlib': ('https://matplotlib.org/', None) } diff --git a/docs/source/io_formats/settings.rst b/docs/source/io_formats/settings.rst index 83aa0691f4..52b52f68cb 100644 --- a/docs/source/io_formats/settings.rst +++ b/docs/source/io_formats/settings.rst @@ -600,67 +600,6 @@ attributes/sub-elements: *Default*: false -.. _custom_source: - -Custom Sources -++++++++++++++ - -It is often the case that one may wish to simulate a complex source -distribution, which may include physics not present within OpenMC or to be phase -space complex. It is possible to define a complex source with an externally -defined source function that is loaded at runtime. A simple example source is -shown below. - -.. code-block:: c++ - - #include "openmc/random_lcg.h" - #include "openmc/source.h" - #include "openmc/particle.h" - - // you must have external C linkage here - extern "C" openmc::Particle::Bank sample_source(uint64_t* seed) { - openmc::Particle::Bank particle; - // weight - particle.particle = openmc::Particle::Type::neutron; - particle.wgt = 1.0; - // position - double angle = 2.0 * M_PI * openmc::prn(seed); - double radius = 3.0; - particle.r.x = radius * std::cos(angle); - particle.r.y = radius * std::sin(angle); - particle.r.z = 0.0; - // angle - particle.u = {1.0, 0.0, 0.0}; - particle.E = 14.08e6; - particle.delayed_group = 0; - return particle; - } - -The above source, creates 14.08 MeV neutrons, with an istropic direction -vector but distributed in a ring with a 3 cm radius. This routine is -not particularly complex, but should serve as an example upon which to build -more complicated sources. - - .. note:: The function signature must be declared to be extern "C". - - .. note:: You should only use the openmc::prn() random number generator - -In order to build your external source, you will need to link it against the -OpenMC shared library. This can be done by writing a CMakeLists.txt file: - -.. code-block:: cmake - - cmake_minimum_required(VERSION 3.3 FATAL_ERROR) - project(openmc_sources CXX) - add_library(source SHARED source_ring.cpp) - find_package(OpenMC REQUIRED HINTS ) - target_link_libraries(source OpenMC::libopenmc) - -After running ``cmake`` and ``make``, you will have a libsource.so (or .dylib) -file in your build directory. Setting the :attr:`openmc.Source.library` -attribute to the path of this shared library will indicate that it should be -used for sampling source particles at runtime. - .. _univariate: Univariate Probability Distributions diff --git a/docs/source/methods/depletion.rst b/docs/source/methods/depletion.rst new file mode 100644 index 0000000000..903d3e5af5 --- /dev/null +++ b/docs/source/methods/depletion.rst @@ -0,0 +1,248 @@ +.. _methods_depletion: + +========= +Depletion +========= + +When materials in a system are subject to irradiation over a long period of +time, nuclides within the material will transmute due to nuclear reactions as +well as spontaneous radioactive decay. The time-dependent process by which +nuclides transmute under irradiation is known as *depletion* or *burnup*. To +accurately analyze nuclear systems, it is often necessary to predict how the +composition of materials will change since this change results in a +corresponding change in the solution of the transport equation. The equation +that governs the transmutation and decay of nuclides inside of an irradiated +environment can be written as + +.. math:: + + \begin{aligned} \frac{dN_i(t)}{dt} = &\sum\limits_j + \underbrace{\left [ \underbrace{f_{j \rightarrow i} \int_0^\infty dE \; + \sigma_j (E, t) \phi(E,t)}_\text{transmutation} + + \underbrace{\lambda_{j\rightarrow i}}_\text{decay} \right ] + N_j(t)}_{\text{Production of nuclide }i\text{ from nuclide }j} \\ + &- \underbrace{\left [\underbrace{\int_0^\infty dE \; \sigma_i + (E,t) \phi(E,t)}_\text{transmutation} + + \underbrace{\sum\limits_j \lambda_{i\rightarrow j}}_\text{decay} \right ] + N_i(t)}_{\text{Loss of nuclide }i} \end{aligned} + +where :math:`N_i` is the density of nuclide :math:`i` at time :math:`t`, +:math:`\sigma_i` is the transmutation cross section for nuclide :math:`i` at +energy :math:`E`, :math:`f_{j \rightarrow i}` is the fraction of transmutation +reactions in nuclide :math:`j` that produce nuclide :math:`i`, and +:math:`\lambda_{j \rightarrow i}` is the decay constant for decay modes in +nuclide :math:`j` that produce nuclide :math:`i`. Note that we have not included +the spatial dependence of the flux or cross sections. As one can see, the +equation simply states that the rate of change of :math:`N_i` is equal to the +production rate minus the loss rate. Because the equation for nuclide :math:`i` +depends on the nuclide density for possibly many other nuclides, we have a +system of first-order differential equations. To form a proper initial value +problem, we also need the nuclide densities at time 0: + +.. math:: + + N_i(0) = N_{i,0}. + +These equations can be written more compactly in matrix notation as + +.. math:: + :label: depletion-matrix + + \frac{d\mathbf{n}}{dt} = \mathbf{A}(\mathbf{n},t)\mathbf{n}, \quad \mathbf{n}(0) = + \mathbf{n}_0 + +where :math:`\mathbf{n} \in \mathbb{R}^n` is the nuclide density vector, +:math:`\mathbf{A}(\mathbf{n},t) \in \mathbb{R}^{n\times n}` is the burnup matrix +containing the decay and transmutation coefficients, and :math:`\mathbf{n}_0` is +the initial density vector. Note that the burnup matrix depends on +:math:`\mathbf{n}` because the solution to the transport equation depends on the +nuclide densities. + +.. _methods_depletion_integration: + +--------------------- +Numerical Integration +--------------------- + +A variety of numerical methods exist for solving Eq. :eq:`depletion-matrix`. The +simplest such method, known as the "predictor" method, is to divide the overall +time interval of interest :math:`[0,t]` into smaller timesteps over which it is +assumed that the burnup matrix is constant. Let :math:`t \in [t_i, t_i + h]` be +one such timestep. Over the timestep, the solution to Eq. :eq:`depletion-matrix` +can be written analytically using the matrix exponential + +.. math:: + + \mathbf{A}_i = \mathbf{A}(\mathbf{n}_i, t_i) \\ + + \mathbf{n}_{i+1} = e^{\mathbf{A}_i h} \mathbf{n}_i + +where :math:`\mathbf{n}_i \equiv \mathbf{n}(t_i)`. The exponential of a matrix +:math:`\mathbf{X}` is defined by the power series expansion + +.. math:: + + e^{\mathbf{X}} = \sum\limits_{k=0}^\infty \frac{1}{k!} \left ( \mathbf{X} + \right )^k + +where :math:`\mathbf{X}^0 = \mathbf{I}`. A series of so-called +predictor-corrector methods that use multiple stages offer improved accuracy +over the predictor method. The simplest of these methods, the CE/CM algorithm, +is defined as + +.. math:: + + \mathbf{n}_{i+1/2} = e^{\frac{h}{2}\mathbf{A}(\mathbf{n}_i, t_i)} \mathbf{n}_i \\ + \mathbf{n}_{i+1} = e^{h \mathbf{A}(\mathbf{n}_{i+1/2},t_{i+1/2})} \mathbf{n}_i + +Here, the value of :math:`\mathbf{n}` at the midpoint is estimated using +:math:`\mathbf{A}` evaluated at the beginning of the timestep. Then, +:math:`\mathbf{A}` is evaluated using the densities at the midpoint and used to +integrate over the entire timestep. + +Our aim here is not to exhaustively describe all integration methods but rather +to give a few examples that elucidate the main considerations one must take into +account when choosing a method. Generally, there is a tradeoff between the +accuracy of the method and its computational expense. The expense is driven +almost entirely by the time to compute a transport solution, i.e., to evaluate +:math:`\mathbf{A}` for a given :math:`\mathbf{n}`. Thus, the cost of a method +scales with the number of :math:`\mathbf{A}` evaluations that are performed per +timestep. On the other hand, methods that require more evaluations generally +achieve higher accuracy. The predictor method only requires one evaluation and +its error converges as :math:`\mathcal{O}(h)`. The CE/CM method requires two +evaluations and is thus twice as expensive as the predictor method, but achieves +an error of :math:`\mathcal{O}(h^2)`. An exhaustive description of time +integration methods and their merits can be found in the `thesis of Colin Josey +`_. + +OpenMC does not rely on a single time integration method but rather has several +classes that implement different algorithms. For example, the +:class:`openmc.deplete.PredictorIntegrator` class implements the predictor +method, and the :class:`openmc.deplete.CECMIntegrator` class implements the +CE/CM method. A full list of the integrator classes available can be found in +the documentation for the :mod:`openmc.deplete` module. + +------------------ +Matrix Exponential +------------------ + +As we saw in the :ref:`previous section `, +numerically integrating Eq. :eq:`depletion-matrix` requires evaluating one or +more matrix exponentials. OpenMC uses the Chebyshev rational approximation +method (CRAM), which was introduced in a series of papers by Pusa (`1 +`_, `2 +`_), to evaluate matrix exponentials. In +particular, OpenMC utilizes an `incomplete partial fraction `_ (IPF) +form of CRAM that provides a good balance of numerical stability and efficiency. +In this representation the matrix exponential is approximated as + +.. math:: + + e^{\mathbf{A}t} \approx \alpha_0 \prod\limits_{\ell=1}^{k/2} \left ( + \mathbf{I} + 2 \text{Re} \left ( \widetilde{\alpha}_\ell \left (\mathbf{A}t + - \theta_\ell \mathbf{I} \right )^{-1} \right ) \right ) + +where :math:`k` is the order of the approximation and :math:`\alpha_0`, +:math:`\widetilde{\alpha}_\ell`, and :math:`\theta_\ell` are coefficients that +have been tabulated for orders up to :math:`k=48`. Rather than computing the +full approximation and then multiplying it by a vector, the following algorithm +is used to incrementally apply the terms within the product (note that the +original description of the algorithm presented by `Pusa `_ contains a +typo): + +1. :math:`\mathbf{n} \gets \mathbf{n_0}` +2. For :math:`\ell = 1, 2, \dots, k/2` + + - :math:`\mathbf{n} \gets \mathbf{n} + 2\text{Re}(\widetilde{\alpha}_\ell + (\mathbf{A}t - \theta_\ell)^{-1})\mathbf{n}` + +3. :math:`\mathbf{n} \gets \alpha_0 \mathbf{n}` + +The :math:`k`\ th order approximation for CRAM requires solving :math:`k/2` +sparse linear systems. OpenMC relies on functionality from +:mod:`scipy.sparse.linalg` for solving the linear systems. + +.. _cram_ipf: https://doi.org/10.13182/NSE15-26 + +------------------- +Data Considerations +------------------- + +In principle, solving Eq. :eq:`depletion-matrix` using CRAM is fairly simple: +just construct the burnup matrix at various times and solve a set of sparse +linear systems. However, constructing the burnup matrix itself involves not only +solving the transport equation to estimate transmutation reaction rates but also +a series of choices about what data to include. In OpenMC, the burnup matrix is +constructed based on data inside of a *depletion chain* file, which includes +fundamental data gathered from ENDF incident neutron, decay, and fission product +yield sublibraries. For each nuclide, this file includes: + +- What transmutation reactions are possible, their Q values, and their products; +- If a nuclide is not stable, what decay modes are possible, their branching + ratios, and their products; and +- If a nuclide is fissionable, the fission products yields at any number of + incident neutron energies. + +Transmutation Reactions +----------------------- + +OpenMC will setup tallies in a problem based on what transmutation reactions are +available in a depletion chain file, so any arbitrary number of transmutation +reactions can be tracked. The pregenerated chain files that are available on +https://openmc.org include the following transmutation reactions: fission, (n,\ +:math:`\gamma`\ ), (n,2n), (n,3n), (n,4n), (n,p), and (n,\ :math:`\alpha`\ ). + +Capture Branching Ratios +------------------------ + +Some (n,\ :math:`\gamma`\ ) reactions may result in a product being in either the +ground or a metastable state. The most well-known example is capture in Am241, +which can produce either Am242 or Am242m. Because the metastable state of Am242m +has a significantly longer half-life than the ground state, it is important to +accurately model the branching of the capture reaction in Am241. This is +complicated by the fact that the branching ratio may depend on the incident +neutron energy causing capture. + +OpenMC does not currently allow energy-dependent capture branching ratios. +However, the depletion chain file does allow a transmutation reaction to be +listed multiple times with different branching ratios resulting in different +products. Spectrum-averaged capture branching ratios have been computed in LWR +and SFR spectra and are available at https://openmc.org/depletion-chains. + +Fission Product Yields +---------------------- + +Fission product yields (FPY) are also energy-dependent in general. ENDF fission +product yield sublibraries typically include yields tabulated at 2 or 3 +energies. It is an open question as to what the best way to handle this energy +dependence is. OpenMC includes three methods for treating the energy dependence +of FPY: + +1. Use FPY data corresponding to a specified energy. +2. Tally fission rates above and below a specified cutoff energy. Assume that + all fissions below the cutoff energy correspond to thermal FPY data and all + fission above the cutoff energy correspond to fast FPY data. +3. Compute the average energy at which fission events occur and use an effective + FPY by linearly interpolating between FPY provided at neighboring energies. + +The method can be selected through the ``fission_yield_mode`` argument to the +:class:`openmc.deplete.Operator` constructor. + +Power Normalization +------------------- + +The reaction rates provided OpenMC are given in units of reactions per source +particle. For depletion, it is necessary to compute an absolute reaction rate in +reactions per second. To do so, the reaction rates are normalized based on a +specified power. A complete description of how this normalization can be +performed is described in :ref:`usersguide_tally_normalization`. Here, we simply +note that the main depletion class, :class:`openmc.deplete.Operator`, allows the +user to choose one of two methods for estimating the heating rate, including: + +1. Using fixed Q values from a depletion chain file (useful for comparisons to + other codes that use fixed Q values), or +2. Using the ``heating`` or ``heating-local`` scores to obtain an nuclide- and + energy-dependent estimate of the true heating rate. + +The method for normalization can be chosen through the ``energy_mode`` argument +to the :class:`openmc.deplete.Operator` class. diff --git a/docs/source/methods/index.rst b/docs/source/methods/index.rst index 5eff6c50e6..59892ac273 100644 --- a/docs/source/methods/index.rst +++ b/docs/source/methods/index.rst @@ -16,6 +16,7 @@ Theory and Methodology photon_physics tallies eigenvalue + depletion + energy_deposition parallelization cmfd - energy_deposition diff --git a/docs/source/usersguide/geometry.rst b/docs/source/usersguide/geometry.rst index f83af0b2f8..c929503df1 100644 --- a/docs/source/usersguide/geometry.rst +++ b/docs/source/usersguide/geometry.rst @@ -113,6 +113,19 @@ Boolean operators ``&`` (intersection), ``|`` (union), and ``~`` (complement):: >>> type(northern_hemisphere) +The ``&`` operator can be thought of as a logical AND, the ``|`` operator as a +logical OR, and the ``~`` operator as a logical NOT. Thus, if you wanted to +create a region that consists of the space for which :math:`-4 < z < -3` or +:math:`3 < z < 4`, a union could be used:: + + >>> region_bottom = +openmc.ZPlane(-4) & -openmc.ZPlane(-3) + >>> region_top = +openmc.ZPlane(3) & -openmc.ZPlane(4) + >>> combined_region = region_bottom | region_top + +Half-spaces and the objects resulting from taking the intersection, union, +and/or complement or half-spaces are all considered *regions* that can be +assigned to :ref:`cells `. + For many regions, a bounding-box can be determined automatically:: >>> northern_hemisphere.bounding_box diff --git a/docs/source/usersguide/settings.rst b/docs/source/usersguide/settings.rst index 5df42fcbed..a879fe6d14 100644 --- a/docs/source/usersguide/settings.rst +++ b/docs/source/usersguide/settings.rst @@ -110,13 +110,24 @@ The spatial distribution can be set equal to a sub-class of :class:`openmc.stats.Spatial`; common choices are :class:`openmc.stats.Point` or :class:`openmc.stats.Box`. To independently specify distributions in the :math:`x`, :math:`y`, and :math:`z` coordinates, you can use -:class:`openmc.stats.CartesianIndependent`. +:class:`openmc.stats.CartesianIndependent`. To independently specify +distributions using spherical or cylindrical coordinates, you can use +:class:`openmc.stats.SphericalIndependent` or +:class:`openmc.stats.CylindricalIndependent`, respectively. The angular distribution can be set equal to a sub-class of :class:`openmc.stats.UnitSphere` such as :class:`openmc.stats.Isotropic`, -:class:`openmc.stats.Monodirectional`, or -:class:`openmc.stats.PolarAzimuthal`. By default, if no angular distribution is -specified, an isotropic angular distribution is used. +:class:`openmc.stats.Monodirectional`, or :class:`openmc.stats.PolarAzimuthal`. +By default, if no angular distribution is specified, an isotropic angular +distribution is used. As an example of a non-trivial angular distribution, the +following code would create a conical distribution with an aperture of 30 +degrees pointed in the positive x direction:: + + from math import pi, cos + aperture = 30.0 + mu = openmc.stats.Uniform(cos(aperture/2), 1.0) + phi = openmc.stats.Uniform(0.0, 2*pi) + angle = openmc.stats.PolarAzimuthal(mu, phi, reference_uvw=(1., 0., 0.)) The energy distribution can be set equal to any univariate probability distribution. This could be a probability mass function @@ -164,6 +175,66 @@ following would generate a photon source:: For a full list of all classes related to statistical distributions, see :ref:`pythonapi_stats`. +.. _custom_source: + +Custom Sources +-------------- + +It is often the case that one may wish to simulate a complex source distribution +that is not possible to represent with the classes described above. For these +situations, it is possible to define a complex source with an externally defined +source function that is loaded at runtime. A simple example source is shown +below. + +.. code-block:: c++ + + #include "openmc/random_lcg.h" + #include "openmc/source.h" + #include "openmc/particle.h" + + // you must have external C linkage here + extern "C" openmc::Particle::Bank sample_source(uint64_t* seed) { + openmc::Particle::Bank particle; + // weight + particle.particle = openmc::Particle::Type::neutron; + particle.wgt = 1.0; + // position + double angle = 2.0 * M_PI * openmc::prn(seed); + double radius = 3.0; + particle.r.x = radius * std::cos(angle); + particle.r.y = radius * std::sin(angle); + particle.r.z = 0.0; + // angle + particle.u = {1.0, 0.0, 0.0}; + particle.E = 14.08e6; + particle.delayed_group = 0; + return particle; + } + +The above source creates monodirectional 14.08 MeV neutrons that are distributed +in a ring with a 3 cm radius. This routine is not particularly complex, but +should serve as an example upon which to build more complicated sources. + + .. note:: The function signature must be declared ``extern "C"``. + + .. note:: You should only use the openmc::prn() random number generator + +In order to build your external source, you will need to link it against the +OpenMC shared library. This can be done by writing a CMakeLists.txt file: + +.. code-block:: cmake + + cmake_minimum_required(VERSION 3.3 FATAL_ERROR) + project(openmc_sources CXX) + add_library(source SHARED source_ring.cpp) + find_package(OpenMC REQUIRED HINTS ) + target_link_libraries(source OpenMC::libopenmc) + +After running ``cmake`` and ``make``, you will have a libsource.so (or .dylib) +file in your build directory. Setting the :attr:`openmc.Source.library` +attribute to the path of this shared library will indicate that it should be +used for sampling source particles at runtime. + --------------- Shannon Entropy --------------- diff --git a/docs/source/usersguide/tallies.rst b/docs/source/usersguide/tallies.rst index c147858eb1..4856bad01f 100644 --- a/docs/source/usersguide/tallies.rst +++ b/docs/source/usersguide/tallies.rst @@ -308,3 +308,65 @@ The following tables show all valid scores: | |particle. This corresponds to MT=444 produced by | | |NJOY's HEATR module. | +----------------------+---------------------------------------------------+ + +.. _usersguide_tally_normalization: + +------------------------------ +Normalization of Tally Results +------------------------------ + +As described in :ref:`usersguide_scores`, all tally scores are normalized per +source particle simulated. However, for analysis of a given system, we usually +want tally scores in a more natural unit. For example, neutron flux is often +reported in units of particles/cm\ :sup:`2`\ -s. For a fixed source simulation, +it is usually straightforward to convert units if the source rate is known. For +example, if the system being modeled includes a source that is emitting 10\ +:sup:`4` neutrons per second, the tally results just need to be multipled by 10\ +:sup:`4`. This can either be done manually or using the +:attr:`openmc.Source.strength` attribute. + +For a :math:`k`\ -eigenvalue calculation, normalizing tally results is not as +simple because the source rate is not actually known. Instead, we typically know +the system power, :math:`P`, which represents how much energy is deposited per +unit time. Most of this energy originates from fission, but a small percentage +also results from other reactions (e.g., photons emitted from :math:`(n,\gamma)` +reactions). The most rigorous method to normalize tally results is to run a +coupled neutron-photon calculation and tally the ``heating`` score over the +entire system. This score provides the heating rate in units of [eV/source], +which we'll denote :math:`H`. Then, calculate the heating rate in J/source as + +.. math:: + + H' = 1.602\times10^{-19} \left [ \frac{\text{J}}{\text{eV}} \right ] \cdot H + \left [\frac{\text{eV}}{\text{source}} \right ]. + +Dividing the power by the observed heating rate then gives us a normalization +factor that can be applied to other tallies: + +.. math:: + + f = \frac{P}{H'} = \frac{[\text{J}/\text{s}]}{[\text{J}/\text{source}]} = + \left [ \frac{\text{source}}{\text{s}} \right ]. + +With this normalization factor, we can then get the flux in typical units: + +.. math:: + + \phi' = \frac{\phi}{fV} = \frac{[\text{particle-cm}/\text{source}]} + {[\text{source}/\text{s}][\text{cm}^3]} = \left [ + \frac{\text{particle}}{\text{cm}^2\cdot\text{s}} \right ] + +There are several slight variations on this procedure: + +- Run a neutron-only calculation and estimate the total heating using the + ``heating-local`` score (this requires that your nuclear data has local + heating data available, such as in the official data library at + https://openmc.org. See :ref:`methods_heating` for more information.) +- Run a neutron-only calculation and use the ``kappa-fission`` or + ``fission-q-recoverable`` scores along with an estimate of the extra heating + due to neutron capture reactions. +- Calculate the overall fission rate and then used a fixed Q value to estimate + the heating rate. + +Note that the only difference between these and the above procedures is in how +:math:`H'` is estimated. diff --git a/openmc/cell.py b/openmc/cell.py index a1709c516b..c55238df86 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -91,6 +91,8 @@ class Cell(IDManagerMixin): present in the cell, or in all of its instances for a 'distribmat' fill. For example, {'U235': 1.0e22, 'U238': 5.0e22, ...}. + .. versionadded:: 0.12 + """ next_id = 1 @@ -654,7 +656,7 @@ class Cell(IDManagerMixin): Returns ------- - Cell + openmc.Cell Cell instance """ diff --git a/openmc/data/library.py b/openmc/data/library.py index 3830334d23..a66260b929 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -31,8 +31,9 @@ class DataLibrary(EqualityMixin): name : str Name of material, e.g. 'Am241' data_type : str - Name of data type, e.g. 'neutron', 'photon', 'wmp', - or 'thermal' + Name of data type, e.g. 'neutron', 'photon', 'wmp', or 'thermal' + + .. versionadded:: 0.12 Returns ------- diff --git a/openmc/deplete/integrators.py b/openmc/deplete/integrators.py index 38a7c33b1f..ddb2130379 100644 --- a/openmc/deplete/integrators.py +++ b/openmc/deplete/integrators.py @@ -54,6 +54,8 @@ class PredictorIntegrator(Integrator): that the values are given in burnup (MW-d of energy deposited per kilogram of initial heavy metal). + .. versionadded:: 0.12 + Attributes ---------- operator : openmc.deplete.TransportOperator @@ -143,6 +145,8 @@ class CECMIntegrator(Integrator): that the values are given in burnup (MW-d of energy deposited per kilogram of initial heavy metal). + .. versionadded:: 0.12 + Attributes ---------- operator : openmc.deplete.TransportOperator @@ -240,6 +244,8 @@ class CF4Integrator(Integrator): that the values are given in burnup (MW-d of energy deposited per kilogram of initial heavy metal). + .. versionadded:: 0.12 + Attributes ---------- operator : openmc.deplete.TransportOperator @@ -354,6 +360,8 @@ class CELIIntegrator(Integrator): that the values are given in burnup (MW-d of energy deposited per kilogram of initial heavy metal). + .. versionadded:: 0.12 + Attributes ---------- operator : openmc.deplete.TransportOperator @@ -455,6 +463,8 @@ class EPCRK4Integrator(Integrator): that the values are given in burnup (MW-d of energy deposited per kilogram of initial heavy metal). + .. versionadded:: 0.12 + Attributes ---------- operator : openmc.deplete.TransportOperator @@ -576,6 +586,8 @@ class LEQIIntegrator(Integrator): that the values are given in burnup (MW-d of energy deposited per kilogram of initial heavy metal). + .. versionadded:: 0.12 + Attributes ---------- operator : openmc.deplete.TransportOperator @@ -693,6 +705,8 @@ class SICELIIntegrator(SIIntegrator): seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates that the values are given in burnup (MW-d of energy deposited per kilogram of initial heavy metal). + + .. versionadded:: 0.12 n_steps : int, optional Number of stochastic iterations per depletion interval. Must be greater than zero. Default : 10 @@ -801,6 +815,8 @@ class SILEQIIntegrator(SIIntegrator): seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates that the values are given in burnup (MW-d of energy deposited per kilogram of initial heavy metal). + + .. versionadded:: 0.12 n_steps : int, optional Number of stochastic iterations per depletion interval. Must be greater than zero. Default : 10 diff --git a/openmc/deplete/nuclide.py b/openmc/deplete/nuclide.py index 854a2abb07..06f217f222 100644 --- a/openmc/deplete/nuclide.py +++ b/openmc/deplete/nuclide.py @@ -470,6 +470,8 @@ class FissionYieldDistribution(Mapping): def restrict_products(self, possible_products): """Return a new distribution with select products + .. versionadded:: 0.12 + Parameters ---------- possible_products : iterable of str diff --git a/openmc/deplete/operator.py b/openmc/deplete/operator.py index c57d9b163c..7e7c2f9e1d 100644 --- a/openmc/deplete/operator.py +++ b/openmc/deplete/operator.py @@ -113,11 +113,15 @@ class Operator(TransportOperator): reduce_chain : bool, optional If True, use :meth:`openmc.deplete.Chain.reduce` to reduce the depletion chain up to ``reduce_chain_level``. Default is False. + + .. versionadded:: 0.12 reduce_chain_level : int, optional Depth of the search when reducing the depletion chain. Only used if ``reduce_chain`` evaluates to true. The default value of ``None`` implies no limit on the depth. + .. versionadded:: 0.12 + Attributes ---------- geometry : openmc.Geometry diff --git a/openmc/deplete/results_list.py b/openmc/deplete/results_list.py index db1f0ff9db..6267a0fccc 100644 --- a/openmc/deplete/results_list.py +++ b/openmc/deplete/results_list.py @@ -44,7 +44,6 @@ class ResultsList(list): """Get number of nuclides over time from a single material .. note:: - Initial values for some isotopes that do not appear in initial concentrations may be non-zero, depending on the value of :class:`openmc.deplete.Operator` ``dilute_initial``. @@ -59,10 +58,14 @@ class ResultsList(list): Nuclide name to evaluate nuc_units : {"atoms", "atom/b-cm", "atom/cm3"}, optional Units for the returned concentration. Default is ``"atoms"`` + + .. versionadded:: 0.12 time_units : {"s", "min", "h", "d"}, optional Units for the returned time array. Default is ``"s"`` to return the value in seconds. + .. versionadded:: 0.12 + Returns ------- time : numpy.ndarray diff --git a/openmc/element.py b/openmc/element.py index 1cf7cdf1fa..1a258715fe 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -59,9 +59,13 @@ class Element(str): enriched U. Default is None (natural composition). enrichment_target: str, optional Single nuclide name to enrich from a natural composition (e.g., 'O16') + + .. versionadded:: 0.12 enrichment_type: {'ao', 'wo'}, optional 'ao' for enrichment as atom percent and 'wo' for weight percent. Default is: 'ao' for two-isotope enrichment; 'wo' for U enrichment + + .. versionadded:: 0.12 cross_sections : str, optional Location of cross_sections.xml file. Default is None. diff --git a/openmc/executor.py b/openmc/executor.py index 55e16a711b..8d208795c7 100644 --- a/openmc/executor.py +++ b/openmc/executor.py @@ -184,6 +184,8 @@ def run(particles=None, threads=None, geometry_debug=False, event_based : bool, optional Turns on event-based parallelism, instead of default history-based + .. versionadded:: 0.12 + Raises ------ subprocess.CalledProcessError diff --git a/openmc/filter.py b/openmc/filter.py index 80827c6a45..f75770e267 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -530,6 +530,8 @@ class CellInstanceFilter(Filter): instances by default) and allows instances from different cells to be specified in a single filter. + .. versionadded:: 0.12 + Parameters ---------- bins : iterable of 2-tuples or numpy.ndarray diff --git a/openmc/geometry.py b/openmc/geometry.py index ac3da5368a..450f223b19 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -86,6 +86,8 @@ class Geometry: Whether or not to remove redundant surfaces from the geometry when exporting + .. versionadded:: 0.12 + """ # Find and remove redundant surfaces from the geometry if remove_surfs: @@ -389,7 +391,9 @@ class Geometry: return surfaces def get_redundant_surfaces(self): - """Return all of the topologically redundant surface ids + """Return all of the topologically redundant surface IDs + + .. versionadded:: 0.12 Returns ------- diff --git a/openmc/material.py b/openmc/material.py index 55d99d7232..92f5132c52 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -489,10 +489,14 @@ class Material(IDManagerMixin): Default is None (natural composition). enrichment_target: str, optional Single nuclide name to enrich from a natural composition (e.g., 'O16') + + .. versionadded:: 0.12 enrichment_type: {'ao', 'wo'}, optional 'ao' for enrichment as atom percent and 'wo' for weight percent. Default is: 'ao' for two-isotope enrichment; 'wo' for U enrichment + .. versionadded:: 0.12 + Notes ----- General enrichment procedure is allowed only for elements composed of @@ -561,6 +565,8 @@ class Material(IDManagerMixin): enrichment_target=None, enrichment_type=None): """Add a elements from a chemical formula to the material. + .. versionadded:: 0.12 + Parameters ---------- formula : str @@ -694,6 +700,8 @@ class Material(IDManagerMixin): def get_elements(self): """Returns all elements in the material + .. versionadded:: 0.12 + Returns ------- elements : list of str @@ -981,6 +989,8 @@ class Material(IDManagerMixin): def mix_materials(cls, materials, fracs, percent_type='ao', name=None): """Mix materials together based on atom, weight, or volume fractions + .. versionadded:: 0.12 + Parameters ---------- materials : Iterable of openmc.Material diff --git a/openmc/mesh.py b/openmc/mesh.py index d10ed1be87..86321df296 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -595,6 +595,8 @@ class RectilinearMesh(MeshBase): class UnstructuredMesh(MeshBase): """A 3D unstructured mesh + .. versionadded:: 0.12 + Parameters ---------- filename : str diff --git a/openmc/model/model.py b/openmc/model/model.py index 89dbfb3536..7d6acb281c 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -201,6 +201,10 @@ class Model: """Creates the XML files, runs OpenMC, and returns the path to the last statepoint file generated. + .. versionchanged:: 0.12 + Instead of returning the final k-effective value, this function now + returns the path to the final statepoint written. + Parameters ---------- **kwargs diff --git a/openmc/polynomial.py b/openmc/polynomial.py index c57b5fbdce..718fc668c5 100644 --- a/openmc/polynomial.py +++ b/openmc/polynomial.py @@ -42,6 +42,8 @@ class ZernikeRadial(Polynomial): The radial only Zernike polynomials are defined as in :class:`ZernikeRadialFilter`. + .. versionadded:: 0.12 + Parameters ---------- coef : Iterable of float @@ -85,6 +87,8 @@ class Zernike(Polynomial): The azimuthal Zernike polynomials are defined as in :class:`ZernikeFilter`. + .. versionadded:: 0.12 + Parameters ---------- coef : Iterable of float diff --git a/openmc/region.py b/openmc/region.py index 5016db651f..69273e5de9 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -64,6 +64,8 @@ class Region(ABC): def remove_redundant_surfaces(self, redundant_surfaces): """Recursively remove all redundant surfaces referenced by this region + .. versionadded:: 0.12 + Parameters ---------- redundant_surfaces : dict @@ -272,6 +274,8 @@ class Region(ABC): memo=None): r"""Rotate surface by angles provided or by applying matrix directly. + .. versionadded:: 0.12 + Parameters ---------- rotation : 3-tuple of float, or 3x3 iterable @@ -587,6 +591,8 @@ class Complement(Region): def remove_redundant_surfaces(self, redundant_surfaces): """Recursively remove all redundant surfaces referenced by this region + .. versionadded:: 0.12 + Parameters ---------- redundant_surfaces : dict diff --git a/openmc/settings.py b/openmc/settings.py index da7d52bb24..6774427554 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -49,6 +49,8 @@ class Settings: Indicate whether to scale the fission photon yield by (EGP + EGD)/EGP where EGP is the energy release of prompt photons and EGD is the energy release of delayed photons. + + .. versionadded:: 0.12 electron_treatment : {'led', 'ttb'} Whether to deposit all energy from electrons locally ('led') or create secondary bremsstrahlung photons ('ttb'). @@ -61,12 +63,18 @@ class Settings: event_based : bool Indicate whether to use event-based parallelism instead of the default history-based parallelism. + + .. versionadded:: 0.12 generations_per_batch : int Number of generations per batch max_lost_particles : int Maximum number of lost particles + + .. versionadded:: 0.12 rel_max_lost_particles : int Maximum number of lost particles, relative to the total number of particles + + .. versionadded:: 0.12 inactive : int Number of inactive batches keff_trigger : dict @@ -80,9 +88,13 @@ class Settings: material_cell_offsets : bool Generate an "offset table" for material cells by default. These tables are necessary when a particular instance of a cell needs to be tallied. + + .. versionadded:: 0.12 max_particles_in_flight : int Number of neutrons to run concurrently when using event-based parallelism. + + .. versionadded:: 0.12 max_order : None or int Maximum scattering order to apply globally when in multi-group mode. no_reduce : bool diff --git a/openmc/source.py b/openmc/source.py index a5e884cd5c..cc749c324f 100644 --- a/openmc/source.py +++ b/openmc/source.py @@ -22,6 +22,8 @@ class Source: Source file from which sites should be sampled library : str Path to a custom source library + + .. versionadded:: 0.12 strength : float Strength of the source particle : {'neutron', 'photon'} diff --git a/openmc/stats/multivariate.py b/openmc/stats/multivariate.py index 2b5f593536..664e760f71 100644 --- a/openmc/stats/multivariate.py +++ b/openmc/stats/multivariate.py @@ -378,6 +378,8 @@ class SphericalIndependent(Spatial): :math:`\theta`, and :math:`\phi` components are sampled independently from one another and centered on the coordinates (x0, y0, z0). + .. versionadded: 0.12 + Parameters ---------- r : openmc.stats.Univariate @@ -498,6 +500,8 @@ class CylindricalIndependent(Spatial): one another and in a reference frame whose origin is specified by the coordinates (x0, y0, z0). + .. versionadded:: 0.12 + Parameters ---------- r : openmc.stats.Univariate diff --git a/openmc/surface.py b/openmc/surface.py index 0b977b6d9b..d71e73788e 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -68,6 +68,8 @@ def _future_kwargs_warning_helper(cls, *args, **kwargs): def get_rotation_matrix(rotation, order='xyz'): r"""Generate a 3x3 rotation matrix from input angles + .. versionadded:: 0.12 + Parameters ---------- rotation : 3-tuple of float @@ -266,6 +268,8 @@ class Surface(IDManagerMixin, ABC): def normalize(self, coeffs=None): """Normalize coefficients by first nonzero value + .. versionadded:: 0.12 + Parameters ---------- coeffs : tuple, optional @@ -347,6 +351,8 @@ class Surface(IDManagerMixin, ABC): def rotate(self, rotation, pivot=(0., 0., 0.), order='xyz', inplace=False): r"""Rotate surface by angles provided or by applying matrix directly. + .. versionadded:: 0.12 + Parameters ---------- rotation : 3-tuple of float, or 3x3 iterable @@ -1223,6 +1229,8 @@ class Cylinder(QuadricMixin, Surface): def from_points(cls, p1, p2, r=1., **kwargs): """Return a cylinder given points that define the axis and a radius. + .. versionadded:: 0.12 + Parameters ---------- p1, p2 : 3-tuples @@ -2294,6 +2302,8 @@ class Halfspace(Region): memo=None): r"""Rotate surface by angles provided or by applying matrix directly. + .. versionadded:: 0.12 + Parameters ---------- rotation : 3-tuple of float, or 3x3 iterable diff --git a/openmc/volume.py b/openmc/volume.py index f7849ce0a0..65307a503e 100644 --- a/openmc/volume.py +++ b/openmc/volume.py @@ -45,8 +45,6 @@ class VolumeCalculation: Lower-left coordinates of bounding box used to sample points upper_right : Iterable of float Upper-right coordinates of bounding box used to sample points - threshold : float - Threshold for the maximum standard deviation of volume in the calculation atoms : dict Dictionary mapping unique IDs of domains to a mapping of nuclides to total number of atoms for each nuclide present in the domain. For @@ -58,11 +56,17 @@ class VolumeCalculation: Dictionary mapping unique IDs of domains to estimated volumes in cm^3. threshold : float Threshold for the maxmimum standard deviation of volumes. + + .. versionadded:: 0.12 trigger_type : {'variance', 'std_dev', 'rel_err'} Value type used to halt volume calculation + + .. versionadded:: 0.12 iterations : int Number of iterations over samples (for calculations with a trigger). + .. versionadded:: 0.12 + """ def __init__(self, domains, samples, lower_left=None, upper_right=None): self._atoms = {} @@ -225,6 +229,8 @@ class VolumeCalculation: def set_trigger(self, threshold, trigger_type): """Set a trigger on the voulme calculation + .. versionadded:: 0.12 + Parameters ---------- threshold : float