From fca4da4bda59c532134a791fe0cd938d08e2e15c Mon Sep 17 00:00:00 2001 From: Gavin Ridley Date: Tue, 23 Jan 2024 06:53:11 -0600 Subject: [PATCH] Export model.tallies to XML in CoupledOperator (#2840) --- openmc/deplete/coupled_operator.py | 46 +++++++++++++++---- .../test_deplete_coupled_operator.py | 8 ++-- tests/unit_tests/test_model.py | 18 ++++++++ 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/openmc/deplete/coupled_operator.py b/openmc/deplete/coupled_operator.py index d591e956f5f..856a26958fe 100644 --- a/openmc/deplete/coupled_operator.py +++ b/openmc/deplete/coupled_operator.py @@ -178,10 +178,6 @@ class CoupledOperator(OpenMCOperator): ---------- model : openmc.model.Model OpenMC model object - geometry : openmc.Geometry - OpenMC geometry object - settings : openmc.Settings - OpenMC settings object output_dir : pathlib.Path Path to output directory to save results. round_number : bool @@ -242,8 +238,6 @@ def __init__(self, model, chain_file=None, prev_results=None, warn("Fission Q dictionary will not be used") fission_q = None self.model = model - self.settings = model.settings - self.geometry = model.geometry # determine set of materials in the model if not model.materials: @@ -358,7 +352,7 @@ def _get_helper_classes(self, helper_kwargs): if normalization_mode == "fission-q": self._normalization_helper = ChainFissionHelper() elif normalization_mode == "energy-deposition": - score = "heating" if self.settings.photon_transport else "heating-local" + score = "heating" if self.model.settings.photon_transport else "heating-local" self._normalization_helper = EnergyScoreHelper(score) else: self._normalization_helper = SourceRateHelper() @@ -380,8 +374,12 @@ def initial_condition(self): # Create XML files if comm.rank == 0: - self.geometry.export_to_xml() - self.settings.export_to_xml() + self.model.geometry.export_to_xml() + self.model.settings.export_to_xml() + if self.model.plots: + self.model.plots.export_to_xml() + if self.model.tallies: + self.model.tallies.export_to_xml() self._generate_materials_xml() # Initialize OpenMC library @@ -528,6 +526,36 @@ def finalize(self): if self.cleanup_when_done: openmc.lib.finalize() + # The next few class variables and methods should be removed after one + # release cycle or so. For now, we will provide compatibility to + # accessing CoupledOperator.settings and CoupledOperator.geometry. In + # the future these should stay on the Model class. + + var_warning_msg = "The CoupledOperator.{0} variable should be \ +accessed through CoupledOperator.model.{0}." + geometry_warning_msg = var_warning_msg.format("geometry") + settings_warning_msg = var_warning_msg.format("settings") + + @property + def settings(self): + warn(self.settings_warning_msg, FutureWarning) + return self.model.settings + + @settings.setter + def settings(self, new_settings): + warn(self.settings_warning_msg, FutureWarning) + self.model.settings = new_settings + + @property + def geometry(self): + warn(self.geometry_warning_msg, FutureWarning) + return self.model.geometry + + @geometry.setter + def geometry(self, new_geometry): + warn(self.geometry_warning_msg, FutureWarning) + self.model.geometry = new_geometry + # Retain deprecated name for the time being def Operator(*args, **kwargs): diff --git a/tests/unit_tests/test_deplete_coupled_operator.py b/tests/unit_tests/test_deplete_coupled_operator.py index 8765020de24..fe79d621b12 100644 --- a/tests/unit_tests/test_deplete_coupled_operator.py +++ b/tests/unit_tests/test_deplete_coupled_operator.py @@ -38,7 +38,8 @@ def model(): pin_surfaces = [openmc.ZCylinder(r=r) for r in radii] pin_univ = openmc.model.pin(pin_surfaces, materials) - bound_box = openmc.model.RectangularPrism(1.24, 1.24, boundary_type="reflective") + bound_box = openmc.model.RectangularPrism( + 1.24, 1.24, boundary_type="reflective") root_cell = openmc.Cell(fill=pin_univ, region=-bound_box) geometry = openmc.Geometry([root_cell]) @@ -95,7 +96,7 @@ def test_diff_volume_method_match_cell(model_with_volumes): chain_file=CHAIN_PATH ) - all_cells = list(operator.geometry.get_all_cells().values()) + all_cells = list(operator.model.geometry.get_all_cells().values()) assert all_cells[0].fill.volume == 4.19 assert all_cells[1].fill.volume == 33.51 # mat2 is not depletable @@ -112,9 +113,8 @@ def test_diff_volume_method_divide_equally(model_with_volumes): chain_file=CHAIN_PATH ) - all_cells = list(operator.geometry.get_all_cells().values()) + all_cells = list(operator.model.geometry.get_all_cells().values()) assert all_cells[0].fill[0].volume == 51 assert all_cells[1].fill[0].volume == 51 # mat2 is not depletable assert all_cells[2].fill.volume is None - diff --git a/tests/unit_tests/test_model.py b/tests/unit_tests/test_model.py index 682afb41a46..24f136c8c4d 100644 --- a/tests/unit_tests/test_model.py +++ b/tests/unit_tests/test_model.py @@ -457,6 +457,20 @@ def test_deplete(run_in_tmpdir, pin_model_attributes, mpi_intracomm): assert after_xe + after_u == pytest.approx(initial_u, abs=1e-15) assert test_model.is_initialized is False + # check the tally output + def check_tally_output(): + with openmc.StatePoint('openmc_simulation_n0.h5') as sp: + flux = sp.get_tally(id=1).get_values(scores=['flux'])[0, 0, 0] + fission = sp.get_tally(id=1).get_values( + scores=['fission'])[0, 0, 0] + + # we're mainly just checking that the result was produced, + # so a rough numerical comparison doesn't hurt to have. + assert flux == pytest.approx(13.1, abs=0.2) + assert fission == pytest.approx(0.47, abs=0.2) + + check_tally_output() + # Reset the initial material densities mats[0].nuclides.clear() densities = initial_mat.get_nuclide_atom_densities() @@ -481,6 +495,8 @@ def test_deplete(run_in_tmpdir, pin_model_attributes, mpi_intracomm): assert after_xe == pytest.approx(after_lib_xe, abs=1e-15) assert after_u == pytest.approx(after_lib_u, abs=1e-15) + check_tally_output() + test_model.finalize_lib() @@ -531,6 +547,7 @@ def test_calc_volumes(run_in_tmpdir, pin_model_attributes, mpi_intracomm): test_model.finalize_lib() + def test_model_xml(run_in_tmpdir): # load a model from examples @@ -549,6 +566,7 @@ def test_model_xml(run_in_tmpdir): # XML files new_model.export_to_xml() + def test_single_xml_exec(run_in_tmpdir): pincell_model = openmc.examples.pwr_pin_cell()