From ae0cdf4b0a55d40f91fa39a966bf58083461f501 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Fri, 8 Oct 2021 09:05:19 -0500 Subject: [PATCH 1/6] Chaning deplete.Operator to take in an openmc.Model object and set materials accordingly. --- openmc/deplete/operator.py | 32 +++++++++++++++++++------------- openmc/model/model.py | 2 +- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/openmc/deplete/operator.py b/openmc/deplete/operator.py index 29370eb8cf..a1c283305f 100644 --- a/openmc/deplete/operator.py +++ b/openmc/deplete/operator.py @@ -67,10 +67,8 @@ class Operator(TransportOperator): Parameters ---------- - geometry : openmc.Geometry - OpenMC geometry object - settings : openmc.Settings - OpenMC Settings object + model : openmc.Model + OpenMC model object chain_file : str, optional Path to the depletion chain XML file. Defaults to the file listed under ``depletion_chain`` in @@ -144,6 +142,8 @@ class Operator(TransportOperator): Attributes ---------- + model : openmc.Model + OpenMC model object geometry : openmc.Geometry OpenMC geometry object settings : openmc.Settings @@ -186,7 +186,7 @@ class Operator(TransportOperator): "cutoff": FissionYieldCutoffHelper, } - def __init__(self, geometry, settings, chain_file=None, prev_results=None, + def __init__(self, model, chain_file=None, prev_results=None, diff_burnable_mats=False, normalization_mode="fission-q", fission_q=None, dilute_initial=1.0e3, fission_yield_mode="constant", fission_yield_opts=None, @@ -202,15 +202,22 @@ class Operator(TransportOperator): fission_q = None super().__init__(chain_file, fission_q, dilute_initial, prev_results) self.round_number = False - self.settings = settings - self.geometry = geometry + self.settings = model.settings + self.geometry = model.geometry + + # determine set of materials in the model + if not model.materials: + model.materials = openmc.Materials(model.geometry. + get_all_materials().values()) + self.materials = model.materials + self.diff_burnable_mats = diff_burnable_mats self.cleanup_when_done = True # Reduce the chain before we create more materials if reduce_chain: all_isotopes = set() - for material in geometry.get_all_materials().values(): + for material in self.materials: if not material.depletable: continue for name, _dens_percent, _dens_type in material.nuclides: @@ -411,7 +418,7 @@ class Operator(TransportOperator): self.heavy_metal = 0.0 # Iterate once through the geometry to get dictionaries - for mat in self.geometry.get_all_materials().values(): + for mat in self.materials: for nuclide in mat.get_nuclides(): model_nuclides.add(nuclide) if mat.depletable: @@ -463,13 +470,13 @@ class Operator(TransportOperator): # Now extract and store the number densities # From the geometry if no previous depletion results if prev_res is None: - for mat in self.geometry.get_all_materials().values(): + for mat in self.materials: if str(mat.id) in local_mats: self._set_number_from_mat(mat) # Else from previous depletion results else: - for mat in self.geometry.get_all_materials().values(): + for mat in self.materials.values(): if str(mat.id) in local_mats: self._set_number_from_results(mat, prev_res) @@ -609,8 +616,7 @@ class Operator(TransportOperator): through direct memory writing. """ - materials = openmc.Materials(self.geometry.get_all_materials() - .values()) + materials = openmc.Materials(self.materials) # Sort nuclides according to order in AtomNumber object nuclides = list(self.number.nuclides) diff --git a/openmc/model/model.py b/openmc/model/model.py index ad898fd0ad..a3a03cdde6 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -326,7 +326,7 @@ class Model: with _change_directory(Path(directory)): with openmc.lib.quiet_dll(output): depletion_operator = \ - dep.Operator(self.geometry, self.settings, **op_kwargs) + dep.Operator(self, **op_kwargs) # Tell depletion_operator.finalize NOT to clear C API memory when # it is done From 7472e330be40c080e44d5bfa60670f6d80476ec5 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Fri, 8 Oct 2021 09:21:03 -0500 Subject: [PATCH 2/6] Updating pincell depletion example. --- examples/pincell_depletion/run_depletion.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/pincell_depletion/run_depletion.py b/examples/pincell_depletion/run_depletion.py index ce4b0cf5e6..72e71afe5a 100644 --- a/examples/pincell_depletion/run_depletion.py +++ b/examples/pincell_depletion/run_depletion.py @@ -84,9 +84,11 @@ settings.entropy_mesh = entropy_mesh # Initialize and run depletion calculation ############################################################################### +model = openmc.Model(geometry=geometry, settings=settings) + # Create depletion "operator" chain_file = './chain_simple.xml' -op = openmc.deplete.Operator(geometry, settings, chain_file) +op = openmc.deplete.Operator(model, chain_file) # Perform simulation using the predictor algorithm time_steps = [1.0, 1.0, 1.0, 1.0, 1.0] # days From f1234a38b0fa1b1a1cb43d6f6fc4282a29a49f89 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Fri, 8 Oct 2021 14:15:40 -0500 Subject: [PATCH 3/6] Updating depletion test files. Further adjustments to how materials are identified for some utility functions. --- openmc/deplete/operator.py | 14 ++++++++------ openmc/deplete/results.py | 20 ++++++++++++++------ tests/regression_tests/deplete/test.py | 6 ++++-- tests/unit_tests/test_deplete_activation.py | 5 +++-- tests/unit_tests/test_transfer_volumes.py | 2 +- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/openmc/deplete/operator.py b/openmc/deplete/operator.py index a1c283305f..9a9605d617 100644 --- a/openmc/deplete/operator.py +++ b/openmc/deplete/operator.py @@ -202,13 +202,15 @@ class Operator(TransportOperator): fission_q = None super().__init__(chain_file, fission_q, dilute_initial, prev_results) self.round_number = False + self.model = model self.settings = model.settings self.geometry = model.geometry # determine set of materials in the model if not model.materials: - model.materials = openmc.Materials(model.geometry. - get_all_materials().values()) + model.materials = openmc.Materials( + model.geometry.get_all_materials().values() + ) self.materials = model.materials self.diff_burnable_mats = diff_burnable_mats @@ -239,7 +241,7 @@ class Operator(TransportOperator): if self.prev_res is not None: # Reload volumes into geometry - prev_results[-1].transfer_volumes(geometry) + prev_results[-1].transfer_volumes(self.model) # Store previous results in operator # Distribute reaction rates according to those tracked @@ -380,7 +382,7 @@ class Operator(TransportOperator): # Extract all burnable materials which have multiple instances distribmats = set( - [mat for mat in self.geometry.get_all_materials().values() + [mat for mat in self.materials if mat.depletable and mat.num_instances > 1]) for mat in distribmats: @@ -476,7 +478,7 @@ class Operator(TransportOperator): # Else from previous depletion results else: - for mat in self.materials.values(): + for mat in self.materials: if str(mat.id) in local_mats: self._set_number_from_results(mat, prev_res) @@ -620,7 +622,7 @@ class Operator(TransportOperator): # Sort nuclides according to order in AtomNumber object nuclides = list(self.number.nuclides) - for mat in materials: + for mat in self.materials: mat._nuclides.sort(key=lambda x: nuclides.index(x[0])) # Grab the cross sections tag from the existing file diff --git a/openmc/deplete/results.py b/openmc/deplete/results.py index 111c8e638e..cda1864a1e 100644 --- a/openmc/deplete/results.py +++ b/openmc/deplete/results.py @@ -9,6 +9,7 @@ import copy import h5py import numpy as np +import openmc from openmc.mpi import comm, MPI from .reaction_rates import ReactionRates @@ -496,16 +497,23 @@ class Results: results.export_to_hdf5("depletion_results.h5", step_ind) - def transfer_volumes(self, geometry): + def transfer_volumes(self, model): """Transfers volumes from depletion results to geometry Parameters ---------- - geometry : OpenMC geometry to be used in a depletion restart + model : OpenMC model to be used in a depletion restart calculation """ - for cell in geometry.get_all_material_cells().values(): - for material in cell.get_all_materials().values(): - if material.depletable: - material.volume = self.volume[str(material.id)] + + if not model.materials: + materials = openmc.Materials( + model.geometry.get_all_materials().values() + ) + else: + materials = model.materials + + for material in materials: + if material.depletable: + material.volume = self.volume[str(material.id)] \ No newline at end of file diff --git a/tests/regression_tests/deplete/test.py b/tests/regression_tests/deplete/test.py index fcc2099cf9..fccd504931 100644 --- a/tests/regression_tests/deplete/test.py +++ b/tests/regression_tests/deplete/test.py @@ -49,9 +49,11 @@ def test_full(run_in_tmpdir, problem, multiproc): settings.seed = 1 settings.verbosity = 1 + model = openmc.Model(geometry=geometry, settings=settings) + # Create operator chain_file = Path(__file__).parents[2] / 'chain_simple.xml' - op = openmc.deplete.Operator(geometry, settings, chain_file) + op = openmc.deplete.Operator(model, chain_file) op.round_number = True # Power and timesteps @@ -170,7 +172,7 @@ def test_depletion_results_to_material(run_in_tmpdir, problem): diff_vs_expected = unified_diff(reference_lines, result_file_lines) # Check all lines match, printing errors along the way - success = True + success = True for line in diff_vs_expected: success = False print(line.rstrip()) diff --git a/tests/unit_tests/test_deplete_activation.py b/tests/unit_tests/test_deplete_activation.py index 6ccee25047..37b29e1eab 100644 --- a/tests/unit_tests/test_deplete_activation.py +++ b/tests/unit_tests/test_deplete_activation.py @@ -65,7 +65,7 @@ def test_activation(run_in_tmpdir, model, reaction_rate_mode, reaction_rate_opts # Create transport operator op = openmc.deplete.Operator( - model.geometry, model.settings, 'test_chain.xml', + model, 'test_chain.xml', normalization_mode="source-rate", reaction_rate_mode=reaction_rate_mode, reaction_rate_opts=reaction_rate_opts, @@ -142,9 +142,10 @@ def test_decay(run_in_tmpdir): chain.add_nuclide(sr89) chain.export_to_xml('test_chain.xml') + model = openmc.Model(geometry=geometry, settings=settings) # Create transport operator op = openmc.deplete.Operator( - geometry, settings, 'test_chain.xml', normalization_mode="source-rate" + model, 'test_chain.xml', normalization_mode="source-rate" ) # Deplete with two decay steps diff --git a/tests/unit_tests/test_transfer_volumes.py b/tests/unit_tests/test_transfer_volumes.py index 2e735c911e..c048778bd2 100644 --- a/tests/unit_tests/test_transfer_volumes.py +++ b/tests/unit_tests/test_transfer_volumes.py @@ -40,7 +40,7 @@ def test_transfer_volumes(run_in_tmpdir): geometry = openmc.Geometry(root) # Transfer volumes - res[0].transfer_volumes(geometry) + res[0].transfer_volumes(openmc.Model(geometry)) assert mat1.volume == 1.5 assert mat2.volume is None From e6cd4449e100e093502e438e6d6344f98c082eea Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 11 Oct 2021 22:04:05 -0500 Subject: [PATCH 4/6] Updating openmc.Materials object used in _generate_materials_xml. --- openmc/deplete/operator.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openmc/deplete/operator.py b/openmc/deplete/operator.py index 9a9605d617..c766dbdf07 100644 --- a/openmc/deplete/operator.py +++ b/openmc/deplete/operator.py @@ -618,8 +618,6 @@ class Operator(TransportOperator): through direct memory writing. """ - materials = openmc.Materials(self.materials) - # Sort nuclides according to order in AtomNumber object nuclides = list(self.number.nuclides) for mat in self.materials: @@ -631,9 +629,9 @@ class Operator(TransportOperator): tree = ET.parse(str(mfile)) xs = tree.find('cross_sections') if xs is not None: - materials.cross_sections = xs.text + self.materials.cross_sections = xs.text - materials.export_to_xml() + self.materials.export_to_xml() def _get_tally_nuclides(self): """Determine nuclides that should be tallied for reaction rates. From 1d211aefe6584562aa5b67cd849c02028539d290 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Sun, 17 Oct 2021 22:27:17 -0500 Subject: [PATCH 5/6] Adding a version change note for Operator.__init_. --- openmc/deplete/operator.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openmc/deplete/operator.py b/openmc/deplete/operator.py index c766dbdf07..9c774a0a42 100644 --- a/openmc/deplete/operator.py +++ b/openmc/deplete/operator.py @@ -65,6 +65,10 @@ class Operator(TransportOperator): directly. Instead, an instance of this class is passed to an integrator class, such as :class:`openmc.deplete.CECMIntegrator`. + .. versionchanged:: 0.13.0 + The geometry and settings parameters have been replaced with a + model parameter that takes an openmc.Model object + Parameters ---------- model : openmc.Model From 2634d1ece871e6334c8f450cf221882fa5f1e46f Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Sun, 17 Oct 2021 23:12:39 -0500 Subject: [PATCH 6/6] Adding type check for first parameter passed to the Operator constructor. --- openmc/deplete/operator.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openmc/deplete/operator.py b/openmc/deplete/operator.py index 9c774a0a42..d727b26317 100644 --- a/openmc/deplete/operator.py +++ b/openmc/deplete/operator.py @@ -10,6 +10,7 @@ densities is all done in-memory instead of through the filesystem. import copy from collections import OrderedDict import os +from typing import Type import xml.etree.ElementTree as ET from warnings import warn from pathlib import Path @@ -196,6 +197,15 @@ class Operator(TransportOperator): fission_yield_mode="constant", fission_yield_opts=None, reaction_rate_mode="direct", reaction_rate_opts=None, reduce_chain=False, reduce_chain_level=None): + # check for old call to constructor + if isinstance(model, openmc.Geometry): + msg = "As of version 0.13.0 openmc.deplete.Operator requires an " \ + "openmc.Model object rather than the openmc.Geometry and " \ + "openmc.Settings parameters. Please use the geometry and " \ + "settings objects passed here to create a model with which " \ + "to generate the depletion Operator." + raise TypeError(msg) + check_value('fission yield mode', fission_yield_mode, self._fission_helpers.keys()) check_value('normalization mode', normalization_mode,