Pass serialization as parameter attribute

Changes the implementation of the serialization to be on an attribute of
the source XML element within settings.xml. This removes the need for a
new file containing the serialization.
Parameters are provided as a key-value string, separated by a comma and
a space, although the implementation can change this is required.
Change example values to align with existing custom_source to make
comparisons easier.
Update documentation to be consistent.
This commit is contained in:
Dan Short 2020-08-03 14:24:17 +01:00
parent 1de3d9ddf9
commit 8bb10563c1
11 changed files with 84 additions and 92 deletions

View file

@ -11,13 +11,13 @@ library, you can run:
After this, you can build the model by running `python build_xml.py`. In the XML
files that are created, you should see a reference to build/libserialized_source.so,
the custom source library that was built by CMake, and the path to the serialized
representation of the source in serialized_source.xml. The model is also set up with a
mesh tally of the flux, so once you run `openmc`, you will get a statepoint file
with the tally results in it. Running `python show_flux.py` will pull in the
results from the statepoint file and display them. If all worked well, you
should see a ring "imprint" as well as a higher flux to the right side (since
the custom source has all particles moving in the positive x direction).
the custom source library that was built by CMake, and the serialized representation
of the source in the parameters attribute. The model is also set up with a mesh tally
of the flux, so once you run `openmc`, you will get a statepoint file with the tally
results in it. Running `python show_flux.py` will pull in the results from the
statepoint file and display them. If all worked well, you should see a ring "imprint"
as well as a higher flux to the right side (since the custom source has all particles
moving in the positive x direction).
Once built, you can edit the serialized_source.xml file to change the radius of the
sampled ring or the energy of the sampled particles.
Once built, you can edit the parameters attribute on the source to change the radius of
the sampled ring or the energy of the sampled particles.

View file

@ -1,14 +1,5 @@
import openmc
# Define the serialized source
serialized_source = """<Source>
<Radius>1.5</Radius>
<Energy>1e3</Energy>
</Source>
"""
with open('serialized_source.xml', 'w') as f:
f.write(serialized_source)
# Create a single material
iron = openmc.Material()
iron.set_density('g/cm3', 5.0)
@ -29,7 +20,7 @@ settings.batches = 10
settings.particles = 1000
source = openmc.Source()
source.library = 'build/libserialized_source.so'
source.serialization = 'serialized_source.xml'
source.parameters = 'radius=3.0, energy=14.08e6'
settings.source = source
settings.export_to_xml()

View file

@ -1,9 +1,9 @@
#include <cmath> // for M_PI
#include <unordered_map>
#include "openmc/random_lcg.h"
#include "openmc/source.h"
#include "openmc/particle.h"
#include "pugixml.hpp"
class SerializedSource {
protected:
@ -21,24 +21,26 @@ class SerializedSource {
double radius() { return radius_; }
double energy() { return energy_; }
// The deserialisation routine populates the constructor from well defined elements
// in the input XML document.
// Note that the source will have already been read from file, so what will be passed
// in here is a string-like serialized value (not the path to the serialized value).
static SerializedSource from_xml(char* serialized_source) {
pugi::xml_document doc;
doc.load_string(serialized_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 SerializedSource(radius, energy);
static SerializedSource from_string(const char* parameters) {
std::unordered_map<std::string, std::string> parameter_mapping;
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;
}
return SerializedSource(std::stod(parameter_mapping["radius"]), std::stod(parameter_mapping["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* serialized_source) {
SerializedSource source = SerializedSource::from_xml(serialized_source);
extern "C" openmc::Particle::Bank sample_source(uint64_t* seed, const char* parameters) {
SerializedSource source = SerializedSource::from_string(parameters);
openmc::Particle::Bank particle;
// wgt