-
Notifications
You must be signed in to change notification settings - Fork 519
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add continue feature for depletion #3272
base: develop
Are you sure you want to change the base?
add continue feature for depletion #3272
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking for input on this line (636)
# validate existing depletion steps are consistent with those passed to operator | ||
if continue_timesteps: | ||
completed_timesteps = operator.prev_res.get_times() | ||
completed_source_rates = operator.prev_res.get_source_rates() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm realizing now that I don't think openmc.deplete.Results
has a get_source_rates()
function. It seems like individual operators have a source_rates
member, but I'm wondering if a method in openmc.deplete.Results
parallel to get_times()
would be useful for others. I noticed openmc.deplete.abc.Integrator
has an __iter__()
method but it doesn't return all the source rates, just the source rate and time (for a given iteration?)
It seems like maybe the appropriate line should be
completed_source_rates = operator.source_rates
though I'm wondering if the length of get_times()
and operator.source_rates
might have different lengths.
Tests were passing because I never added a test that hits this code, I will push up a test very soon (and likely it will fail)
c7324fa
to
1b9dbbd
Compare
1b9dbbd
to
b5fe00b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one fairly minor comment.
openmc/deplete/abc.py
Outdated
num_previous_steps_run = len(completed_timesteps) | ||
for step in len(completed_timesteps): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You make this num_previous_steps_run
variable which has a value of len(completed_timesteps)
, and then in the next line you call len(completed_timesteps)
. Should you not use that variable you just created?
Optional variable name change suggestion: num_previous_steps_run
--> num_completed_timesteps
for more consistency with the variable completed_timesteps
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
re-use variable and add missing range Co-authored-by: Edgar-21 <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-suggesting my comment from before since it was outdated by the commit of Edgar's suggestion. Might need to apply proper formatting for OpenMC, if applicable (should be black-compliant)
num_previous_steps_run = len(completed_timesteps) | ||
for step in range(num_previous_steps_run): | ||
if ( | ||
timesteps[step] == completed_timesteps[step] | ||
and source_rates[step] == completed_source_rates[step] | ||
): | ||
continue | ||
else: | ||
raise ValueError( | ||
"You are attempting to continue a run in which the previous results " | ||
"do not have the same initial steps as those provided to the " | ||
"Integrator. Please make sure you are using the correct timesteps," | ||
"powers or power densities, and previous results file." | ||
) | ||
seconds = seconds[num_previous_steps_run:] | ||
source_rates = source_rates[num_previous_steps_run:] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
num_previous_steps_run = len(completed_timesteps) | |
for step in range(num_previous_steps_run): | |
if ( | |
timesteps[step] == completed_timesteps[step] | |
and source_rates[step] == completed_source_rates[step] | |
): | |
continue | |
else: | |
raise ValueError( | |
"You are attempting to continue a run in which the previous results " | |
"do not have the same initial steps as those provided to the " | |
"Integrator. Please make sure you are using the correct timesteps," | |
"powers or power densities, and previous results file." | |
) | |
seconds = seconds[num_previous_steps_run:] | |
source_rates = source_rates[num_previous_steps_run:] | |
num_previous_steps_run = len(completed_timesteps) | |
if ( | |
np.allclose(completed_timesteps, timesteps[: num_previous_steps_run]) and | |
np.allclose(completed_source_rates, source_rates[: num_previous_steps_run]) | |
): | |
seconds = seconds[num_previous_steps_run:] | |
source_rates = source_rates[num_previous_steps_run:] | |
else: | |
raise ValueError( | |
"You are attempting to continue a run in which the previous results " | |
"do not have the same initial steps as those provided to the " | |
"Integrator. Please make sure you are using the correct timesteps," | |
"powers or power densities, and previous results file." | |
) |
Description
This PR closes #2871. To summarize the motivation, I'd like depletion restarts to be a bit easier for users. If you set up a depletion simulation that doesn't end up getting run all the way (think hitting max wall time on an HPC or some other interrupt), the burden then falls to the user to correctly determine what time steps were not run and to create a new script that picks up where the other one left off. In my own experience, it is easy to make a mistake and re-run a simulation that is not what I desired.
All we do here is add a
continue_timesteps
flag (default toFalse
) that adds a new logic block to theIntegrator
class. It would be useful in the above case and requires users to provide theIntegrator
with a set oftimesteps
and one ofpower
/power_density
/source_rate
that matches what already exists in aprev_results
passed to theOpperator
.With this flag, the depletion restart python script can now be exactly the same as the initial script, just with a
continue_timesteps = True
flag and aprev_results
object loaded from adepletion_statepoint.h5
passed to theOperator
. It could contain more timesteps at the end too, but the only requirement is that the data matches what is in theOperator
provided to theIntegrator
for all the existing steps in the results.This PR does not eliminate any of the existing capability of the depletion API, so all the old use cases/syntax for restarts remain. The flag is optional and defaults to
False
so no one will need to update past scripts with this change.Checklist
I have run clang-format (version 15) on any C++ source files (if applicable)