From 21e8d91e9074538f743c8cd9ee3000065af89525 Mon Sep 17 00:00:00 2001 From: Dan Short Date: Fri, 28 Aug 2020 09:49:36 +0100 Subject: [PATCH] Requested updates to source Rename sample_source -> sample. Use std::string as type of argument to openmc_create_source. Use reinterpret_cast when accessing dlsym. Also moves check for dlerror to be before the attempt to create the source (avoids null reference if fails) and capture error message before dlclose, so that the error message is still available. Formatting updates and some refactoring for examples and tests. --- examples/custom_source/source_ring.cpp | 6 ++-- .../parameterized_source_ring.cpp | 35 +++++++------------ include/openmc/source.h | 4 +-- src/source.cpp | 16 +++++---- .../source_dlopen/source_sampling.cpp | 6 ++-- .../parameterized_source_sampling.cpp | 22 ++++++------ 6 files changed, 40 insertions(+), 49 deletions(-) diff --git a/examples/custom_source/source_ring.cpp b/examples/custom_source/source_ring.cpp index 5b7bb837c..bc8a8a7f8 100644 --- a/examples/custom_source/source_ring.cpp +++ b/examples/custom_source/source_ring.cpp @@ -7,7 +7,7 @@ class Source : public openmc::CustomSource { - openmc::Particle::Bank sample_source(uint64_t* seed) + openmc::Particle::Bank sample(uint64_t* seed) { openmc::Particle::Bank particle; // wgt @@ -30,7 +30,7 @@ class Source : public openmc::CustomSource // A function to create a unique pointer to an instance of this class when generated // via a plugin call using dlopen/dlsym. // You must have external C linkage here otherwise dlopen will not find the file -extern "C" std::unique_ptr openmc_create_source() +extern "C" std::unique_ptr openmc_create_source(std::string parameters) { - return std::unique_ptr (new Source()); + return std::make_unique(); } diff --git a/examples/parameterized_custom_source/parameterized_source_ring.cpp b/examples/parameterized_custom_source/parameterized_source_ring.cpp index abcaa975a..c88333e15 100644 --- a/examples/parameterized_custom_source/parameterized_source_ring.cpp +++ b/examples/parameterized_custom_source/parameterized_source_ring.cpp @@ -8,25 +8,12 @@ class Source : public openmc::CustomSource { - protected: - double radius_; - double energy_; - - // Protect the constructor as we only want the class to be created by the from_string method. - Source(double radius, double energy) - { - radius_ = radius; - energy_ = energy; - } - public: - // Getters for the values that we want to use in sampling. - double radius() { return radius_; } - double energy() { return energy_; } + Source(double radius, double energy) : radius_(radius), energy_(energy) { } // Defines a function that can create a unique pointer to a new instance of this class // by extracting the parameters from the provided string. - static std::unique_ptr from_string(const char* parameters) + static std::unique_ptr from_string(std::string parameters) { std::unordered_map parameter_mapping; @@ -39,13 +26,13 @@ class Source : public openmc::CustomSource parameter_mapping[key] = value; } - return std::unique_ptr ( - new Source(std::stod(parameter_mapping["radius"]), std::stod(parameter_mapping["energy"])) - ); + double radius = std::stod(parameter_mapping["radius"]); + double energy = std::stod(parameter_mapping["energy"]); + return std::make_unique(radius, energy); } // Samples from an instance of this class. - openmc::Particle::Bank sample_source(uint64_t* seed) + openmc::Particle::Bank sample(uint64_t* seed) { openmc::Particle::Bank particle; // wgt @@ -53,23 +40,27 @@ class Source : public openmc::CustomSource particle.wgt = 1.0; // position double angle = 2.0 * M_PI * openmc::prn(seed); - double radius = this->radius(); + double radius = this->radius_; particle.r.x = radius * std::cos(angle); particle.r.y = radius * std::sin(angle); particle.r.z = 0.0; // angle particle.u = {1.0, 0.0, 0.0}; - particle.E = this->energy(); + particle.E = this->energy_; particle.delayed_group = 0; return particle; } + + private: + double radius_; + double energy_; }; // A function to create a unique pointer to an instance of this class when generated // via a plugin call using dlopen/dlsym. // You must have external C linkage here otherwise dlopen will not find the file -extern "C" std::unique_ptr openmc_create_source(const char* parameters) +extern "C" std::unique_ptr openmc_create_source(std::string parameters) { return Source::from_string(parameters); } diff --git a/include/openmc/source.h b/include/openmc/source.h index 460e7eca3..529cb1836 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -63,10 +63,10 @@ class CustomSource { public: virtual ~CustomSource() {} - virtual Particle::Bank sample_source(uint64_t* seed) = 0; + virtual Particle::Bank sample(uint64_t* seed) = 0; }; -typedef std::unique_ptr create_custom_source_t(const char* parameters); +typedef std::unique_ptr create_custom_source_t(std::string parameters); //============================================================================== // Functions diff --git a/src/source.cpp b/src/source.cpp index 7c40147ce..b80a2ce7a 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -46,7 +46,7 @@ std::vector external_sources; namespace { void* custom_source_library; -std::string custom_source_parameters = ""; +std::string custom_source_parameters; std::unique_ptr custom_source; } @@ -373,18 +373,20 @@ void load_custom_source_library() dlerror(); // get the function to create the CustomSource from the library - create_custom_source_t* create_custom_source = (create_custom_source_t*) dlsym(custom_source_library, "openmc_create_source"); - - // create a pointer to an instance of the CustomSource - custom_source = create_custom_source(custom_source_parameters.c_str()); + auto create_custom_source = reinterpret_cast( + dlsym(custom_source_library, "openmc_create_source")); // check for any dlsym errors auto dlsym_error = dlerror(); if (dlsym_error) { + std::string error_msg = fmt::format("Couldn't open the openmc_create_source symbol: {}", dlsym_error); dlclose(custom_source_library); - fatal_error(fmt::format("Couldn't open the sample_source symbol: {}", dlsym_error)); + fatal_error(error_msg); } + // create a pointer to an instance of the CustomSource + custom_source = create_custom_source(custom_source_parameters); + #else fatal_error("Custom source libraries have not yet been implemented for " "non-POSIX systems"); @@ -409,7 +411,7 @@ void close_custom_source_library() Particle::Bank sample_custom_source_library(uint64_t* seed) { // sample from the instance of the CustomSource - return custom_source->sample_source(seed); + return custom_source->sample(seed); } void fill_source_bank_custom_source() diff --git a/tests/regression_tests/source_dlopen/source_sampling.cpp b/tests/regression_tests/source_dlopen/source_sampling.cpp index 529e3a547..ea74afdd9 100644 --- a/tests/regression_tests/source_dlopen/source_sampling.cpp +++ b/tests/regression_tests/source_dlopen/source_sampling.cpp @@ -7,7 +7,7 @@ class Source : openmc::CustomSource { - openmc::Particle::Bank sample_source(uint64_t *seed) + openmc::Particle::Bank sample(uint64_t *seed) { openmc::Particle::Bank particle; // wgt @@ -29,7 +29,7 @@ class Source : openmc::CustomSource // A function to create a unique pointer to an instance of this class when generated // via a plugin call using dlopen/dlsym. // You must have external C linkage here otherwise dlopen will not find the file -extern "C" std::unique_ptr openmc_create_source() +extern "C" std::unique_ptr openmc_create_source(std::string parameters) { - return std::unique_ptr (new Source()); + return std::make_unique(); } diff --git a/tests/regression_tests/source_parameterized_dlopen/parameterized_source_sampling.cpp b/tests/regression_tests/source_parameterized_dlopen/parameterized_source_sampling.cpp index 162164f01..3b0875bb0 100644 --- a/tests/regression_tests/source_parameterized_dlopen/parameterized_source_sampling.cpp +++ b/tests/regression_tests/source_parameterized_dlopen/parameterized_source_sampling.cpp @@ -1,18 +1,12 @@ #include "openmc/source.h" #include "openmc/particle.h" -class Source : public openmc::CustomSource -{ +class Source : public openmc::CustomSource { public: - double energy; - - Source(double energy) - { - this->energy = energy; - } + Source(double energy) : energy_(energy) { } // Samples from an instance of this class. - openmc::Particle::Bank sample_source(uint64_t* seed) + openmc::Particle::Bank sample(uint64_t* seed) { openmc::Particle::Bank particle; // wgt @@ -24,17 +18,21 @@ class Source : public openmc::CustomSource particle.r.z = 0.0; // angle particle.u = {1.0, 0.0, 0.0}; - particle.E = this->energy; + particle.E = this->energy_; particle.delayed_group = 0; return particle; } + + private: + double energy_; }; // A function to create a unique pointer to an instance of this class when generated // via a plugin call using dlopen/dlsym. // You must have external C linkage here otherwise dlopen will not find the file -extern "C" std::unique_ptr openmc_create_source(const char* parameter) +extern "C" std::unique_ptr openmc_create_source(std::string parameter) { - return std::unique_ptr (new Source(atof(parameter))); + double energy = std::stod(parameter); + return std::make_unique(energy); }