Skip to content

Commit f544d02

Browse files
authored
Don't write reaction rates in depletion results by default, remove per-stage data for multistage integrators (#3609)
1 parent 028f440 commit f544d02

File tree

8 files changed

+338
-275
lines changed

8 files changed

+338
-275
lines changed

docs/source/io_formats/depletion_results.rst

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,28 @@
44
Depletion Results File Format
55
=============================
66

7-
The current version of the depletion results file format is 1.1.
7+
The current version of the depletion results file format is 1.2.
88

99
**/**
1010

1111
:Attributes: - **filetype** (*char[]*) -- String indicating the type of file.
1212
- **version** (*int[2]*) -- Major and minor version of the
1313
statepoint file format.
1414

15-
:Datasets: - **eigenvalues** (*double[][][2]*) -- k-eigenvalues at each
16-
time/stage. This array has shape (number of timesteps, number of
17-
stages, value). The last axis contains the eigenvalue and the
18-
associated uncertainty
19-
- **number** (*double[][][][]*) -- Total number of atoms. This array
20-
has shape (number of timesteps, number of stages, number of
15+
:Datasets: - **eigenvalues** (*double[][2]*) -- k-eigenvalues at each timestep.
16+
This array has shape (number of timesteps, 2). The second axis
17+
contains the eigenvalue and its associated uncertainty.
18+
- **number** (*double[][][]*) -- Total number of atoms at each
19+
timestep. This array has shape (number of timesteps, number of
2120
materials, number of nuclides).
22-
- **reaction rates** (*double[][][][][]*) -- Reaction rates used to
23-
build depletion matrices. This array has shape (number of
24-
timesteps, number of stages, number of materials, number of
25-
nuclides, number of reactions).
21+
- **reaction rates** (*double[][][][]*) -- Reaction rates at each
22+
timestep. This array has shape (number of timesteps, number of
23+
materials, number of nuclides, number of reactions). Only stored if
24+
write_rates=True.
2625
- **time** (*double[][2]*) -- Time in [s] at beginning/end of each
2726
step.
28-
- **source_rate** (*double[][]*) -- Power in [W] or source rate in
29-
[neutron/sec]. This array has shape (number of timesteps, number
30-
of stages).
27+
- **source_rate** (*double[]*) -- Power in [W] or source rate in
28+
[neutron/sec] for each timestep.
3129
- **depletion time** (*double[]*) -- Average process time in [s]
3230
spent depleting a material across all burnable materials and,
3331
if applicable, MPI processes.

openmc/deplete/abc.py

Lines changed: 104 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -631,17 +631,7 @@ def __init__(
631631
solver: str = "cram48",
632632
continue_timesteps: bool = False,
633633
):
634-
# Check number of stages previously used
635-
if operator.prev_res is not None:
636-
res = operator.prev_res[-1]
637-
if res.data.shape[0] != self._num_stages:
638-
raise ValueError(
639-
"{} incompatible with previous restart calculation. "
640-
"Previous scheme used {} intermediate solutions, while "
641-
"this uses {}".format(
642-
self.__class__.__name__, res.data.shape[0],
643-
self._num_stages))
644-
elif continue_timesteps:
634+
if continue_timesteps and operator.prev_res is None:
645635
raise ValueError("Continuation run requires passing prev_results.")
646636
self.operator = operator
647637
self.chain = operator.chain
@@ -775,12 +765,8 @@ def __call__(
775765
-------
776766
proc_time : float
777767
Time spent in CRAM routines for all materials in [s]
778-
n_list : list of list of numpy.ndarray
779-
Concentrations at each of the intermediate points with
780-
the final concentration as the last element
781-
op_results : list of openmc.deplete.OperatorResult
782-
Eigenvalue and reaction rates from intermediate transport
783-
simulations
768+
n_end : list of numpy.ndarray
769+
Concentrations at end of timestep
784770
"""
785771

786772
@property
@@ -811,9 +797,9 @@ def _get_bos_data_from_restart(self, source_rate, bos_conc):
811797
"""Get beginning of step concentrations, reaction rates from restart"""
812798
res = self.operator.prev_res[-1]
813799
# Depletion methods expect list of arrays
814-
bos_conc = list(res.data[0])
815-
rates = res.rates[0]
816-
k = ufloat(res.k[0, 0], res.k[0, 1])
800+
bos_conc = list(res.data)
801+
rates = res.rates
802+
k = ufloat(res.k[0], res.k[1])
817803

818804
if res.source_rate != 0.0:
819805
# Scale reaction rates by ratio of source rates
@@ -855,7 +841,8 @@ def integrate(
855841
self,
856842
final_step: bool = True,
857843
output: bool = True,
858-
path: PathLike = 'depletion_results.h5'
844+
path: PathLike = 'depletion_results.h5',
845+
write_rates: bool = False
859846
):
860847
"""Perform the entire depletion process across all steps
861848
@@ -874,6 +861,11 @@ def integrate(
874861
Path to file to write. Defaults to 'depletion_results.h5'.
875862
876863
.. versionadded:: 0.15.0
864+
write_rates : bool, optional
865+
Whether reaction rates should be written to the results file for
866+
each step. Defaults to ``False`` to reduce file size.
867+
868+
.. versionadded:: 0.15.3
877869
"""
878870
with change_directory(self.operator.output_dir):
879871
n = self.operator.initial_condition()
@@ -890,18 +882,22 @@ def integrate(
890882
n, res = self._get_bos_data_from_restart(source_rate, n)
891883

892884
# Solve Bateman equations over time interval
893-
proc_time, n_list, res_list = self(n, res.rates, dt, source_rate, i)
894-
895-
# Insert BOS concentration, transport results
896-
n_list.insert(0, n)
897-
res_list.insert(0, res)
898-
899-
# Remove actual EOS concentration for next step
900-
n = n_list.pop()
901-
902-
StepResult.save(self.operator, n_list, res_list, [t, t + dt],
903-
source_rate, self._i_res + i, proc_time, path)
885+
proc_time, n_end = self(n, res.rates, dt, source_rate, i)
886+
887+
StepResult.save(
888+
self.operator,
889+
n,
890+
res,
891+
[t, t + dt],
892+
source_rate,
893+
self._i_res + i,
894+
proc_time,
895+
write_rates=write_rates,
896+
path=path
897+
)
904898

899+
# Update for next step
900+
n = n_end
905901
t += dt
906902

907903
# Final simulation -- in the case that final_step is False, a zero
@@ -910,9 +906,18 @@ def integrate(
910906
# solve)
911907
if output and final_step and comm.rank == 0:
912908
print(f"[openmc.deplete] t={t} (final operator evaluation)")
913-
res_list = [self.operator(n, source_rate if final_step else 0.0)]
914-
StepResult.save(self.operator, [n], res_list, [t, t],
915-
source_rate, self._i_res + len(self), proc_time, path)
909+
res_final = self.operator(n, source_rate if final_step else 0.0)
910+
StepResult.save(
911+
self.operator,
912+
n,
913+
res_final,
914+
[t, t],
915+
source_rate,
916+
self._i_res + len(self),
917+
proc_time,
918+
write_rates=write_rates,
919+
path=path
920+
)
916921
self.operator.write_bos_data(len(self) + self._i_res)
917922

918923
self.operator.finalize()
@@ -1171,10 +1176,40 @@ def _get_bos_data_from_operator(self, step_index, step_power, n_bos):
11711176
self.operator.settings.particles //= self.n_steps
11721177
return inherited
11731178

1179+
@abstractmethod
1180+
def __call__(self, n, rates, dt, source_rate, i):
1181+
"""Perform the integration across one time step
1182+
1183+
Parameters
1184+
----------
1185+
n : list of numpy.ndarray
1186+
List of atom number arrays for each material. Each array has
1187+
shape ``(n_nucs,)`` where ``n_nucs`` is the number of nuclides
1188+
rates : openmc.deplete.ReactionRates
1189+
Reaction rates (from transport operator)
1190+
dt : float
1191+
Time step in [s]
1192+
source_rate : float
1193+
Power in [W] or source rate in [neutron/sec]
1194+
i : int
1195+
Current time step index
1196+
1197+
Returns
1198+
-------
1199+
proc_time : float
1200+
Time spent in transport simulation
1201+
n_end : list of numpy.ndarray
1202+
Updated atom number densities for each material
1203+
op_result : OperatorResult
1204+
Eigenvalue and reaction rates resulting from transport simulation
1205+
1206+
"""
1207+
11741208
def integrate(
11751209
self,
11761210
output: bool = True,
1177-
path: PathLike = "depletion_results.h5"
1211+
path: PathLike = "depletion_results.h5",
1212+
write_rates: bool = False
11781213
):
11791214
"""Perform the entire depletion process across all steps
11801215
@@ -1186,11 +1221,17 @@ def integrate(
11861221
Path to file to write. Defaults to 'depletion_results.h5'.
11871222
11881223
.. versionadded:: 0.15.0
1224+
write_rates : bool, optional
1225+
Whether reaction rates should be written to the results file for
1226+
each step. Defaults to ``False`` to reduce file size.
1227+
1228+
.. versionadded:: 0.15.3
11891229
"""
11901230
with change_directory(self.operator.output_dir):
11911231
n = self.operator.initial_condition()
11921232
t, self._i_res = self._get_start_data()
11931233

1234+
res_end = None # Will be set in first iteration
11941235
for i, (dt, p) in enumerate(self):
11951236
if output:
11961237
print(f"[openmc.deplete] t={t} s, dt={dt} s, source={p}")
@@ -1200,28 +1241,38 @@ def integrate(
12001241
n, res = self._get_bos_data_from_operator(i, p, n)
12011242
else:
12021243
n, res = self._get_bos_data_from_restart(p, n)
1203-
else:
1204-
# Pull rates, k from previous iteration w/o
1205-
# re-running transport
1206-
res = res_list[-1] # defined in previous i iteration
1207-
1208-
proc_time, n_list, res_list = self(n, res.rates, dt, p, i)
12091244

1210-
# Insert BOS concentration, transport results
1211-
n_list.insert(0, n)
1212-
res_list.insert(0, res)
1213-
1214-
# Remove actual EOS concentration for next step
1215-
n = n_list.pop()
1216-
1217-
StepResult.save(self.operator, n_list, res_list, [t, t + dt],
1218-
p, self._i_res + i, proc_time, path)
1245+
proc_time, n_end, res_end = self(n, res.rates, dt, p, i)
1246+
1247+
StepResult.save(
1248+
self.operator,
1249+
n,
1250+
res,
1251+
[t, t + dt],
1252+
p,
1253+
self._i_res + i,
1254+
proc_time,
1255+
write_rates=write_rates,
1256+
path=path
1257+
)
12191258

1259+
# Update for next step
1260+
n = n_end
1261+
res = res_end
12201262
t += dt
12211263

12221264
# No final simulation for SIE, use last iteration results
1223-
StepResult.save(self.operator, [n], [res_list[-1]], [t, t],
1224-
p, self._i_res + len(self), proc_time, path)
1265+
StepResult.save(
1266+
self.operator,
1267+
n,
1268+
res_end,
1269+
[t, t],
1270+
p,
1271+
self._i_res + len(self),
1272+
proc_time,
1273+
write_rates=write_rates,
1274+
path=path
1275+
)
12251276
self.operator.write_bos_data(self._i_res + len(self))
12261277

12271278
self.operator.finalize()

0 commit comments

Comments
 (0)