Class and sampling function of serialized source

Generates a source ring in a similar manner to the existing
custom_source example.
Allows the radius and energy to be defined via a serialized
representation of the source.
Builds using CMake.
This commit is contained in:
Dan Short 2020-07-31 11:41:43 +01:00
parent 1b60181ddb
commit 6b193882c3
2 changed files with 66 additions and 0 deletions

View file

@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
project(openmc_sources CXX)
add_library(serialized_source SHARED serialized_source_ring.cpp)
find_package(OpenMC REQUIRED)
if (OpenMC_FOUND)
message(STATUS "Found OpenMC: ${OpenMC_DIR}")
endif()
target_link_libraries(serialized_source OpenMC::libopenmc)

View file

@ -0,0 +1,58 @@
#include <cmath> // for M_PI
#include "openmc/random_lcg.h"
#include "openmc/source.h"
#include "openmc/particle.h"
#include "pugixml.hpp"
class SerialisedSource {
protected:
double radius_;
double energy_;
// Protect the constructor so that the class can only be created by serialisation.
SerialisedSource(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_; }
// The deserialisation routine populates the constructor from well defined elements
// in the input XML document.
static SerialisedSource from_xml(char* serialised_source) {
pugi::xml_document doc;
doc.load_file(serialised_source);
pugi::xml_node root_node = doc.root().child("Source");
double radius = root_node.child("Radius").text().as_double();
double energy = root_node.child("Energy").text().as_double();
return SerialisedSource(radius, energy);
}
};
// you must have external C linkage here otherwise
// dlopen will not find the file
extern "C" openmc::Particle::Bank sample_source(uint64_t* seed, char* serialised_source)
{
SerialisedSource source = SerialisedSource::from_xml(serialised_source);
openmc::Particle::Bank particle;
// wgt
particle.particle = openmc::Particle::Type::neutron;
particle.wgt = 1.0;
// position
double angle = 2. * M_PI * openmc::prn(seed);
double radius = source.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 = source.energy();
particle.delayed_group = 0;
return particle;
}