diff --git a/examples/python/custom_source/CMakeLists.txt b/examples/python/custom_source/CMakeLists.txt new file mode 100644 index 0000000000..9498176944 --- /dev/null +++ b/examples/python/custom_source/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.3 FATAL_ERROR) +project(openmc_sources CXX) +add_library(source SHARED source_ring.cpp) +find_package(OpenMC REQUIRED) +if (OpenMC_FOUND) + message(STATUS "Found OpenMC: ${OpenMC_DIR}") +endif() +target_link_libraries(source OpenMC::libopenmc) diff --git a/examples/python/custom_source/build_xml.py b/examples/python/custom_source/build_xml.py new file mode 100644 index 0000000000..a0817d4223 --- /dev/null +++ b/examples/python/custom_source/build_xml.py @@ -0,0 +1,36 @@ +import openmc + +# Create a single material +iron = openmc.Material() +iron.set_density('g/cm3', 5.0) +iron.add_element('Fe', 1.0) +mats = openmc.Materials([iron]) +mats.export_to_xml() + +# Create a 5 cm x 5 cm box filled with iron +box = openmc.model.rectangular_prism(10.0, 10.0, boundary_type='vacuum') +cell = openmc.Cell(fill=iron, region=box) +geometry = openmc.Geometry([cell]) +geometry.export_to_xml() + +# Tell OpenMC we're going to use our custom source +settings = openmc.Settings() +settings.run_mode = 'fixed source' +settings.batches = 10 +settings.particles = 1000 +source = openmc.Source() +source.library = 'build/libsource.so' +settings.source = source +settings.export_to_xml() + +# Finally, define a mesh tally so that we can see the resulting flux +mesh = openmc.RegularMesh() +mesh.lower_left = (-5.0, -5.0) +mesh.upper_right = (5.0, 5.0) +mesh.dimension = (50, 50) + +tally = openmc.Tally() +tally.filters = [openmc.MeshFilter(mesh)] +tally.scores = ['flux'] +tallies = openmc.Tallies([tally]) +tallies.export_to_xml() diff --git a/examples/python/custom_source/show_flux.py b/examples/python/custom_source/show_flux.py new file mode 100644 index 0000000000..9c49e1978c --- /dev/null +++ b/examples/python/custom_source/show_flux.py @@ -0,0 +1,18 @@ +import matplotlib.pyplot as plt +import openmc + +# Get the flux from the statepoint +with openmc.StatePoint('statepoint.10.h5') as sp: + flux = sp.tallies[1].mean + flux.shape = (50, 50) + +# Plot the flux +fig, ax = plt.subplots() +ax.imshow(flux, origin='lower', extent=(-5.0, 5.0, -5.0, 5.0)) +ax.set_xlabel('x [cm]') +ax.set_ylabel('y [cm]') +plt.show() + +# 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)) diff --git a/examples/python/custom_source/source_ring.cpp b/examples/python/custom_source/source_ring.cpp new file mode 100644 index 0000000000..d68122dd75 --- /dev/null +++ b/examples/python/custom_source/source_ring.cpp @@ -0,0 +1,26 @@ +#include // for M_PI + +#include "openmc/random_lcg.h" +#include "openmc/source.h" +#include "openmc/particle.h" + +// you must have external C linkage here otherwise +// dlopen will not find the file +extern "C" openmc::Particle::Bank sample_source(uint64_t* seed) +{ + 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 = 3.0; + 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 = 14.08e6; + particle.delayed_group = 0; + return particle; +}