Implement vector fitting to replace external `vectfit` package
Description
This pull request removes the dependency on the unmaintained external vectfit package (https://github.com/liangjg/vectfit) used in OpenMC's windowed multipole (WMP) infrastructure. In its place, a vector fitting is introduced based on the vectorFitting.py module from scikit-rf project.
The implementation will be made in several steps as suggested by Paul:
- [x] Confirm whether the wrapper code it produced is correct or needs updating
- [x] Vendor a stripped version of the necessary vector fitting functionality from scikit-rf's vectorFitting.py module
- [x] Test it out by generating multipole data from an ENDF file and compare what you get with the updated implementation compared to the vectfit module. Hopefully it agrees but if not it will require some more digging.
This change improves long-term maintainability and compatibility of OpenMC.
Fixes #3487
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)
This PR is currently a draft. The code is a copy-pasting of the suggestion by chatGPT provided by Paul. The following repository provides an installation of openmc with vectfit dependency as it currently is implemented: https://github.com/azimgivron/openmc-vectfit.git This will be used to make the comparisons between the implementations.
Hello guys,
I've taken the time to re-implement the code using NumPy and SciPy. The unit tests are adapted from Jingang Liang’s implementation for consistency.
To validate the results, I generated WMP data from ENDF/B-VII for both Na-23 and Fe-56, and ran both implementations on these datasets. I will soon share plots comparing the absolute error in absorption cross sections between the two codes but there almost 0.
I also benchmarked the compute time, though I haven’t yet post-processed those results. In any case, I believe this additional performance data isn’t critical for this PR.
📊 Interpolation Benchmark: C++ vs Python
Note that the legend says $|\text{C++}-\text{Python}|$ where it should say $\frac{\text{C++}-\text{Python}}{\text{C++}}$.
This benchmark compares the C++ and Python implementations of vectfit for the WMP absorption cross sections of Na23 and Fe56. The relative error plots show that the results are close but differ at some points, I guess its energy frontier between interpolations, though further investigation could be done.
As expected, the Python implementation is slightly slower than the C++ counterpart, though still functionally equivalent in output.
🧬 Interpolation Metadata
Na23:
- 56 resonance poles
- 425 energy windows
- 0.63 poles per window
- 5th-order Chebyshev fit for the smooth background
Fe56:
- 408 resonance poles
- 1273 energy windows
- 2.7 poles per window
- 2nd-order Chebyshev fit for the smooth background
Hi, is this PR blocked because something is expected from me ?
@azimgivron Any chance you can update the results you had shared above with the normalization correction? I'm curious how much of the relative error shown before may be due to that.
This PR looks ready to be merge for me. @azimgivron, could you provide the scripts used to make the comparison between python and cpp vector fitting?