Consolidate Parametric Functionality in C and Python APIs
Description
Background
A couple of months ago, I started a discussion on the forum as I was getting started on this topic: https://openmc.discourse.group/t/dedicated-parametric-simulation-module-development/3502
All models are parametric by default when built via the Python API. Unfortunately, there is an unnecessary overhead of cross section reloads which wastes CPU run time. During repetitive model rebuilds and reruns which have single point changes, such as for reactivity coefficient calculation, reactor design scoping or keff searches, those reloads become inefficient and waste time.
Use Cases and Problem Statement
There are use cases of in-memory parametric simulation. For reactor design scoping, the simulations' low complexity leads to short calculation times while the initialization and cross section load times dominate.
For shutdown configuration and stability margin calculations, models require single point modifications to material compositions or control configurations to find the value that makes the core just critical. The keff search algorithm provides a way to find this data. However, it rebuilds and reloads whole model instead of offering users ways to modify the model in-memory to accelerate calculations which makes these sorts of investigations inefficient in OpenMC.
Users could avoid overheads by loading the model through the C API and openmc.Model class but it was found during discussion on the forum that its documentation is not very visible nor complete. There are no official examples and the general user might feel discouraged to have to tangle with the C API to gain this added performance or functionality. The documentation and ease of understanding problem might need another dedicated PR later but this PR aims to simplify things in the code and start making things more user friendly and feature complete.
Contents
I have discovered a lot of functionality I thought didn't exist at that time of the forum post by reviewing the code directly along with relying on existing documentation. Following that, I have attempted to consolidate functionality already present in openmc.lib and introduce new functions which enable users to fully exploit OpenMC's unique advantage in the modelling community when it comes to parametric simulations.
Prior to this PR, the only in-memory changes allowed were limited to cell temperatures, translations and rotations, along with material densities. With this PR, the following new scenarios are possible for model updates in-memory which formally complete the parametric modelling feature set:
- Material composition updates accounting for new nuclides
- C API accelerated keff searches through the openmc.Model class
- C API accelerated reactivity calculation through the openmc.Model class
- Geometry/Cell updates in memory through the openmc.Model class
Issues
As of now, there are 2 standing issues with this PR:
- The geometry parameterization in memory is clunky, I've not been able to find other elegant ways to do it.
- The nuclides being loaded or modified in memory may not have cross section data loaded at the right temperatures.
All feedback, comments and suggestions welcome!
Credits
Credits to @shimwell and @gridley for their code and examples which helped me to get to this point!
Checklist
- [x] I have performed a self-review of my own code
- [x] I have run clang-format (version 15) on any C++ source files (if applicable)
- [x] I have followed the style guidelines for Python source files (if applicable)
- [x] I have made corresponding changes to the documentation (if applicable)
- [x] I have added tests that prove my fix is effective or that my feature works (if applicable)