diff --git a/docs/source/io_formats/settings.rst b/docs/source/io_formats/settings.rst index 09d7db1236..588b58b478 100644 --- a/docs/source/io_formats/settings.rst +++ b/docs/source/io_formats/settings.rst @@ -465,7 +465,7 @@ attributes/sub-elements: as complex as is required to define the source for your problem. The library has a few basic requirements: - * It must contain a class that inherits from ``openmc::CustomSource``; + * It must contain a class that inherits from ``openmc::Source``; * The class must implement a function called ``sample()``; * There must be an ``openmc_create_source()`` function that creates the source as a unique pointer. This function can be used to pass parameters through to diff --git a/docs/source/usersguide/settings.rst b/docs/source/usersguide/settings.rst index 340d4af00c..df22328e3a 100644 --- a/docs/source/usersguide/settings.rst +++ b/docs/source/usersguide/settings.rst @@ -194,9 +194,9 @@ below. #include "openmc/source.h" #include "openmc/particle.h" - class Source : public openmc::CustomSource + class CustomSource : public openmc::Source { - openmc::Particle::Bank sample(uint64_t* seed) + openmc::Particle::Bank sample(uint64_t* seed) const { openmc::Particle::Bank particle; // weight @@ -216,16 +216,16 @@ below. } }; - extern "C" std::unique_ptr openmc_create_source(std::string parameters) + extern "C" std::unique_ptr openmc_create_source(std::string parameters) { - return std::make_unique(); + return std::make_unique(); } The above source creates monodirectional 14.08 MeV neutrons that are distributed in a ring with a 3 cm radius. This routine is not particularly complex, but should serve as an example upon which to build more complicated sources. - .. note:: The source class must inherit from ``openmc::CustomSource`` and + .. note:: The source class must inherit from ``openmc::Source`` and implement a ``sample()`` function. .. note:: The ``openmc_create_source()`` function signature must be declared @@ -266,12 +266,12 @@ the source class when it is created: #include "openmc/source.h" #include "openmc/particle.h" - class Source : public openmc::CustomSource { + class CustomSource : public openmc::Source { public: - Source(double energy) : energy_{energy} { } + CustomSource(double energy) : energy_{energy} { } // Samples from an instance of this class. - openmc::Particle::Bank sample(uint64_t* seed) + openmc::Particle::Bank sample(uint64_t* seed) const { openmc::Particle::Bank particle; // weight @@ -293,9 +293,9 @@ the source class when it is created: double energy_; }; - extern "C" std::unique_ptr openmc_create_source(std::string parameter) { + extern "C" std::unique_ptr openmc_create_source(std::string parameter) { double energy = std::stod(parameter); - return std::make_unique(energy); + return std::make_unique(energy); } As with the basic custom source functionality, the custom source library diff --git a/examples/custom_source/source_ring.cpp b/examples/custom_source/source_ring.cpp index bc8a8a7f8d..a752216dce 100644 --- a/examples/custom_source/source_ring.cpp +++ b/examples/custom_source/source_ring.cpp @@ -5,9 +5,9 @@ #include "openmc/source.h" #include "openmc/particle.h" -class Source : public openmc::CustomSource +class RingSource : public openmc::Source { - openmc::Particle::Bank sample(uint64_t* seed) + openmc::Particle::Bank sample(uint64_t* seed) const { 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(std::string parameters) +extern "C" std::unique_ptr openmc_create_source(std::string parameters) { - return std::make_unique(); + 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 c88333e15b..9f913dfee3 100644 --- a/examples/parameterized_custom_source/parameterized_source_ring.cpp +++ b/examples/parameterized_custom_source/parameterized_source_ring.cpp @@ -6,14 +6,13 @@ #include "openmc/source.h" #include "openmc/particle.h" -class Source : public openmc::CustomSource -{ +class RingSource : public openmc::Source { public: - Source(double radius, double energy) : radius_(radius), energy_(energy) { } + RingSource(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(std::string parameters) + static std::unique_ptr from_string(std::string parameters) { std::unordered_map parameter_mapping; @@ -28,11 +27,11 @@ class Source : public openmc::CustomSource double radius = std::stod(parameter_mapping["radius"]); double energy = std::stod(parameter_mapping["energy"]); - return std::make_unique(radius, energy); + return std::make_unique(radius, energy); } // Samples from an instance of this class. - openmc::Particle::Bank sample(uint64_t* seed) + openmc::Particle::Bank sample(uint64_t* seed) const { openmc::Particle::Bank particle; // wgt @@ -60,7 +59,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(std::string parameters) +extern "C" std::unique_ptr openmc_create_source(std::string parameters) { - return Source::from_string(parameters); + return RingSource::from_string(parameters); } diff --git a/include/openmc/settings.h b/include/openmc/settings.h index 85ef1c71ea..74cbbc1328 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -59,8 +59,6 @@ extern std::string path_cross_sections; //!< path to cross_sections.xml extern std::string path_input; //!< directory where main .xml files resides extern std::string path_output; //!< directory where output files are written extern std::string path_particle_restart; //!< path to a particle restart file -extern std::string path_source; -extern std::string path_source_library; //!< path to the source shared object extern std::string path_sourcepoint; //!< path to a source file extern "C" std::string path_statepoint; //!< path to a statepoint file diff --git a/include/openmc/source.h b/include/openmc/source.h index 529cb1836e..12e8156992 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -19,32 +19,47 @@ namespace openmc { // Global variables //============================================================================== -class SourceDistribution; +class Source; namespace model { -extern std::vector external_sources; +extern std::vector> external_sources; } // namespace model //============================================================================== -//! External source distribution +//! Abstract source interface //============================================================================== -class SourceDistribution { +class Source { +public: + virtual ~Source() = default; + + // Methods that must be implemented + virtual Particle::Bank sample(uint64_t* seed) const = 0; + + // Methods that can be overridden + virtual double strength() const { return 1.0; } +}; + +//============================================================================== +//! Source composed of independent spatial, angle, and energy distributions +//============================================================================== + +class IndependentSource : public Source { public: // Constructors - SourceDistribution(UPtrSpace space, UPtrAngle angle, UPtrDist energy); - explicit SourceDistribution(pugi::xml_node node); + IndependentSource(UPtrSpace space, UPtrAngle angle, UPtrDist energy); + explicit IndependentSource(pugi::xml_node node); //! Sample from the external source distribution //! \param[inout] seed Pseudorandom seed pointer //! \return Sampled site - Particle::Bank sample(uint64_t* seed) const; + Particle::Bank sample(uint64_t* seed) const override; // Properties Particle::Type particle_type() const { return particle_; } - double strength() const { return strength_; } + double strength() const override { return strength_; } // Make observing pointers available SpatialDistribution* space() const { return space_.get(); } @@ -59,14 +74,45 @@ private: UPtrDist energy_; //!< Energy distribution }; -class CustomSource { - public: - virtual ~CustomSource() {} +//============================================================================== +//! Source composed of particles read from a file +//============================================================================== - virtual Particle::Bank sample(uint64_t* seed) = 0; +class FileSource : public Source { +public: + // Constructors + explicit FileSource(std::string path); + + // Methods + Particle::Bank sample(uint64_t* seed) const override; + +private: + std::vector sites_; //!< Source sites from a file }; -typedef std::unique_ptr create_custom_source_t(std::string parameters); +//============================================================================== +//! Wrapper for custom sources that manages opening/closing shared library +//============================================================================== + +class CustomSourceWrapper : public Source { +public: + // Constructors, destructors + CustomSourceWrapper(std::string path, std::string parameters); + ~CustomSourceWrapper(); + + // Defer implementation to custom source library + Particle::Bank sample(uint64_t* seed) const override + { + return custom_source_->sample(seed); + } + + double strength() const override { return custom_source_->strength(); } +private: + void* shared_library_; //!< library from dlopen + std::unique_ptr custom_source_; +}; + +typedef std::unique_ptr create_custom_source_t(std::string parameters); //============================================================================== // Functions @@ -81,18 +127,6 @@ extern "C" void initialize_source(); //! \return Sampled source site Particle::Bank sample_external_source(uint64_t* seed); -//! Sample a site from custom source library -Particle::Bank sample_custom_source_library(uint64_t* seed); - -//! Load custom source library -void load_custom_source_library(); - -//! Release custom source library -void close_custom_source_library(); - -//! Fill source bank at the end of a generation for dlopen based source simulation -void fill_source_bank_custom_source(); - void free_memory_source(); } // namespace openmc diff --git a/include/openmc/state_point.h b/include/openmc/state_point.h index 4a901ac2a2..c50ca355b8 100644 --- a/include/openmc/state_point.h +++ b/include/openmc/state_point.h @@ -2,17 +2,19 @@ #define OPENMC_STATE_POINT_H #include +#include #include "hdf5.h" #include "openmc/capi.h" +#include "openmc/particle.h" namespace openmc { void load_state_point(); void write_source_point(const char* filename); void write_source_bank(hid_t group_id); -void read_source_bank(hid_t group_id); +void read_source_bank(hid_t group_id, std::vector& sites, bool distribute); void write_tally_results_nr(hid_t file_id); void restart_set_keff(); diff --git a/src/settings.cpp b/src/settings.cpp index 8e402b7110..5a868d445b 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -73,8 +73,6 @@ std::string path_cross_sections; std::string path_input; std::string path_output; std::string path_particle_restart; -std::string path_source; -std::string path_source_library; std::string path_sourcepoint; std::string path_statepoint; @@ -421,17 +419,31 @@ void read_settings_xml() // Get point to list of elements and make sure there is at least one for (pugi::xml_node node : root.children("source")) { - model::external_sources.emplace_back(node); + if (check_for_node(node, "file")) { + auto path = get_node_value(node, "file", false, true); + model::external_sources.push_back(std::make_unique(path)); + } else if (check_for_node(node, "library")) { + // Get shared library path and parameters + auto path = get_node_value(node, "library", false, true); + std::string parameters; + if (check_for_node(node, "parameters")) { + parameters = get_node_value(node, "parameters", false, true); + } + + // Create custom source + model::external_sources.push_back(std::make_unique(path, parameters)); + } else { + model::external_sources.push_back(std::make_unique(node)); + } } // If no source specified, default to isotropic point source at origin with Watt spectrum if (model::external_sources.empty()) { - SourceDistribution source { + model::external_sources.push_back(std::make_unique( UPtrSpace{new SpatialPoint({0.0, 0.0, 0.0})}, UPtrAngle{new Isotropic()}, UPtrDist{new Watt(0.988e6, 2.249e-6)} - }; - model::external_sources.push_back(std::move(source)); + )); } // Check if we want to write out source diff --git a/src/simulation.cpp b/src/simulation.cpp index c95c0386c0..1e35adeeea 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -121,12 +121,6 @@ int openmc_simulation_init() } } - // If fixed source and using custom source library then need to load - if (settings::run_mode == RunMode::FIXED_SOURCE && - !settings::path_source_library.empty()) { - load_custom_source_library(); - } - // Display header if (mpi::master) { if (settings::run_mode == RunMode::FIXED_SOURCE) { @@ -173,12 +167,6 @@ int openmc_simulation_finalize() t->active_ = false; } - // If fixed source and using custom source library then need to close - if (settings::run_mode == RunMode::FIXED_SOURCE && - !settings::path_source_library.empty()) { - close_custom_source_library(); - } - // Stop timers and show timing statistics simulation::time_finalize.stop(); simulation::time_total.stop(); diff --git a/src/source.cpp b/src/source.cpp index 4f4ad117bb..87644f054d 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -39,27 +39,18 @@ namespace openmc { namespace model { -std::vector external_sources; +std::vector> external_sources; } -namespace { - -void* custom_source_library; -std::string custom_source_parameters; -std::unique_ptr custom_source; - -} - - //============================================================================== -// SourceDistribution implementation +// IndependentSource implementation //============================================================================== -SourceDistribution::SourceDistribution(UPtrSpace space, UPtrAngle angle, UPtrDist energy) +IndependentSource::IndependentSource(UPtrSpace space, UPtrAngle angle, UPtrDist energy) : space_{std::move(space)}, angle_{std::move(angle)}, energy_{std::move(energy)} { } -SourceDistribution::SourceDistribution(pugi::xml_node node) +IndependentSource::IndependentSource(pugi::xml_node node) { // Check for particle type if (check_for_node(node, "particle")) { @@ -81,24 +72,7 @@ SourceDistribution::SourceDistribution(pugi::xml_node node) // Check for external source file if (check_for_node(node, "file")) { - // Copy path of source file - settings::path_source = get_node_value(node, "file", false, true); - // Check if source file exists - if (!file_exists(settings::path_source)) { - fatal_error(fmt::format("Source file '{}' does not exist.", - settings::path_source)); - } - } else if (check_for_node(node, "library")) { - 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)); - } - - if (check_for_node(node, "parameters")) { - custom_source_parameters = get_node_value(node, "parameters", false, true); - } } else { // Spatial distribution for external source @@ -167,8 +141,7 @@ SourceDistribution::SourceDistribution(pugi::xml_node node) } } - -Particle::Bank SourceDistribution::sample(uint64_t* seed) const +Particle::Bank IndependentSource::sample(uint64_t* seed) const { Particle::Bank site; @@ -185,10 +158,10 @@ Particle::Bank SourceDistribution::sample(uint64_t* seed) const // Sample spatial distribution site.r = space_->sample(seed); - double xyz[] {site.r.x, site.r.y, site.r.z}; // Now search to see if location exists in geometry int32_t cell_index, instance; + double xyz[] {site.r.x, site.r.y, site.r.z}; int err = openmc_find_cell(xyz, &cell_index, &instance); found = (err != OPENMC_E_GEOMETRY); @@ -256,6 +229,94 @@ Particle::Bank SourceDistribution::sample(uint64_t* seed) const return site; } +//============================================================================== +// FileSource implementation +//============================================================================== + +FileSource::FileSource(std::string path) +{ + // Check if source file exists + if (!file_exists(path)) { + fatal_error(fmt::format("Source file '{}' does not exist.", path)); + } + + // Read the source from a binary file instead of sampling from some + // assumed source distribution + write_message(6, "Reading source file from {}...", path); + + // Open the binary file + hid_t file_id = file_open(path, 'r', true); + + // Check to make sure this is a source file + std::string filetype; + read_attribute(file_id, "filetype", filetype); + if (filetype != "source" && filetype != "statepoint") { + fatal_error("Specified starting source file not a source file type."); + } + + // Read in the source particles + read_source_bank(file_id, sites_, false); + + // Close file + file_close(file_id); +} + +Particle::Bank FileSource::sample(uint64_t* seed) const +{ + size_t i_site = sites_.size()*prn(seed); + return sites_[i_site]; +} + +//============================================================================== +// CustomSourceWrapper implementation +//============================================================================== + +CustomSourceWrapper::CustomSourceWrapper(std::string path, std::string parameters) +{ +#ifdef HAS_DYNAMIC_LINKING + // Open the library + shared_library_ = dlopen(path.c_str(), RTLD_LAZY); + if (!shared_library_) { + fatal_error("Couldn't open source library " + path); + } + + // reset errors + dlerror(); + + // get the function to create the custom source from the library + auto create_custom_source = reinterpret_cast( + dlsym(shared_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(shared_library_); + fatal_error(error_msg); + } + + // create a pointer to an instance of the custom source + custom_source_ = create_custom_source(parameters); + +#else + fatal_error("Custom source libraries have not yet been implemented for " + "non-POSIX systems"); +#endif +} + +CustomSourceWrapper::~CustomSourceWrapper() +{ + // Make sure custom source is cleared before closing shared library + if (custom_source_.get()) custom_source_.reset(); + +#ifdef HAS_DYNAMIC_LINKING + dlclose(shared_library_); +#else + fatal_error("Custom source libraries have not yet been implemented for " + "non-POSIX systems"); +#endif +} + //============================================================================== // Non-member functions //============================================================================== @@ -264,47 +325,16 @@ void initialize_source() { write_message("Initializing source particles...", 5); - if (!settings::path_source.empty()) { - // Read the source from a binary file instead of sampling from some - // assumed source distribution + // Generation source sites from specified distribution in user input + #pragma omp parallel for + 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; + uint64_t seed = init_seed(id, STREAM_SOURCE); - write_message(6, "Reading source file from {}...", settings::path_source); - - // Open the binary file - hid_t file_id = file_open(settings::path_source, 'r', true); - - // Read the file type - std::string filetype; - read_attribute(file_id, "filetype", filetype); - - // Check to make sure this is a source file - if (filetype != "source" && filetype != "statepoint") { - fatal_error("Specified starting source file not a source file type."); - } - - // Read in the source bank - read_source_bank(file_id); - - // Close file - file_close(file_id); - } else if (!settings::path_source_library.empty()) { - - write_message(6, "Sampling library source {}...", settings::path_source); - - fill_source_bank_custom_source(); - - } else { - // Generation source sites from specified distribution in user input - #pragma omp parallel for - 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; - uint64_t seed = init_seed(id, STREAM_SOURCE); - - // sample external source distribution - simulation::source_bank[i] = sample_external_source(&seed); - } + // sample external source distribution + simulation::source_bank[i] = sample_external_source(&seed); } // Write out initial source @@ -319,15 +349,10 @@ void initialize_source() Particle::Bank sample_external_source(uint64_t* seed) { - // return values from custom source if using - if (!settings::path_source_library.empty()) { - return sample_custom_source_library(seed); - } - // Determine total source strength double total_strength = 0.0; for (auto& s : model::external_sources) - total_strength += s.strength(); + total_strength += s->strength(); // Sample from among multiple source distributions int i = 0; @@ -335,13 +360,13 @@ Particle::Bank sample_external_source(uint64_t* seed) double xi = prn(seed)*total_strength; double c = 0.0; for (; i < model::external_sources.size(); ++i) { - c += model::external_sources[i].strength(); + c += model::external_sources[i]->strength(); if (xi < c) break; } } // Sample source site from i-th source distribution - Particle::Bank site {model::external_sources[i].sample(seed)}; + Particle::Bank site {model::external_sources[i]->sample(seed)}; // If running in MG, convert site.E to group if (!settings::run_CE) { @@ -358,80 +383,4 @@ void free_memory_source() model::external_sources.clear(); } -void load_custom_source_library() -{ -#ifdef HAS_DYNAMIC_LINKING - - // Open the library - custom_source_library = dlopen(settings::path_source_library.c_str(), RTLD_LAZY); - if (!custom_source_library) { - fatal_error("Couldn't open source library " + settings::path_source_library); - } - - // reset errors - dlerror(); - - // get the function to create the CustomSource from the library - 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(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"); -#endif -} - -void close_custom_source_library() -{ - if (custom_source.get()) { - // Make sure the custom source is destroyed before we close it's libary. - custom_source.reset(); - } - -#ifdef HAS_DYNAMIC_LINKING - dlclose(custom_source_library); -#else - fatal_error("Custom source libraries have not yet been implemented for " - "non-POSIX systems"); -#endif -} - -Particle::Bank sample_custom_source_library(uint64_t* seed) -{ - // sample from the instance of the CustomSource - return custom_source->sample(seed); -} - -void fill_source_bank_custom_source() -{ - // Load the custom library - load_custom_source_library(); - - // Generation source sites from specified distribution in the - // library source - for (int64_t i = 0; i < simulation::work_per_rank; ++i) { - // initialize random number seed - 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 custom library source - simulation::source_bank[i] = sample_custom_source_library(&seed); - } - - // release the library - close_custom_source_library(); -} - } // namespace openmc diff --git a/src/state_point.cpp b/src/state_point.cpp index e3484d1a25..66706a676f 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -485,11 +485,11 @@ void load_state_point() + "...", 5); // Open source file - file_id = file_open(settings::path_source.c_str(), 'r', true); + file_id = file_open(settings::path_sourcepoint.c_str(), 'r', true); } // Read source - read_source_bank(file_id); + read_source_bank(file_id, simulation::source_bank, true); } @@ -653,43 +653,51 @@ write_source_bank(hid_t group_id) } -void read_source_bank(hid_t group_id) +void read_source_bank(hid_t group_id, std::vector& sites, bool distribute) { hid_t banktype = h5banktype(); // Open the dataset hid_t dset = H5Dopen(group_id, "source_bank", H5P_DEFAULT); - - // Create another data space but for each proc individually - hsize_t dims[] {static_cast(simulation::work_per_rank)}; - hid_t memspace = H5Screate_simple(1, dims, nullptr); - - // Make sure source bank is big enough hid_t dspace = H5Dget_space(dset); - hsize_t dims_all[1]; - H5Sget_simple_extent_dims(dspace, dims_all, nullptr); - if (simulation::work_index[mpi::n_procs] > dims_all[0]) { - fatal_error("Number of source sites in source file is less " - "than number of source particles per generation."); - } + hsize_t n_sites; + H5Sget_simple_extent_dims(dspace, &n_sites, nullptr); - // Select hyperslab for each process - hsize_t start[] {static_cast(simulation::work_index[mpi::rank])}; - H5Sselect_hyperslab(dspace, H5S_SELECT_SET, start, nullptr, dims, nullptr); + // Make sure vector is big enough in case where we're reading entire source on + // each process + if (!distribute) sites.resize(n_sites); + + hid_t memspace; + if (distribute) { + if (simulation::work_index[mpi::n_procs] > n_sites) { + fatal_error("Number of source sites in source file is less " + "than number of source particles per generation."); + } + + // Create another data space but for each proc individually + hsize_t n_sites_local = simulation::work_per_rank; + memspace = H5Screate_simple(1, &n_sites_local, nullptr); + + // Select hyperslab for each process + hsize_t offset = simulation::work_index[mpi::rank]; + H5Sselect_hyperslab(dspace, H5S_SELECT_SET, &offset, nullptr, &n_sites_local, nullptr); + } else { + memspace = H5S_ALL; + } #ifdef PHDF5 // Read data in parallel hid_t plist = H5Pcreate(H5P_DATASET_XFER); H5Pset_dxpl_mpio(plist, H5FD_MPIO_COLLECTIVE); - H5Dread(dset, banktype, memspace, dspace, plist, simulation::source_bank.data()); + H5Dread(dset, banktype, memspace, dspace, plist, sites.data()); H5Pclose(plist); #else - H5Dread(dset, banktype, memspace, dspace, H5P_DEFAULT, simulation::source_bank.data()); + H5Dread(dset, banktype, memspace, dspace, H5P_DEFAULT, sites.data()); #endif // Close all ids H5Sclose(dspace); - H5Sclose(memspace); + if (distribute) H5Sclose(memspace); H5Dclose(dset); H5Tclose(banktype); } diff --git a/src/tallies/tally.cpp b/src/tallies/tally.cpp index d5cc7dfb6f..038bcec649 100644 --- a/src/tallies/tally.cpp +++ b/src/tallies/tally.cpp @@ -632,7 +632,7 @@ void Tally::accumulate() double total_source = 0.0; if (settings::run_mode == RunMode::FIXED_SOURCE) { for (const auto& s : model::external_sources) { - total_source += s.strength(); + total_source += s->strength(); } } else { total_source = 1.0; diff --git a/tests/regression_tests/source_dlopen/source_sampling.cpp b/tests/regression_tests/source_dlopen/source_sampling.cpp index ea74afdd97..8eaf6265cc 100644 --- a/tests/regression_tests/source_dlopen/source_sampling.cpp +++ b/tests/regression_tests/source_dlopen/source_sampling.cpp @@ -5,16 +5,16 @@ #include "openmc/source.h" #include "openmc/particle.h" -class Source : openmc::CustomSource +class CustomSource : public openmc::Source { - openmc::Particle::Bank sample(uint64_t *seed) + openmc::Particle::Bank sample(uint64_t *seed) const { openmc::Particle::Bank particle; // wgt particle.particle = openmc::Particle::Type::neutron; particle.wgt = 1.0; // position - + particle.r.x = 0.; particle.r.y = 0.; particle.r.z = 0.; @@ -22,14 +22,14 @@ class Source : openmc::CustomSource particle.u = {1.0, 0.0, 0.0}; particle.E = 14.08e6; particle.delayed_group = 0; - return particle; + return particle; } }; // 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(std::string parameters) +extern "C" std::unique_ptr openmc_create_source(std::string parameters) { - return std::make_unique(); + return std::make_unique(); } diff --git a/tests/regression_tests/source_file/results_true.dat b/tests/regression_tests/source_file/results_true.dat index 4ab7993d88..44c422eeff 100644 --- a/tests/regression_tests/source_file/results_true.dat +++ b/tests/regression_tests/source_file/results_true.dat @@ -1,2 +1,2 @@ k-combined: -2.939525E-01 6.311780E-03 +3.080726E-01 9.554124E-03 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 3b0875bb03..da7d70e378 100644 --- a/tests/regression_tests/source_parameterized_dlopen/parameterized_source_sampling.cpp +++ b/tests/regression_tests/source_parameterized_dlopen/parameterized_source_sampling.cpp @@ -1,12 +1,12 @@ #include "openmc/source.h" #include "openmc/particle.h" -class Source : public openmc::CustomSource { +class CustomSource : public openmc::Source { public: - Source(double energy) : energy_(energy) { } + CustomSource(double energy) : energy_(energy) { } // Samples from an instance of this class. - openmc::Particle::Bank sample(uint64_t* seed) + openmc::Particle::Bank sample(uint64_t* seed) const { openmc::Particle::Bank particle; // wgt @@ -31,8 +31,8 @@ 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(std::string parameter) +extern "C" std::unique_ptr openmc_create_source(std::string parameter) { double energy = std::stod(parameter); - return std::make_unique(energy); + return std::make_unique(energy); }