2026-02-03 01:23:24 -06:00
|
|
|
#include <cmath> // for M_PI
|
2020-08-21 12:05:43 +01:00
|
|
|
#include <memory> // for unique_ptr
|
2020-08-03 14:24:17 +01:00
|
|
|
#include <unordered_map>
|
2020-07-31 11:41:43 +01:00
|
|
|
|
2026-02-03 01:23:24 -06:00
|
|
|
#include "openmc/particle.h"
|
2020-07-31 11:41:43 +01:00
|
|
|
#include "openmc/random_lcg.h"
|
|
|
|
|
#include "openmc/source.h"
|
|
|
|
|
|
2020-10-23 13:45:28 -05:00
|
|
|
class RingSource : public openmc::Source {
|
2026-02-03 01:23:24 -06:00
|
|
|
public:
|
|
|
|
|
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<RingSource> from_string(std::string parameters)
|
|
|
|
|
{
|
|
|
|
|
std::unordered_map<std::string, std::string> parameter_mapping;
|
2020-08-03 17:38:12 +01:00
|
|
|
|
2026-02-03 01:23:24 -06:00
|
|
|
std::stringstream ss(parameters);
|
|
|
|
|
std::string parameter;
|
|
|
|
|
while (std::getline(ss, parameter, ',')) {
|
|
|
|
|
parameter.erase(0, parameter.find_first_not_of(' '));
|
|
|
|
|
std::string key = parameter.substr(0, parameter.find_first_of('='));
|
|
|
|
|
std::string value =
|
|
|
|
|
parameter.substr(parameter.find_first_of('=') + 1, parameter.length());
|
|
|
|
|
parameter_mapping[key] = value;
|
2020-07-31 11:41:43 +01:00
|
|
|
}
|
2020-08-28 09:49:36 +01:00
|
|
|
|
2026-02-03 01:23:24 -06:00
|
|
|
double radius = std::stod(parameter_mapping["radius"]);
|
|
|
|
|
double energy = std::stod(parameter_mapping["energy"]);
|
|
|
|
|
return std::make_unique<RingSource>(radius, energy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Samples from an instance of this class.
|
|
|
|
|
openmc::SourceSite sample(uint64_t* seed) const
|
|
|
|
|
{
|
|
|
|
|
openmc::SourceSite particle;
|
|
|
|
|
// particle type
|
|
|
|
|
particle.particle = openmc::ParticleType::neutron();
|
|
|
|
|
// position
|
|
|
|
|
double angle = 2.0 * M_PI * openmc::prn(seed);
|
|
|
|
|
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_;
|
|
|
|
|
|
|
|
|
|
return particle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
double radius_;
|
|
|
|
|
double energy_;
|
2020-07-31 11:41:43 +01:00
|
|
|
};
|
|
|
|
|
|
2026-02-03 01:23:24 -06:00
|
|
|
// 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<RingSource> openmc_create_source(
|
|
|
|
|
std::string parameters)
|
2020-08-21 12:05:43 +01:00
|
|
|
{
|
2020-10-23 13:45:28 -05:00
|
|
|
return RingSource::from_string(parameters);
|
2020-08-03 17:38:12 +01:00
|
|
|
}
|