Repository: openmc-dev/openmc

Issue:
`StatePoint.runtime` incorrectly written from depletion simulation.
When running a depletion simulation, OpenMC generates a statepoint file for each depletion step.

The expected behavior is that OpenMC stores all data in these statepoint files that it normally would when running a transport simulation. However, I have noticed that this is not the case. On inspection of the `runtime` attribute, I get the following output:

```python

>>> sp = openmc.StatePoint('dep-res/openmc_simulation_n0.h5')
>>> sp.runtime
{'SEND-RECV source sites': 0.0, 'accumulating tallies': 0.0, 'active batches': 0.0, 'inactive batches': 0.0, 'reading cross sections': 0.0, 'sampling source sites': 0.0, 'simulation': 0.0, 'synchronizing fission bank': 0.0, 'total': 0.0, 'total initialization': 0.0, 'transport': 0.0, 'writing statepoints': 0.001705276}
>>> sp.close()
>>> sp = openmc.StatePoint('dep-res/openmc_simulation_n10.h5')
>>> sp.runtime
{'SEND-RECV source sites': 0.0, 'accumulating tallies': 0.0, 'active batches': 0.0, 'inactive batches': 0.0, 'reading cross sections': 0.0, 'sampling source sites': 0.0, 'simulation': 0.0, 'synchronizing fission bank': 0.0, 'total': 0.0, 'total initialization': 0.0, 'transport': 0.0, 'writing statepoints': 0.001968965}
```
wheras the output we get from a transport simulation is:
```python
sp2 = openmc.StatePoint('trans-res/statepoint.50.h5')
>>> sp2.runtime
{'SEND-RECV source sites': 0.00023556000000000006, 'accumulating tallies': 3.6788999999999996e-05, 'active batches': 0.294044768, 'inactive batches': 0.076043973, 'reading cross sections': 0.563972203, 'sampling source sites': 0.0023178319999999993, 'simulation': 0.369967645, 'synchronizing fission bank': 0.0026567239999999996, 'total': 0.948286129, 'total initialization': 0.573223358, 'transport': 0.36242318100000004, 'writing statepoints': 0.001678007}
```

It is possible that there are other attributes that are erroneously written as well.

The dummy model and depletion running script are below:
[dep-test.zip](https://github.com/openmc-dev/openmc/files/9922464/dep-test.zip)

### System Info:
OpenMC v0.13.3-dev
HDF5 1.12.1
Ubuntu 22.04


This issue can be closed when a PR exists that ensures that statepoint files from depletion simulations correctly store the `runtime` attribute.

## Update
I checked the statepoint files from my experiments this summer with the depletion module and all the statepoint files there have the same issue.


Discussion:
Is anyone able to reproduce this? Pinging @paulromano @pshriwise @shimwell or others for support.
One item of note I found: the `CoupledOperator.write_bos_data()` function calls `openmc.lib.statepoint_write()` to write the `openmc_simulation_n{i}.h5` file. The `cmfd.py` file also uses this function, so that may be affected as well.

Resolving patch:
diff --git a/openmc/deplete/coupled_operator.py b/openmc/deplete/coupled_operator.py
--- a/openmc/deplete/coupled_operator.py
+++ b/openmc/deplete/coupled_operator.py
@@ -460,7 +460,6 @@ def __call__(self, vec, source_rate):
 
         # Run OpenMC
         openmc.lib.run()
-        openmc.lib.reset_timers()
 
         # Extract results
         rates = self._calculate_reaction_rates(source_rate)
@@ -529,6 +528,8 @@ def write_bos_data(step):
             "openmc_simulation_n{}.h5".format(step),
             write_source=False)
 
+        openmc.lib.reset_timers()
+
     def finalize(self):
         """Finalize a depletion simulation and release resources."""
         if self.cleanup_when_done:


Test patch:
diff --git a/tests/regression_tests/deplete_with_transport/test.py b/tests/regression_tests/deplete_with_transport/test.py
--- a/tests/regression_tests/deplete_with_transport/test.py
+++ b/tests/regression_tests/deplete_with_transport/test.py
@@ -3,6 +3,7 @@
 from math import floor
 import shutil
 from pathlib import Path
+from collections import defaultdict
 
 from difflib import unified_diff
 import numpy as np
@@ -122,8 +123,11 @@ def test_full(run_in_tmpdir, problem, multiproc):
     n_tallies = np.empty(N + 1, dtype=int)
 
     # Get statepoint files for all BOS points and EOL
+    runtimes = defaultdict(list)
     for n in range(N + 1):
         statepoint = openmc.StatePoint(f"openmc_simulation_n{n}.h5")
+        for measure, time in statepoint.runtime.items():
+            runtimes[measure].append(time)
         k_n = statepoint.keff
         k_state[n] = [k_n.nominal_value, k_n.std_dev]
         n_tallies[n] = len(statepoint.tallies)
@@ -134,6 +138,21 @@ def test_full(run_in_tmpdir, problem, multiproc):
     # Check that no additional tallies are loaded from the files
     assert np.all(n_tallies == 0)
 
+    # Convert values in runtimes to arrays
+    runtimes = {k: np.array(v) for k, v in runtimes.items()}
+
+    # Check that runtimes are qualitatively correct
+    assert runtimes['reading cross sections'][0] != 0
+    assert runtimes['total initialization'][0] != 0
+    assert np.all(runtimes['reading cross sections'][1:] == 0)
+    assert np.all(runtimes['total initialization'][1:] == 0)
+    assert np.all(runtimes['inactive batches'] == 0)
+    del runtimes['reading cross sections']
+    del runtimes['total initialization']
+    del runtimes['inactive batches']
+    for measure, times in runtimes.items():
+        assert np.all(times != 0)
+
 
 def test_depletion_results_to_material(run_in_tmpdir, problem):
     """Checks openmc.Materials objects can be created from depletion results"""