From 0b77cc7edc6ec1d83a45e10a4beb2ebbf0aba34b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 28 Apr 2022 17:11:21 -0500 Subject: [PATCH 1/9] Allow normal instantiation of ResultsList (instead of from_hdf5) --- docs/source/usersguide/depletion.rst | 2 +- .../pincell_depletion/restart_depletion.py | 4 +-- examples/pincell_depletion/run_depletion.py | 2 +- openmc/deplete/abc.py | 2 +- openmc/deplete/results.py | 7 +++- openmc/deplete/results_list.py | 36 ++++++++++++------- tests/regression_tests/deplete/test.py | 6 ++-- tests/unit_tests/test_deplete_activation.py | 4 +-- tests/unit_tests/test_deplete_integrator.py | 5 ++- tests/unit_tests/test_deplete_restart.py | 10 +++--- tests/unit_tests/test_deplete_resultslist.py | 2 +- tests/unit_tests/test_transfer_volumes.py | 2 +- 12 files changed, 48 insertions(+), 34 deletions(-) diff --git a/docs/source/usersguide/depletion.rst b/docs/source/usersguide/depletion.rst index 78a12c4ca..e3f4017f2 100644 --- a/docs/source/usersguide/depletion.rst +++ b/docs/source/usersguide/depletion.rst @@ -53,7 +53,7 @@ The coupled transport-depletion problem is executed, and once it is done a easy retrieval of k-effective, nuclide concentrations, and reaction rates over time:: - results = openmc.deplete.ResultsList.from_hdf5("depletion_results.h5") + results = openmc.deplete.ResultsList("depletion_results.h5") time, keff = results.get_keff() Note that the coupling between the transport solver and the transmutation solver diff --git a/examples/pincell_depletion/restart_depletion.py b/examples/pincell_depletion/restart_depletion.py index 72209d2ab..45bb4343d 100644 --- a/examples/pincell_depletion/restart_depletion.py +++ b/examples/pincell_depletion/restart_depletion.py @@ -12,7 +12,7 @@ with openmc.StatePoint(statepoint) as sp: geometry = sp.summary.geometry # Load previous depletion results -previous_results = openmc.deplete.ResultsList.from_hdf5("depletion_results.h5") +previous_results = openmc.deplete.ResultsList("depletion_results.h5") ############################################################################### # Transport calculation settings @@ -56,7 +56,7 @@ integrator.integrate() ############################################################################### # Open results file -results = openmc.deplete.ResultsList.from_hdf5("depletion_results.h5") +results = openmc.deplete.ResultsList("depletion_results.h5") # Obtain K_eff as a function of time time, keff = results.get_keff(time_units='d') diff --git a/examples/pincell_depletion/run_depletion.py b/examples/pincell_depletion/run_depletion.py index 53b0614d1..727039a29 100644 --- a/examples/pincell_depletion/run_depletion.py +++ b/examples/pincell_depletion/run_depletion.py @@ -101,7 +101,7 @@ integrator.integrate() ############################################################################### # Open results file -results = openmc.deplete.ResultsList.from_hdf5("depletion_results.h5") +results = openmc.deplete.ResultsList("depletion_results.h5") # Obtain K_eff as a function of time time, keff = results.get_keff(time_units='d') diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index 0d1e8ad41..7c3fc42f7 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -842,7 +842,7 @@ class Integrator(ABC): k = ufloat(res.k[0, 0], res.k[0, 1]) # Scale reaction rates by ratio of source rates - rates *= source_rate / res.source_rate[0] + rates *= source_rate / res.source_rate return bos_conc, OperatorResult(k, rates) def _get_start_data(self): diff --git a/openmc/deplete/results.py b/openmc/deplete/results.py index 3916fb4d7..9ff07b049 100644 --- a/openmc/deplete/results.py +++ b/openmc/deplete/results.py @@ -69,6 +69,11 @@ class Results: self.data = None + def __repr__(self): + t = self.time[0] + dt = self.time[1] - self.time[0] + return f"" + def __getitem__(self, pos): """Retrieves an item from results. @@ -406,7 +411,7 @@ class Results: results.data = number_dset[step, :, :, :] results.k = eigenvalues_dset[step, :] results.time = time_dset[step, :] - results.source_rate = source_rate_dset[step, :] + results.source_rate = source_rate_dset[step, 0] if "depletion time" in handle: proc_time_dset = handle["/depletion time"] diff --git a/openmc/deplete/results_list.py b/openmc/deplete/results_list.py index f2f2be0ab..843e3aec6 100644 --- a/openmc/deplete/results_list.py +++ b/openmc/deplete/results_list.py @@ -29,9 +29,24 @@ def _get_time_as(seconds, units): class ResultsList(list): """A list of openmc.deplete.Results objects - It is recommended to use :meth:`from_hdf5` over - direct creation. + Parameters + ---------- + filename : str + Path to depletion result file + """ + def __init__(self, filename): + with h5py.File(str(filename), "r") as fh: + cv.check_filetype_version(fh, 'depletion results', VERSION_RESULTS[0]) + data = [] + + # Get number of results stored + n = fh["number"][...].shape[0] + + for i in range(n): + data.append(Results.from_hdf5(fh, i)) + super().__init__(data) + @classmethod def from_hdf5(cls, filename): @@ -46,17 +61,14 @@ class ResultsList(list): ------- new : ResultsList New instance of depletion results + """ - with h5py.File(str(filename), "r") as fh: - cv.check_filetype_version(fh, 'depletion results', VERSION_RESULTS[0]) - new = cls() - - # Get number of results stored - n = fh["number"][...].shape[0] - - for i in range(n): - new.append(Results.from_hdf5(fh, i)) - return new + warn( + "The from_hdf5(...) method is no longer necessary and will be removed " + "in a future version of OpenMC. Use ResultsList(...) instead.", + FutureWarning + ) + return cls(filename) def get_atoms(self, mat, nuc, nuc_units="atoms", time_units="s"): """Get number of nuclides over time from a single material diff --git a/tests/regression_tests/deplete/test.py b/tests/regression_tests/deplete/test.py index 4f0e738a3..91f18667e 100644 --- a/tests/regression_tests/deplete/test.py +++ b/tests/regression_tests/deplete/test.py @@ -77,8 +77,8 @@ def test_full(run_in_tmpdir, problem, multiproc): return # Load the reference/test results - res_test = openmc.deplete.ResultsList.from_hdf5(path_test) - res_ref = openmc.deplete.ResultsList.from_hdf5(path_reference) + res_test = openmc.deplete.ResultsList(path_test) + res_ref = openmc.deplete.ResultsList(path_reference) # Assert same mats for mat in res_ref[0].mat_to_ind: @@ -139,7 +139,7 @@ def test_depletion_results_to_material(run_in_tmpdir, problem): """Checks openmc.Materials objects can be created from depletion results""" # Load the reference/test results path_reference = Path(__file__).with_name('test_reference.h5') - res_ref = openmc.deplete.ResultsList.from_hdf5(path_reference) + res_ref = openmc.deplete.ResultsList(path_reference) # Firstly need to export materials.xml file for the initial simulation state geometry, lower_left, upper_right = problem diff --git a/tests/unit_tests/test_deplete_activation.py b/tests/unit_tests/test_deplete_activation.py index 2f02ec4b8..2c3e0c053 100644 --- a/tests/unit_tests/test_deplete_activation.py +++ b/tests/unit_tests/test_deplete_activation.py @@ -107,7 +107,7 @@ def test_activation(run_in_tmpdir, model, reaction_rate_mode, reaction_rate_opts integrator.integrate() # Get resulting number of atoms - results = openmc.deplete.ResultsList.from_hdf5('depletion_results.h5') + results = openmc.deplete.ResultsList('depletion_results.h5') _, atoms = results.get_atoms(w, "W186") assert atoms[0] == pytest.approx(n0) @@ -155,7 +155,7 @@ def test_decay(run_in_tmpdir): integrator.integrate() # Get resulting number of atoms - results = openmc.deplete.ResultsList.from_hdf5('depletion_results.h5') + results = openmc.deplete.ResultsList('depletion_results.h5') _, atoms = results.get_atoms(mat, "Sr89") # Ensure density goes down by a factor of 2 after each half-life diff --git a/tests/unit_tests/test_deplete_integrator.py b/tests/unit_tests/test_deplete_integrator.py index a08d8738c..9c53ad7e2 100644 --- a/tests/unit_tests/test_deplete_integrator.py +++ b/tests/unit_tests/test_deplete_integrator.py @@ -103,7 +103,7 @@ def test_results_save(run_in_tmpdir): Results.save(op, x2, op_result2, t2, 0, 1) # Load the files - res = ResultsList.from_hdf5("depletion_results.h5") + res = ResultsList("depletion_results.h5") for i in range(stages): for mat_i, mat in enumerate(burn_list): @@ -176,8 +176,7 @@ def test_integrator(run_in_tmpdir, scheme): # get expected results - res = ResultsList.from_hdf5( - operator.output_dir / "depletion_results.h5") + res = ResultsList(operator.output_dir / "depletion_results.h5") t1, y1 = res.get_atoms("1", "1") t2, y2 = res.get_atoms("1", "2") diff --git a/tests/unit_tests/test_deplete_restart.py b/tests/unit_tests/test_deplete_restart.py index 82ef05ac7..2bfcfea7d 100644 --- a/tests/unit_tests/test_deplete_restart.py +++ b/tests/unit_tests/test_deplete_restart.py @@ -24,8 +24,7 @@ def test_restart_predictor_cecm(run_in_tmpdir): openmc.deplete.PredictorIntegrator(op, dt, power).integrate() # Load the files - prev_res = openmc.deplete.ResultsList.from_hdf5( - op.output_dir / "depletion_results.h5") + prev_res = openmc.deplete.ResultsList(op.output_dir / "depletion_results.h5") # Re-create depletion operator and load previous results op = dummy_operator.DummyOperator(prev_res) @@ -51,8 +50,7 @@ def test_restart_cecm_predictor(run_in_tmpdir): cecm.integrate() # Load the files - prev_res = openmc.deplete.ResultsList.from_hdf5( - op.output_dir / "depletion_results.h5") + prev_res = openmc.deplete.ResultsList(op.output_dir / "depletion_results.h5") # Re-create depletion operator and load previous results op = dummy_operator.DummyOperator(prev_res) @@ -75,7 +73,7 @@ def test_restart(run_in_tmpdir, scheme): bundle.solver(operator, [0.75], 1.0).integrate() # restart - prev_res = openmc.deplete.ResultsList.from_hdf5( + prev_res = openmc.deplete.ResultsList( operator.output_dir / "depletion_results.h5") operator = dummy_operator.DummyOperator(prev_res) @@ -84,7 +82,7 @@ def test_restart(run_in_tmpdir, scheme): # compare results - results = openmc.deplete.ResultsList.from_hdf5( + results = openmc.deplete.ResultsList( operator.output_dir / "depletion_results.h5") _t, y1 = results.get_atoms("1", "1") diff --git a/tests/unit_tests/test_deplete_resultslist.py b/tests/unit_tests/test_deplete_resultslist.py index 03e7c3eb0..2554d2188 100644 --- a/tests/unit_tests/test_deplete_resultslist.py +++ b/tests/unit_tests/test_deplete_resultslist.py @@ -13,7 +13,7 @@ def res(): """Load the reference results""" filename = (Path(__file__).parents[1] / 'regression_tests' / 'deplete' / 'test_reference.h5') - return openmc.deplete.ResultsList.from_hdf5(filename) + return openmc.deplete.ResultsList(filename) def test_get_atoms(res): diff --git a/tests/unit_tests/test_transfer_volumes.py b/tests/unit_tests/test_transfer_volumes.py index e1f3c1053..50e222b95 100644 --- a/tests/unit_tests/test_transfer_volumes.py +++ b/tests/unit_tests/test_transfer_volumes.py @@ -19,7 +19,7 @@ def test_transfer_volumes(run_in_tmpdir): PredictorIntegrator(op, dt, power).integrate() # Load the files - res = openmc.deplete.ResultsList.from_hdf5(op.output_dir / "depletion_results.h5") + res = openmc.deplete.ResultsList(op.output_dir / "depletion_results.h5") # Create a dictionary of volumes to transfer res[0].volume['1'] = 1.5 From aacf3c4938f2ce04ec9b75794f4a73f6bb162442 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 28 Apr 2022 17:18:00 -0500 Subject: [PATCH 2/9] Rename deplete.Results -> deplete.StepResult --- docs/source/pythonapi/deplete.rst | 2 +- openmc/deplete/abc.py | 10 +++++----- openmc/deplete/results.py | 14 +++++++------- openmc/deplete/results_list.py | 12 ++++++++---- tests/unit_tests/test_deplete_integrator.py | 6 +++--- tests/unit_tests/test_deplete_resultslist.py | 2 +- 6 files changed, 25 insertions(+), 21 deletions(-) diff --git a/docs/source/pythonapi/deplete.rst b/docs/source/pythonapi/deplete.rst index 383268f8b..41be2d88a 100644 --- a/docs/source/pythonapi/deplete.rst +++ b/docs/source/pythonapi/deplete.rst @@ -133,8 +133,8 @@ data, such as number densities and reaction rates for each material. AtomNumber OperatorResult ReactionRates - Results ResultsList + StepResult The following class and functions are used to solve the depletion equations, with :func:`cram.CRAM48` being the default. diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index 7c3fc42f7..7d6e33924 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -22,7 +22,7 @@ from uncertainties import ufloat from openmc.lib import MaterialFilter, Tally from openmc.checkvalue import check_type, check_greater_than from openmc.mpi import comm -from .results import Results +from .results import StepResult from .chain import Chain from .results_list import ResultsList from .pool import deplete @@ -889,7 +889,7 @@ class Integrator(ABC): # Remove actual EOS concentration for next step conc = conc_list.pop() - Results.save(self.operator, conc_list, res_list, [t, t + dt], + StepResult.save(self.operator, conc_list, res_list, [t, t + dt], source_rate, self._i_res + i, proc_time) t += dt @@ -901,7 +901,7 @@ class Integrator(ABC): if output and final_step: print(f"[openmc.deplete] t={t} (final operator evaluation)") res_list = [self.operator(conc, source_rate if final_step else 0.0)] - Results.save(self.operator, [conc], res_list, [t, t], + StepResult.save(self.operator, [conc], res_list, [t, t], source_rate, self._i_res + len(self), proc_time) self.operator.write_bos_data(len(self) + self._i_res) @@ -1048,13 +1048,13 @@ class SIIntegrator(Integrator): # Remove actual EOS concentration for next step conc = conc_list.pop() - Results.save(self.operator, conc_list, res_list, [t, t + dt], + StepResult.save(self.operator, conc_list, res_list, [t, t + dt], p, self._i_res + i, proc_time) t += dt # No final simulation for SIE, use last iteration results - Results.save(self.operator, [conc], [res_list[-1]], [t, t], + StepResult.save(self.operator, [conc], [res_list[-1]], [t, t], p, self._i_res + len(self), proc_time) self.operator.write_bos_data(self._i_res + len(self)) diff --git a/openmc/deplete/results.py b/openmc/deplete/results.py index 9ff07b049..bfd165481 100644 --- a/openmc/deplete/results.py +++ b/openmc/deplete/results.py @@ -16,10 +16,10 @@ from .reaction_rates import ReactionRates VERSION_RESULTS = (1, 1) -__all__ = ["Results"] +__all__ = ["StepResult"] -class Results: +class StepResult: """Output of a depletion run Attributes @@ -72,7 +72,7 @@ class Results: def __repr__(self): t = self.time[0] dt = self.time[1] - self.time[0] - return f"" + return f"" def __getitem__(self, pos): """Retrieves an item from results. @@ -139,7 +139,7 @@ class Results: return self.data.shape[0] def allocate(self, volume, nuc_list, burn_list, full_burn_list, stages): - """Allocates memory of Results. + """Allocate memory for depletion step data Parameters ---------- @@ -177,10 +177,10 @@ class Results: Returns ------- - Results + StepResult New results object """ - new = Results() + new = StepResult() new.volume = {lm: self.volume[lm] for lm in local_materials} new.mat_to_ind = {mat: idx for (idx, mat) in enumerate(local_materials)} @@ -485,7 +485,7 @@ class Results: stages = len(x) # Create results - results = Results() + results = StepResult() results.allocate(vol_dict, nuc_list, burn_list, full_burn_list, stages) n_mat = len(burn_list) diff --git a/openmc/deplete/results_list.py b/openmc/deplete/results_list.py index 843e3aec6..97170f226 100644 --- a/openmc/deplete/results_list.py +++ b/openmc/deplete/results_list.py @@ -6,7 +6,7 @@ from warnings import warn import h5py import numpy as np -from .results import Results, VERSION_RESULTS +from .results import StepResult, VERSION_RESULTS import openmc.checkvalue as cv from openmc.data.library import DataLibrary from openmc.material import Material, Materials @@ -27,7 +27,11 @@ def _get_time_as(seconds, units): class ResultsList(list): - """A list of openmc.deplete.Results objects + """Results from a depletion simulation + + The :class:`ResultsList` class acts as a list that stores the results from + each depletion step and provides extra methods for interrogating these + results. Parameters ---------- @@ -44,7 +48,7 @@ class ResultsList(list): n = fh["number"][...].shape[0] for i in range(n): - data.append(Results.from_hdf5(fh, i)) + data.append(StepResult.from_hdf5(fh, i)) super().__init__(data) @@ -59,7 +63,7 @@ class ResultsList(list): Returns ------- - new : ResultsList + ResultsList New instance of depletion results """ diff --git a/tests/unit_tests/test_deplete_integrator.py b/tests/unit_tests/test_deplete_integrator.py index 9c53ad7e2..4348b8c34 100644 --- a/tests/unit_tests/test_deplete_integrator.py +++ b/tests/unit_tests/test_deplete_integrator.py @@ -16,7 +16,7 @@ import pytest from openmc.mpi import comm from openmc.deplete import ( - ReactionRates, Results, ResultsList, OperatorResult, PredictorIntegrator, + ReactionRates, StepResult, ResultsList, OperatorResult, PredictorIntegrator, CECMIntegrator, CF4Integrator, CELIIntegrator, EPCRK4Integrator, LEQIIntegrator, SICELIIntegrator, SILEQIIntegrator, cram) @@ -99,8 +99,8 @@ def test_results_save(run_in_tmpdir): for k, rates in zip(eigvl1, rate1)] op_result2 = [OperatorResult(ufloat(*k), rates) for k, rates in zip(eigvl2, rate2)] - Results.save(op, x1, op_result1, t1, 0, 0) - Results.save(op, x2, op_result2, t2, 0, 1) + StepResult.save(op, x1, op_result1, t1, 0, 0) + StepResult.save(op, x2, op_result2, t2, 0, 1) # Load the files res = ResultsList("depletion_results.h5") diff --git a/tests/unit_tests/test_deplete_resultslist.py b/tests/unit_tests/test_deplete_resultslist.py index 2554d2188..2a2669920 100644 --- a/tests/unit_tests/test_deplete_resultslist.py +++ b/tests/unit_tests/test_deplete_resultslist.py @@ -87,7 +87,7 @@ def test_get_steps(unit): conversion_to_seconds = 1 for ix in range(times.size): - res = openmc.deplete.Results() + res = openmc.deplete.StepResult() res.time = times[ix:ix + 1] * conversion_to_seconds results.append(res) From 8bfb1889b972ed31ab48da6b5c88810c8ddc38c2 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 28 Apr 2022 17:20:55 -0500 Subject: [PATCH 3/9] Rename deplete.ResultsList -> deplete.Results --- docs/source/pythonapi/deplete.rst | 2 +- docs/source/usersguide/depletion.rst | 4 ++-- examples/pincell_depletion/restart_depletion.py | 4 ++-- examples/pincell_depletion/run_depletion.py | 2 +- openmc/deplete/abc.py | 8 ++++---- openmc/deplete/operator.py | 12 ++++++------ openmc/deplete/results_list.py | 10 +++++----- tests/regression_tests/deplete/test.py | 6 +++--- tests/unit_tests/test_deplete_activation.py | 4 ++-- tests/unit_tests/test_deplete_integrator.py | 6 +++--- tests/unit_tests/test_deplete_restart.py | 8 ++++---- tests/unit_tests/test_deplete_resultslist.py | 8 ++++---- tests/unit_tests/test_transfer_volumes.py | 4 ++-- 13 files changed, 39 insertions(+), 39 deletions(-) diff --git a/docs/source/pythonapi/deplete.rst b/docs/source/pythonapi/deplete.rst index 41be2d88a..9f7d8c447 100644 --- a/docs/source/pythonapi/deplete.rst +++ b/docs/source/pythonapi/deplete.rst @@ -133,7 +133,7 @@ data, such as number densities and reaction rates for each material. AtomNumber OperatorResult ReactionRates - ResultsList + Results StepResult The following class and functions are used to solve the depletion equations, diff --git a/docs/source/usersguide/depletion.rst b/docs/source/usersguide/depletion.rst index e3f4017f2..57619611f 100644 --- a/docs/source/usersguide/depletion.rst +++ b/docs/source/usersguide/depletion.rst @@ -49,11 +49,11 @@ one of these functions along with the timesteps and power level:: The coupled transport-depletion problem is executed, and once it is done a ``depletion_results.h5`` file is written. The results can be analyzed using the -:class:`openmc.deplete.ResultsList` class. This class has methods that allow for +:class:`openmc.deplete.Results` class. This class has methods that allow for easy retrieval of k-effective, nuclide concentrations, and reaction rates over time:: - results = openmc.deplete.ResultsList("depletion_results.h5") + results = openmc.deplete.Results("depletion_results.h5") time, keff = results.get_keff() Note that the coupling between the transport solver and the transmutation solver diff --git a/examples/pincell_depletion/restart_depletion.py b/examples/pincell_depletion/restart_depletion.py index 45bb4343d..95bbb9954 100644 --- a/examples/pincell_depletion/restart_depletion.py +++ b/examples/pincell_depletion/restart_depletion.py @@ -12,7 +12,7 @@ with openmc.StatePoint(statepoint) as sp: geometry = sp.summary.geometry # Load previous depletion results -previous_results = openmc.deplete.ResultsList("depletion_results.h5") +previous_results = openmc.deplete.Results("depletion_results.h5") ############################################################################### # Transport calculation settings @@ -56,7 +56,7 @@ integrator.integrate() ############################################################################### # Open results file -results = openmc.deplete.ResultsList("depletion_results.h5") +results = openmc.deplete.Results("depletion_results.h5") # Obtain K_eff as a function of time time, keff = results.get_keff(time_units='d') diff --git a/examples/pincell_depletion/run_depletion.py b/examples/pincell_depletion/run_depletion.py index 727039a29..ae069334e 100644 --- a/examples/pincell_depletion/run_depletion.py +++ b/examples/pincell_depletion/run_depletion.py @@ -101,7 +101,7 @@ integrator.integrate() ############################################################################### # Open results file -results = openmc.deplete.ResultsList("depletion_results.h5") +results = openmc.deplete.Results("depletion_results.h5") # Obtain K_eff as a function of time time, keff = results.get_keff(time_units='d') diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index 7d6e33924..9ba70af37 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -24,7 +24,7 @@ from openmc.checkvalue import check_type, check_greater_than from openmc.mpi import comm from .results import StepResult from .chain import Chain -from .results_list import ResultsList +from .results_list import Results from .pool import deplete @@ -79,7 +79,7 @@ class TransportOperator(ABC): in initial condition to ensure they exist in the decay chain. Only done for nuclides with reaction rates. Defaults to 1.0e3. - prev_results : ResultsList, optional + prev_results : Results, optional Results from a previous depletion calculation. Attributes @@ -88,7 +88,7 @@ class TransportOperator(ABC): Initial atom density [atoms/cm^3] to add for nuclides that are zero in initial condition to ensure they exist in the decay chain. Only done for nuclides with reaction rates. - prev_res : ResultsList or None + prev_res : Results or None Results from a previous depletion calculation. ``None`` if no results are to be used. """ @@ -102,7 +102,7 @@ class TransportOperator(ABC): if prev_results is None: self.prev_res = None else: - check_type("previous results", prev_results, ResultsList) + check_type("previous results", prev_results, Results) self.prev_res = prev_results @property diff --git a/openmc/deplete/operator.py b/openmc/deplete/operator.py index 1f31a22b6..da9588b87 100644 --- a/openmc/deplete/operator.py +++ b/openmc/deplete/operator.py @@ -25,7 +25,7 @@ from .abc import TransportOperator, OperatorResult from .atom_number import AtomNumber from .chain import _find_chain_file from .reaction_rates import ReactionRates -from .results_list import ResultsList +from .results_list import Results from .helpers import ( DirectReactionRateHelper, ChainFissionHelper, ConstantFissionYieldHelper, FissionYieldCutoffHelper, AveragedFissionYieldHelper, EnergyScoreHelper, @@ -94,7 +94,7 @@ class Operator(TransportOperator): Path to the depletion chain XML file. Defaults to the file listed under ``depletion_chain`` in :envvar:`OPENMC_CROSS_SECTIONS` environment variable. - prev_results : ResultsList, optional + prev_results : Results, optional Results from a previous depletion calculation. If this argument is specified, the depletion calculation will start from the latest state in the previous results. @@ -192,7 +192,7 @@ class Operator(TransportOperator): Initial heavy metal inventory [g] local_mats : list of str All burnable material IDs being managed by a single process - prev_res : ResultsList or None + prev_res : Results or None Results from a previous depletion calculation. ``None`` if no results are to be used. cleanup_when_done : bool @@ -284,7 +284,7 @@ class Operator(TransportOperator): if comm.size == 1: self.prev_res = prev_results else: - self.prev_res = ResultsList() + self.prev_res = Results() mat_indexes = _distribute(range(len(self.burnable_mats))) for res_obj in prev_results: new_res = res_obj.distribute(self.local_mats, mat_indexes) @@ -494,7 +494,7 @@ class Operator(TransportOperator): Volumes for the above materials in [cm^3] nuclides : list of str Nuclides to be used in the simulation. - prev_res : ResultsList, optional + prev_res : Results, optional Results from a previous depletion calculation """ @@ -543,7 +543,7 @@ class Operator(TransportOperator): ---------- mat : openmc.Material The material to read from - prev_res : ResultsList + prev_res : Results Results from a previous depletion calculation """ diff --git a/openmc/deplete/results_list.py b/openmc/deplete/results_list.py index 97170f226..fb45792f6 100644 --- a/openmc/deplete/results_list.py +++ b/openmc/deplete/results_list.py @@ -12,7 +12,7 @@ from openmc.data.library import DataLibrary from openmc.material import Material, Materials from openmc.exceptions import DataError, InvalidArgumentError -__all__ = ["ResultsList"] +__all__ = ["Results"] def _get_time_as(seconds, units): @@ -26,10 +26,10 @@ def _get_time_as(seconds, units): return seconds -class ResultsList(list): +class Results(list): """Results from a depletion simulation - The :class:`ResultsList` class acts as a list that stores the results from + The :class:`Results` class acts as a list that stores the results from each depletion step and provides extra methods for interrogating these results. @@ -63,13 +63,13 @@ class ResultsList(list): Returns ------- - ResultsList + Results New instance of depletion results """ warn( "The from_hdf5(...) method is no longer necessary and will be removed " - "in a future version of OpenMC. Use ResultsList(...) instead.", + "in a future version of OpenMC. Use Results(...) instead.", FutureWarning ) return cls(filename) diff --git a/tests/regression_tests/deplete/test.py b/tests/regression_tests/deplete/test.py index 91f18667e..6c431fb33 100644 --- a/tests/regression_tests/deplete/test.py +++ b/tests/regression_tests/deplete/test.py @@ -77,8 +77,8 @@ def test_full(run_in_tmpdir, problem, multiproc): return # Load the reference/test results - res_test = openmc.deplete.ResultsList(path_test) - res_ref = openmc.deplete.ResultsList(path_reference) + res_test = openmc.deplete.Results(path_test) + res_ref = openmc.deplete.Results(path_reference) # Assert same mats for mat in res_ref[0].mat_to_ind: @@ -139,7 +139,7 @@ def test_depletion_results_to_material(run_in_tmpdir, problem): """Checks openmc.Materials objects can be created from depletion results""" # Load the reference/test results path_reference = Path(__file__).with_name('test_reference.h5') - res_ref = openmc.deplete.ResultsList(path_reference) + res_ref = openmc.deplete.Results(path_reference) # Firstly need to export materials.xml file for the initial simulation state geometry, lower_left, upper_right = problem diff --git a/tests/unit_tests/test_deplete_activation.py b/tests/unit_tests/test_deplete_activation.py index 2c3e0c053..0b82a5fbc 100644 --- a/tests/unit_tests/test_deplete_activation.py +++ b/tests/unit_tests/test_deplete_activation.py @@ -107,7 +107,7 @@ def test_activation(run_in_tmpdir, model, reaction_rate_mode, reaction_rate_opts integrator.integrate() # Get resulting number of atoms - results = openmc.deplete.ResultsList('depletion_results.h5') + results = openmc.deplete.Results('depletion_results.h5') _, atoms = results.get_atoms(w, "W186") assert atoms[0] == pytest.approx(n0) @@ -155,7 +155,7 @@ def test_decay(run_in_tmpdir): integrator.integrate() # Get resulting number of atoms - results = openmc.deplete.ResultsList('depletion_results.h5') + results = openmc.deplete.Results('depletion_results.h5') _, atoms = results.get_atoms(mat, "Sr89") # Ensure density goes down by a factor of 2 after each half-life diff --git a/tests/unit_tests/test_deplete_integrator.py b/tests/unit_tests/test_deplete_integrator.py index 4348b8c34..cb6374152 100644 --- a/tests/unit_tests/test_deplete_integrator.py +++ b/tests/unit_tests/test_deplete_integrator.py @@ -16,7 +16,7 @@ import pytest from openmc.mpi import comm from openmc.deplete import ( - ReactionRates, StepResult, ResultsList, OperatorResult, PredictorIntegrator, + ReactionRates, StepResult, Results, OperatorResult, PredictorIntegrator, CECMIntegrator, CF4Integrator, CELIIntegrator, EPCRK4Integrator, LEQIIntegrator, SICELIIntegrator, SILEQIIntegrator, cram) @@ -103,7 +103,7 @@ def test_results_save(run_in_tmpdir): StepResult.save(op, x2, op_result2, t2, 0, 1) # Load the files - res = ResultsList("depletion_results.h5") + res = Results("depletion_results.h5") for i in range(stages): for mat_i, mat in enumerate(burn_list): @@ -176,7 +176,7 @@ def test_integrator(run_in_tmpdir, scheme): # get expected results - res = ResultsList(operator.output_dir / "depletion_results.h5") + res = Results(operator.output_dir / "depletion_results.h5") t1, y1 = res.get_atoms("1", "1") t2, y2 = res.get_atoms("1", "2") diff --git a/tests/unit_tests/test_deplete_restart.py b/tests/unit_tests/test_deplete_restart.py index 2bfcfea7d..e8bfc062a 100644 --- a/tests/unit_tests/test_deplete_restart.py +++ b/tests/unit_tests/test_deplete_restart.py @@ -24,7 +24,7 @@ def test_restart_predictor_cecm(run_in_tmpdir): openmc.deplete.PredictorIntegrator(op, dt, power).integrate() # Load the files - prev_res = openmc.deplete.ResultsList(op.output_dir / "depletion_results.h5") + prev_res = openmc.deplete.Results(op.output_dir / "depletion_results.h5") # Re-create depletion operator and load previous results op = dummy_operator.DummyOperator(prev_res) @@ -50,7 +50,7 @@ def test_restart_cecm_predictor(run_in_tmpdir): cecm.integrate() # Load the files - prev_res = openmc.deplete.ResultsList(op.output_dir / "depletion_results.h5") + prev_res = openmc.deplete.Results(op.output_dir / "depletion_results.h5") # Re-create depletion operator and load previous results op = dummy_operator.DummyOperator(prev_res) @@ -73,7 +73,7 @@ def test_restart(run_in_tmpdir, scheme): bundle.solver(operator, [0.75], 1.0).integrate() # restart - prev_res = openmc.deplete.ResultsList( + prev_res = openmc.deplete.Results( operator.output_dir / "depletion_results.h5") operator = dummy_operator.DummyOperator(prev_res) @@ -82,7 +82,7 @@ def test_restart(run_in_tmpdir, scheme): # compare results - results = openmc.deplete.ResultsList( + results = openmc.deplete.Results( operator.output_dir / "depletion_results.h5") _t, y1 = results.get_atoms("1", "1") diff --git a/tests/unit_tests/test_deplete_resultslist.py b/tests/unit_tests/test_deplete_resultslist.py index 2a2669920..6ce15601f 100644 --- a/tests/unit_tests/test_deplete_resultslist.py +++ b/tests/unit_tests/test_deplete_resultslist.py @@ -1,4 +1,4 @@ -"""Tests the ResultsList class""" +"""Tests the Results class""" from pathlib import Path from math import inf @@ -13,7 +13,7 @@ def res(): """Load the reference results""" filename = (Path(__file__).parents[1] / 'regression_tests' / 'deplete' / 'test_reference.h5') - return openmc.deplete.ResultsList(filename) + return openmc.deplete.Results(filename) def test_get_atoms(res): @@ -72,9 +72,9 @@ def test_get_keff(res): @pytest.mark.parametrize("unit", ("s", "d", "min", "h")) def test_get_steps(unit): - # Make a ResultsList full of near-empty Result instances + # Make a Results full of near-empty Result instances # Just fill out a time schedule - results = openmc.deplete.ResultsList() + results = openmc.deplete.Results() # Time in units of unit times = np.linspace(0, 100, num=5) if unit == "d": diff --git a/tests/unit_tests/test_transfer_volumes.py b/tests/unit_tests/test_transfer_volumes.py index 50e222b95..b768bc88a 100644 --- a/tests/unit_tests/test_transfer_volumes.py +++ b/tests/unit_tests/test_transfer_volumes.py @@ -2,7 +2,7 @@ from pytest import approx import openmc -from openmc.deplete import PredictorIntegrator, ResultsList +from openmc.deplete import PredictorIntegrator, Results from tests import dummy_operator @@ -19,7 +19,7 @@ def test_transfer_volumes(run_in_tmpdir): PredictorIntegrator(op, dt, power).integrate() # Load the files - res = openmc.deplete.ResultsList(op.output_dir / "depletion_results.h5") + res = openmc.deplete.Results(op.output_dir / "depletion_results.h5") # Create a dictionary of volumes to transfer res[0].volume['1'] = 1.5 From bd7b33c636628cd4826dd4507fc01a9fc628896d Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 28 Apr 2022 17:23:37 -0500 Subject: [PATCH 4/9] Rename results.py stepresult.py --- openmc/deplete/__init__.py | 2 +- openmc/deplete/abc.py | 2 +- openmc/deplete/results_list.py | 2 +- openmc/deplete/{results.py => stepresult.py} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename openmc/deplete/{results.py => stepresult.py} (100%) diff --git a/openmc/deplete/__init__.py b/openmc/deplete/__init__.py index b8c1cdfff..e15a368de 100644 --- a/openmc/deplete/__init__.py +++ b/openmc/deplete/__init__.py @@ -10,7 +10,7 @@ from .chain import * from .operator import * from .reaction_rates import * from .atom_number import * -from .results import * +from .stepresult import * from .results_list import * from .integrators import * from . import abc diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index 9ba70af37..3d8d08c76 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -22,7 +22,7 @@ from uncertainties import ufloat from openmc.lib import MaterialFilter, Tally from openmc.checkvalue import check_type, check_greater_than from openmc.mpi import comm -from .results import StepResult +from .stepresult import StepResult from .chain import Chain from .results_list import Results from .pool import deplete diff --git a/openmc/deplete/results_list.py b/openmc/deplete/results_list.py index fb45792f6..952fb37f7 100644 --- a/openmc/deplete/results_list.py +++ b/openmc/deplete/results_list.py @@ -6,7 +6,7 @@ from warnings import warn import h5py import numpy as np -from .results import StepResult, VERSION_RESULTS +from .stepresult import StepResult, VERSION_RESULTS import openmc.checkvalue as cv from openmc.data.library import DataLibrary from openmc.material import Material, Materials diff --git a/openmc/deplete/results.py b/openmc/deplete/stepresult.py similarity index 100% rename from openmc/deplete/results.py rename to openmc/deplete/stepresult.py From 5421bf0b1f0a3186aa033be915d5d120c5b084cf Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 28 Apr 2022 17:25:10 -0500 Subject: [PATCH 5/9] Rename results_list.py -> results.py --- openmc/deplete/__init__.py | 2 +- openmc/deplete/abc.py | 2 +- openmc/deplete/operator.py | 2 +- openmc/deplete/{results_list.py => results.py} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename openmc/deplete/{results_list.py => results.py} (100%) diff --git a/openmc/deplete/__init__.py b/openmc/deplete/__init__.py index e15a368de..5891555a2 100644 --- a/openmc/deplete/__init__.py +++ b/openmc/deplete/__init__.py @@ -11,7 +11,7 @@ from .operator import * from .reaction_rates import * from .atom_number import * from .stepresult import * -from .results_list import * +from .results import * from .integrators import * from . import abc from . import cram diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index 3d8d08c76..df30579e5 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -24,7 +24,7 @@ from openmc.checkvalue import check_type, check_greater_than from openmc.mpi import comm from .stepresult import StepResult from .chain import Chain -from .results_list import Results +from .results import Results from .pool import deplete diff --git a/openmc/deplete/operator.py b/openmc/deplete/operator.py index da9588b87..327c762e0 100644 --- a/openmc/deplete/operator.py +++ b/openmc/deplete/operator.py @@ -25,7 +25,7 @@ from .abc import TransportOperator, OperatorResult from .atom_number import AtomNumber from .chain import _find_chain_file from .reaction_rates import ReactionRates -from .results_list import Results +from .results import Results from .helpers import ( DirectReactionRateHelper, ChainFissionHelper, ConstantFissionYieldHelper, FissionYieldCutoffHelper, AveragedFissionYieldHelper, EnergyScoreHelper, diff --git a/openmc/deplete/results_list.py b/openmc/deplete/results.py similarity index 100% rename from openmc/deplete/results_list.py rename to openmc/deplete/results.py From 8a4fd95b9bea56d83a9ded8467cb2da41be66605 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 2 May 2022 12:27:28 -0500 Subject: [PATCH 6/9] Retain ResultsList name for backwards compatibility --- openmc/deplete/results.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/openmc/deplete/results.py b/openmc/deplete/results.py index 952fb37f7..fd6d72fba 100644 --- a/openmc/deplete/results.py +++ b/openmc/deplete/results.py @@ -10,9 +10,9 @@ from .stepresult import StepResult, VERSION_RESULTS import openmc.checkvalue as cv from openmc.data.library import DataLibrary from openmc.material import Material, Materials -from openmc.exceptions import DataError, InvalidArgumentError +from openmc.exceptions import DataError -__all__ = ["Results"] +__all__ = ["Results", "ResultsList"] def _get_time_as(seconds, units): @@ -68,8 +68,8 @@ class Results(list): """ warn( - "The from_hdf5(...) method is no longer necessary and will be removed " - "in a future version of OpenMC. Use Results(...) instead.", + "The ResultsList.from_hdf5(...) method is no longer necessary and will " + "be removed in a future version of OpenMC. Use Results(...) instead.", FutureWarning ) return cls(filename) @@ -410,3 +410,7 @@ class Results(list): mat.add_nuclide(nuc, atoms_per_barn_cm) return mat_file + + +# Retain deprecated name for the time being +ResultsList = Results From 355ecd374751c5d773d5d97278c7d88e6cabf5f4 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 5 May 2022 22:05:33 -0500 Subject: [PATCH 7/9] Allow deplete.Results() to be instantiated empty --- openmc/deplete/results.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/openmc/deplete/results.py b/openmc/deplete/results.py index fd6d72fba..514c04820 100644 --- a/openmc/deplete/results.py +++ b/openmc/deplete/results.py @@ -39,16 +39,17 @@ class Results(list): Path to depletion result file """ - def __init__(self, filename): - with h5py.File(str(filename), "r") as fh: - cv.check_filetype_version(fh, 'depletion results', VERSION_RESULTS[0]) - data = [] + def __init__(self, filename=None): + data = [] + if filename is not None: + with h5py.File(str(filename), "r") as fh: + cv.check_filetype_version(fh, 'depletion results', VERSION_RESULTS[0]) - # Get number of results stored - n = fh["number"][...].shape[0] + # Get number of results stored + n = fh["number"][...].shape[0] - for i in range(n): - data.append(StepResult.from_hdf5(fh, i)) + for i in range(n): + data.append(StepResult.from_hdf5(fh, i)) super().__init__(data) From bc1ab31746518ab420f01695ab91da4390134cd4 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 3 Jun 2022 09:09:52 -0500 Subject: [PATCH 8/9] Raise exception if timestep in [MWd/kg] is given with zero power --- openmc/deplete/abc.py | 3 +++ openmc/deplete/stepresult.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index df30579e5..457c51a8a 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -719,6 +719,9 @@ class Integrator(ABC): elif unit.lower() == 'mwd/kg': watt_days_per_kg = 1e6*timestep kilograms = 1e-3*operator.heavy_metal + if rate == 0.0: + raise ValueError("Cannot specify a timestep in [MWd/kg] when" + " the power is zero.") days = watt_days_per_kg * kilograms / rate seconds.append(days*_SECONDS_PER_DAY) else: diff --git a/openmc/deplete/stepresult.py b/openmc/deplete/stepresult.py index bfd165481..6f30e934d 100644 --- a/openmc/deplete/stepresult.py +++ b/openmc/deplete/stepresult.py @@ -20,7 +20,7 @@ __all__ = ["StepResult"] class StepResult: - """Output of a depletion run + """Result of a single depletion timestep Attributes ---------- From 382867db7feed2cd10223afe8397659edca1695b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 13 Jun 2022 12:32:09 -0500 Subject: [PATCH 9/9] Address @drewejohnson comments on #2077 --- openmc/deplete/results.py | 11 +++++------ openmc/deplete/stepresult.py | 5 +++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openmc/deplete/results.py b/openmc/deplete/results.py index 514c04820..c238002fe 100644 --- a/openmc/deplete/results.py +++ b/openmc/deplete/results.py @@ -81,9 +81,9 @@ class Results(list): .. 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``. - The :class:`openmc.deplete.Operator` adds isotopes according - to this setting, which can be set to zero. + value of the :attr:`openmc.deplete.Operator.dilute_initial` + attribute. The :class:`openmc.deplete.Operator` class adds isotopes + according to this setting, which can be set to zero. Parameters ---------- @@ -186,6 +186,8 @@ class Results(list): def get_keff(self, time_units='s'): """Evaluates the eigenvalue from a results list. + .. versionadded:: 0.13.1 + Parameters ---------- time_units : {"s", "d", "h", "min"}, optional @@ -220,7 +222,6 @@ class Results(list): "will be removed in a future version of OpenMC.", FutureWarning) return self.get_keff(time_units) - def get_depletion_time(self): """Return an array of the average time to deplete a material @@ -252,7 +253,6 @@ class Results(list): def get_times(self, time_units="d") -> np.ndarray: """Return the points in time that define the depletion schedule - .. versionadded:: 0.12.1 Parameters @@ -290,7 +290,6 @@ class Results(list): Passing ``atol=math.inf`` and ``rtol=math.inf`` will return the closest index to the requested point. - .. versionadded:: 0.12.1 Parameters diff --git a/openmc/deplete/stepresult.py b/openmc/deplete/stepresult.py index 6f30e934d..6e2373c45 100644 --- a/openmc/deplete/stepresult.py +++ b/openmc/deplete/stepresult.py @@ -1,6 +1,7 @@ -"""The results module. +"""The stepresult module. -Contains results generation and saving capabilities. +Contains capabilities for generating and saving results of a single depletion +timestep. """ from collections import OrderedDict