Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
0e0cd0a
Added hooks for NCrystal
marquezj Sep 13, 2021
0f33e0b
Add temporary requirement of natural elements in NCrystal materials
tkittel Sep 13, 2022
9c54ac0
Fix access to private attributes
marquezj Sep 13, 2022
70d5c76
Fixed material.h
marquezj Sep 13, 2022
29a10ea
Removed MacroNCrystalXS
marquezj Sep 16, 2022
2e19260
Implement recommended changes
marquezj Sep 26, 2022
5afcc9e
Apply clang-format
marquezj Sep 26, 2022
fdf763e
Couple of fixes
marquezj Sep 26, 2022
52ee2c3
Print where NCrystal was found as suggested by @paulromano
tkittel Oct 20, 2022
a5b811e
Use new NCrystal getFlattenedComposition method to better support mor…
tkittel Oct 20, 2022
f2e807e
Move NCrystalRNGWrapper data member into explicit private section as …
tkittel Oct 20, 2022
aca4fcb
NCrystal cfgstr printout now mentions material ID
tkittel Oct 21, 2022
a3dd55d
first stab at gha-install-ncrystal.sh
tkittel Oct 21, 2022
e64bf6a
Add installation instructions for NCrystal
marquezj Nov 10, 2022
1f3c5ed
Add use instructions and examples for NCrystal
marquezj Nov 10, 2022
cf96ddf
Basic introduction to NCrystal
marquezj Nov 17, 2022
24572a7
Added simple NCrystal test
marquezj Nov 17, 2022
54745f5
Changed example NCrystal cfg strings
marquezj Nov 18, 2022
91f939a
Add flag for NCrystal
marquezj Nov 18, 2022
5f8e64b
Add NCrystal vairables to ci.yml
marquezj Nov 18, 2022
87ed26b
Add option to install NCrystal
marquezj Nov 18, 2022
8cf9dbe
Fixed in NCrystal docs
marquezj Nov 18, 2022
b9e8f13
Attempt to fix NCrystal installation script
marquezj Nov 18, 2022
b9a1fd5
Merge branch 'mixed_ncrystal' of https://github.com/highness-eu/openm…
marquezj Nov 18, 2022
d7ab491
Try fix of NCrystal install
marquezj Nov 19, 2022
b199db9
Update gha-install-ncrystal.sh
marquezj Nov 19, 2022
39d0c5c
Try to initialize with setup.sh
marquezj Nov 19, 2022
9e1abb3
Update gha-install-ncrystal.sh
marquezj Nov 19, 2022
3e6bb9d
Upgrade installation script to NCrystal 3.5.0
marquezj Nov 28, 2022
be330a1
Update gha-install-ncrystal.sh
marquezj Nov 28, 2022
fff545a
Update gha-install-ncrystal.sh
marquezj Nov 28, 2022
8598ff7
Pass CMAKE_PREFIX_PATH from NCrystall installation
marquezj Nov 28, 2022
c98a121
Update gha-install.py
marquezj Nov 28, 2022
19bf624
Add NCrystal installation test
marquezj Nov 28, 2022
4391d60
find NCrystal
marquezj Nov 28, 2022
e626447
Update gha-script.sh
marquezj Nov 28, 2022
e7b4285
Cleanup
marquezj Nov 29, 2022
f2c2870
Apply suggestions from code review
tkittel Dec 7, 2022
a86e74f
Rename compute_angular_distribution to pencil_beam_model
tkittel Dec 7, 2022
b6d6bdf
Merge branch 'develop' into mixed_ncrystal_pr
paulromano Jan 9, 2023
7dae457
Merge pull request #1 from paulromano/ncrystal_mixed
tkittel Jan 10, 2023
62af773
Refactor NCrystal interface code to ncrystal_interface.h/cpp
paulromano Jan 9, 2023
4eda693
Style and spacing changes
paulromano Jan 10, 2023
c4227f7
Change Material.from_ncrystal to accept kwargs
paulromano Jan 10, 2023
fe4a1de
Merge pull request #2 from paulromano/mixed_ncrystal_pr
tkittel Jan 10, 2023
e83ced8
Change ncrystal_max_energy to be a global constant
paulromano Jan 10, 2023
93aaa32
Merge pull request #3 from paulromano/mixed_ncrystal_const
tkittel Jan 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Added hooks for NCrystal
  • Loading branch information
marquezj authored and tkittel committed Oct 21, 2022
commit 0e0cd0a22d059159a8799906f57d12cec99c1a89
16 changes: 16 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ option(OPENMC_ENABLE_COVERAGE "Compile with coverage analysis flags"
option(OPENMC_USE_DAGMC "Enable support for DAGMC (CAD) geometry" OFF)
option(OPENMC_USE_LIBMESH "Enable support for libMesh unstructured mesh tallies" OFF)
option(OPENMC_USE_MPI "Enable MPI" 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")
Expand Down Expand Up @@ -98,6 +99,14 @@ macro(find_package_write_status pkg)
endif()
endmacro()

#===============================================================================
# NCrystal Scattering Support
#===============================================================================

if(OPENMC_USE_NCRYSTAL)
find_package(NCrystal REQUIRED PATH_SUFFIXES ./)#fixme
Comment thread
paulromano marked this conversation as resolved.
Resolved
endif()

#===============================================================================
# DAGMC Geometry Support - need DAGMC/MOAB
#===============================================================================
Expand Down Expand Up @@ -482,6 +491,13 @@ if (OPENMC_USE_MPI)
target_link_libraries(libopenmc MPI::MPI_CXX)
endif()

if(OPENMC_USE_NCRYSTAL)
target_compile_definitions(libopenmc PRIVATE NCRYSTAL)
target_link_libraries(libopenmc NCrystal::NCrystal)
endif()



Comment thread
tkittel marked this conversation as resolved.
Resolved
#===============================================================================
# openmc executable
#===============================================================================
Expand Down
8 changes: 8 additions & 0 deletions include/openmc/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
#include "openmc/particle.h"
#include "openmc/vector.h"

#ifdef NCRYSTAL
#include "NCrystal/NCrystal.hh"
#endif

namespace openmc {

//==============================================================================
Expand Down Expand Up @@ -157,6 +161,10 @@ class Material {
std::string name_; //!< Name of material
vector<int> nuclide_; //!< Indices in nuclides vector
vector<int> element_; //!< Indices in elements vector
#ifdef NCRYSTAL
std::string cfg_; //!< NCrystal configuration string
std::shared_ptr<const NCrystal::ProcImpl::Process> m_NCrystal_mat_;
Comment thread
marquezj marked this conversation as resolved.
Resolved
#endif
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]
Expand Down
3 changes: 3 additions & 0 deletions include/openmc/particle_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ struct MacroXS {
double fission; //!< macroscopic fission xs
double nu_fission; //!< macroscopic production xs
double photon_prod; //!< macroscopic photon production xs
#ifdef NCRYSTAL
double NCrystal_XS; //!< macroscopic cross section of processes handled by NCrystal
#endif

// Photon cross sections
double coherent; //!< macroscopic coherent xs
Expand Down
27 changes: 27 additions & 0 deletions include/openmc/physics.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#include "openmc/reaction.h"
#include "openmc/vector.h"

#ifdef NCRYSTAL
#include "NCrystal/NCRNG.hh"
#endif

namespace openmc {

//==============================================================================
Expand Down Expand Up @@ -101,6 +105,29 @@ void sample_secondary_photons(Particle& p, int i_nuclide);
//! \param[in] p, particle to be split or rouletted with the weight window.
void split_particle(Particle& p);

#ifdef NCRYSTAL
//==============================================================================
// NCrystal wrapper class for the OpenMC random number generator
//==============================================================================

class NcrystalRNG_Wrapper : public NCrystal::RNGStream {
uint64_t* openmc_seed_;
public:
constexpr NcrystalRNG_Wrapper(uint64_t* s) noexcept : openmc_seed_(s) {}
Comment thread
marquezj marked this conversation as resolved.
Resolved
//Can be cheaply created on the stack just before being used in calls to
//ProcImpl::Scatter objects, like:
//
// RNG_Wrapper rng(seed);
//
Comment thread
marquezj marked this conversation as resolved.
Resolved
protected:
//double actualGenerate() override { return prn(openmc_seed_); }
Comment thread
marquezj marked this conversation as resolved.
Resolved
double actualGenerate() override {
return std::max<double>( std::numeric_limits<double>::min(), prn(openmc_seed_) );
}

};
#endif

} // namespace openmc

#endif // OPENMC_PHYSICS_H
3 changes: 3 additions & 0 deletions include/openmc/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ extern int trigger_batch_interval; //!< Batch interval for triggers
extern "C" int verbosity; //!< How verbose to make output
extern double weight_cutoff; //!< Weight cutoff for Russian roulette
extern double weight_survive; //!< Survival weight after Russian roulette
#ifdef NCRYSTAL
extern double ncrystal_max_energy; // Energy in eV to switch between NCrystal and ENDF
#endif
} // namespace settings

//==============================================================================
Expand Down
59 changes: 59 additions & 0 deletions openmc/material.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ def __init__(self, material_id=None, name='', temperature=None):
self._volume = None
self._atoms = {}
self._isotropic = []
self._NCrystal_cfg = None
Comment thread
marquezj marked this conversation as resolved.
Resolved

# A list of tuples (nuclide, percent, percent type)
self._nuclides = []
Expand All @@ -140,6 +141,8 @@ def __repr__(self):

string += '{: <16}\n'.format('\tS(a,b) Tables')

string += '{: <16}=\t{}\n'.format('\tNCrystal conf', self._NCrystal_cfg)
Comment thread
marquezj marked this conversation as resolved.
Resolved

for sab in self._sab:
string += '{: <16}=\t{}\n'.format('\tS(a,b)', sab)

Expand Down Expand Up @@ -331,6 +334,48 @@ def from_hdf5(cls, group: h5py.Group):

return material

@classmethod
def from_NCrystal(cls, cfg):
Comment thread
marquezj marked this conversation as resolved.
Resolved
"""Create material from NCrystal configuration string
Density is set from the NCrystal value,
and material temperature from the configuration string.

Parameters
----------
cfg : str
NCrystal configuration string

Returns
-------
openmc.Material
Material instance

"""

try:
import NCrystal
except ImportError:
raise SystemExit("ERROR: NCrystal Python module is required.")
Comment thread
marquezj marked this conversation as resolved.
Resolved

NC_mat = NCrystal.createInfo(cfg)
NC_comp = NC_mat.getComposition()
Comment thread
marquezj marked this conversation as resolved.
Resolved

# Create the Material
material = cls()

for frac, atom in NC_comp:
if (atom.A() == 0):
material.add_element(atom.displayLabel(), frac, 'ao')
else:
material.add_nuclide(atom.displayLabel(), frac, 'ao')

material._NCrystal_cfg = cfg
material._density_units = "g/cm3"
material._density = NC_mat.getDensity()
material.temperature = NC_mat.getTemperature()
Comment thread
marquezj marked this conversation as resolved.
Resolved

return material

def add_volume_information(self, volume_calc):
"""Add volume information to a material.

Expand Down Expand Up @@ -405,6 +450,9 @@ def add_nuclide(self, nuclide: str, percent: float, percent_type: str = 'ao'):
'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)
Expand Down Expand Up @@ -609,6 +657,9 @@ def add_element(self, element: str, percent: float, percent_type: str = 'ao',
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")
Comment thread
marquezj marked this conversation as resolved.
Resolved

# Allow for element identifier to be given as a symbol or name
if len(element) > 2:
el = element.lower()
Expand Down Expand Up @@ -1135,6 +1186,14 @@ def to_xml_element(self):
if self._volume:
element.set("volume", str(self._volume))

if self._NCrystal_cfg:
Comment thread
marquezj marked this conversation as resolved.
Resolved
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 macroscopic cross sections.")

element.set("cfg", str(self._NCrystal_cfg))
Comment thread
marquezj marked this conversation as resolved.
Resolved

# Create temperature XML subelement
if self.temperature is not None:
element.set("temperature", str(self.temperature))
Expand Down
36 changes: 35 additions & 1 deletion src/material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ Material::Material(pugi::xml_node node)
name_ = get_node_value(node, "name");
}

#ifdef NCRYSTAL
if (check_for_node(node, "cfg")) {
cfg_ = get_node_value(node, "cfg");
write_message(5, "NCrystal config string: >>{}<< ", cfg_);
m_NCrystal_mat_ = NCrystal::FactImpl::createScatter(cfg_);
Comment thread
marquezj marked this conversation as resolved.
Resolved
}
#endif

if (check_for_node(node, "depletable")) {
depletable_ = get_node_value_bool(node, "depletable");
}
Expand Down Expand Up @@ -792,6 +800,17 @@ void Material::calculate_neutron_xs(Particle& p) const
// Initialize position in i_sab_nuclides
int j = 0;

#ifdef NCRYSTAL
double ncrystal_xs = -1;

if (m_NCrystal_mat_ != nullptr && p.E() < settings::ncrystal_max_energy){
Comment thread
marquezj marked this conversation as resolved.
Resolved
// Calculate scattering XS per atom with NCrystal, only once per material
NCrystal::CachePtr dummyCache;
auto nc_energy = NCrystal::NeutronEnergy{p.E()};
ncrystal_xs = m_NCrystal_mat_->crossSection( dummyCache, nc_energy, {p.u().x, p.u().y, p.u().z}).get();
Comment thread
marquezj marked this conversation as resolved.
Resolved
}
#endif

// Add contribution from each nuclide in material
for (int i = 0; i < nuclide_.size(); ++i) {
// ======================================================================
Expand Down Expand Up @@ -830,10 +849,25 @@ 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)};
#ifndef NCRYSTAL
const
#endif
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);
#ifdef NCRYSTAL
if (ncrystal_xs >= 0.0){
if ( micro.thermal > 0 || micro.thermal_elastic > 0) {
fatal_error("S(a,b) treatment and NCrystal are not compatible.");
}
data::nuclides[i_nuclide]->calculate_elastic_xs(p);
// remove free atom cross section
// and replace it by scattering cross section per atom from NCrystal
micro.total = micro.total - micro.elastic + ncrystal_xs;
micro.elastic = ncrystal_xs;
}
#endif
}

// ======================================================================
Expand Down
21 changes: 20 additions & 1 deletion src/physics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,27 @@ void sample_neutron_reaction(Particle& p)

// Sample a scattering reaction and determine the secondary energy of the
// exiting neutron
scatter(p, i_nuclide);

#ifdef NCRYSTAL
if (model::materials[p.material_]->m_NCrystal_mat_ != nullptr && p.E() < settings::ncrystal_max_energy){

NcrystalRNG_Wrapper rng(p.current_seed()); // Initialize RNG
//create a cache pointer for multi thread physics
NCrystal::CachePtr dummyCache;//fixme: avoid recreating here (triggers malloc)
Comment thread
paulromano marked this conversation as resolved.
Resolved
auto nc_energy = NCrystal::NeutronEnergy{p.E()};
auto outcome = model::materials[p.material_]->m_NCrystal_mat_->sampleScatter( dummyCache, rng , nc_energy, {p.u().x, p.u().y, p.u().z});
p.E_last() = p.E();
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;//fixme: define a new label for NCrystal?
} else {
scatter(p, i_nuclide);
}
#else
scatter(p, i_nuclide);
#endif
// Advance URR seed stream 'N' times after energy changes
if (p.E() != p.E_last()) {
p.stream() = STREAM_URR_PTABLE;
Expand Down
4 changes: 4 additions & 0 deletions src/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ int verbosity {7};
double weight_cutoff {0.25};
double weight_survive {1.0};

#ifdef NCRYSTAL
double ncrystal_max_energy{5.0};
#endif

} // namespace settings

//==============================================================================
Expand Down