Fixes to custom source feature

This commit is contained in:
Paul Romano 2020-02-14 10:02:36 -06:00
parent 5457326d37
commit c5dbff356a
6 changed files with 92 additions and 95 deletions

View file

@ -1,10 +1,13 @@
#include "openmc/source.h"
#include <algorithm> // for move
#include <sstream> // for stringstream
#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
#include <dlfcn.h> // for dlopen
#define HAS_DYNAMIC_LINKING
#endif
#include <algorithm> // for move
#ifdef HAS_DYNAMIC_LINKING
#include <dlfcn.h> // for dlopen, dlsym, dlclose, dlerror
#endif
#include <fmt/core.h>
@ -77,13 +80,11 @@ SourceDistribution::SourceDistribution(pugi::xml_node node)
settings::path_source));
}
} else if (check_for_node(node, "library")) {
settings::path_source_library = get_node_value(node, "library", false, true);
// check if it exists
if (!file_exists(settings::path_source_library)) {
std::stringstream msg;
msg << "Library file " << settings::path_source_library << "' does not exist.";
fatal_error(msg);
}
settings::path_source_library = get_node_value(node, "library", false, true);
if (!file_exists(settings::path_source_library)) {
fatal_error(fmt::format("Source library '{}' does not exist.",
settings::path_source_library));
}
} else {
// Spatial distribution for external source
@ -249,7 +250,7 @@ void initialize_source()
{
write_message("Initializing source particles...", 5);
if (settings::path_source != "") {
if (!settings::path_source.empty()) {
// Read the source from a binary file instead of sampling from some
// assumed source distribution
@ -273,31 +274,27 @@ void initialize_source()
// Close file
file_close(file_id);
} else if ( settings::path_source_library != "" ) {
// Get the source from a library object
std::stringstream msg;
msg << "Sampling from library source " << settings::path_source << "...";
write_message(msg, 6);
} else if (!settings::path_source_library.empty()) {
#ifdef HAS_DYNAMIC_LINKING
// Get the source from a library object
write_message(fmt::format("Sampling from library source {}...",
settings::path_source), 6);
#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
// Open the library
void* source_library = dlopen(settings::path_source_library.c_str(),RTLD_LAZY);
if(!source_library) {
std::stringstream msg("Couldn't open source library " + settings::path_source_library);
fatal_error(msg);
auto source_library = dlopen(settings::path_source_library.c_str(), RTLD_LAZY);
if (!source_library) {
fatal_error("Couldn't open source library " + settings::path_source_library);
}
#else
std::stringstream msg("This feature has not yet been implemented for non POSIX systems");
fatal_error(msg);
#endif
// load the symbol
typedef Particle::Bank (*sample_t)(uint64_t seed);
// reset errors
dlerror();
fill_source_bank_dlopen_source();
fill_source_bank_custom_source();
#else
fatal_error("Custom source libraries have not yet been implemented for "
"non-POSIX systems");
#endif
} else {
// Generation source sites from specified distribution in user input
@ -359,47 +356,44 @@ void free_memory_source()
}
// fill the source bank from the external source
void fill_source_bank_dlopen_source()
void fill_source_bank_custom_source()
{
std::stringstream msg;
#ifdef HAS_DYNAMIC_LINKING
// Open the library
void* source_library = dlopen(settings::path_source_library.c_str(),RTLD_LAZY);
if(!source_library) {
std::stringstream msg("Couldn't open source library " + settings::path_source_library);
fatal_error(msg);
auto source_library = dlopen(settings::path_source_library.c_str(), RTLD_LAZY);
if (!source_library) {
fatal_error("Couldn't open source library " + settings::path_source_library);
}
// load the symbol
typedef Particle::Bank (*sample_t)(uint64_t seed);
// reset errors
dlerror();
// get the function from the library
sample_t sample_source = (sample_t) dlsym(source_library, "sample_source");
const char *dlsym_error = dlerror();
using sample_t = Particle::Bank (*)(uint64_t* seed);
auto sample_source = reinterpret_cast<sample_t>(dlsym(source_library, "sample_source"));
// check for any dlsym errors
auto dlsym_error = dlerror();
if (dlsym_error) {
std::cout << dlsym_error << std::endl;
dlclose(source_library);
fatal_error("Couldn't open the sample_source symbol");
fatal_error(fmt::format("Couldn't open the sample_source symbol: {}", dlsym_error));
}
// Generation source sites from specified distribution in the
// library source
// library source
for (int64_t i = 0; i < simulation::work_per_rank; ++i) {
// initialize random number seed
int64_t id = simulation::total_gen*settings::n_particles +
simulation::work_index[mpi::rank] + i + 1;
int64_t id = (simulation::total_gen + overall_generation()) *
settings::n_particles + simulation::work_index[mpi::rank] + i + 1;
uint64_t seed = init_seed(id, STREAM_SOURCE);
// sample external source distribution
simulation::source_bank[i] = sample_source(seed);
simulation::source_bank[i] = sample_source(&seed);
}
// release the library
dlclose(source_library);
#endif
}
void fill_source_bank_fixedsource()
@ -414,8 +408,8 @@ void fill_source_bank_fixedsource()
// sample external source distribution
simulation::source_bank[i] = sample_external_source(&seed);
}
} else if (settings::path_source.empty() && !settings::path_source.empty()) {
fill_source_bank_dlopen_source();
} else if (settings::path_source.empty() && !settings::path_source_library.empty()) {
fill_source_bank_custom_source();
}
}