From 954154fa4828662da65b7db0ce13aa5ee1b35c5f Mon Sep 17 00:00:00 2001 From: alex-lyons Date: Fri, 7 Feb 2020 16:24:10 +0000 Subject: [PATCH 01/12] Changed PyAPI model and executor to read correct last statepoint after runs with trigger, including new test case --- openmc/executor.py | 20 ++- openmc/model/model.py | 21 +-- .../trigger_statepoint_restart/__init__.py | 0 .../inputs_true.dat | 34 +++++ .../results_true.dat | 5 + .../trigger_statepoint_restart/test.py | 120 ++++++++++++++++++ 6 files changed, 189 insertions(+), 11 deletions(-) create mode 100644 tests/regression_tests/trigger_statepoint_restart/__init__.py create mode 100644 tests/regression_tests/trigger_statepoint_restart/inputs_true.dat create mode 100644 tests/regression_tests/trigger_statepoint_restart/results_true.dat create mode 100644 tests/regression_tests/trigger_statepoint_restart/test.py diff --git a/openmc/executor.py b/openmc/executor.py index 9faf18b332..76d100d32a 100644 --- a/openmc/executor.py +++ b/openmc/executor.py @@ -1,6 +1,7 @@ from collections.abc import Iterable -import subprocess from numbers import Integral +import re +import subprocess import openmc @@ -10,6 +11,10 @@ def _run(args, output, cwd): p = subprocess.Popen(args, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) + # Compile a regex object to identify statepoint writes + sp_rxprog = re.compile(r'Creating state point (.+)\.\.\.') + last_statepoint = None + # Capture and re-print OpenMC output in real-time lines = [] while True: @@ -18,6 +23,11 @@ def _run(args, output, cwd): if not line and p.poll() is not None: break + # If a statepoint was written, capture its filename + sp_match = sp_rxprog.search(line) + if sp_match: + last_statepoint = sp_match.group(1) + lines.append(line) if output: # If user requested output, print to screen @@ -27,6 +37,7 @@ def _run(args, output, cwd): if p.returncode != 0: raise subprocess.CalledProcessError(p.returncode, ' '.join(args), ''.join(lines)) + return last_statepoint def plot_geometry(output=True, openmc_exec='openmc', cwd='.'): @@ -184,6 +195,11 @@ def run(particles=None, threads=None, geometry_debug=False, event_based : bool, optional Turns on event-based parallelism, instead of default history-based + Returns + ------- + str + Name of the last written statepoint file, or None + Raises ------ subprocess.CalledProcessError @@ -213,4 +229,4 @@ def run(particles=None, threads=None, geometry_debug=False, if mpi_args is not None: args = mpi_args + args - _run(args, output, cwd) + return _run(args, output, cwd) diff --git a/openmc/model/model.py b/openmc/model/model.py index b5c190716b..08ba300dd1 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -41,6 +41,8 @@ class Model: Tallies information plots : openmc.Plots Plot information + statepoint : openmc.Statepoint + The last statepoint filename written when the model is run """ @@ -51,6 +53,7 @@ class Model: self.settings = openmc.Settings() self.tallies = openmc.Tallies() self.plots = openmc.Plots() + self.statepoint = None if geometry is not None: self.geometry = geometry @@ -197,7 +200,8 @@ class Model: self.plots.export_to_xml(d) def run(self, **kwargs): - """Creates the XML files, runs OpenMC, and returns k-effective + """Creates the XML files, runs OpenMC, and returns k-effective. + The last statepoint filename is available in model.statepoint Parameters ---------- @@ -210,14 +214,13 @@ class Model: Combined estimator of k-effective from the statepoint """ + self.export_to_xml() - openmc.run(**kwargs) + self.statepoint = openmc.run(**kwargs) - n = self.settings.batches - if self.settings.statepoint is not None: - if 'batches' in self.settings.statepoint: - n = self.settings.statepoint['batches'][-1] - - with openmc.StatePoint('statepoint.{}.h5'.format(n)) as sp: - return sp.k_combined + keff = None + if self.statepoint: + with openmc.StatePoint(self.statepoint) as sp: + keff = sp.k_combined + return keff diff --git a/tests/regression_tests/trigger_statepoint_restart/__init__.py b/tests/regression_tests/trigger_statepoint_restart/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/trigger_statepoint_restart/inputs_true.dat b/tests/regression_tests/trigger_statepoint_restart/inputs_true.dat new file mode 100644 index 0000000000..decc87b0c5 --- /dev/null +++ b/tests/regression_tests/trigger_statepoint_restart/inputs_true.dat @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + eigenvalue + 200 + 10 + 5 + + std_dev + 0.002 + + + true + 1000 + 1 + + + + + + flux + + diff --git a/tests/regression_tests/trigger_statepoint_restart/results_true.dat b/tests/regression_tests/trigger_statepoint_restart/results_true.dat new file mode 100644 index 0000000000..84363f8696 --- /dev/null +++ b/tests/regression_tests/trigger_statepoint_restart/results_true.dat @@ -0,0 +1,5 @@ +k-combined: +2.909598E-01 6.161987E-03 +tally 1: +3.852896E+01 +2.976246E+02 diff --git a/tests/regression_tests/trigger_statepoint_restart/test.py b/tests/regression_tests/trigger_statepoint_restart/test.py new file mode 100644 index 0000000000..66416297b1 --- /dev/null +++ b/tests/regression_tests/trigger_statepoint_restart/test.py @@ -0,0 +1,120 @@ +import glob +import os + +import openmc +import pytest + +from tests.testing_harness import PyAPITestHarness +from tests.regression_tests import config + + +@pytest.fixture +def model(): + + # Materials + materials = openmc.Materials() + mat = openmc.Material() + mat.set_density('g/cm3', 4.5) + mat.add_nuclide('U235', 1.0) + materials.append(mat) + + # Geometry + sph = openmc.Sphere(r=10.0, boundary_type='vacuum') + cell = openmc.Cell(fill=mat, region=-sph) + geometry = openmc.Geometry([cell]) + + # Settings + settings = openmc.Settings() + settings.run_mode = 'eigenvalue' + settings.batches = 10 + settings.inactive = 5 + settings.particles = 200 + settings.keff_trigger = {'type': 'std_dev', 'threshold': 0.002} + settings.trigger_max_batches = 1000 + settings.trigger_batch_interval = 1 + settings.trigger_active = True + + # Tallies + tallies = openmc.Tallies() + t = openmc.Tally() + t.scores = ['flux'] + tallies.append(t) + + # Plots (none) + plots = openmc.Plots() + + # Put it all together + model = openmc.model.Model(materials=materials, + geometry=geometry, + settings=settings, + tallies=tallies, + plots=plots) + return model + +class TriggerStatepointRestartTestHarness(PyAPITestHarness): + def __init__(self, statepoint, model=None): + super().__init__(statepoint, model) + self._restart_sp = None + self._final_sp = None + + def _test_output_created(self): + """Make sure statepoint files have been created.""" + spfiles = glob.glob(self._sp_name) + assert len(spfiles) == 2, \ + 'Two statepoint files should have been created' + if self._final_sp: + # Second restart run + assert spfiles[1] == self._final_sp, \ + 'Final statepoint names were different' + else: + # First non-restart run + self._restart_sp = spfiles[0] + self._final_sp = spfiles[1] + + def execute_test(self): + """ + Perform initial and restart runs using the model.run method, + Check all inputs and outputs which should be the same as those + generated using the normal PyAPITestHarness update methods. + """ + try: + args = {'openmc_exec': config['exe'], 'event_based': config['event']} + if config['mpi']: + args['mpi_args'] = [config['mpiexec'], '-n', config['mpi_np']] + # First non-restart run + k_combined_1 = self._model.run(**args) + sp_batchno_1 = 0 + with openmc.StatePoint(self._model.statepoint) as sp: + sp_batchno_1 = sp.current_batch + assert sp_batchno_1 > 10 + self._write_inputs(self._get_inputs()) + self._compare_inputs() + self._test_output_created() + self._write_results(self._get_results()) + self._compare_results() + # Second restart run + restart_spfile = glob.glob(os.path.join(os.getcwd(), self._restart_sp)) + assert len(restart_spfile) == 1 + args['restart_file'] = restart_spfile[0] + k_combined_2 = self._model.run(**args) + sp_batchno_2 = 0 + with openmc.StatePoint(self._model.statepoint) as sp: + sp_batchno_2 = sp.current_batch + assert sp_batchno_2 > 10 + self._write_inputs(self._get_inputs()) + self._compare_inputs() + self._test_output_created() + self._write_results(self._get_results()) + self._compare_results() + assert str(k_combined_1) == str(k_combined_2), \ + 'Different final k_combined after restart' + assert sp_batchno_1 == sp_batchno_2, \ + 'Different final batch number after restart' + finally: + self._cleanup() + +def test_trigger_statepoint_restart(model): + # Assuming we converge within 1000 batches, the statepoint filename + # should include the batch number padded by at least one '0'. + harness = TriggerStatepointRestartTestHarness('statepoint.0*.h5', model) + harness.main() From f98c34b7c9bc84cf827c7e403552d137356d25f0 Mon Sep 17 00:00:00 2001 From: alex-lyons Date: Fri, 7 Feb 2020 16:36:53 +0000 Subject: [PATCH 02/12] fix comment description --- openmc/model/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/model/model.py b/openmc/model/model.py index 08ba300dd1..e59c679b52 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -41,7 +41,7 @@ class Model: Tallies information plots : openmc.Plots Plot information - statepoint : openmc.Statepoint + statepoint : str The last statepoint filename written when the model is run """ From 4c96fc11d0e69601468afd7fb5f9ba1d0d188657 Mon Sep 17 00:00:00 2001 From: alex-lyons Date: Mon, 17 Feb 2020 16:13:11 +0000 Subject: [PATCH 03/12] ensure results are loaded from the last statepoint for testing --- .../results_true.dat | 6 ++--- .../trigger_statepoint_restart/test.py | 24 +++++++++++-------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/tests/regression_tests/trigger_statepoint_restart/results_true.dat b/tests/regression_tests/trigger_statepoint_restart/results_true.dat index 84363f8696..dc5ed98310 100644 --- a/tests/regression_tests/trigger_statepoint_restart/results_true.dat +++ b/tests/regression_tests/trigger_statepoint_restart/results_true.dat @@ -1,5 +1,5 @@ k-combined: -2.909598E-01 6.161987E-03 +3.040704E-01 1.976825E-03 tally 1: -3.852896E+01 -2.976246E+02 +3.389935E+02 +2.743454E+03 diff --git a/tests/regression_tests/trigger_statepoint_restart/test.py b/tests/regression_tests/trigger_statepoint_restart/test.py index 66416297b1..961a576a55 100644 --- a/tests/regression_tests/trigger_statepoint_restart/test.py +++ b/tests/regression_tests/trigger_statepoint_restart/test.py @@ -56,20 +56,24 @@ class TriggerStatepointRestartTestHarness(PyAPITestHarness): super().__init__(statepoint, model) self._restart_sp = None self._final_sp = None + # store the statepoint filename pattern separately to sp_name so we can reuse it + self._sp_pattern = self._sp_name def _test_output_created(self): """Make sure statepoint files have been created.""" - spfiles = glob.glob(self._sp_name) + spfiles = glob.glob(self._sp_pattern) assert len(spfiles) == 2, \ 'Two statepoint files should have been created' - if self._final_sp: - # Second restart run - assert spfiles[1] == self._final_sp, \ - 'Final statepoint names were different' - else: + if not self._final_sp: # First non-restart run self._restart_sp = spfiles[0] self._final_sp = spfiles[1] + else: + # Second restart run + assert spfiles[1] == self._final_sp, \ + 'Final statepoint names were different' + # Use the final_sp as the sp_name for the 'standard' results tests + self._sp_name = self._final_sp def execute_test(self): """ @@ -101,15 +105,15 @@ class TriggerStatepointRestartTestHarness(PyAPITestHarness): with openmc.StatePoint(self._model.statepoint) as sp: sp_batchno_2 = sp.current_batch assert sp_batchno_2 > 10 + assert sp_batchno_1 == sp_batchno_2, \ + 'Different final batch number after restart' + assert str(k_combined_1) == str(k_combined_2), \ + 'Different final k_combined after restart' self._write_inputs(self._get_inputs()) self._compare_inputs() self._test_output_created() self._write_results(self._get_results()) self._compare_results() - assert str(k_combined_1) == str(k_combined_2), \ - 'Different final k_combined after restart' - assert sp_batchno_1 == sp_batchno_2, \ - 'Different final batch number after restart' finally: self._cleanup() From 1312a1cc637b82c69757a282849e20edf57ca5eb Mon Sep 17 00:00:00 2001 From: alex-lyons Date: Tue, 3 Mar 2020 13:37:24 +0000 Subject: [PATCH 04/12] Obtain last statepoint from a glob of output dir. Reverted regex filter in executor as this is no longer needed --- openmc/executor.py | 17 +----------- openmc/model/model.py | 27 ++++++++++++++++--- .../inputs_true.dat | 1 + .../trigger_statepoint_restart/test.py | 3 +++ 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/openmc/executor.py b/openmc/executor.py index 76d100d32a..ebd1a450bc 100644 --- a/openmc/executor.py +++ b/openmc/executor.py @@ -11,10 +11,6 @@ def _run(args, output, cwd): p = subprocess.Popen(args, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) - # Compile a regex object to identify statepoint writes - sp_rxprog = re.compile(r'Creating state point (.+)\.\.\.') - last_statepoint = None - # Capture and re-print OpenMC output in real-time lines = [] while True: @@ -23,11 +19,6 @@ def _run(args, output, cwd): if not line and p.poll() is not None: break - # If a statepoint was written, capture its filename - sp_match = sp_rxprog.search(line) - if sp_match: - last_statepoint = sp_match.group(1) - lines.append(line) if output: # If user requested output, print to screen @@ -37,7 +28,6 @@ def _run(args, output, cwd): if p.returncode != 0: raise subprocess.CalledProcessError(p.returncode, ' '.join(args), ''.join(lines)) - return last_statepoint def plot_geometry(output=True, openmc_exec='openmc', cwd='.'): @@ -195,11 +185,6 @@ def run(particles=None, threads=None, geometry_debug=False, event_based : bool, optional Turns on event-based parallelism, instead of default history-based - Returns - ------- - str - Name of the last written statepoint file, or None - Raises ------ subprocess.CalledProcessError @@ -229,4 +214,4 @@ def run(particles=None, threads=None, geometry_debug=False, if mpi_args is not None: args = mpi_args + args - return _run(args, output, cwd) + _run(args, output, cwd) diff --git a/openmc/model/model.py b/openmc/model/model.py index e59c679b52..2089721032 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -1,5 +1,6 @@ from collections.abc import Iterable from pathlib import Path +import time import openmc from openmc.checkvalue import check_type, check_value @@ -175,7 +176,7 @@ class Model: will be created. """ - # Create directory if + # Create directory if required d = Path(directory) if not d.is_dir(): d.mkdir(parents=True) @@ -201,7 +202,7 @@ class Model: def run(self, **kwargs): """Creates the XML files, runs OpenMC, and returns k-effective. - The last statepoint filename is available in model.statepoint + The last statepoint Path is available in model.statepoint Parameters ---------- @@ -211,14 +212,32 @@ class Model: Returns ------- uncertainties.UFloat - Combined estimator of k-effective from the statepoint + Combined estimator of k-effective from the last statepoint + (None if no statepoint was written) """ self.export_to_xml() - self.statepoint = openmc.run(**kwargs) + # Setting tstart here ensures we don't pick up any old statepoint + # files that might preexist in the output directory + tstart = time.time() + self.statepoint = None + openmc.run(**kwargs) + + # Get output directory and last statepoint written by this run + if self.settings.output and 'path' in self.settings.output: + output_dir = Path(self.settings.output['path']) + else: + output_dir = Path.cwd() + for sp in output_dir.glob('statepoint.*.h5'): + mtime = sp.stat().st_mtime + if mtime >= tstart: # >= allows for poor clock resolution + tstart = mtime + self.statepoint = sp + + # Open the last statepoint to get the final k-effective keff = None if self.statepoint: with openmc.StatePoint(self.statepoint) as sp: diff --git a/tests/regression_tests/trigger_statepoint_restart/inputs_true.dat b/tests/regression_tests/trigger_statepoint_restart/inputs_true.dat index decc87b0c5..26890f9f86 100644 --- a/tests/regression_tests/trigger_statepoint_restart/inputs_true.dat +++ b/tests/regression_tests/trigger_statepoint_restart/inputs_true.dat @@ -25,6 +25,7 @@ 1000 1 + 1 diff --git a/tests/regression_tests/trigger_statepoint_restart/test.py b/tests/regression_tests/trigger_statepoint_restart/test.py index 961a576a55..44b809454b 100644 --- a/tests/regression_tests/trigger_statepoint_restart/test.py +++ b/tests/regression_tests/trigger_statepoint_restart/test.py @@ -33,6 +33,7 @@ def model(): settings.trigger_max_batches = 1000 settings.trigger_batch_interval = 1 settings.trigger_active = True + settings.verbosity = 1 # to test that this works even with no output # Tallies tallies = openmc.Tallies() @@ -88,6 +89,7 @@ class TriggerStatepointRestartTestHarness(PyAPITestHarness): # First non-restart run k_combined_1 = self._model.run(**args) sp_batchno_1 = 0 + assert self._model.statepoint with openmc.StatePoint(self._model.statepoint) as sp: sp_batchno_1 = sp.current_batch assert sp_batchno_1 > 10 @@ -102,6 +104,7 @@ class TriggerStatepointRestartTestHarness(PyAPITestHarness): args['restart_file'] = restart_spfile[0] k_combined_2 = self._model.run(**args) sp_batchno_2 = 0 + assert self._model.statepoint with openmc.StatePoint(self._model.statepoint) as sp: sp_batchno_2 = sp.current_batch assert sp_batchno_2 > 10 From 5a9fe17323047048b6f9609b51d9cbda06aa4022 Mon Sep 17 00:00:00 2001 From: alex-lyons Date: Wed, 4 Mar 2020 09:17:44 +0000 Subject: [PATCH 05/12] remove unneeded import --- openmc/executor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openmc/executor.py b/openmc/executor.py index ebd1a450bc..55e16a711b 100644 --- a/openmc/executor.py +++ b/openmc/executor.py @@ -1,6 +1,5 @@ from collections.abc import Iterable from numbers import Integral -import re import subprocess import openmc From e98ddf9d8a54b9cbb0b3ba50a00ba8c6b9343be0 Mon Sep 17 00:00:00 2001 From: alex-lyons Date: Wed, 4 Mar 2020 14:43:10 +0000 Subject: [PATCH 06/12] Model.run now returns last statepoint path rather than k_eff. Updated tests and search. --- openmc/model/model.py | 20 ++++++------------- openmc/search.py | 4 +++- openmc/statepoint.py | 5 +++-- .../trigger_statepoint_restart/test.py | 18 ++++++++++------- tests/unit_tests/test_filters.py | 4 ++-- 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/openmc/model/model.py b/openmc/model/model.py index 2089721032..cb9907331f 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -42,8 +42,6 @@ class Model: Tallies information plots : openmc.Plots Plot information - statepoint : str - The last statepoint filename written when the model is run """ @@ -211,8 +209,8 @@ class Model: Returns ------- - uncertainties.UFloat - Combined estimator of k-effective from the last statepoint + Path + the name of the last statepoint written by this run (None if no statepoint was written) """ @@ -222,11 +220,11 @@ class Model: # Setting tstart here ensures we don't pick up any old statepoint # files that might preexist in the output directory tstart = time.time() - self.statepoint = None + last_statepoint = None openmc.run(**kwargs) - # Get output directory and last statepoint written by this run + # Get output directory and return the last statepoint written by this run if self.settings.output and 'path' in self.settings.output: output_dir = Path(self.settings.output['path']) else: @@ -235,11 +233,5 @@ class Model: mtime = sp.stat().st_mtime if mtime >= tstart: # >= allows for poor clock resolution tstart = mtime - self.statepoint = sp - - # Open the last statepoint to get the final k-effective - keff = None - if self.statepoint: - with openmc.StatePoint(self.statepoint) as sp: - keff = sp.k_combined - return keff + last_statepoint = sp + return last_statepoint diff --git a/openmc/search.py b/openmc/search.py index 6be8a50ea5..ee5dd1f077 100644 --- a/openmc/search.py +++ b/openmc/search.py @@ -51,7 +51,9 @@ def _search_keff(guess, target, model_builder, model_args, print_iterations, model = model_builder(guess, **model_args) # Run the model and obtain keff - keff = model.run(output=print_output) + sp_filepath = model.run(output=print_output) + with openmc.StatePoint(sp_filepath) as sp: + keff = sp.k_combined # Record the history guesses.append(guess) diff --git a/openmc/statepoint.py b/openmc/statepoint.py index 7d9895f8e3..dcb8b7924c 100644 --- a/openmc/statepoint.py +++ b/openmc/statepoint.py @@ -21,7 +21,7 @@ class StatePoint: Parameters ---------- - filename : str + filepath : str or Path Path to file to load autolink : bool, optional Whether to automatically link in metadata from a summary.h5 file and @@ -115,7 +115,8 @@ class StatePoint: """ - def __init__(self, filename, autolink=True): + def __init__(self, filepath, autolink=True): + filename = str(filepath) # in case it's a Path self._f = h5py.File(filename, 'r') self._meshes = {} self._filters = {} diff --git a/tests/regression_tests/trigger_statepoint_restart/test.py b/tests/regression_tests/trigger_statepoint_restart/test.py index 44b809454b..5f37383abd 100644 --- a/tests/regression_tests/trigger_statepoint_restart/test.py +++ b/tests/regression_tests/trigger_statepoint_restart/test.py @@ -86,31 +86,35 @@ class TriggerStatepointRestartTestHarness(PyAPITestHarness): args = {'openmc_exec': config['exe'], 'event_based': config['event']} if config['mpi']: args['mpi_args'] = [config['mpiexec'], '-n', config['mpi_np']] + # First non-restart run - k_combined_1 = self._model.run(**args) + spfile = self._model.run(**args) sp_batchno_1 = 0 - assert self._model.statepoint - with openmc.StatePoint(self._model.statepoint) as sp: + assert sp_file + with openmc.StatePoint(spfile) as sp: sp_batchno_1 = sp.current_batch + k_combined_1 = sp.k_combined assert sp_batchno_1 > 10 self._write_inputs(self._get_inputs()) self._compare_inputs() self._test_output_created() self._write_results(self._get_results()) self._compare_results() + # Second restart run restart_spfile = glob.glob(os.path.join(os.getcwd(), self._restart_sp)) assert len(restart_spfile) == 1 args['restart_file'] = restart_spfile[0] - k_combined_2 = self._model.run(**args) + spfile = self._model.run(**args) sp_batchno_2 = 0 - assert self._model.statepoint - with openmc.StatePoint(self._model.statepoint) as sp: + assert spfile + with openmc.StatePoint(spfile) as sp: sp_batchno_2 = sp.current_batch + k_combined_2 = sp.k_combined assert sp_batchno_2 > 10 assert sp_batchno_1 == sp_batchno_2, \ 'Different final batch number after restart' - assert str(k_combined_1) == str(k_combined_2), \ + assert k_combined_1 == k_combined_2, \ 'Different final k_combined after restart' self._write_inputs(self._get_inputs()) self._compare_inputs() diff --git a/tests/unit_tests/test_filters.py b/tests/unit_tests/test_filters.py index 10587a8125..bf62abb65d 100644 --- a/tests/unit_tests/test_filters.py +++ b/tests/unit_tests/test_filters.py @@ -173,10 +173,10 @@ def test_first_moment(run_in_tmpdir, box_model): for t in box_model.tallies: t.estimator = 'analog' - box_model.run() + sp_name = box_model.run() # Check that first moment matches the score from the plain tally - with openmc.StatePoint('statepoint.10.h5') as sp: + with openmc.StatePoint(sp_name) as sp: # Get scores from tally without expansion filters flux, scatter = sp.tallies[plain_tally.id].mean.ravel() From a7e924e545fda3773cc09be0c81b064599b5c29c Mon Sep 17 00:00:00 2001 From: alex-lyons Date: Wed, 4 Mar 2020 15:43:16 +0000 Subject: [PATCH 07/12] Fix typos and redundant line --- openmc/model/model.py | 1 - tests/regression_tests/trigger_statepoint_restart/test.py | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openmc/model/model.py b/openmc/model/model.py index cb9907331f..896e061194 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -52,7 +52,6 @@ class Model: self.settings = openmc.Settings() self.tallies = openmc.Tallies() self.plots = openmc.Plots() - self.statepoint = None if geometry is not None: self.geometry = geometry diff --git a/tests/regression_tests/trigger_statepoint_restart/test.py b/tests/regression_tests/trigger_statepoint_restart/test.py index 5f37383abd..eb0be0e191 100644 --- a/tests/regression_tests/trigger_statepoint_restart/test.py +++ b/tests/regression_tests/trigger_statepoint_restart/test.py @@ -90,7 +90,7 @@ class TriggerStatepointRestartTestHarness(PyAPITestHarness): # First non-restart run spfile = self._model.run(**args) sp_batchno_1 = 0 - assert sp_file + assert spfile with openmc.StatePoint(spfile) as sp: sp_batchno_1 = sp.current_batch k_combined_1 = sp.k_combined @@ -114,7 +114,8 @@ class TriggerStatepointRestartTestHarness(PyAPITestHarness): assert sp_batchno_2 > 10 assert sp_batchno_1 == sp_batchno_2, \ 'Different final batch number after restart' - assert k_combined_1 == k_combined_2, \ + # need str() here as uncertainties.ufloat instances are always different + assert str(k_combined_1) == str(k_combined_2), \ 'Different final k_combined after restart' self._write_inputs(self._get_inputs()) self._compare_inputs() From bd71ac0588ec327027477fbd808d80b15aec1f28 Mon Sep 17 00:00:00 2001 From: Alex Lyons <59739325+alex-lyons@users.noreply.github.com> Date: Thu, 19 Mar 2020 16:37:11 +0000 Subject: [PATCH 08/12] Update tests/regression_tests/trigger_statepoint_restart/test.py Co-Authored-By: Paul Romano --- .../trigger_statepoint_restart/test.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/regression_tests/trigger_statepoint_restart/test.py b/tests/regression_tests/trigger_statepoint_restart/test.py index eb0be0e191..67ba598072 100644 --- a/tests/regression_tests/trigger_statepoint_restart/test.py +++ b/tests/regression_tests/trigger_statepoint_restart/test.py @@ -12,11 +12,10 @@ from tests.regression_tests import config def model(): # Materials - materials = openmc.Materials() mat = openmc.Material() mat.set_density('g/cm3', 4.5) mat.add_nuclide('U235', 1.0) - materials.append(mat) + materials = openmc.Materials([mat]) # Geometry sph = openmc.Sphere(r=10.0, boundary_type='vacuum') @@ -36,22 +35,18 @@ def model(): settings.verbosity = 1 # to test that this works even with no output # Tallies - tallies = openmc.Tallies() t = openmc.Tally() t.scores = ['flux'] - tallies.append(t) + tallies = openmc.Tallies([t]) - # Plots (none) - plots = openmc.Plots() - # Put it all together model = openmc.model.Model(materials=materials, geometry=geometry, settings=settings, - tallies=tallies, - plots=plots) + tallies=tallies) return model + class TriggerStatepointRestartTestHarness(PyAPITestHarness): def __init__(self, statepoint, model=None): super().__init__(statepoint, model) @@ -125,6 +120,7 @@ class TriggerStatepointRestartTestHarness(PyAPITestHarness): finally: self._cleanup() + def test_trigger_statepoint_restart(model): # Assuming we converge within 1000 batches, the statepoint filename # should include the batch number padded by at least one '0'. From f2bc95afa5f59129af8a9e8e446d4f7c309e7f5f Mon Sep 17 00:00:00 2001 From: alex-lyons Date: Thu, 19 Mar 2020 17:50:45 +0000 Subject: [PATCH 09/12] Reduce no of batches for trigger from ~47 to ~13 to try to avoid test failures due to numerical differences in platform libraries --- openmc/settings.py | 8 +++----- .../trigger_statepoint_restart/inputs_true.dat | 2 +- .../trigger_statepoint_restart/results_true.dat | 6 +++--- tests/regression_tests/trigger_statepoint_restart/test.py | 6 +++++- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/openmc/settings.py b/openmc/settings.py index 3f1cbe2c39..8ea110be13 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -813,10 +813,9 @@ class Settings: def _create_keff_trigger_subelement(self, root): if self._keff_trigger is not None: element = ET.SubElement(root, "keff_trigger") - - for key in self._keff_trigger: + for key, value in sorted(self._keff_trigger.items()): subelement = ET.SubElement(element, key) - subelement.text = str(self._keff_trigger[key]).lower() + subelement.text = str(value).lower() def _create_energy_mode_subelement(self, root): if self._energy_mode is not None: @@ -839,8 +838,7 @@ class Settings: def _create_output_subelement(self, root): if self._output is not None: element = ET.SubElement(root, "output") - - for key, value in self._output.items(): + for key, value in sorted(self._output.items()): subelement = ET.SubElement(element, key) if key in ('summary', 'tallies'): subelement.text = str(value).lower() diff --git a/tests/regression_tests/trigger_statepoint_restart/inputs_true.dat b/tests/regression_tests/trigger_statepoint_restart/inputs_true.dat index 26890f9f86..51ed9ee61a 100644 --- a/tests/regression_tests/trigger_statepoint_restart/inputs_true.dat +++ b/tests/regression_tests/trigger_statepoint_restart/inputs_true.dat @@ -17,8 +17,8 @@ 10 5 + 0.004 std_dev - 0.002 true diff --git a/tests/regression_tests/trigger_statepoint_restart/results_true.dat b/tests/regression_tests/trigger_statepoint_restart/results_true.dat index dc5ed98310..1fdfb64447 100644 --- a/tests/regression_tests/trigger_statepoint_restart/results_true.dat +++ b/tests/regression_tests/trigger_statepoint_restart/results_true.dat @@ -1,5 +1,5 @@ k-combined: -3.040704E-01 1.976825E-03 +2.916922E-01 3.293799E-03 tally 1: -3.389935E+02 -2.743454E+03 +6.184423E+01 +4.789617E+02 diff --git a/tests/regression_tests/trigger_statepoint_restart/test.py b/tests/regression_tests/trigger_statepoint_restart/test.py index 67ba598072..ba99c94ced 100644 --- a/tests/regression_tests/trigger_statepoint_restart/test.py +++ b/tests/regression_tests/trigger_statepoint_restart/test.py @@ -28,7 +28,9 @@ def model(): settings.batches = 10 settings.inactive = 5 settings.particles = 200 - settings.keff_trigger = {'type': 'std_dev', 'threshold': 0.002} + # Choose a sufficiently low threshold to trigger after more than 10 batches. + # 0.004 seems to take 13 batches. + settings.keff_trigger = {'type': 'std_dev', 'threshold': 0.004} settings.trigger_max_batches = 1000 settings.trigger_batch_interval = 1 settings.trigger_active = True @@ -85,11 +87,13 @@ class TriggerStatepointRestartTestHarness(PyAPITestHarness): # First non-restart run spfile = self._model.run(**args) sp_batchno_1 = 0 + print('Last sp file: %s' % spfile) assert spfile with openmc.StatePoint(spfile) as sp: sp_batchno_1 = sp.current_batch k_combined_1 = sp.k_combined assert sp_batchno_1 > 10 + print('Last batch no = %d' % sp_batchno_1) self._write_inputs(self._get_inputs()) self._compare_inputs() self._test_output_created() From 11807ae1f160def266fe8e38795b102fd13ddd3d Mon Sep 17 00:00:00 2001 From: alex-lyons Date: Tue, 24 Mar 2020 14:08:47 +0000 Subject: [PATCH 10/12] In the test, ensure the globbed statepoint filenames are sorted --- tests/regression_tests/trigger_statepoint_restart/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/regression_tests/trigger_statepoint_restart/test.py b/tests/regression_tests/trigger_statepoint_restart/test.py index ba99c94ced..1b47641474 100644 --- a/tests/regression_tests/trigger_statepoint_restart/test.py +++ b/tests/regression_tests/trigger_statepoint_restart/test.py @@ -59,7 +59,7 @@ class TriggerStatepointRestartTestHarness(PyAPITestHarness): def _test_output_created(self): """Make sure statepoint files have been created.""" - spfiles = glob.glob(self._sp_pattern) + spfiles = sorted(glob.glob(self._sp_pattern)) assert len(spfiles) == 2, \ 'Two statepoint files should have been created' if not self._final_sp: From 3e36801ea328385bb4dfaad5969ebcdf1b41353b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 27 Mar 2020 07:49:53 -0500 Subject: [PATCH 11/12] Update docstring for Model.run --- openmc/model/model.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openmc/model/model.py b/openmc/model/model.py index 896e061194..4115e4f917 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -198,18 +198,18 @@ class Model: self.plots.export_to_xml(d) def run(self, **kwargs): - """Creates the XML files, runs OpenMC, and returns k-effective. - The last statepoint Path is available in model.statepoint + """Creates the XML files, runs OpenMC, and returns the path to the last + statepoint file generated. Parameters ---------- **kwargs - All keyword arguments are passed to :func:`openmc.run` + Keyword arguments passed to :func:`openmc.run` Returns ------- Path - the name of the last statepoint written by this run + Path to the last statepoint written by this run (None if no statepoint was written) """ From 070a83d7733d988022235e77233764abb6f337e6 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 27 Mar 2020 11:21:18 -0500 Subject: [PATCH 12/12] Apply @pshriwise suggestion from code review Co-Authored-By: Patrick Shriwise --- openmc/model/model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openmc/model/model.py b/openmc/model/model.py index 4115e4f917..89dbfb3536 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -216,8 +216,8 @@ class Model: self.export_to_xml() - # Setting tstart here ensures we don't pick up any old statepoint - # files that might preexist in the output directory + # Setting tstart here ensures we don't pick up any pre-existing statepoint + # files in the output directory tstart = time.time() last_statepoint = None