mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 13:45:36 -04:00
Fix restart integration offset bugs
Changes in d32139b993 highlighted
the repeated data that was saved during non-predictor restart runs.
All Integrator subclasses now have the same
_get_bos_data_from_openmc and _get_bos_data_from_restart methods,
where the restart index ``self._ires`` is one less than the number of
previous results stored on the Operator. This allows all schemes to
write their data in the correct index during restart calculations.
A side benefit of this is that now, the Predictor implementation
can rely entirely on the updated Integrator, without the
need for re-writing the integrate method nor __init__ method.
This commit is contained in:
parent
d5fa7b5c00
commit
afe1b5b68c
4 changed files with 7 additions and 75 deletions
|
|
@ -110,7 +110,7 @@ class Integrator(ABC):
|
|||
def _get_start_data(self):
|
||||
if self.operator.prev_res is None:
|
||||
return 0.0, 0
|
||||
return self.operator.prev_res[-1].time[-1], len(self.operator.prev_res)
|
||||
return self.operator.prev_res[-1].time[-1], len(self.operator.prev_res) - 1
|
||||
|
||||
def integrate(self):
|
||||
"""Perform the entire depletion process across all steps"""
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class LEQIIntegrator(Integrator):
|
|||
simulation
|
||||
"""
|
||||
if i == 0:
|
||||
if self._ires <= 1: # need at least previous transport solution
|
||||
if self._ires < 1: # need at least previous transport solution
|
||||
self._prev_rates = bos_rates
|
||||
return CELIIntegrator.__call__(
|
||||
self, bos_conc, bos_rates, dt, power, i)
|
||||
|
|
|
|||
|
|
@ -40,32 +40,7 @@ class PredictorIntegrator(Integrator):
|
|||
is not speficied.
|
||||
"""
|
||||
|
||||
def __init__(self, operator, timesteps, power=None, power_density=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
operator : openmc.deplete.TransportOperator
|
||||
The operator object to simulate on.
|
||||
timesteps : iterable of float
|
||||
Array of timesteps in units of [s]. Note that values are not
|
||||
cumulative.
|
||||
power : float or iterable of float, optional
|
||||
Power of the reactor in [W]. A single value indicates that
|
||||
the power is constant over all timesteps. An iterable
|
||||
indicates potentially different power levels for each timestep.
|
||||
For a 2D problem, the power can be given in [W/cm] as long
|
||||
as the "volume" assigned to a depletion material is actually
|
||||
an area in [cm^2]. Either ``power`` or ``power_density`` must be
|
||||
specified.
|
||||
power_density : float or iterable of float, optional
|
||||
Power density of the reactor in [W/gHM]. It is multiplied by
|
||||
initial heavy metal inventory to get total power if ``power``
|
||||
is not speficied.
|
||||
"""
|
||||
super().__init__(operator, timesteps, power, power_density)
|
||||
self._dep_proc_time = None
|
||||
|
||||
def __call__(self, conc, rates, dt, power):
|
||||
def __call__(self, conc, rates, dt, power, _i=None):
|
||||
"""Perform the integration across one time step
|
||||
|
||||
Parameters
|
||||
|
|
@ -78,6 +53,8 @@ class PredictorIntegrator(Integrator):
|
|||
Time in [s] for the entire depletion interval
|
||||
power : float
|
||||
Power of the system [W]
|
||||
_i : int or None
|
||||
Iteration index. Not used
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
|
@ -91,49 +68,4 @@ class PredictorIntegrator(Integrator):
|
|||
|
||||
"""
|
||||
proc_time, conc_end = timed_deplete(self.chain, conc, rates, dt)
|
||||
return proc_time, conc_end, []
|
||||
|
||||
def _get_start_data(self):
|
||||
if self.operator.prev_res is None:
|
||||
return 0.0, 0
|
||||
return (
|
||||
self.operator.prev_res[-1].time[-1],
|
||||
len(self.operator.prev_res) - 1)
|
||||
|
||||
def _get_bos_data_from_openmc(self, step_index, step_power, prev_conc):
|
||||
conc = deepcopy(prev_conc)
|
||||
res = self.operator(conc, step_power)
|
||||
if step_index == len(self) - 1:
|
||||
tvec = [self.timesteps[step_index]] * 2
|
||||
else:
|
||||
tvec = self.timesteps[step_index:step_index + 2]
|
||||
|
||||
self._save_results(
|
||||
[conc], [res], tvec, step_power,
|
||||
self._istart + step_index, self._dep_proc_time)
|
||||
return conc, res
|
||||
|
||||
def integrate(self):
|
||||
"""Perform the entire depletion process across all steps"""
|
||||
|
||||
with self.operator as conc:
|
||||
t, self._istart = self._get_start_data()
|
||||
|
||||
for i, (dt, p) in enumerate(self):
|
||||
if i > 0 or self.operator.prev_res is None:
|
||||
conc, res = self._get_bos_data_from_openmc(i, p, conc)
|
||||
else:
|
||||
conc, res = self._get_bos_data_from_restart(i, p, conc)
|
||||
|
||||
# __call__ returns empty list since there aren't
|
||||
# intermediate transport solutions
|
||||
self._dep_proc_time, conc, _res_list = self(
|
||||
conc, res.rates, dt, p)
|
||||
|
||||
t += dt
|
||||
|
||||
# Final simulation
|
||||
res_list = [self.operator(conc, p)]
|
||||
self._save_results(
|
||||
[conc], res_list, [t, t], p,
|
||||
self._istart + len(self), self._dep_proc_time)
|
||||
return proc_time, [conc_end], []
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class SI_LEQI_Integrator(SI_Integrator):
|
|||
simulation
|
||||
"""
|
||||
if i == 0:
|
||||
if self._ires <= 1:
|
||||
if self._ires < 1:
|
||||
self._prev_rates = bos_rates
|
||||
# Perform CELI for initial steps
|
||||
return SI_CELI_Integrator.__call__(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue