mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-26 05:05:30 -04:00
Merge pull request #2222 from highness-eu/mixed_ncrystal
Adding support for NCrystal materials in OpenMC
This commit is contained in:
commit
a62bb50b27
30 changed files with 861 additions and 45 deletions
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
|
|
@ -29,6 +29,7 @@ jobs:
|
|||
mpi: [n, y]
|
||||
omp: [n, y]
|
||||
dagmc: [n]
|
||||
ncrystal: [n]
|
||||
libmesh: [n]
|
||||
event: [n]
|
||||
vectfit: [n]
|
||||
|
|
@ -47,6 +48,10 @@ jobs:
|
|||
python-version: '3.10'
|
||||
mpi: y
|
||||
omp: y
|
||||
- ncrystal: y
|
||||
python-version: '3.10'
|
||||
mpi: n
|
||||
omp: n
|
||||
- libmesh: y
|
||||
python-version: '3.10'
|
||||
mpi: y
|
||||
|
|
@ -64,7 +69,7 @@ jobs:
|
|||
omp: n
|
||||
mpi: y
|
||||
name: "Python ${{ matrix.python-version }} (omp=${{ matrix.omp }},
|
||||
mpi=${{ matrix.mpi }}, dagmc=${{ matrix.dagmc }},
|
||||
mpi=${{ matrix.mpi }}, dagmc=${{ matrix.dagmc }}, ncrystal=${{ matrix.ncrystal }},
|
||||
libmesh=${{ matrix.libmesh }}, event=${{ matrix.event }}
|
||||
vectfit=${{ matrix.vectfit }})"
|
||||
|
||||
|
|
@ -73,6 +78,7 @@ jobs:
|
|||
PHDF5: ${{ matrix.mpi }}
|
||||
OMP: ${{ matrix.omp }}
|
||||
DAGMC: ${{ matrix.dagmc }}
|
||||
NCRYSTAL: ${{ matrix.ncrystal }}
|
||||
EVENT: ${{ matrix.event }}
|
||||
VECTFIT: ${{ matrix.vectfit }}
|
||||
LIBMESH: ${{ matrix.libmesh }}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ 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)
|
||||
|
||||
# Warnings for deprecated options
|
||||
foreach(OLD_OPT IN ITEMS "openmp" "profile" "coverage" "dagmc" "libmesh")
|
||||
|
|
@ -99,6 +100,15 @@ macro(find_package_write_status pkg)
|
|||
endif()
|
||||
endmacro()
|
||||
|
||||
#===============================================================================
|
||||
# NCrystal Scattering Support
|
||||
#===============================================================================
|
||||
|
||||
if(OPENMC_USE_NCRYSTAL)
|
||||
find_package(NCrystal REQUIRED)
|
||||
message(STATUS "Found NCrystal: ${NCrystal_DIR} (version ${NCrystal_VERSION})")
|
||||
endif()
|
||||
|
||||
#===============================================================================
|
||||
# DAGMC Geometry Support - need DAGMC/MOAB
|
||||
#===============================================================================
|
||||
|
|
@ -338,6 +348,7 @@ list(APPEND libopenmc_SOURCES
|
|||
src/message_passing.cpp
|
||||
src/mgxs.cpp
|
||||
src/mgxs_interface.cpp
|
||||
src/ncrystal_interface.cpp
|
||||
src/nuclide.cpp
|
||||
src/output.cpp
|
||||
src/particle.cpp
|
||||
|
|
@ -498,6 +509,11 @@ 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
|
||||
#===============================================================================
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ if(@OPENMC_USE_DAGMC@)
|
|||
find_package(DAGMC REQUIRED HINTS @DAGMC_DIR@)
|
||||
endif()
|
||||
|
||||
if(@OPENMC_USE_NCRYSTAL@)
|
||||
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@)
|
||||
|
|
|
|||
|
|
@ -178,6 +178,27 @@ been selected. There are three methods available:
|
|||
section data is loaded for a single temperature and is used in the
|
||||
unresolved resonance and fast energy ranges.
|
||||
|
||||
------------------
|
||||
NCrystal materials
|
||||
------------------
|
||||
|
||||
As an alternative of the standard thermal scattering treatment using
|
||||
:math:`S(\alpha,\beta)` tables, OpenMC allows to create materials using
|
||||
NCrystal_. In addition to the regular thermal elastic, and thermal inelastic
|
||||
processes, NCrystal allows the generation of models for materials that cannot
|
||||
currently included in ACE files such as oriented single crystals (see the
|
||||
`NCrystal paper`_), and further extend the physics `using plugins`_. Thermal
|
||||
scattering kernels are generated on the fly from dynamic and structural data, or
|
||||
loaded from :math:`S(\alpha,\beta)` tables converted from ENDF6 evaluations.
|
||||
These kernels are sampled in a direct way using a fast `rejection algorithm`_
|
||||
that does not require previous processing. A `large library`_ of materials is
|
||||
already included in the NCrystal distribution, and new materials can be easily
|
||||
defined from scratch in the `NCMAT format`_ or `combining existing files`_.
|
||||
|
||||
The compositions of the materials defined in NCrystal are passed on to OpenMC
|
||||
all other reactions except for thermal neutron scattering are handled by
|
||||
continuous energy ACE libraries.
|
||||
|
||||
----------------
|
||||
Multi-Group Data
|
||||
----------------
|
||||
|
|
@ -279,3 +300,10 @@ or even isotropic scattering.
|
|||
.. _ENDF/B data: https://www.nndc.bnl.gov/endf-b8.0/
|
||||
.. _Leppanen: https://doi.org/10.1016/j.anucene.2009.03.019
|
||||
.. _algorithms: http://ab-initio.mit.edu/wiki/index.php/Faddeeva_Package
|
||||
.. _NCrystal: https://github.com/mctools/ncrystal
|
||||
.. _NCrystal paper: https://doi.org/10.1016/j.cpc.2019.07.015
|
||||
.. _using plugins: https://doi.org/10.1016/j.cpc.2021.108082
|
||||
.. _rejection algorithm: https://doi.org/10.1016/j.jcp.2018.11.043
|
||||
.. _large library: https://github.com/mctools/ncrystal/wiki/Data-library
|
||||
.. _NCMAT format: https://github.com/mctools/ncrystal/wiki/NCMAT-format
|
||||
.. _combining existing files: https://github.com/mctools/ncrystal/wiki/Announcement-Release3.0.0#2-multiphase-materials
|
||||
|
|
|
|||
|
|
@ -271,6 +271,17 @@ Prerequisites
|
|||
|
||||
cmake -DOPENMC_USE_DAGMC=on -DCMAKE_PREFIX_PATH=/path/to/dagmc/installation ..
|
||||
|
||||
* 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>`_ and `initialize
|
||||
<https://github.com/mctools/ncrystal/wiki/Using-NCrystal#setting-up>`_
|
||||
NCrystal and turn on the option in the CMake configuration step:
|
||||
|
||||
cmake -DOPENMC_USE_NCRYSTAL=on ..
|
||||
|
||||
* libMesh_ mesh library framework for numerical simulations of partial differential equations
|
||||
|
||||
This optional dependency enables support for unstructured mesh tally
|
||||
|
|
@ -294,6 +305,7 @@ Prerequisites
|
|||
.. _MOAB: https://bitbucket.org/fathomteam/moab
|
||||
.. _libMesh: https://libmesh.github.io/
|
||||
.. _libpng: http://www.libpng.org/pub/png/libpng.html
|
||||
.. _NCrystal: https://github.com/mctools/ncrystal
|
||||
|
||||
Obtaining the Source
|
||||
--------------------
|
||||
|
|
@ -362,6 +374,12 @@ OPENMC_USE_DAGMC
|
|||
should also be defined as `DAGMC_ROOT` in the CMake configuration command.
|
||||
(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)
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,42 @@ you would need to add hydrogen and oxygen to a material and then assign the
|
|||
|
||||
.. _usersguide_naming:
|
||||
|
||||
-------------------------
|
||||
Adding NCrystal materials
|
||||
-------------------------
|
||||
|
||||
Additional support for thermal scattering can be added by using NCrystal_. The
|
||||
:meth:`Material.from_ncrystal` class method generates a :class:`openmc.Material`
|
||||
object from an `NCrystal configuration string
|
||||
<https://github.com/mctools/ncrystal/wiki/Using-NCrystal#uniform-material-configuration-syntax>`_.
|
||||
Temperature, material composition, and density are passed from the configuration
|
||||
string and the `NCMAT file
|
||||
<https://github.com/mctools/ncrystal/wiki/NCMAT-format>`_ that define the
|
||||
material, e.g.::
|
||||
|
||||
mat = openmc.Material.from_ncrystal('Al_sg225.ncmat;temp=300K')
|
||||
|
||||
defines a material containing polycrystalline alumnium,
|
||||
|
||||
::
|
||||
|
||||
mat = openmc.Material.from_ncrystal("""Ge_sg227.ncmat;dcutoff=0.5;mos=40arcsec;
|
||||
dir1=@crys_hkl:5,1,1@lab:0,0,1;
|
||||
dir2=@crys_hkl:0,-1,1@lab:0,1,0""")
|
||||
|
||||
defines an oriented germanium single crystal with 40 arcsec mosaicity.
|
||||
|
||||
NCrystal only handles low energy neutron interactions. Other interactions are
|
||||
provided by standard ACE files. NCrystal_ comes with a `predefined library
|
||||
<https://github.com/mctools/ncrystal/wiki/Data-library>`_ but more materials can
|
||||
be added by creating NCMAT files or on-the-fly in the configuration string.
|
||||
|
||||
.. warning:: Currently, NCrystal_ materials cannot be modified after they are created.
|
||||
Density, temperature and composition should be defined in the
|
||||
configuration string or the NCMAT file.
|
||||
|
||||
.. _NCrystal: https://github.com/mctools/ncrystal
|
||||
|
||||
------------------
|
||||
Naming Conventions
|
||||
------------------
|
||||
|
|
@ -222,3 +258,4 @@ been generated, you can tell OpenMC to use this file either by setting
|
|||
materials.cross_sections = '/path/to/cross_sections.xml'
|
||||
|
||||
.. _MCNP: https://mcnp.lanl.gov/
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ namespace openmc {
|
|||
inline bool dir_exists(const std::string& path)
|
||||
{
|
||||
struct stat s;
|
||||
if (stat(path.c_str(), &s) != 0) return false;
|
||||
if (stat(path.c_str(), &s) != 0)
|
||||
return false;
|
||||
|
||||
return s.st_mode & S_IFDIR;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "openmc/bremsstrahlung.h"
|
||||
#include "openmc/constants.h"
|
||||
#include "openmc/memory.h" // for unique_ptr
|
||||
#include "openmc/ncrystal_interface.h"
|
||||
#include "openmc/particle.h"
|
||||
#include "openmc/vector.h"
|
||||
|
||||
|
|
@ -151,12 +152,17 @@ public:
|
|||
//! \return Temperature in [K]
|
||||
double temperature() const;
|
||||
|
||||
//! Get pointer to NCrystal material object
|
||||
//! \return Pointer to NCrystal material object
|
||||
const NCrystalMat& ncrystal_mat() const { return ncrystal_mat_; };
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Data
|
||||
int32_t id_ {C_NONE}; //!< Unique ID
|
||||
std::string name_; //!< Name of material
|
||||
vector<int> nuclide_; //!< Indices in nuclides vector
|
||||
vector<int> element_; //!< Indices in elements vector
|
||||
NCrystalMat ncrystal_mat_; //!< NCrystal material object
|
||||
xt::xtensor<double, 1> atom_density_; //!< Nuclide atom density in [atom/b-cm]
|
||||
double density_; //!< Total atom density in [atom/b-cm]
|
||||
double density_gpcc_; //!< Total atom density in [g/cm^3]
|
||||
|
|
|
|||
94
include/openmc/ncrystal_interface.h
Normal file
94
include/openmc/ncrystal_interface.h
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#ifndef OPENMC_NCRYSTAL_INTERFACE_H
|
||||
#define OPENMC_NCRYSTAL_INTERFACE_H
|
||||
|
||||
#ifdef NCRYSTAL
|
||||
#include "NCrystal/NCRNG.hh"
|
||||
#include "NCrystal/NCrystal.hh"
|
||||
#endif
|
||||
|
||||
#include "openmc/particle.h"
|
||||
|
||||
#include <cstdint> // for uint64_t
|
||||
#include <limits> // for numeric_limits
|
||||
#include <string>
|
||||
|
||||
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
|
||||
//==============================================================================
|
||||
|
||||
class NCrystalMat {
|
||||
public:
|
||||
//----------------------------------------------------------------------------
|
||||
// Constructors
|
||||
NCrystalMat() = default;
|
||||
explicit NCrystalMat(const std::string& cfg);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Methods
|
||||
|
||||
#ifdef NCRYSTAL
|
||||
//! Return configuration string
|
||||
std::string cfg() const;
|
||||
|
||||
//! Get cross section from NCrystal material
|
||||
//
|
||||
//! \param[in] p Particle object
|
||||
//! \return Cross section in [b]
|
||||
double xs(const Particle& p) const;
|
||||
|
||||
// Process scattering event
|
||||
//
|
||||
//! \param[in] p Particle object
|
||||
void scatter(Particle& p) const;
|
||||
|
||||
//! Whether the object holds a valid NCrystal material
|
||||
operator bool() const;
|
||||
#else
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// 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
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Functions
|
||||
//==============================================================================
|
||||
|
||||
void ncrystal_update_micro(double xs, NuclideMicroXS& micro);
|
||||
|
||||
} // namespace openmc
|
||||
|
||||
#endif // OPENMC_NCRYSTAL_INTERFACE_H
|
||||
|
|
@ -96,8 +96,9 @@ void inelastic_scatter(const Nuclide& nuc, const Reaction& rx, Particle& p);
|
|||
|
||||
void sample_secondary_photons(Particle& p, int i_nuclide);
|
||||
|
||||
//!Split or Roulette particles based their weight and the lower weight window
|
||||
// bound.
|
||||
//! Split or Roulette particles based their weight and the lower weight window
|
||||
//! bound.
|
||||
//
|
||||
//! \param[in] p, particle to be split or rouletted with the weight window.
|
||||
void split_particle(Particle& p);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ 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
|
||||
|
||||
|
|
|
|||
|
|
@ -99,6 +99,10 @@ class Material(IDManagerMixin):
|
|||
[decay/sec].
|
||||
|
||||
.. versionadded:: 0.13.2
|
||||
ncrystal_cfg : str
|
||||
NCrystal configuration string
|
||||
|
||||
.. versionadded:: 0.13.3
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -118,6 +122,7 @@ class Material(IDManagerMixin):
|
|||
self._volume = None
|
||||
self._atoms = {}
|
||||
self._isotropic = []
|
||||
self._ncrystal_cfg = None
|
||||
|
||||
# A list of tuples (nuclide, percent, percent type)
|
||||
self._nuclides = []
|
||||
|
|
@ -140,6 +145,9 @@ class Material(IDManagerMixin):
|
|||
|
||||
string += '{: <16}\n'.format('\tS(a,b) Tables')
|
||||
|
||||
if self._ncrystal_cfg:
|
||||
string += '{: <16}=\t{}\n'.format('\tNCrystal conf', self._ncrystal_cfg)
|
||||
|
||||
for sab in self._sab:
|
||||
string += '{: <16}=\t{}\n'.format('\tS(a,b)', sab)
|
||||
|
||||
|
|
@ -219,6 +227,10 @@ class Material(IDManagerMixin):
|
|||
def volume(self):
|
||||
return self._volume
|
||||
|
||||
@property
|
||||
def ncrystal_cfg(self):
|
||||
return self._ncrystal_cfg
|
||||
|
||||
@name.setter
|
||||
def name(self, name: Optional[str]):
|
||||
if name is not None:
|
||||
|
|
@ -331,6 +343,64 @@ class Material(IDManagerMixin):
|
|||
|
||||
return material
|
||||
|
||||
@classmethod
|
||||
def from_ncrystal(cls, cfg, **kwargs):
|
||||
"""Create material from NCrystal configuration string.
|
||||
|
||||
Density, temperature, and material composition, and (ultimately) thermal
|
||||
neutron scattering will be automatically be provided by NCrystal based
|
||||
on this string. The name and material_id parameters are simply passed on
|
||||
to the Material constructor.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
cfg : str
|
||||
NCrystal configuration string
|
||||
**kwargs
|
||||
Keyword arguments passed to :class:`openmc.Material`
|
||||
|
||||
Returns
|
||||
-------
|
||||
openmc.Material
|
||||
Material instance
|
||||
|
||||
"""
|
||||
|
||||
import NCrystal
|
||||
nc_mat = NCrystal.createInfo(cfg)
|
||||
|
||||
def openmc_natabund(Z):
|
||||
#nc_mat.getFlattenedComposition might need natural abundancies.
|
||||
#This call-back function is used so NCrystal can flatten composition
|
||||
#using OpenMC's natural abundancies. In practice this function will
|
||||
#only get invoked in the unlikely case where a material is specified
|
||||
#by referring both to natural elements and specific isotopes of the
|
||||
#same element.
|
||||
elem_name = openmc.data.ATOMIC_SYMBOL[Z]
|
||||
return [
|
||||
(int(iso_name[len(elem_name):]), abund)
|
||||
for iso_name, abund in openmc.data.isotopes(elem_name)
|
||||
]
|
||||
|
||||
flat_compos = nc_mat.getFlattenedComposition(
|
||||
preferNaturalElements=True, naturalAbundProvider=openmc_natabund)
|
||||
|
||||
# Create the Material
|
||||
material = cls(temperature=nc_mat.getTemperature(), **kwargs)
|
||||
|
||||
for Z, A_vals in flat_compos:
|
||||
elemname = openmc.data.ATOMIC_SYMBOL[Z]
|
||||
for A, frac in A_vals:
|
||||
if A:
|
||||
material.add_nuclide(f'{elemname}{A}', frac)
|
||||
else:
|
||||
material.add_element(elemname, frac)
|
||||
|
||||
material.set_density('g/cm3', nc_mat.getDensity())
|
||||
material._ncrystal_cfg = NCrystal.normaliseCfg(cfg)
|
||||
|
||||
return material
|
||||
|
||||
def add_volume_information(self, volume_calc):
|
||||
"""Add volume information to a material.
|
||||
|
||||
|
|
@ -405,6 +475,9 @@ class Material(IDManagerMixin):
|
|||
'macroscopic data-set has already been added'.format(self._id)
|
||||
raise ValueError(msg)
|
||||
|
||||
if self._ncrystal_cfg is not None:
|
||||
raise ValueError("Cannot add nuclides to NCrystal material")
|
||||
|
||||
# If nuclide name doesn't look valid, give a warning
|
||||
try:
|
||||
Z, _, _ = openmc.data.zam(nuclide)
|
||||
|
|
@ -609,6 +682,9 @@ class Material(IDManagerMixin):
|
|||
raise ValueError("Element name should be given by the "
|
||||
"element's symbol or name, e.g., 'Zr', 'zirconium'")
|
||||
|
||||
if self._ncrystal_cfg is not None:
|
||||
raise ValueError("Cannot add elements to NCrystal material")
|
||||
|
||||
# Allow for element identifier to be given as a symbol or name
|
||||
if len(element) > 2:
|
||||
el = element.lower()
|
||||
|
|
@ -990,7 +1066,7 @@ class Material(IDManagerMixin):
|
|||
activity[nuclide] = inv_seconds * 1e24 * atoms_per_bcm * multiplier
|
||||
|
||||
return activity if by_nuclide else sum(activity.values())
|
||||
|
||||
|
||||
def get_decay_heat(self, units: str = 'W', by_nuclide: bool = False):
|
||||
"""Returns the decay heat of the material or for each nuclide in the
|
||||
material in units of [W], [W/g] or [W/cm3].
|
||||
|
|
@ -1024,16 +1100,16 @@ class Material(IDManagerMixin):
|
|||
multiplier = 1
|
||||
elif units == 'W/g':
|
||||
multiplier = 1.0 / self.get_mass_density()
|
||||
|
||||
decayheat = {}
|
||||
|
||||
decayheat = {}
|
||||
for nuclide, atoms_per_bcm in self.get_nuclide_atom_densities().items():
|
||||
decay_erg = openmc.data.decay_energy(nuclide)
|
||||
inv_seconds = openmc.data.decay_constant(nuclide)
|
||||
decay_erg *= openmc.data.JOULE_PER_EV
|
||||
decayheat[nuclide] = inv_seconds * decay_erg * 1e24 * atoms_per_bcm * multiplier
|
||||
|
||||
return decayheat if by_nuclide else sum(decayheat.values())
|
||||
|
||||
return decayheat if by_nuclide else sum(decayheat.values())
|
||||
|
||||
def get_nuclide_atoms(self):
|
||||
"""Return number of atoms of each nuclide in the material
|
||||
|
||||
|
|
@ -1182,6 +1258,14 @@ class Material(IDManagerMixin):
|
|||
if self._volume:
|
||||
element.set("volume", str(self._volume))
|
||||
|
||||
if self._ncrystal_cfg:
|
||||
if self._sab:
|
||||
raise ValueError("NCrystal materials are not compatible with S(a,b).")
|
||||
if self._macroscopic is not None:
|
||||
raise ValueError("NCrystal materials are not compatible with macroscopic cross sections.")
|
||||
|
||||
element.set("cfg", str(self._ncrystal_cfg))
|
||||
|
||||
# Create temperature XML subelement
|
||||
if self.temperature is not None:
|
||||
element.set("temperature", str(self.temperature))
|
||||
|
|
@ -1566,4 +1650,4 @@ class Materials(cv.CheckedList):
|
|||
tree = ET.parse(path)
|
||||
root = tree.getroot()
|
||||
|
||||
return cls.from_xml_element(root)
|
||||
return cls.from_xml_element(root)
|
||||
|
|
|
|||
|
|
@ -91,7 +91,8 @@ Library::Library(pugi::xml_node node, const std::string& directory)
|
|||
// Non-member functions
|
||||
//==============================================================================
|
||||
|
||||
void read_cross_sections_xml() {
|
||||
void read_cross_sections_xml()
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
std::string filename = settings::path_input + "materials.xml";
|
||||
// Check if materials.xml exists
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ void update_universe_cell_count(int32_t a, int32_t b)
|
|||
}
|
||||
}
|
||||
|
||||
void read_geometry_xml() {
|
||||
void read_geometry_xml()
|
||||
{
|
||||
// Display output message
|
||||
write_message("Reading geometry XML file...", 5);
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,8 @@ int openmc_init(int argc, char* argv[], const void* intracomm)
|
|||
openmc::openmc_set_seed(DEFAULT_SEED);
|
||||
|
||||
// Read XML input files
|
||||
if (!read_model_xml()) read_separate_xml_files();
|
||||
if (!read_model_xml())
|
||||
read_separate_xml_files();
|
||||
|
||||
// Write some initial output under the header if needed
|
||||
initial_output();
|
||||
|
|
@ -299,7 +300,8 @@ int parse_command_line(int argc, char* argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool read_model_xml() {
|
||||
bool read_model_xml()
|
||||
{
|
||||
std::string model_filename =
|
||||
settings::path_input.empty() ? "." : settings::path_input;
|
||||
|
||||
|
|
@ -314,7 +316,8 @@ bool read_model_xml() {
|
|||
model_filename += "/model.xml";
|
||||
|
||||
// if this file doesn't exist, stop here
|
||||
if (!file_exists(model_filename)) return false;
|
||||
if (!file_exists(model_filename))
|
||||
return false;
|
||||
|
||||
// try to process the path input as an XML file
|
||||
pugi::xml_document doc;
|
||||
|
|
@ -327,7 +330,7 @@ bool read_model_xml() {
|
|||
|
||||
// Read settings
|
||||
if (!check_for_node(root, "settings")) {
|
||||
fatal_error("No <settings> node present in the model.xml file.");
|
||||
fatal_error("No <settings> node present in the model.xml file.");
|
||||
}
|
||||
auto settings_root = root.child("settings");
|
||||
|
||||
|
|
@ -343,13 +346,15 @@ bool read_model_xml() {
|
|||
title();
|
||||
}
|
||||
|
||||
write_message(fmt::format("Reading model XML file '{}' ...", model_filename), 5);
|
||||
write_message(
|
||||
fmt::format("Reading model XML file '{}' ...", model_filename), 5);
|
||||
|
||||
read_settings_xml(settings_root);
|
||||
|
||||
// If other XML files are present, display warning
|
||||
// that they will be ignored
|
||||
auto other_inputs = {"materials.xml", "geometry.xml", "settings.xml", "tallies.xml", "plots.xml"};
|
||||
auto other_inputs = {"materials.xml", "geometry.xml", "settings.xml",
|
||||
"tallies.xml", "plots.xml"};
|
||||
for (const auto& input : other_inputs) {
|
||||
if (file_exists(settings::path_input + input)) {
|
||||
warning((fmt::format("Other XML file input(s) are present. These files "
|
||||
|
|
@ -384,7 +389,7 @@ bool read_model_xml() {
|
|||
if (check_for_node(root, "tallies"))
|
||||
read_tallies_xml(root.child("tallies"));
|
||||
|
||||
// Initialize distribcell_filters
|
||||
// Initialize distribcell_filters
|
||||
prepare_distribcell();
|
||||
|
||||
if (check_for_node(root, "plots"))
|
||||
|
|
@ -416,7 +421,8 @@ void read_separate_xml_files()
|
|||
read_plots_xml();
|
||||
}
|
||||
|
||||
void initial_output() {
|
||||
void initial_output()
|
||||
{
|
||||
// write initial output
|
||||
if (settings::run_mode == RunMode::PLOTTING) {
|
||||
// Read plots.xml if it exists
|
||||
|
|
|
|||
|
|
@ -60,6 +60,13 @@ Material::Material(pugi::xml_node node)
|
|||
name_ = get_node_value(node, "name");
|
||||
}
|
||||
|
||||
if (check_for_node(node, "cfg")) {
|
||||
auto cfg = get_node_value(node, "cfg");
|
||||
write_message(
|
||||
5, "NCrystal config string for material #{}: '{}'", this->id(), cfg);
|
||||
ncrystal_mat_ = NCrystalMat(cfg);
|
||||
}
|
||||
|
||||
if (check_for_node(node, "depletable")) {
|
||||
depletable_ = get_node_value_bool(node, "depletable");
|
||||
}
|
||||
|
|
@ -367,8 +374,8 @@ void Material::finalize()
|
|||
this->init_thermal();
|
||||
}
|
||||
|
||||
// Normalize density
|
||||
this->normalize_density();
|
||||
// Normalize density
|
||||
this->normalize_density();
|
||||
}
|
||||
|
||||
void Material::normalize_density()
|
||||
|
|
@ -792,6 +799,12 @@ void Material::calculate_neutron_xs(Particle& p) const
|
|||
// Initialize position in i_sab_nuclides
|
||||
int j = 0;
|
||||
|
||||
// Calculate NCrystal cross section
|
||||
double ncrystal_xs = -1.0;
|
||||
if (ncrystal_mat_ && p.E() < NCRYSTAL_MAX_ENERGY) {
|
||||
ncrystal_xs = ncrystal_mat_.xs(p);
|
||||
}
|
||||
|
||||
// Add contribution from each nuclide in material
|
||||
for (int i = 0; i < nuclide_.size(); ++i) {
|
||||
// ======================================================================
|
||||
|
|
@ -830,10 +843,16 @@ void Material::calculate_neutron_xs(Particle& p) const
|
|||
int i_nuclide = nuclide_[i];
|
||||
|
||||
// Calculate microscopic cross section for this nuclide
|
||||
const auto& micro {p.neutron_xs(i_nuclide)};
|
||||
auto& micro {p.neutron_xs(i_nuclide)};
|
||||
if (p.E() != micro.last_E || p.sqrtkT() != micro.last_sqrtkT ||
|
||||
i_sab != micro.index_sab || sab_frac != micro.sab_frac) {
|
||||
data::nuclides[i_nuclide]->calculate_xs(i_sab, i_grid, sab_frac, p);
|
||||
|
||||
// If NCrystal is being used, update micro cross section cache
|
||||
if (ncrystal_xs >= 0.0) {
|
||||
data::nuclides[i_nuclide]->calculate_elastic_xs(p);
|
||||
ncrystal_update_micro(ncrystal_xs, micro);
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
|
@ -1264,7 +1283,8 @@ double density_effect(const vector<double>& f, const vector<double>& e_b_sq,
|
|||
return delta - w_sq * (1.0 - beta_sq);
|
||||
}
|
||||
|
||||
void read_materials_xml() {
|
||||
void read_materials_xml()
|
||||
{
|
||||
write_message("Reading materials XML file...", 5);
|
||||
|
||||
pugi::xml_document doc;
|
||||
|
|
|
|||
108
src/ncrystal_interface.cpp
Normal file
108
src/ncrystal_interface.cpp
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
#include "openmc/ncrystal_interface.h"
|
||||
|
||||
#include "openmc/error.h"
|
||||
#include "openmc/material.h"
|
||||
#include "openmc/random_lcg.h"
|
||||
|
||||
namespace openmc {
|
||||
|
||||
//==============================================================================
|
||||
// Constants
|
||||
//==============================================================================
|
||||
|
||||
#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_;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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});
|
||||
|
||||
// Modify attributes of particle
|
||||
p.E() = outcome.ekin.get();
|
||||
Direction u_old {p.u()};
|
||||
p.u() =
|
||||
Direction(outcome.direction[0], outcome.direction[1], outcome.direction[2]);
|
||||
p.mu() = u_old.dot(p.u());
|
||||
p.event_mt() = ELASTIC;
|
||||
}
|
||||
|
||||
NCrystalMat::operator bool() const
|
||||
{
|
||||
return ptr_.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// Functions
|
||||
//==============================================================================
|
||||
|
||||
void ncrystal_update_micro(double xs, NuclideMicroXS& micro)
|
||||
{
|
||||
if (micro.thermal > 0 || micro.thermal_elastic > 0) {
|
||||
fatal_error("S(a,b) treatment and NCrystal are not compatible.");
|
||||
}
|
||||
// remove free atom cross section
|
||||
// and replace it by scattering cross section per atom from NCrystal
|
||||
micro.total = micro.total - micro.elastic + xs;
|
||||
micro.elastic = xs;
|
||||
}
|
||||
|
||||
} // namespace openmc
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
#include "openmc/material.h"
|
||||
#include "openmc/math_functions.h"
|
||||
#include "openmc/message_passing.h"
|
||||
#include "openmc/ncrystal_interface.h"
|
||||
#include "openmc/nuclide.h"
|
||||
#include "openmc/photon.h"
|
||||
#include "openmc/physics_common.h"
|
||||
|
|
@ -140,7 +141,12 @@ void sample_neutron_reaction(Particle& p)
|
|||
|
||||
// Sample a scattering reaction and determine the secondary energy of the
|
||||
// exiting neutron
|
||||
scatter(p, i_nuclide);
|
||||
const auto& ncrystal_mat = model::materials[p.material()]->ncrystal_mat();
|
||||
if (ncrystal_mat && p.E() < NCRYSTAL_MAX_ENERGY) {
|
||||
ncrystal_mat.scatter(p);
|
||||
} else {
|
||||
scatter(p, i_nuclide);
|
||||
}
|
||||
|
||||
// Advance URR seed stream 'N' times after energy changes
|
||||
if (p.E() != p.E_last()) {
|
||||
|
|
|
|||
|
|
@ -124,7 +124,8 @@ extern "C" int openmc_plot_geometry()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void read_plots_xml() {
|
||||
void read_plots_xml()
|
||||
{
|
||||
// Check if plots.xml exists; this is only necessary when the plot runmode is
|
||||
// initiated. Otherwise, we want to read plots.xml because it may be called
|
||||
// later via the API. In that case, its ok for a plots.xml to not exist
|
||||
|
|
|
|||
|
|
@ -214,7 +214,8 @@ void get_run_parameters(pugi::xml_node node_base)
|
|||
}
|
||||
}
|
||||
|
||||
void read_settings_xml() {
|
||||
void read_settings_xml()
|
||||
{
|
||||
using namespace settings;
|
||||
using namespace pugi;
|
||||
// Check if settings.xml exists
|
||||
|
|
|
|||
|
|
@ -705,7 +705,8 @@ std::string Tally::nuclide_name(int nuclide_idx) const
|
|||
// Non-member functions
|
||||
//==============================================================================
|
||||
|
||||
void read_tallies_xml() {
|
||||
void read_tallies_xml()
|
||||
{
|
||||
// Check if tallies.xml exists. If not, just return since it is optional
|
||||
std::string filename = settings::path_input + "tallies.xml";
|
||||
if (!file_exists(filename))
|
||||
|
|
|
|||
|
|
@ -119,22 +119,24 @@ ThermalScattering::ThermalScattering(
|
|||
if (!found) {
|
||||
// If no pairs found, check if the desired temperature falls within
|
||||
// bounds' tolerance
|
||||
if (std::abs(T - temps_available[0]) <= settings::temperature_tolerance){
|
||||
if (std::find(temps_to_read.begin(), temps_to_read.end(), std::round(temps_available[0])) ==
|
||||
temps_to_read.end()) {
|
||||
temps_to_read.push_back(std::round(temps_available[0]));
|
||||
}}
|
||||
else if (std::abs(T - temps_available[n - 1]) <= settings::temperature_tolerance){
|
||||
if (std::find(temps_to_read.begin(), temps_to_read.end(), std::round(temps_available[n - 1])) ==
|
||||
temps_to_read.end()){
|
||||
temps_to_read.push_back(std::round(temps_available[n - 1]));
|
||||
}}
|
||||
else {
|
||||
if (std::abs(T - temps_available[0]) <=
|
||||
settings::temperature_tolerance) {
|
||||
if (std::find(temps_to_read.begin(), temps_to_read.end(),
|
||||
std::round(temps_available[0])) == temps_to_read.end()) {
|
||||
temps_to_read.push_back(std::round(temps_available[0]));
|
||||
}
|
||||
} else if (std::abs(T - temps_available[n - 1]) <=
|
||||
settings::temperature_tolerance) {
|
||||
if (std::find(temps_to_read.begin(), temps_to_read.end(),
|
||||
std::round(temps_available[n - 1])) == temps_to_read.end()) {
|
||||
temps_to_read.push_back(std::round(temps_available[n - 1]));
|
||||
}
|
||||
} else {
|
||||
fatal_error(
|
||||
fmt::format("Nuclear data library does not contain cross "
|
||||
"sections for {} at temperatures that bound {} K.",
|
||||
name_, std::round(T)));
|
||||
}
|
||||
fmt::format("Nuclear data library does not contain cross "
|
||||
"sections for {} at temperatures that bound {} K.",
|
||||
name_, std::round(T)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
0
tests/regression_tests/ncrystal/__init__.py
Normal file
0
tests/regression_tests/ncrystal/__init__.py
Normal file
45
tests/regression_tests/ncrystal/inputs_true.dat
Normal file
45
tests/regression_tests/ncrystal/inputs_true.dat
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<geometry>
|
||||
<cell id="1" material="1" region="-1" universe="1" />
|
||||
<cell id="2" material="void" region="1 -2" universe="1" />
|
||||
<surface coeffs="0.0 0.0 0.0 0.1" id="1" type="sphere" />
|
||||
<surface boundary="vacuum" coeffs="0.0 0.0 0.0 100" id="2" type="sphere" />
|
||||
</geometry>
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<materials>
|
||||
<material cfg="Al_sg225.ncmat" id="1" temperature="293.15">
|
||||
<density units="g/cm3" value="2.6986455176922477" />
|
||||
<nuclide ao="1.0" name="Al27" />
|
||||
</material>
|
||||
</materials>
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<settings>
|
||||
<run_mode>fixed source</run_mode>
|
||||
<particles>100000</particles>
|
||||
<batches>10</batches>
|
||||
<source strength="1.0">
|
||||
<space type="point">
|
||||
<parameters>0 0 -20</parameters>
|
||||
</space>
|
||||
<angle reference_uvw="0.0 0.0 1.0" type="monodirectional" />
|
||||
<energy type="discrete">
|
||||
<parameters>0.012 1.0</parameters>
|
||||
</energy>
|
||||
</source>
|
||||
</settings>
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<tallies>
|
||||
<filter id="1" type="surface">
|
||||
<bins>1</bins>
|
||||
</filter>
|
||||
<filter id="2" type="polar">
|
||||
<bins>0.0 0.017453292519943295 0.03490658503988659 0.05235987755982989 0.06981317007977318 0.08726646259971647 0.10471975511965978 0.12217304763960307 0.13962634015954636 0.15707963267948966 0.17453292519943295 0.19198621771937624 0.20943951023931956 0.22689280275926285 0.24434609527920614 0.2617993877991494 0.2792526803190927 0.29670597283903605 0.3141592653589793 0.33161255787892263 0.3490658503988659 0.3665191429188092 0.3839724354387525 0.4014257279586958 0.4188790204786391 0.4363323129985824 0.4537856055185257 0.47123889803846897 0.4886921905584123 0.5061454830783556 0.5235987755982988 0.5410520681182421 0.5585053606381855 0.5759586531581288 0.5934119456780721 0.6108652381980153 0.6283185307179586 0.6457718232379019 0.6632251157578453 0.6806784082777885 0.6981317007977318 0.7155849933176751 0.7330382858376184 0.7504915783575618 0.767944870877505 0.7853981633974483 0.8028514559173916 0.8203047484373349 0.8377580409572782 0.8552113334772214 0.8726646259971648 0.8901179185171081 0.9075712110370514 0.9250245035569946 0.9424777960769379 0.9599310885968813 0.9773843811168246 0.9948376736367679 1.0122909661567112 1.0297442586766545 1.0471975511965976 1.064650843716541 1.0821041362364843 1.0995574287564276 1.117010721276371 1.1344640137963142 1.1519173063162575 1.1693705988362009 1.1868238913561442 1.2042771838760873 1.2217304763960306 1.239183768915974 1.2566370614359172 1.2740903539558606 1.2915436464758039 1.3089969389957472 1.3264502315156905 1.3439035240356338 1.361356816555577 1.3788101090755203 1.3962634015954636 1.413716694115407 1.4311699866353502 1.4486232791552935 1.4660765716752369 1.4835298641951802 1.5009831567151235 1.5184364492350666 1.53588974175501 1.5533430342749532 1.5707963267948966 1.5882496193148399 1.6057029118347832 1.6231562043547265 1.6406094968746698 1.6580627893946132 1.6755160819145565 1.6929693744344996 1.710422666954443 1.7278759594743862 1.7453292519943295 1.7627825445142729 1.7802358370342162 1.7976891295541595 1.8151424220741028 1.8325957145940461 1.8500490071139892 1.8675022996339325 1.8849555921538759 1.9024088846738192 1.9198621771937625 1.9373154697137058 1.9547687622336491 1.9722220547535925 1.9896753472735358 2.007128639793479 2.0245819323134224 2.0420352248333655 2.059488517353309 2.076941809873252 2.0943951023931953 2.111848394913139 2.129301687433082 2.1467549799530254 2.1642082724729685 2.181661564992912 2.199114857512855 2.2165681500327987 2.234021442552742 2.251474735072685 2.2689280275926285 2.2863813201125716 2.303834612632515 2.321287905152458 2.3387411976724017 2.356194490192345 2.3736477827122884 2.3911010752322315 2.4085543677521746 2.426007660272118 2.443460952792061 2.4609142453120048 2.478367537831948 2.4958208303518914 2.5132741228718345 2.530727415391778 2.548180707911721 2.5656340004316642 2.5830872929516078 2.600540585471551 2.6179938779914944 2.6354471705114375 2.652900463031381 2.670353755551324 2.6878070480712677 2.705260340591211 2.722713633111154 2.7401669256310974 2.7576202181510405 2.775073510670984 2.792526803190927 2.8099800957108707 2.827433388230814 2.8448866807507573 2.8623399732707004 2.8797932657906435 2.897246558310587 2.91469985083053 2.9321531433504737 2.949606435870417 2.9670597283903604 2.9845130209103035 3.001966313430247 3.01941960595019 3.036872898470133 3.0543261909900767 3.07177948351002 3.0892327760299634 3.1066860685499065 3.12413936106985 3.141592653589793</bins>
|
||||
</filter>
|
||||
<filter id="3" type="cellfrom">
|
||||
<bins>1</bins>
|
||||
</filter>
|
||||
<tally id="1" name="angular distribution">
|
||||
<filters>1 2 3</filters>
|
||||
<scores>current</scores>
|
||||
</tally>
|
||||
</tallies>
|
||||
181
tests/regression_tests/ncrystal/results_true.dat
Normal file
181
tests/regression_tests/ncrystal/results_true.dat
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
surface polar low [rad] polar high [rad] cellfrom nuclide score mean std. dev.
|
||||
0 1 0.00e+00 1.75e-02 1 total current 9.82e-01 1.43e-04
|
||||
1 1 1.75e-02 3.49e-02 1 total current 0.00e+00 0.00e+00
|
||||
2 1 3.49e-02 5.24e-02 1 total current 1.00e-06 1.00e-06
|
||||
3 1 5.24e-02 6.98e-02 1 total current 0.00e+00 0.00e+00
|
||||
4 1 6.98e-02 8.73e-02 1 total current 0.00e+00 0.00e+00
|
||||
5 1 8.73e-02 1.05e-01 1 total current 1.00e-06 1.00e-06
|
||||
6 1 1.05e-01 1.22e-01 1 total current 0.00e+00 0.00e+00
|
||||
7 1 1.22e-01 1.40e-01 1 total current 1.00e-06 1.00e-06
|
||||
8 1 1.40e-01 1.57e-01 1 total current 1.00e-06 1.00e-06
|
||||
9 1 1.57e-01 1.75e-01 1 total current 1.00e-06 1.00e-06
|
||||
10 1 1.75e-01 1.92e-01 1 total current 0.00e+00 0.00e+00
|
||||
11 1 1.92e-01 2.09e-01 1 total current 2.00e-06 1.33e-06
|
||||
12 1 2.09e-01 2.27e-01 1 total current 0.00e+00 0.00e+00
|
||||
13 1 2.27e-01 2.44e-01 1 total current 1.00e-06 1.00e-06
|
||||
14 1 2.44e-01 2.62e-01 1 total current 1.00e-06 1.00e-06
|
||||
15 1 2.62e-01 2.79e-01 1 total current 2.00e-06 1.33e-06
|
||||
16 1 2.79e-01 2.97e-01 1 total current 0.00e+00 0.00e+00
|
||||
17 1 2.97e-01 3.14e-01 1 total current 2.00e-06 2.00e-06
|
||||
18 1 3.14e-01 3.32e-01 1 total current 1.00e-06 1.00e-06
|
||||
19 1 3.32e-01 3.49e-01 1 total current 1.00e-06 1.00e-06
|
||||
20 1 3.49e-01 3.67e-01 1 total current 2.00e-06 1.33e-06
|
||||
21 1 3.67e-01 3.84e-01 1 total current 0.00e+00 0.00e+00
|
||||
22 1 3.84e-01 4.01e-01 1 total current 2.00e-06 1.33e-06
|
||||
23 1 4.01e-01 4.19e-01 1 total current 2.00e-06 1.33e-06
|
||||
24 1 4.19e-01 4.36e-01 1 total current 1.00e-06 1.00e-06
|
||||
25 1 4.36e-01 4.54e-01 1 total current 2.00e-06 2.00e-06
|
||||
26 1 4.54e-01 4.71e-01 1 total current 5.00e-06 2.24e-06
|
||||
27 1 4.71e-01 4.89e-01 1 total current 4.00e-06 1.63e-06
|
||||
28 1 4.89e-01 5.06e-01 1 total current 3.00e-06 1.53e-06
|
||||
29 1 5.06e-01 5.24e-01 1 total current 3.00e-06 1.53e-06
|
||||
30 1 5.24e-01 5.41e-01 1 total current 3.00e-06 1.53e-06
|
||||
31 1 5.41e-01 5.59e-01 1 total current 7.00e-06 2.13e-06
|
||||
32 1 5.59e-01 5.76e-01 1 total current 3.00e-06 1.53e-06
|
||||
33 1 5.76e-01 5.93e-01 1 total current 3.00e-06 1.53e-06
|
||||
34 1 5.93e-01 6.11e-01 1 total current 2.00e-06 1.33e-06
|
||||
35 1 6.11e-01 6.28e-01 1 total current 2.00e-06 1.33e-06
|
||||
36 1 6.28e-01 6.46e-01 1 total current 3.00e-06 2.13e-06
|
||||
37 1 6.46e-01 6.63e-01 1 total current 3.00e-06 1.53e-06
|
||||
38 1 6.63e-01 6.81e-01 1 total current 2.00e-06 1.33e-06
|
||||
39 1 6.81e-01 6.98e-01 1 total current 3.00e-06 1.53e-06
|
||||
40 1 6.98e-01 7.16e-01 1 total current 1.00e-06 1.00e-06
|
||||
41 1 7.16e-01 7.33e-01 1 total current 6.00e-06 2.67e-06
|
||||
42 1 7.33e-01 7.50e-01 1 total current 6.00e-06 2.21e-06
|
||||
43 1 7.50e-01 7.68e-01 1 total current 7.00e-06 3.35e-06
|
||||
44 1 7.68e-01 7.85e-01 1 total current 6.00e-06 2.67e-06
|
||||
45 1 7.85e-01 8.03e-01 1 total current 6.00e-06 2.21e-06
|
||||
46 1 8.03e-01 8.20e-01 1 total current 7.00e-06 2.13e-06
|
||||
47 1 8.20e-01 8.38e-01 1 total current 5.00e-06 2.24e-06
|
||||
48 1 8.38e-01 8.55e-01 1 total current 3.00e-06 1.53e-06
|
||||
49 1 8.55e-01 8.73e-01 1 total current 8.00e-06 3.27e-06
|
||||
50 1 8.73e-01 8.90e-01 1 total current 7.00e-06 2.13e-06
|
||||
51 1 8.90e-01 9.08e-01 1 total current 6.00e-06 2.21e-06
|
||||
52 1 9.08e-01 9.25e-01 1 total current 4.00e-06 2.21e-06
|
||||
53 1 9.25e-01 9.42e-01 1 total current 1.20e-05 3.27e-06
|
||||
54 1 9.42e-01 9.60e-01 1 total current 8.00e-06 3.89e-06
|
||||
55 1 9.60e-01 9.77e-01 1 total current 1.20e-05 4.42e-06
|
||||
56 1 9.77e-01 9.95e-01 1 total current 7.00e-06 3.67e-06
|
||||
57 1 9.95e-01 1.01e+00 1 total current 1.20e-05 3.89e-06
|
||||
58 1 1.01e+00 1.03e+00 1 total current 9.00e-06 2.33e-06
|
||||
59 1 1.03e+00 1.05e+00 1 total current 6.00e-06 2.67e-06
|
||||
60 1 1.05e+00 1.06e+00 1 total current 7.00e-06 2.13e-06
|
||||
61 1 1.06e+00 1.08e+00 1 total current 5.00e-06 2.24e-06
|
||||
62 1 1.08e+00 1.10e+00 1 total current 1.20e-05 2.91e-06
|
||||
63 1 1.10e+00 1.12e+00 1 total current 1.30e-05 3.35e-06
|
||||
64 1 1.12e+00 1.13e+00 1 total current 9.00e-06 3.14e-06
|
||||
65 1 1.13e+00 1.15e+00 1 total current 1.20e-05 3.89e-06
|
||||
66 1 1.15e+00 1.17e+00 1 total current 6.00e-06 2.21e-06
|
||||
67 1 1.17e+00 1.19e+00 1 total current 5.11e-03 4.20e-05
|
||||
68 1 1.19e+00 1.20e+00 1 total current 8.00e-06 3.27e-06
|
||||
69 1 1.20e+00 1.22e+00 1 total current 1.30e-05 4.48e-06
|
||||
70 1 1.22e+00 1.24e+00 1 total current 1.20e-05 3.89e-06
|
||||
71 1 1.24e+00 1.26e+00 1 total current 1.50e-05 4.28e-06
|
||||
72 1 1.26e+00 1.27e+00 1 total current 7.00e-06 3.00e-06
|
||||
73 1 1.27e+00 1.29e+00 1 total current 1.60e-05 3.71e-06
|
||||
74 1 1.29e+00 1.31e+00 1 total current 9.00e-06 3.79e-06
|
||||
75 1 1.31e+00 1.33e+00 1 total current 1.30e-05 2.60e-06
|
||||
76 1 1.33e+00 1.34e+00 1 total current 1.60e-05 3.06e-06
|
||||
77 1 1.34e+00 1.36e+00 1 total current 1.40e-05 2.67e-06
|
||||
78 1 1.36e+00 1.38e+00 1 total current 1.40e-05 6.86e-06
|
||||
79 1 1.38e+00 1.40e+00 1 total current 1.50e-05 4.28e-06
|
||||
80 1 1.40e+00 1.41e+00 1 total current 3.26e-03 6.93e-05
|
||||
81 1 1.41e+00 1.43e+00 1 total current 1.40e-05 3.71e-06
|
||||
82 1 1.43e+00 1.45e+00 1 total current 1.30e-05 3.00e-06
|
||||
83 1 1.45e+00 1.47e+00 1 total current 1.30e-05 3.67e-06
|
||||
84 1 1.47e+00 1.48e+00 1 total current 1.70e-05 5.59e-06
|
||||
85 1 1.48e+00 1.50e+00 1 total current 1.70e-05 3.67e-06
|
||||
86 1 1.50e+00 1.52e+00 1 total current 1.40e-05 3.40e-06
|
||||
87 1 1.52e+00 1.54e+00 1 total current 2.50e-05 4.53e-06
|
||||
88 1 1.54e+00 1.55e+00 1 total current 1.30e-05 5.39e-06
|
||||
89 1 1.55e+00 1.57e+00 1 total current 1.80e-05 4.67e-06
|
||||
90 1 1.57e+00 1.59e+00 1 total current 1.40e-05 4.52e-06
|
||||
91 1 1.59e+00 1.61e+00 1 total current 1.70e-05 4.23e-06
|
||||
92 1 1.61e+00 1.62e+00 1 total current 1.40e-05 3.71e-06
|
||||
93 1 1.62e+00 1.64e+00 1 total current 1.00e-05 2.11e-06
|
||||
94 1 1.64e+00 1.66e+00 1 total current 2.00e-05 4.22e-06
|
||||
95 1 1.66e+00 1.68e+00 1 total current 2.30e-05 5.59e-06
|
||||
96 1 1.68e+00 1.69e+00 1 total current 1.70e-05 6.51e-06
|
||||
97 1 1.69e+00 1.71e+00 1 total current 1.30e-05 3.00e-06
|
||||
98 1 1.71e+00 1.73e+00 1 total current 1.50e-05 4.01e-06
|
||||
99 1 1.73e+00 1.75e+00 1 total current 1.70e-05 3.96e-06
|
||||
100 1 1.75e+00 1.76e+00 1 total current 1.80e-05 5.12e-06
|
||||
101 1 1.76e+00 1.78e+00 1 total current 2.50e-05 6.54e-06
|
||||
102 1 1.78e+00 1.80e+00 1 total current 1.80e-05 3.59e-06
|
||||
103 1 1.80e+00 1.82e+00 1 total current 1.50e-05 4.01e-06
|
||||
104 1 1.82e+00 1.83e+00 1 total current 1.10e-05 4.07e-06
|
||||
105 1 1.83e+00 1.85e+00 1 total current 1.50e-05 4.01e-06
|
||||
106 1 1.85e+00 1.87e+00 1 total current 1.90e-05 4.82e-06
|
||||
107 1 1.87e+00 1.88e+00 1 total current 2.20e-05 3.89e-06
|
||||
108 1 1.88e+00 1.90e+00 1 total current 2.10e-05 3.79e-06
|
||||
109 1 1.90e+00 1.92e+00 1 total current 1.50e-05 3.42e-06
|
||||
110 1 1.92e+00 1.94e+00 1 total current 2.20e-05 5.12e-06
|
||||
111 1 1.94e+00 1.95e+00 1 total current 2.10e-05 5.86e-06
|
||||
112 1 1.95e+00 1.97e+00 1 total current 2.60e-05 4.27e-06
|
||||
113 1 1.97e+00 1.99e+00 1 total current 2.20e-05 4.16e-06
|
||||
114 1 1.99e+00 2.01e+00 1 total current 2.40e-05 5.42e-06
|
||||
115 1 2.01e+00 2.02e+00 1 total current 1.60e-05 4.52e-06
|
||||
116 1 2.02e+00 2.04e+00 1 total current 1.30e-05 3.35e-06
|
||||
117 1 2.04e+00 2.06e+00 1 total current 1.90e-05 4.07e-06
|
||||
118 1 2.06e+00 2.08e+00 1 total current 1.30e-05 3.00e-06
|
||||
119 1 2.08e+00 2.09e+00 1 total current 1.40e-05 4.00e-06
|
||||
120 1 2.09e+00 2.11e+00 1 total current 3.10e-05 5.47e-06
|
||||
121 1 2.11e+00 2.13e+00 1 total current 2.30e-05 5.39e-06
|
||||
122 1 2.13e+00 2.15e+00 1 total current 2.20e-05 4.67e-06
|
||||
123 1 2.15e+00 2.16e+00 1 total current 1.70e-05 4.48e-06
|
||||
124 1 2.16e+00 2.18e+00 1 total current 1.60e-05 4.00e-06
|
||||
125 1 2.18e+00 2.20e+00 1 total current 1.80e-05 4.16e-06
|
||||
126 1 2.20e+00 2.22e+00 1 total current 1.80e-05 4.42e-06
|
||||
127 1 2.22e+00 2.23e+00 1 total current 1.80e-05 5.54e-06
|
||||
128 1 2.23e+00 2.25e+00 1 total current 1.90e-05 4.33e-06
|
||||
129 1 2.25e+00 2.27e+00 1 total current 1.00e-05 3.33e-06
|
||||
130 1 2.27e+00 2.29e+00 1 total current 1.80e-05 4.42e-06
|
||||
131 1 2.29e+00 2.30e+00 1 total current 4.15e-03 5.40e-05
|
||||
132 1 2.30e+00 2.32e+00 1 total current 1.90e-05 2.33e-06
|
||||
133 1 2.32e+00 2.34e+00 1 total current 2.30e-05 3.96e-06
|
||||
134 1 2.34e+00 2.36e+00 1 total current 1.90e-05 3.48e-06
|
||||
135 1 2.36e+00 2.37e+00 1 total current 1.60e-05 3.71e-06
|
||||
136 1 2.37e+00 2.39e+00 1 total current 1.60e-05 4.27e-06
|
||||
137 1 2.39e+00 2.41e+00 1 total current 2.30e-05 4.48e-06
|
||||
138 1 2.41e+00 2.43e+00 1 total current 2.10e-05 3.48e-06
|
||||
139 1 2.43e+00 2.44e+00 1 total current 1.60e-05 2.21e-06
|
||||
140 1 2.44e+00 2.46e+00 1 total current 9.00e-06 2.77e-06
|
||||
141 1 2.46e+00 2.48e+00 1 total current 1.30e-05 3.00e-06
|
||||
142 1 2.48e+00 2.50e+00 1 total current 2.70e-05 3.67e-06
|
||||
143 1 2.50e+00 2.51e+00 1 total current 1.90e-05 4.07e-06
|
||||
144 1 2.51e+00 2.53e+00 1 total current 1.20e-05 4.16e-06
|
||||
145 1 2.53e+00 2.55e+00 1 total current 1.30e-05 2.13e-06
|
||||
146 1 2.55e+00 2.57e+00 1 total current 1.10e-05 2.33e-06
|
||||
147 1 2.57e+00 2.58e+00 1 total current 1.50e-05 3.07e-06
|
||||
148 1 2.58e+00 2.60e+00 1 total current 1.20e-05 2.49e-06
|
||||
149 1 2.60e+00 2.62e+00 1 total current 1.80e-05 5.54e-06
|
||||
150 1 2.62e+00 2.64e+00 1 total current 1.30e-05 3.67e-06
|
||||
151 1 2.64e+00 2.65e+00 1 total current 1.60e-05 3.40e-06
|
||||
152 1 2.65e+00 2.67e+00 1 total current 7.00e-06 3.35e-06
|
||||
153 1 2.67e+00 2.69e+00 1 total current 1.00e-05 2.98e-06
|
||||
154 1 2.69e+00 2.71e+00 1 total current 7.00e-06 3.35e-06
|
||||
155 1 2.71e+00 2.72e+00 1 total current 1.20e-05 2.91e-06
|
||||
156 1 2.72e+00 2.74e+00 1 total current 9.00e-06 2.33e-06
|
||||
157 1 2.74e+00 2.76e+00 1 total current 1.00e-05 3.33e-06
|
||||
158 1 2.76e+00 2.78e+00 1 total current 1.10e-05 3.14e-06
|
||||
159 1 2.78e+00 2.79e+00 1 total current 1.00e-05 3.33e-06
|
||||
160 1 2.79e+00 2.81e+00 1 total current 1.40e-05 4.76e-06
|
||||
161 1 2.81e+00 2.83e+00 1 total current 8.00e-06 2.91e-06
|
||||
162 1 2.83e+00 2.84e+00 1 total current 5.00e-06 2.69e-06
|
||||
163 1 2.84e+00 2.86e+00 1 total current 6.00e-06 2.21e-06
|
||||
164 1 2.86e+00 2.88e+00 1 total current 5.00e-06 1.67e-06
|
||||
165 1 2.88e+00 2.90e+00 1 total current 4.00e-06 2.21e-06
|
||||
166 1 2.90e+00 2.91e+00 1 total current 7.00e-06 2.13e-06
|
||||
167 1 2.91e+00 2.93e+00 1 total current 6.00e-06 2.67e-06
|
||||
168 1 2.93e+00 2.95e+00 1 total current 7.00e-06 2.13e-06
|
||||
169 1 2.95e+00 2.97e+00 1 total current 5.00e-06 1.67e-06
|
||||
170 1 2.97e+00 2.98e+00 1 total current 3.00e-06 1.53e-06
|
||||
171 1 2.98e+00 3.00e+00 1 total current 6.00e-06 2.21e-06
|
||||
172 1 3.00e+00 3.02e+00 1 total current 3.00e-06 1.53e-06
|
||||
173 1 3.02e+00 3.04e+00 1 total current 1.00e-05 2.98e-06
|
||||
174 1 3.04e+00 3.05e+00 1 total current 2.00e-06 1.33e-06
|
||||
175 1 3.05e+00 3.07e+00 1 total current 1.00e-06 1.00e-06
|
||||
176 1 3.07e+00 3.09e+00 1 total current 2.00e-06 1.33e-06
|
||||
177 1 3.09e+00 3.11e+00 1 total current 0.00e+00 0.00e+00
|
||||
178 1 3.11e+00 3.12e+00 1 total current 1.00e-06 1.00e-06
|
||||
179 1 3.12e+00 3.14e+00 1 total current 0.00e+00 0.00e+00
|
||||
80
tests/regression_tests/ncrystal/test.py
Normal file
80
tests/regression_tests/ncrystal/test.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
from math import pi
|
||||
|
||||
import numpy as np
|
||||
import openmc
|
||||
import openmc.lib
|
||||
import pytest
|
||||
|
||||
from tests.testing_harness import PyAPITestHarness
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
not openmc.lib._ncrystal_enabled(),
|
||||
reason="NCrystal materials are not enabled.")
|
||||
|
||||
|
||||
def pencil_beam_model(cfg, E0, N):
|
||||
"""Return an openmc.Model() object for a monoenergetic pencil
|
||||
beam hitting a 1 mm sphere filled with the material defined by
|
||||
the cfg string, and compute the angular distribution"""
|
||||
|
||||
# Material definition
|
||||
|
||||
m1 = openmc.Material.from_ncrystal(cfg)
|
||||
materials = openmc.Materials([m1])
|
||||
|
||||
# Geometry definition
|
||||
|
||||
sample_sphere = openmc.Sphere(r=0.1)
|
||||
outer_sphere = openmc.Sphere(r=100, boundary_type="vacuum")
|
||||
cell1 = openmc.Cell(region=-sample_sphere, fill=m1)
|
||||
cell2_region = +sample_sphere & -outer_sphere
|
||||
cell2 = openmc.Cell(region=cell2_region, fill=None)
|
||||
geometry = openmc.Geometry([cell1, cell2])
|
||||
|
||||
# Source definition
|
||||
|
||||
source = openmc.Source()
|
||||
source.space = openmc.stats.Point((0, 0, -20))
|
||||
source.angle = openmc.stats.Monodirectional(reference_uvw=(0, 0, 1))
|
||||
source.energy = openmc.stats.Discrete([E0], [1.0])
|
||||
|
||||
# Execution settings
|
||||
|
||||
settings = openmc.Settings()
|
||||
settings.source = source
|
||||
settings.run_mode = "fixed source"
|
||||
settings.batches = 10
|
||||
settings.particles = N
|
||||
|
||||
# Tally definition
|
||||
|
||||
tally1 = openmc.Tally(name="angular distribution")
|
||||
tally1.scores = ["current"]
|
||||
filter1 = openmc.SurfaceFilter(sample_sphere)
|
||||
filter2 = openmc.PolarFilter(np.linspace(0, pi, 180+1))
|
||||
filter3 = openmc.CellFromFilter(cell1)
|
||||
tally1.filters = [filter1, filter2, filter3]
|
||||
tallies = openmc.Tallies([tally1])
|
||||
|
||||
return openmc.Model(geometry, materials, settings, tallies)
|
||||
|
||||
|
||||
class NCrystalTest(PyAPITestHarness):
|
||||
def _get_results(self):
|
||||
"""Digest info in the statepoint and return as a string."""
|
||||
|
||||
# Read the statepoint file.
|
||||
with openmc.StatePoint(self._sp_name) as sp:
|
||||
tal = sp.get_tally(name='angular distribution')
|
||||
df = tal.get_pandas_dataframe()
|
||||
return df.to_string()
|
||||
|
||||
|
||||
def test_ncrystal():
|
||||
n_particles = 100000
|
||||
T = 293.6 # K
|
||||
E0 = 0.012 # eV
|
||||
cfg = 'Al_sg225.ncmat'
|
||||
test = pencil_beam_model(cfg, E0, n_particles)
|
||||
harness = NCrystalTest('statepoint.10.h5', model=test)
|
||||
harness.main()
|
||||
46
tools/ci/gha-install-ncrystal.sh
Executable file
46
tools/ci/gha-install-ncrystal.sh
Executable file
|
|
@ -0,0 +1,46 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
cd $HOME
|
||||
|
||||
#Use the NCrystal develop branch (in the near future we can move this to master):
|
||||
git clone https://github.com/mctools/ncrystal --branch develop --single-branch --depth 1 ncrystal_src
|
||||
|
||||
SRC_DIR="$PWD/ncrystal_src"
|
||||
BLD_DIR="$PWD/ncrystal_bld"
|
||||
INST_DIR="$PWD/ncrystal_inst"
|
||||
PYTHON=$(which python3)
|
||||
|
||||
CPU_COUNT=1
|
||||
|
||||
mkdir "$BLD_DIR"
|
||||
cd ncrystal_bld
|
||||
|
||||
cmake \
|
||||
"${SRC_DIR}" \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DNCRYSTAL_NOTOUCH_CMAKE_BUILD_TYPE=ON \
|
||||
-DNCRYSTAL_MODIFY_RPATH=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DNCRYSTAL_ENABLE_EXAMPLES=OFF \
|
||||
-DNCRYSTAL_ENABLE_SETUPSH=OFF \
|
||||
-DNCRYSTAL_ENABLE_DATA=EMBED \
|
||||
-DCMAKE_INSTALL_PREFIX="${INST_DIR}" \
|
||||
-DPython3_EXECUTABLE="$PYTHON"
|
||||
|
||||
make -j${CPU_COUNT:-1}
|
||||
make install
|
||||
|
||||
#Note: There is no "make test" or "make ctest" functionality for NCrystal
|
||||
# yet. If it appears in the future, we should add it here.
|
||||
|
||||
# Output the configuration to the log
|
||||
|
||||
"${INST_DIR}/bin/ncrystal-config" --setup
|
||||
|
||||
# Change environmental variables
|
||||
|
||||
eval $( "${INST_DIR}/bin/ncrystal-config" --setup )
|
||||
|
||||
# Check installation worked
|
||||
|
||||
nctool --test
|
||||
|
|
@ -19,7 +19,7 @@ def which(program):
|
|||
return None
|
||||
|
||||
|
||||
def install(omp=False, mpi=False, phdf5=False, dagmc=False, libmesh=False):
|
||||
def install(omp=False, mpi=False, phdf5=False, dagmc=False, libmesh=False, ncrystal=False):
|
||||
# Create build directory and change to it
|
||||
shutil.rmtree('build', ignore_errors=True)
|
||||
os.mkdir('build')
|
||||
|
|
@ -54,6 +54,11 @@ def install(omp=False, mpi=False, phdf5=False, dagmc=False, libmesh=False):
|
|||
libmesh_path = os.environ.get('HOME') + '/LIBMESH'
|
||||
cmake_cmd.append('-DCMAKE_PREFIX_PATH=' + libmesh_path)
|
||||
|
||||
if ncrystal:
|
||||
cmake_cmd.append('-DOPENMC_USE_NCRYSTAL=ON')
|
||||
ncrystal_cmake_path = os.environ.get('HOME') + '/ncrystal_inst/lib/cmake'
|
||||
cmake_cmd.append(f'-DCMAKE_PREFIX_PATH={ncrystal_cmake_path}')
|
||||
|
||||
# Build in coverage mode for coverage testing
|
||||
cmake_cmd.append('-DOPENMC_ENABLE_COVERAGE=on')
|
||||
|
||||
|
|
@ -70,10 +75,11 @@ 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)
|
||||
install(omp, mpi, phdf5, dagmc, libmesh, ncrystal)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ if [[ $DAGMC = 'y' ]]; then
|
|||
./tools/ci/gha-install-dagmc.sh
|
||||
fi
|
||||
|
||||
# Install NCrystal if needed
|
||||
if [[ $NCRYSTAL = 'y' ]]; then
|
||||
./tools/ci/gha-install-ncrystal.sh
|
||||
fi
|
||||
|
||||
# Install vectfit for WMP generation if needed
|
||||
if [[ $VECTFIT = 'y' ]]; then
|
||||
./tools/ci/gha-install-vectfit.sh
|
||||
|
|
|
|||
|
|
@ -14,5 +14,12 @@ if [[ $EVENT == 'y' ]]; then
|
|||
args="${args} --event "
|
||||
fi
|
||||
|
||||
# Check NCrystal installation
|
||||
if [[ $NCRYSTAL = 'y' ]]; then
|
||||
# Change environmental variables
|
||||
eval $( "${HOME}/ncrystal_inst/bin/ncrystal-config" --setup )
|
||||
nctool --test
|
||||
fi
|
||||
|
||||
# Run regression and unit tests
|
||||
pytest --cov=openmc -v $args tests
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue