-
Notifications
You must be signed in to change notification settings - Fork 609
NCrystal becomes runtime rather than buildtime dependency #3328
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
Merged
paulromano
merged 21 commits into
openmc-dev:develop
from
tkittel:tk_ncrystal_nobuilddep
Mar 5, 2025
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
7bb140c
add ncrystal_load.h/.cpp infrastructure for accessing NCrystal at run…
tkittel 2628813
Try to follow openmc coding style in ncrystal_load.h/.cpp files
tkittel 2c21caf
Move ncrystal_load.h to include folder
tkittel a7c59ed
More fixes
tkittel bfdcb71
clang-format
tkittel 11e0bce
Better error messages
tkittel 0041ed3
Require NCrystal 4.1.0 or later
tkittel 611e923
Fix syntax error
tkittel f70c1bb
Fix lint
tkittel bf4f72c
Remove a few lingering ncrystal=y/n flags
tkittel b4a70bf
update install.rst concerning NCrystal
tkittel 6d7036a
Add doxygen comments
tkittel 7f600af
fix lint
tkittel 165e582
Add src/ncrystal_load.cpp to CODEOWNERS
tkittel 42e96ea
Remove one mention of OPENMC_USE_NCRYSTAL
paulromano 15aa74a
Use fmt::format in one place
paulromano 78e75fa
Only check WIN32 not _WIN32 in ncrystal_load.cpp
tkittel 14e741a
Remove unused variable in Windows path
tkittel d01339e
Simplify ifdefs in ncrystal_load.cpp
paulromano cb131d2
Remove ncrystal-specific build config
paulromano c34b79a
Remove leftover unused variable
tkittel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| //! \file ncrystal_load.h | ||
| //! \brief Helper class taking care of loading NCrystal at runtime. | ||
|
|
||
| #ifndef OPENMC_NCRYSTAL_LOAD_H | ||
| #define OPENMC_NCRYSTAL_LOAD_H | ||
|
|
||
| #include <algorithm> // for swap | ||
| #include <functional> // for function | ||
| #include <memory> // for shared_ptr | ||
| #include <utility> // for move | ||
|
|
||
| namespace NCrystalVirtualAPI { | ||
|
|
||
| // NOTICE: Do NOT make ANY changes in the NCrystalVirtualAPI::VirtAPI_Type1_v1 | ||
| // class, it is required to stay exactly constant over time and compatible with | ||
| // the same definition used to compile the NCrystal library! But changes to | ||
| // white space, comments, and formatting is of course allowed. This API was | ||
| // introduced in NCrystal 4.1.0. | ||
|
|
||
| //! Abstract base class for NCrystal interface which must be declared exactly as | ||
| // it is in NCrystal itself. | ||
|
|
||
| class VirtAPI_Type1_v1 { | ||
| public: | ||
| // Note: neutron must be an array of length 4 with values {ekin,ux,uy,uz} | ||
| class ScatterProcess; | ||
| virtual const ScatterProcess* createScatter(const char* cfgstr) const = 0; | ||
| virtual const ScatterProcess* cloneScatter(const ScatterProcess*) const = 0; | ||
| virtual void deallocateScatter(const ScatterProcess*) const = 0; | ||
| virtual double crossSectionUncached( | ||
| const ScatterProcess&, const double* neutron) const = 0; | ||
| virtual void sampleScatterUncached(const ScatterProcess&, | ||
| std::function<double()>& rng, double* neutron) const = 0; | ||
| // Plumbing: | ||
| static constexpr unsigned interface_id = 1001; | ||
| virtual ~VirtAPI_Type1_v1() = default; | ||
| VirtAPI_Type1_v1() = default; | ||
| VirtAPI_Type1_v1(const VirtAPI_Type1_v1&) = delete; | ||
| VirtAPI_Type1_v1& operator=(const VirtAPI_Type1_v1&) = delete; | ||
| VirtAPI_Type1_v1(VirtAPI_Type1_v1&&) = delete; | ||
| VirtAPI_Type1_v1& operator=(VirtAPI_Type1_v1&&) = delete; | ||
| }; | ||
|
|
||
| } // namespace NCrystalVirtualAPI | ||
|
|
||
| namespace openmc { | ||
|
|
||
| using NCrystalAPI = NCrystalVirtualAPI::VirtAPI_Type1_v1; | ||
|
|
||
| //! Function which locates and loads NCrystal at runtime using the virtual API | ||
| std::shared_ptr<const NCrystalAPI> load_ncrystal_api(); | ||
|
|
||
| //! Class encapsulating exactly the parts of NCrystal needed by OpenMC | ||
|
|
||
| class NCrystalScatProc final { | ||
| public: | ||
| //! Empty constructor which does not load NCrystal | ||
| NCrystalScatProc() {} | ||
|
|
||
| //! Load NCrystal and instantiate a scattering process | ||
| //! \param cfgstr NCrystal cfg-string defining the material. | ||
| NCrystalScatProc(const char* cfgstr) | ||
| : api_(load_ncrystal_api()), p_(api_->createScatter(cfgstr)) | ||
| {} | ||
|
|
||
| // Note: Neutron state array is {ekin,ux,uy,uz} | ||
|
|
||
| //! Returns total scattering cross section in units of barns per atom. | ||
| //! \param neutron_state array {ekin,ux,uy,uz} with ekin (eV) and direction. | ||
| double cross_section(const double* neutron_state) const | ||
| { | ||
| return api_->crossSectionUncached(*p_, neutron_state); | ||
| } | ||
|
|
||
| //! Returns total scattering cross section in units of barns per atom. | ||
| //! \param rng function returning random numbers in the unit interval | ||
| //! \param neutron_state array {ekin,ux,uy,uz} with ekin (eV) and direction. | ||
| void scatter(std::function<double()>& rng, double* neutron_state) const | ||
| { | ||
| api_->sampleScatterUncached(*p_, rng, neutron_state); | ||
| } | ||
|
|
||
| //! Clones the object which is otherwise move-only | ||
| NCrystalScatProc clone() const | ||
| { | ||
| NCrystalScatProc c; | ||
| if (p_) { | ||
| c.api_ = api_; | ||
| c.p_ = api_->cloneScatter(p_); | ||
| } | ||
| return c; | ||
| } | ||
|
|
||
| // Plumbing (move-only semantics, but supports explicit clone): | ||
| NCrystalScatProc(const NCrystalScatProc&) = delete; | ||
| NCrystalScatProc& operator=(const NCrystalScatProc&) = delete; | ||
|
|
||
| NCrystalScatProc(NCrystalScatProc&& o) : api_(std::move(o.api_)), p_(nullptr) | ||
| { | ||
| std::swap(p_, o.p_); | ||
| } | ||
|
|
||
| NCrystalScatProc& operator=(NCrystalScatProc&& o) | ||
| { | ||
| if (p_) { | ||
| api_->deallocateScatter(p_); | ||
| p_ = nullptr; | ||
| } | ||
| std::swap(api_, o.api_); | ||
| std::swap(p_, o.p_); | ||
| return *this; | ||
| } | ||
|
|
||
| ~NCrystalScatProc() | ||
| { | ||
| if (p_) | ||
| api_->deallocateScatter(p_); | ||
| } | ||
|
|
||
| private: | ||
| std::shared_ptr<const NCrystalAPI> api_; | ||
| const NCrystalAPI::ScatterProcess* p_ = nullptr; | ||
| }; | ||
|
|
||
| } // namespace openmc | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.