diff --git a/docs/source/conf.py b/docs/source/conf.py index db44e34f4..b25d5abbe 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -21,12 +21,14 @@ on_rtd = os.environ.get('READTHEDOCS', None) == 'True' from unittest.mock import MagicMock -MOCK_MODULES = ['numpy', 'numpy.polynomial', 'numpy.polynomial.polynomial', - 'numpy.ctypeslib', 'scipy', 'scipy.sparse', 'scipy.interpolate', - 'scipy.integrate', 'scipy.optimize', 'scipy.special', - 'scipy.stats', 'scipy.spatial', 'h5py', 'pandas', 'uncertainties', - 'matplotlib', 'matplotlib.pyplot','openmoc', - 'openmc.data.reconstruct'] +MOCK_MODULES = [ + 'numpy', 'numpy.polynomial', 'numpy.polynomial.polynomial', + 'numpy.ctypeslib', 'scipy', 'scipy.sparse', 'scipy.sparse.linalg', + 'scipy.interpolate', 'scipy.integrate', 'scipy.optimize', 'scipy.special', + 'scipy.stats', 'scipy.spatial', 'h5py', 'pandas', 'uncertainties', + 'matplotlib', 'matplotlib.pyplot', 'tqdm', 'openmoc', + 'openmc.data.reconstruct' +] sys.modules.update((mod_name, MagicMock()) for mod_name in MOCK_MODULES) import numpy as np diff --git a/docs/source/pythonapi/deplete.rst b/docs/source/pythonapi/deplete.rst new file mode 100644 index 000000000..13f2fd155 --- /dev/null +++ b/docs/source/pythonapi/deplete.rst @@ -0,0 +1,62 @@ +.. _pythonapi_deplete: + +---------------------------------- +:mod:`openmc.deplete` -- Depletion +---------------------------------- + +Integrators +----------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.deplete.integrator.predictor + openmc.deplete.integrator.cecm + +Integrator Helper Functions +--------------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.deplete.integrator.CRAM16 + openmc.deplete.integrator.CRAM48 + openmc.deplete.integrator.save_results + +Metaclasses +----------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.deplete.TransportOperator + +OpenMC Classes +-------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.deplete.Operator + openmc.deplete.OperatorResult + +Data Classes +------------ +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.deplete.AtomNumber + openmc.deplete.Chain + openmc.deplete.Nuclide + openmc.deplete.ReactionRates + openmc.deplete.Results diff --git a/docs/source/pythonapi/deplete/index.rst b/docs/source/pythonapi/deplete/index.rst deleted file mode 100644 index f3212bd61..000000000 --- a/docs/source/pythonapi/deplete/index.rst +++ /dev/null @@ -1,54 +0,0 @@ -.. _api: - -================= -API Documentation -================= - -Integrators ------------ - -.. toctree:: - :maxdepth: 2 - - integrator.predictor - integrator.cecm - -Integrator Helper Functions ---------------------------- -.. toctree:: - :maxdepth: 2 - - integrator.CRAM16 - integrator.CRAM48 - integrator.save_results - -Metaclasses ------------ - -.. autosummary:: - :toctree: generated - :nosignatures: - - openmc.deplete.Operator - -OpenMC Classes --------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - - openmc.deplete.Materials - openmc.deplete.OpenMCOperator - -Data Classes ------------- -.. autosummary:: - :toctree: generated - :nosignatures: - - openmc.deplete.AtomNumber - openmc.deplete.Chain - openmc.deplete.Nuclide - openmc.deplete.ReactionRates - openmc.deplete.Results diff --git a/docs/source/pythonapi/deplete/integrator.CRAM16.rst b/docs/source/pythonapi/deplete/integrator.CRAM16.rst deleted file mode 100644 index a0dc64805..000000000 --- a/docs/source/pythonapi/deplete/integrator.CRAM16.rst +++ /dev/null @@ -1,6 +0,0 @@ -integrator\.CRAM16 -================== - -.. currentmodule:: openmc.deplete.integrator - -.. autofunction:: CRAM16 diff --git a/docs/source/pythonapi/deplete/integrator.CRAM48.rst b/docs/source/pythonapi/deplete/integrator.CRAM48.rst deleted file mode 100644 index f9720f7ad..000000000 --- a/docs/source/pythonapi/deplete/integrator.CRAM48.rst +++ /dev/null @@ -1,6 +0,0 @@ -integrator\.CRAM48 -================== - -.. currentmodule:: openmc.deplete.integrator - -.. autofunction:: CRAM48 diff --git a/docs/source/pythonapi/deplete/integrator.cecm.rst b/docs/source/pythonapi/deplete/integrator.cecm.rst deleted file mode 100644 index 4851b20b3..000000000 --- a/docs/source/pythonapi/deplete/integrator.cecm.rst +++ /dev/null @@ -1,6 +0,0 @@ -integrator\.cecm -================= - -.. currentmodule:: openmc.deplete.integrator - -.. autofunction:: cecm diff --git a/docs/source/pythonapi/deplete/integrator.predictor.rst b/docs/source/pythonapi/deplete/integrator.predictor.rst deleted file mode 100644 index 2243e77f7..000000000 --- a/docs/source/pythonapi/deplete/integrator.predictor.rst +++ /dev/null @@ -1,6 +0,0 @@ -integrator\.predictor -===================== - -.. currentmodule:: openmc.deplete.integrator - -.. autofunction:: predictor diff --git a/docs/source/pythonapi/deplete/integrator.save_results.rst b/docs/source/pythonapi/deplete/integrator.save_results.rst deleted file mode 100644 index f9c830cd5..000000000 --- a/docs/source/pythonapi/deplete/integrator.save_results.rst +++ /dev/null @@ -1,6 +0,0 @@ -integrator\.save_results -======================== - -.. currentmodule:: openmc.deplete.integrator - -.. autofunction:: save_results diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index 862acb238..3c28a2185 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -15,14 +15,15 @@ there are many substantial benefits to using the Python API, including: - The ability to define dimensions using variables. - Availability of standard-library modules for working with files. - An entire ecosystem of third-party packages for scientific computing. -- Ability to create materials based on natural elements or uranium enrichment - Automated multi-group cross section generation (:mod:`openmc.mgxs`) +- A fully-featured nuclear data interface (:mod:`openmc.data`) +- Depletion capability (:mod:`openmc.deplete`) - Convenience functions (e.g., a function returning a hexagonal region) - Ability to plot individual universes as geometry is being created - A :math:`k_\text{eff}` search function (:func:`openmc.search_for_keff`) - Random sphere packing for generating TRISO particle locations (:func:`openmc.model.pack_trisos`) -- A fully-featured nuclear data interface (:mod:`openmc.data`) +- Ability to create materials based on natural elements or uranium enrichment For those new to Python, there are many good tutorials available online. We recommend going through the modules from `Codecademy @@ -45,6 +46,7 @@ Modules base model examples + deplete mgxs stats data diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index 9d53f40bf..53e71c195 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -12,15 +12,33 @@ from abc import ABCMeta, abstractmethod from .chain import Chain OperatorResult = namedtuple('OperatorResult', ['k', 'rates']) +OperatorResult.__doc__ = """\ +Result of applying transport operator + +Parameters +---------- +k : float + Resulting eigenvalue +rates : openmc.deplete.ReactionRates + Resulting reaction rates + +""" -class Operator(metaclass=ABCMeta): +class TransportOperator(metaclass=ABCMeta): """Abstract class defining a transport operator + Each depletion integrator is written to work with a generic transport + operator that takes a vector of material compositions and returns an + eigenvalue and reaction rates. This abstract class sets the requirements for + such a transport operator. Users should instantiate + :class:`openmc.deplete.Operator` rather than this class. + Parameters ---------- chain_file : str, optional - + Path to the depletion chain XML file. Defaults to the + :envvar:`OPENMC_DEPLETE_CHAIN` environment variable if it exists. Attributes ---------- diff --git a/openmc/deplete/chain.py b/openmc/deplete/chain.py index 9ffc3d93e..348103ea9 100644 --- a/openmc/deplete/chain.py +++ b/openmc/deplete/chain.py @@ -321,9 +321,6 @@ class Chain(object): filename : str The path to the depletion chain XML file. - Todo - ---- - Allow for branching on capture, etc. """ chain = cls() diff --git a/openmc/deplete/integrator/cecm.py b/openmc/deplete/integrator/cecm.py index 7d6c11190..db58d5d52 100644 --- a/openmc/deplete/integrator/cecm.py +++ b/openmc/deplete/integrator/cecm.py @@ -8,10 +8,11 @@ from .save_results import save_results def cecm(operator, timesteps, power, print_out=True): - r"""The CE/CM integrator. + r"""Deplete using the CE/CM algorithm. - Implements the second order CE/CM Predictor-Corrector algorithm [ref]_. - This algorithm is mathematically defined as: + Implements the second order `CE/CM Predictor-Corrector algorithm + `_. This algorithm is mathematically + defined as: .. math:: y' &= A(y, t) y(t) @@ -24,17 +25,12 @@ def cecm(operator, timesteps, power, print_out=True): y_{n+1} &= \text{expm}(A_c h) y_n - .. [ref] - Isotalo, Aarno. "Comparison of Neutronics-Depletion Coupling Schemes - for Burnup Calculations-Continued Study." Nuclear Science and - Engineering 180.3 (2015): 286-300. - Parameters ---------- - operator : openmc.deplete.Operator + operator : openmc.deplete.TransportOperator The operator object to simulate on. timesteps : iterable of float - Array of timesteps in units of [s] + Array of timesteps in units of [s]. Note that values are not cumulative. power : float or iterable of float Power of the reactor in [W]. A single value indicates that the power is constant over all timesteps. An iterable indicates potentially different diff --git a/openmc/deplete/integrator/cram.py b/openmc/deplete/integrator/cram.py index 09207fbc6..85954603a 100644 --- a/openmc/deplete/integrator/cram.py +++ b/openmc/deplete/integrator/cram.py @@ -48,7 +48,7 @@ def deplete(chain, x, op_result, dt, print_out): # Use multiprocessing pool to distribute work with Pool() as pool: iters = zip(chains, vecs, rates, dts) - x_result = list(pool.starmap(cram_wrapper, iters)) + x_result = list(pool.starmap(_cram_wrapper, iters)) t_end = time.time() if comm.rank == 0: @@ -58,7 +58,7 @@ def deplete(chain, x, op_result, dt, print_out): return x_result -def cram_wrapper(chain, n0, rates, dt): +def _cram_wrapper(chain, n0, rates, dt): """Wraps depletion matrix creation / CRAM solve for multiprocess execution Parameters @@ -82,16 +82,11 @@ def cram_wrapper(chain, n0, rates, dt): def CRAM16(A, n0, dt): - """ Chebyshev Rational Approximation Method, order 16 + """Chebyshev Rational Approximation Method, order 16 Algorithm is the 16th order Chebyshev Rational Approximation Method, - implemented in the more stable incomplete partial fraction (IPF) form - [cram16]_. - - .. [cram16] - Pusa, Maria. "Higher-Order Chebyshev Rational Approximation Method and - Application to Burnup Equations." Nuclear Science and Engineering 182.3 - (2016). + implemented in the more stable `incomplete partial fraction (IPF) + `_ form. Parameters ---------- @@ -106,6 +101,7 @@ def CRAM16(A, n0, dt): ------- numpy.array Results of the matrix exponent. + """ alpha = np.array([+2.124853710495224e-16, @@ -144,16 +140,11 @@ def CRAM16(A, n0, dt): def CRAM48(A, n0, dt): - """ Chebyshev Rational Approximation Method, order 48 + """Chebyshev Rational Approximation Method, order 48 Algorithm is the 48th order Chebyshev Rational Approximation Method, - implemented in the more stable incomplete partial fraction (IPF) form - [cram48]_. - - .. [cram48] - Pusa, Maria. "Higher-Order Chebyshev Rational Approximation Method and - Application to Burnup Equations." Nuclear Science and Engineering 182.3 - (2016). + implemented in the more stable `incomplete partial fraction (IPF) + `_ form. Parameters ---------- @@ -168,6 +159,7 @@ def CRAM48(A, n0, dt): ------- numpy.array Results of the matrix exponent. + """ theta_r = np.array([-4.465731934165702e+1, -5.284616241568964e+0, diff --git a/openmc/deplete/integrator/predictor.py b/openmc/deplete/integrator/predictor.py index 038c0778d..444ca7baa 100644 --- a/openmc/deplete/integrator/predictor.py +++ b/openmc/deplete/integrator/predictor.py @@ -22,10 +22,10 @@ def predictor(operator, timesteps, power, print_out=True): Parameters ---------- - operator : openmc.deplete.Operator + operator : openmc.deplete.TransportOperator The operator object to simulate on. timesteps : iterable of float - Array of timesteps in units of [s] + Array of timesteps in units of [s]. Note that values are not cumulative. power : float or iterable of float Power of the reactor in [W]. A single value indicates that the power is constant over all timesteps. An iterable indicates potentially different diff --git a/openmc/deplete/integrator/save_results.py b/openmc/deplete/integrator/save_results.py index 8a0ae9204..40d2f70b6 100644 --- a/openmc/deplete/integrator/save_results.py +++ b/openmc/deplete/integrator/save_results.py @@ -9,7 +9,7 @@ def save_results(op, x, op_results, t, step_ind): Parameters ---------- - op : openmc.deplete.Operator + op : openmc.deplete.TransportOperator The operator used to generate these results. x : list of list of numpy.array The prior x vectors. Indexed [i][cell] using the above equation. diff --git a/openmc/deplete/openmc_wrapper.py b/openmc/deplete/openmc_wrapper.py index 12ed27f22..5104ab2f1 100644 --- a/openmc/deplete/openmc_wrapper.py +++ b/openmc/deplete/openmc_wrapper.py @@ -1,6 +1,10 @@ -"""The OpenMC wrapper module. +"""OpenMC transport operator + +This module implements a transport operator for OpenMC so that it can be used by +depletion integrators. The implementation makes use of the Python bindings to +OpenMC's C API so that reading tally results and updating material number +densities is all done in-memory instead of through the filesystem. -This module implements the depletion -> OpenMC linkage. """ import copy @@ -24,7 +28,7 @@ import openmc import openmc.capi from openmc.data import JOULE_PER_EV from . import comm -from .abc import Operator, OperatorResult +from .abc import TransportOperator, OperatorResult from .atom_number import AtomNumber from .reaction_rates import ReactionRates @@ -39,8 +43,8 @@ def _distribute(items): j += chunk_size -class OpenMCOperator(Operator): - """OpenMC transport operator +class Operator(TransportOperator): + """OpenMC transport operator for depletion Parameters ---------- diff --git a/tests/dummy_geometry.py b/tests/dummy_operator.py similarity index 95% rename from tests/dummy_geometry.py rename to tests/dummy_operator.py index ca2efd663..706793d93 100644 --- a/tests/dummy_geometry.py +++ b/tests/dummy_operator.py @@ -1,11 +1,11 @@ import numpy as np import scipy.sparse as sp from openmc.deplete.reaction_rates import ReactionRates -from openmc.deplete.abc import Operator, OperatorResult +from openmc.deplete.abc import TransportOperator, OperatorResult -class DummyGeometry(Operator): - """This is a dummy geometry class with no statistical uncertainty. +class DummyOperator(TransportOperator): + """This is a dummy operator class with no statistical uncertainty. y_1' = sin(y_2) y_1 + cos(y_1) y_2 y_2' = -cos(y_2) y_1 + sin(y_1) y_2 diff --git a/tests/regression_tests/test_deplete_full.py b/tests/regression_tests/test_deplete_full.py index 22125d039..2286af908 100644 --- a/tests/regression_tests/test_deplete_full.py +++ b/tests/regression_tests/test_deplete_full.py @@ -44,7 +44,7 @@ def test_full(run_in_tmpdir): # Create operator chain_file = Path(__file__).parents[2] / 'chains' / 'chain_simple.xml' - op = openmc.deplete.OpenMCOperator(geometry, settings, chain_file) + op = openmc.deplete.Operator(geometry, settings, chain_file) op.round_number = True # Power and timesteps diff --git a/tests/regression_tests/test_deplete_utilities.py b/tests/regression_tests/test_deplete_utilities.py index f38129cc7..82d4d56a4 100644 --- a/tests/regression_tests/test_deplete_utilities.py +++ b/tests/regression_tests/test_deplete_utilities.py @@ -14,7 +14,7 @@ from openmc.deplete import utilities @pytest.fixture def res(): """Load the reference results""" - filename = str(Path(__file__).with_name('test_reference.h5')) + filename = Path(__file__).with_name('test_reference.h5') return results.read_results(filename) diff --git a/tests/unit_tests/test_deplete_cecm.py b/tests/unit_tests/test_deplete_cecm.py index 97659b892..6deb6cd3d 100644 --- a/tests/unit_tests/test_deplete_cecm.py +++ b/tests/unit_tests/test_deplete_cecm.py @@ -8,13 +8,13 @@ import openmc.deplete from openmc.deplete import results from openmc.deplete import utilities -from tests import dummy_geometry +from tests import dummy_operator def test_cecm(run_in_tmpdir): """Integral regression test of integrator algorithm using CE/CM.""" - op = dummy_geometry.DummyGeometry() + op = dummy_operator.DummyOperator() op.output_dir = "test_integrator_regression" # Perform simulation using the MCNPX/MCNP6 algorithm diff --git a/tests/unit_tests/test_deplete_predictor.py b/tests/unit_tests/test_deplete_predictor.py index 42a3c13a3..0d283855c 100644 --- a/tests/unit_tests/test_deplete_predictor.py +++ b/tests/unit_tests/test_deplete_predictor.py @@ -8,13 +8,13 @@ import openmc.deplete from openmc.deplete import results from openmc.deplete import utilities -from tests import dummy_geometry +from tests import dummy_operator def test_predictor(run_in_tmpdir): """Integral regression test of integrator algorithm using predictor/corrector""" - op = dummy_geometry.DummyGeometry() + op = dummy_operator.DummyOperator() op.output_dir = "test_integrator_regression" # Perform simulation using the predictor algorithm