NCrystal becomes runtime rather than buildtime dependency (#3328)

Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
This commit is contained in:
Thomas Kittelmann 2025-03-05 22:45:27 +01:00 committed by GitHub
parent 239f7fed5e
commit ced8929128
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 331 additions and 180 deletions

View file

@ -29,7 +29,6 @@ jobs:
mpi: [n, y]
omp: [n, y]
dagmc: [n]
ncrystal: [n]
libmesh: [n]
event: [n]
vectfit: [n]
@ -45,10 +44,6 @@ jobs:
python-version: "3.11"
mpi: y
omp: y
- ncrystal: y
python-version: "3.11"
mpi: n
omp: n
- libmesh: y
python-version: "3.11"
mpi: y
@ -66,7 +61,7 @@ jobs:
omp: n
mpi: y
name: "Python ${{ matrix.python-version }} (omp=${{ matrix.omp }},
mpi=${{ matrix.mpi }}, dagmc=${{ matrix.dagmc }}, ncrystal=${{ matrix.ncrystal }},
mpi=${{ matrix.mpi }}, dagmc=${{ matrix.dagmc }},
libmesh=${{ matrix.libmesh }}, event=${{ matrix.event }}
vectfit=${{ matrix.vectfit }})"
@ -75,7 +70,6 @@ jobs:
PHDF5: ${{ matrix.mpi }}
OMP: ${{ matrix.omp }}
DAGMC: ${{ matrix.dagmc }}
NCRYSTAL: ${{ matrix.ncrystal }}
EVENT: ${{ matrix.event }}
VECTFIT: ${{ matrix.vectfit }}
LIBMESH: ${{ matrix.libmesh }}

View file

@ -37,7 +37,6 @@ option(OPENMC_USE_DAGMC "Enable support for DAGMC (CAD) geometry"
option(OPENMC_USE_LIBMESH "Enable support for libMesh unstructured mesh tallies" OFF)
option(OPENMC_USE_MPI "Enable MPI" OFF)
option(OPENMC_USE_MCPL "Enable MCPL" OFF)
option(OPENMC_USE_NCRYSTAL "Enable support for NCrystal scattering" OFF)
option(OPENMC_USE_UWUW "Enable UWUW" OFF)
message(STATUS "OPENMC_USE_OPENMP ${OPENMC_USE_OPENMP}")
@ -48,7 +47,6 @@ message(STATUS "OPENMC_USE_DAGMC ${OPENMC_USE_DAGMC}")
message(STATUS "OPENMC_USE_LIBMESH ${OPENMC_USE_LIBMESH}")
message(STATUS "OPENMC_USE_MPI ${OPENMC_USE_MPI}")
message(STATUS "OPENMC_USE_MCPL ${OPENMC_USE_MCPL}")
message(STATUS "OPENMC_USE_NCRYSTAL ${OPENMC_USE_NCRYSTAL}")
message(STATUS "OPENMC_USE_UWUW ${OPENMC_USE_UWUW}")
# Warnings for deprecated options
@ -120,23 +118,6 @@ macro(find_package_write_status pkg)
endif()
endmacro()
#===============================================================================
# NCrystal Scattering Support
#===============================================================================
if(OPENMC_USE_NCRYSTAL)
if(NOT DEFINED "NCrystal_DIR")
#Invocation of "ncrystal-config --show cmakedir" is needed to find NCrystal
#when it is installed from Python wheels:
execute_process(
COMMAND "ncrystal-config" "--show" "cmakedir"
OUTPUT_VARIABLE "NCrystal_DIR" OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
find_package(NCrystal 3.8.0 REQUIRED)
message(STATUS "Found NCrystal: ${NCrystal_DIR} (version ${NCrystal_VERSION})")
endif()
#===============================================================================
# DAGMC Geometry Support - need DAGMC/MOAB
#===============================================================================
@ -372,6 +353,7 @@ list(APPEND libopenmc_SOURCES
src/mgxs.cpp
src/mgxs_interface.cpp
src/ncrystal_interface.cpp
src/ncrystal_load.cpp
src/nuclide.cpp
src/output.cpp
src/particle.cpp
@ -548,11 +530,6 @@ if (OPENMC_USE_MCPL)
target_link_libraries(libopenmc MCPL::mcpl)
endif()
if(OPENMC_USE_NCRYSTAL)
target_compile_definitions(libopenmc PRIVATE NCRYSTAL)
target_link_libraries(libopenmc NCrystal::NCrystal)
endif()
#===============================================================================
# Log build info that this executable can report later
#===============================================================================

View file

@ -60,7 +60,8 @@ Dockerfile @shimwell
src/random_ray/ @jtramm
# NCrystal interface
src/ncrystal_interface.cpp @marquezj
src/ncrystal_interface.cpp @marquezj @tkittel
src/ncrystal_load.cpp @marquezj @tkittel
# MCPL interface
src/mcpl_interface.cpp @ebknudsen

View file

@ -8,19 +8,6 @@ if(@OPENMC_USE_DAGMC@)
find_package(DAGMC REQUIRED HINTS @DAGMC_DIR@)
endif()
if(@OPENMC_USE_NCRYSTAL@)
if(NOT DEFINED "NCrystal_DIR")
#Invocation of "ncrystal-config --show cmakedir" is needed to find NCrystal
#when it is installed from Python wheels:
execute_process(
COMMAND "ncrystal-config" "--show" "cmakedir"
OUTPUT_VARIABLE "NCrystal_DIR" OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
find_package(NCrystal REQUIRED)
message(STATUS "Found NCrystal: ${NCrystal_DIR} (version ${NCrystal_VERSION})")
endif()
if(@OPENMC_USE_LIBMESH@)
include(FindPkgConfig)
list(APPEND CMAKE_PREFIX_PATH @LIBMESH_PREFIX@)

View file

@ -284,13 +284,13 @@ Prerequisites
* NCrystal_ library for defining materials with enhanced thermal neutron transport
Adding this option allows the creation of materials from NCrystal, which
replaces the scattering kernel treatment of ACE files with a modular,
on-the-fly approach. To use it `install
<https://github.com/mctools/ncrystal/wiki/Get-NCrystal>`_ NCrystal and
turn on the option in the CMake configuration step::
cmake -DOPENMC_USE_NCRYSTAL=on ..
OpenMC supports the creation of materials from NCrystal, which replaces
the scattering kernel treatment of ACE files with a modular, on-the-fly
approach. OpenMC does not need any particular build option to use this,
but NCrystal must be installed on the system. Refer to `NCrystal
documentation
<https://github.com/mctools/ncrystal/wiki/Get-NCrystal>`_ for how this is
achieved.
* libMesh_ mesh library framework for numerical simulations of partial differential equations
@ -393,12 +393,6 @@ OPENMC_USE_MCPL
Turns on support for reading MCPL_ source files and writing MCPL source points
and surface sources. (Default: off)
OPENMC_USE_NCRYSTAL
Turns on support for NCrystal materials. NCrystal must be `installed
<https://github.com/mctools/ncrystal/wiki/Get-NCrystal>`_ and `initialized
<https://github.com/mctools/ncrystal/wiki/Using-NCrystal#setting-up>`_.
(Default: off)
OPENMC_USE_LIBMESH
Enables the use of unstructured mesh tallies with libMesh_. (Default: off)

View file

@ -1,10 +1,7 @@
#ifndef OPENMC_NCRYSTAL_INTERFACE_H
#define OPENMC_NCRYSTAL_INTERFACE_H
#ifdef NCRYSTAL
#include "NCrystal/NCrystal.hh"
#endif
#include "openmc/ncrystal_load.h"
#include "openmc/particle.h"
#include <cstdint> // for uint64_t
@ -17,28 +14,25 @@ namespace openmc {
// Constants
//==============================================================================
extern "C" const bool NCRYSTAL_ENABLED;
//! Energy in [eV] to switch between NCrystal and ENDF
constexpr double NCRYSTAL_MAX_ENERGY {5.0};
//==============================================================================
// Wrapper class an NCrystal material
// Wrapper class for an NCrystal material
//==============================================================================
class NCrystalMat {
public:
//----------------------------------------------------------------------------
// Constructors
NCrystalMat() = default;
NCrystalMat() = default; // empty object
explicit NCrystalMat(const std::string& cfg);
//----------------------------------------------------------------------------
// Methods
#ifdef NCRYSTAL
//! Return configuration string
std::string cfg() const;
//! Return configuration string:
const std::string& cfg() const { return cfg_; }
//! Get cross section from NCrystal material
//
@ -52,25 +46,21 @@ public:
void scatter(Particle& p) const;
//! Whether the object holds a valid NCrystal material
operator bool() const;
#else
operator bool() const { return !cfg_.empty(); }
//----------------------------------------------------------------------------
// Trivial methods when compiling without NCRYSTAL
std::string cfg() const { return ""; }
double xs(const Particle& p) const { return -1.0; }
void scatter(Particle& p) const {}
operator bool() const { return false; }
#endif
NCrystalMat clone() const
{
NCrystalMat c;
c.cfg_ = cfg_;
c.proc_ = proc_.clone();
return c;
}
private:
//----------------------------------------------------------------------------
// Data members (only present when compiling with NCrystal support)
#ifdef NCRYSTAL
std::string cfg_; //!< NCrystal configuration string
std::shared_ptr<const NCrystal::ProcImpl::Process>
ptr_; //!< Pointer to NCrystal material object
#endif
std::string cfg_; //!< NCrystal configuration string
NCrystalScatProc proc_; //!< NCrystal scatter process
};
//==============================================================================

View file

@ -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

View file

@ -40,9 +40,6 @@ else:
def _dagmc_enabled():
return c_bool.in_dll(_dll, "DAGMC_ENABLED").value
def _ncrystal_enabled():
return c_bool.in_dll(_dll, "NCRYSTAL_ENABLED").value
def _coord_levels():
return c_int.in_dll(_dll, "n_coord_levels").value

View file

@ -429,7 +429,11 @@ class Material(IDManagerMixin):
"""
import NCrystal
try:
import NCrystal
except ModuleNotFoundError as e:
raise RuntimeError('The .from_ncrystal method requires'
' NCrystal to be installed.') from e
nc_mat = NCrystal.createInfo(cfg)
def openmc_natabund(Z):

View file

@ -368,7 +368,7 @@ Material& Material::clone()
mat->name_ = name_;
mat->nuclide_ = nuclide_;
mat->element_ = element_;
mat->ncrystal_mat_ = ncrystal_mat_;
mat->ncrystal_mat_ = ncrystal_mat_.clone();
mat->atom_density_ = atom_density_;
mat->density_ = density_;
mat->density_gpcc_ = density_gpcc_;

View file

@ -7,89 +7,34 @@
namespace openmc {
//==============================================================================
// Constants
// NCrystalMat implementation
//==============================================================================
#ifdef NCRYSTAL
const bool NCRYSTAL_ENABLED = true;
#else
const bool NCRYSTAL_ENABLED = false;
#endif
//==============================================================================
// NCrystal wrapper class for the OpenMC random number generator
//==============================================================================
#ifdef NCRYSTAL
class NCrystalRNGWrapper : public NCrystal::RNGStream {
public:
constexpr NCrystalRNGWrapper(uint64_t* seed) noexcept : openmc_seed_(seed) {}
protected:
double actualGenerate() override
{
return std::max<double>(
std::numeric_limits<double>::min(), prn(openmc_seed_));
}
private:
uint64_t* openmc_seed_;
};
#endif
//==============================================================================
// NCrystal implementation
//==============================================================================
NCrystalMat::NCrystalMat(const std::string& cfg)
{
#ifdef NCRYSTAL
cfg_ = cfg;
ptr_ = NCrystal::FactImpl::createScatter(cfg);
#else
fatal_error("Your build of OpenMC does not support NCrystal materials.");
#endif
}
#ifdef NCRYSTAL
std::string NCrystalMat::cfg() const
{
return cfg_;
}
NCrystalMat::NCrystalMat(const std::string& cfg) : cfg_(cfg), proc_(cfg.c_str())
{}
double NCrystalMat::xs(const Particle& p) const
{
// Calculate scattering XS per atom with NCrystal, only once per material
NCrystal::CachePtr dummy_cache;
auto nc_energy = NCrystal::NeutronEnergy {p.E()};
return ptr_->crossSection(dummy_cache, nc_energy, {p.u().x, p.u().y, p.u().z})
.get();
double neutron_state[4] = {p.E(), p.u().x, p.u().y, p.u().z};
return proc_.cross_section(neutron_state);
}
void NCrystalMat::scatter(Particle& p) const
{
NCrystalRNGWrapper rng(p.current_seed()); // Initialize RNG
// create a cache pointer for multi thread physics
NCrystal::CachePtr dummy_cache;
auto nc_energy = NCrystal::NeutronEnergy {p.E()};
auto outcome = ptr_->sampleScatter(
dummy_cache, rng, nc_energy, {p.u().x, p.u().y, p.u().z});
// Scatter with NCrystal, using the OpenMC RNG stream:
uint64_t* seed = p.current_seed();
std::function<double()> rng = [&seed]() { return prn(seed); };
double neutron_state[4] = {p.E(), p.u().x, p.u().y, p.u().z};
proc_.scatter(rng, neutron_state);
// Modify attributes of particle
p.E() = outcome.ekin.get();
p.E() = neutron_state[0];
Direction u_old {p.u()};
p.u() =
Direction(outcome.direction[0], outcome.direction[1], outcome.direction[2]);
p.u() = Direction(neutron_state[1], neutron_state[2], neutron_state[3]);
p.mu() = u_old.dot(p.u());
p.event_mt() = ELASTIC;
}
NCrystalMat::operator bool() const
{
return ptr_.get();
}
#endif
//==============================================================================
// Functions
//==============================================================================

151
src/ncrystal_load.cpp Normal file
View file

@ -0,0 +1,151 @@
#include "openmc/ncrystal_load.h"
#include <cctype> // for isspace
#include <cstdlib> // for strtoul
#include <memory> // for shared_ptr
#include <mutex> // for mutex, lock_guard
#include <string>
#include <fmt/core.h>
#include <stdio.h> // for popen, pclose
#include "openmc/error.h"
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h> // for LoadLibrary, GetProcAddress
#else
#include <dlfcn.h> // for dlopen, dlsym, dlerror
#endif
namespace openmc {
namespace {
struct NCrystalConfig {
std::string shlibpath;
unsigned long intversion = 0;
std::string symbol_namespace;
};
NCrystalConfig query_ncrystal_config()
{
#ifdef _WIN32
FILE* pipe = _popen("ncrystal-config --show "
"intversion shlibpath namespace",
"r");
#else
FILE* pipe = popen("ncrystal-config --show "
"intversion shlibpath namespace 2>/dev/null",
"r");
#endif
if (!pipe)
return {}; // failure
auto readLine = [pipe](std::string& tgt) -> bool {
// Read line and discard trailing whitespace (including newline chars).
char buffer[4096];
if (fgets(buffer, sizeof(buffer), pipe) == NULL)
return false;
tgt = buffer;
while (!tgt.empty() && std::isspace(tgt.back()))
tgt.pop_back();
return true;
};
auto parseIntVersion = [](const std::string& s) {
char* str_end = nullptr;
unsigned long v = std::strtoul(s.c_str(), &str_end, 10);
return (v >= 2002000 && v < 999999999 && str_end == s.c_str() + s.size())
? v
: 0;
};
NCrystalConfig res;
if (!readLine(res.shlibpath) ||
!(res.intversion = parseIntVersion(res.shlibpath)) ||
!readLine(res.shlibpath) || res.shlibpath.empty() ||
!readLine(res.symbol_namespace)) {
res.intversion = 0; // failure
}
#ifdef _WIN32
auto returnCode = _pclose(pipe);
#else
auto returnCode = pclose(pipe);
#endif
if (returnCode == 0 && res.intversion >= 2002000)
return res;
return {}; // failure
}
struct NCrystalAPIDB {
std::mutex mtx;
std::shared_ptr<const NCrystalAPI> api;
using FctSignature = void* (*)(int);
FctSignature ncrystal_access_virtapi_fct = nullptr;
};
void* load_virtapi_raw(unsigned interface_id, NCrystalAPIDB& db)
{
if (!db.ncrystal_access_virtapi_fct) {
auto cfg = query_ncrystal_config();
if (!(cfg.intversion >= 4001000)) {
// This is the most likely error message people will see:
fatal_error("Could not locate a functioning and recent enough"
" NCrystal installation (required since geometry"
" contains NCrystal materials).");
}
#ifdef _WIN32
auto handle = LoadLibrary(cfg.shlibpath.c_str());
#else
dlerror(); // clear previous errors
void* handle = dlopen(cfg.shlibpath.c_str(), RTLD_LOCAL | RTLD_LAZY);
#endif
if (!handle)
fatal_error("Loading of the NCrystal library failed");
std::string symbol =
fmt::format("ncrystal{}_access_virtual_api", cfg.symbol_namespace);
#ifdef _WIN32
void* addr = (void*)(intptr_t)GetProcAddress(handle, symbol.c_str());
if (!addr)
fatal_error("GetProcAddress("
"ncrystal_access_virtual_api) failed");
#else
dlerror(); // clear previous errors
void* addr = dlsym(handle, symbol.c_str());
if (!addr)
fatal_error("dlsym(ncrystal_access_virtual_api) failed");
#endif
db.ncrystal_access_virtapi_fct =
reinterpret_cast<NCrystalAPIDB::FctSignature>(addr);
}
void* result = (*db.ncrystal_access_virtapi_fct)(interface_id);
if (!result)
fatal_error("NCrystal installation does not support required interface.");
return result;
}
NCrystalAPIDB& get_ncrystal_api_db()
{
static NCrystalAPIDB db;
return db;
}
} // namespace
std::shared_ptr<const NCrystalAPI> load_ncrystal_api()
{
auto& db = get_ncrystal_api_db();
std::lock_guard<std::mutex> lock(db.mtx);
if (!db.api) {
void* raw_api = load_virtapi_raw(NCrystalAPI::interface_id, db);
if (!raw_api)
fatal_error("Problems loading NCrystal.");
db.api = *reinterpret_cast<std::shared_ptr<const NCrystalAPI>*>(raw_api);
}
return db.api;
}
} // namespace openmc

View file

@ -314,7 +314,6 @@ void print_build_info()
std::string profiling(n);
std::string coverage(n);
std::string mcpl(n);
std::string ncrystal(n);
std::string uwuw(n);
#ifdef PHDF5
@ -332,9 +331,6 @@ void print_build_info()
#ifdef OPENMC_MCPL
mcpl = y;
#endif
#ifdef NCRYSTAL
ncrystal = y;
#endif
#ifdef USE_LIBPNG
png = y;
#endif
@ -362,7 +358,6 @@ void print_build_info()
fmt::print("DAGMC support: {}\n", dagmc);
fmt::print("libMesh support: {}\n", libmesh);
fmt::print("MCPL support: {}\n", mcpl);
fmt::print("NCrystal support: {}\n", ncrystal);
fmt::print("Coverage testing: {}\n", coverage);
fmt::print("Profiling flags: {}\n", profiling);
fmt::print("UWUW support: {}\n", uwuw);

View file

@ -4,7 +4,7 @@
#define HAS_DYNAMIC_LINKING
#endif
#include <algorithm> // for move
#include <utility> // for move
#ifdef HAS_DYNAMIC_LINKING
#include <dlfcn.h> // for dlopen, dlsym, dlclose, dlerror

View file

@ -6,12 +6,13 @@ import numpy as np
import openmc
import openmc.lib
import pytest
import shutil
from tests.testing_harness import PyAPITestHarness
pytestmark = pytest.mark.skipif(
not openmc.lib._ncrystal_enabled(),
reason="NCrystal materials are not enabled.")
not shutil.which('ncrystal-config'),
reason="NCrystal is not installed.")
def pencil_beam_model(cfg, E0, N):

View file

@ -3,7 +3,7 @@ import shutil
import subprocess
def install(omp=False, mpi=False, phdf5=False, dagmc=False, libmesh=False, ncrystal=False):
def install(omp=False, mpi=False, phdf5=False, dagmc=False, libmesh=False):
# Create build directory and change to it
shutil.rmtree('build', ignore_errors=True)
os.mkdir('build')
@ -40,9 +40,6 @@ def install(omp=False, mpi=False, phdf5=False, dagmc=False, libmesh=False, ncrys
libmesh_path = os.environ.get('HOME') + '/LIBMESH'
cmake_cmd.append('-DCMAKE_PREFIX_PATH=' + libmesh_path)
if ncrystal:
cmake_cmd.append('-DOPENMC_USE_NCRYSTAL=ON')
# Build in coverage mode for coverage testing
cmake_cmd.append('-DOPENMC_ENABLE_COVERAGE=on')
@ -59,11 +56,10 @@ def main():
mpi = (os.environ.get('MPI') == 'y')
phdf5 = (os.environ.get('PHDF5') == 'y')
dagmc = (os.environ.get('DAGMC') == 'y')
ncrystal = (os.environ.get('NCRYSTAL') == 'y')
libmesh = (os.environ.get('LIBMESH') == 'y')
# Build and install
install(omp, mpi, phdf5, dagmc, libmesh, ncrystal)
install(omp, mpi, phdf5, dagmc, libmesh)
if __name__ == '__main__':
main()

View file

@ -14,12 +14,9 @@ if [[ $DAGMC = 'y' ]]; then
./tools/ci/gha-install-dagmc.sh
fi
# Install NCrystal if needed
if [[ $NCRYSTAL = 'y' ]]; then
pip install 'ncrystal>=4.0.0'
#Basic quick verification:
nctool --test
fi
# Install NCrystal and verify installation
pip install 'ncrystal>=4.1.0'
nctool --test
# Install vectfit for WMP generation if needed
if [[ $VECTFIT = 'y' ]]; then

View file

@ -14,10 +14,5 @@ if [[ $EVENT == 'y' ]]; then
args="${args} --event "
fi
# Check NCrystal installation
if [[ $NCRYSTAL = 'y' ]]; then
nctool --test
fi
# Run regression and unit tests
pytest --cov=openmc -v $args tests