Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mesh Source Class #2759

Merged
merged 73 commits into from
Dec 2, 2023
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
3a13013
Refactored source distribution creation to reuse code for a new MeshS…
pshriwise Dec 28, 2022
8a2307a
Updating name of high-level sampling method
pshriwise Dec 28, 2022
8cbdc09
Updating name of high-level sampling method
pshriwise Dec 28, 2022
dcfbd1e
Adding Python class and XML infrastructure
pshriwise May 3, 2023
f5a1cf4
Changing C++ side to use IndependentSource rather than independent so…
pshriwise May 11, 2023
b3ae8f8
Small adjustments to get source read working
pshriwise May 11, 2023
7d94b4a
Small adjustments to get source read working
pshriwise May 11, 2023
0243953
Fix attribute check in reading MeshSource node
pshriwise May 11, 2023
4799ddb
Make sure all necessary info gets to the XML file
pshriwise May 11, 2023
2861964
Corrections after rebase
pshriwise May 11, 2023
be946c0
Updates to get RegularMesh working for sampling
pshriwise May 12, 2023
a6ff4cc
Updates to get RegularMesh working for sampling
pshriwise May 12, 2023
5cb5dd8
Getting rid of old mesh functions from rebase
pshriwise May 12, 2023
4785e0c
Getting rid of old mesh functions from rebase
pshriwise May 12, 2023
f9aa88d
Refactoring Source creation
pshriwise May 12, 2023
8e7ba81
Adding missing import
pshriwise May 12, 2023
44a46d2
Adding cylindrical and spherical sampling
pshriwise May 12, 2023
6e4e56c
Removing assert
pshriwise May 12, 2023
1f39b28
Using parameter argument. Fixing odd type hint.
pshriwise May 12, 2023
9c618c8
Mesh src file formatting
pshriwise Sep 9, 2023
41ceb8f
Some quick fixes after rebase
pshriwise Sep 12, 2023
004c123
Adding from_xml_element for MeshSource
pshriwise Sep 22, 2023
f341c2c
Adding an inital test for mesh sources
pshriwise Sep 22, 2023
a8a4be3
Updating check for source type
pshriwise Sep 22, 2023
b744406
Correcting detection of a mesh source
pshriwise Sep 22, 2023
71a43ed
Adding proper test check and explanation of test
pshriwise Sep 22, 2023
119e5f3
Improvement to mesh source test
pshriwise Sep 23, 2023
e5bb413
Write type and strength in the base source class
pshriwise Sep 25, 2023
0ede245
Refactor of source class constructors s.t. they all accept an XML node
pshriwise Sep 25, 2023
bf82136
More informative error messages
pshriwise Sep 25, 2023
ea08318
Altering some aspects of the MeshSource class
pshriwise Sep 25, 2023
66fdcf8
Adding IO format documentation for the mesh source type
pshriwise Sep 25, 2023
eecd0ec
Improving mesh source test by using indices ordering for setting sources
pshriwise Sep 25, 2023
609f0a1
Handling case where all source strengths are zero
pshriwise Sep 27, 2023
8f11fb3
Allowing construction of DiscreteIndex with gsl::span. Adding new con…
pshriwise Sep 27, 2023
c481fdf
MeshSpatial object is not only on the C++ side.
pshriwise Sep 27, 2023
8c9305e
Expand test to include cylindrical mesh
pshriwise Sep 27, 2023
d73c002
Use total strength from DiscreteIndex data member
pshriwise Sep 28, 2023
5ab09b7
Fix in StructuredMesh::sample_element
paulromano Oct 18, 2023
52d0431
Patching up some I/O methods
pshriwise Oct 19, 2023
807fb3f
Test updates
pshriwise Oct 19, 2023
a11949e
rm print
pshriwise Oct 24, 2023
2e58d77
Removing mesh source test from unit test dir
pshriwise Oct 25, 2023
1879e16
Cleaning up mesh indexing after reordering PR
pshriwise Nov 6, 2023
a0e2b47
Add some roundtrip testing
pshriwise Nov 6, 2023
7f220f8
Updating format check triggers
pshriwise Nov 6, 2023
827b755
Applying formatter
pshriwise Nov 6, 2023
06f7b3a
Update openmc/stats/multivariate.py
pshriwise Nov 6, 2023
c1f7034
Remove redundant to_xml_element, small fixes in MeshSource
paulromano Nov 2, 2023
95f7c8d
Don't allow MeshSources.sources to be empty
paulromano Nov 2, 2023
b22a710
Add type hints to MeshSource
paulromano Nov 3, 2023
e1a2495
Don't require populate_xml_element to call super
paulromano Nov 9, 2023
1300b01
Switch to to_xml_element for mesh source element sources
pshriwise Nov 9, 2023
7eabd79
Allow any source type to be used in the MeshSource (C++).
pshriwise Nov 9, 2023
21405df
Add check for source normalization method on mesh sources
pshriwise Nov 9, 2023
4d2f221
Only display warning about spatial distributions for IndependentSourc…
pshriwise Nov 9, 2023
ab2c5eb
Move MeshSource test to uni tests directory and add tmpdir fixture
pshriwise Nov 9, 2023
b4369f7
Adding a test for a file source
pshriwise Nov 9, 2023
1f5b99c
applying C++ style guide
pshriwise Nov 9, 2023
1a755c7
Adding tmate debug option
pshriwise Nov 15, 2023
3ab9ff5
Fix openmc.lib use in test_source_mesh.py
paulromano Nov 27, 2023
71e6630
Comment cleanup
pshriwise Nov 28, 2023
f0b5a34
Making public data member placement consistent
pshriwise Nov 29, 2023
9c16efe
Back to SourceBase for settings.source CheckedList
pshriwise Nov 29, 2023
ddbd73c
I don't think we need the parent element argument for MeshSpatial
pshriwise Nov 29, 2023
66b6baa
Replacing old tests for MeshSpatial that I clobbered accidentally
pshriwise Nov 29, 2023
5f0f958
Update mesh source io_formats documentation
paulromano Dec 2, 2023
b2f8bd1
Utilize UnitSphereDistribution::create in source.cpp
paulromano Dec 2, 2023
fa6edfd
Style, documentation fixed
paulromano Dec 2, 2023
8fbd212
Use uniform_distribution in sample_element methods
paulromano Dec 2, 2023
05902a2
Small changes in MeshSource tests
paulromano Dec 2, 2023
77ceb62
Swap order of arguments in sample_element
paulromano Dec 2, 2023
709b952
Make sure MeshSource writing updates mesh_memo
paulromano Dec 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/format-check.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
name: C++ Format Check

on: pull_request
on:
# allow workflow to be run manually
workflow_dispatch:

pull_request:
branches:
- develop
- master

jobs:
cpp-linter:
Expand Down
6 changes: 5 additions & 1 deletion docs/source/io_formats/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,8 @@ attributes/sub-elements:
*Default*: 1.0

:type:
Indicator of source type. One of ``independent``, ``file``, or ``compiled``.
Indicator of source type. One of ``independent``, ``file``, ``compiled``, or ``mesh``.
The type of the source will be determined by this attribute if it is present.

:particle:
The source particle type, either ``neutron`` or ``photon``.
Expand Down Expand Up @@ -664,6 +665,9 @@ attributes/sub-elements:

*Default*: false

:source:
For mesh sources, a set of sources that will be applied to each element.

.. _univariate:

Univariate Probability Distributions
Expand Down
7 changes: 4 additions & 3 deletions include/openmc/distribution.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <cstddef> // for size_t

#include "pugixml.hpp"
#include <gsl/gsl-lite.hpp>

#include "openmc/constants.h"
#include "openmc/memory.h" // for unique_ptr
Expand Down Expand Up @@ -43,9 +44,9 @@ class DiscreteIndex {
public:
DiscreteIndex() {};
DiscreteIndex(pugi::xml_node node);
DiscreteIndex(const double* p, int n);
DiscreteIndex(gsl::span<const double> p);

void assign(const double* p, int n);
void assign(gsl::span<const double> p);

//! Sample a value from the distribution
//! \param seed Pseudorandom number seed pointer
Expand Down Expand Up @@ -77,7 +78,7 @@ class DiscreteIndex {
class Discrete : public Distribution {
public:
explicit Discrete(pugi::xml_node node);
Discrete(const double* x, const double* p, int n);
Discrete(const double* x, const double* p, size_t n);

//! Sample a value from the distribution
//! \param seed Pseudorandom number seed pointer
Expand Down
2 changes: 2 additions & 0 deletions include/openmc/distribution_multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class UnitSphereDistribution {
explicit UnitSphereDistribution(pugi::xml_node node);
virtual ~UnitSphereDistribution() = default;

static unique_ptr<UnitSphereDistribution> create(pugi::xml_node node);

//! Sample a direction from the distribution
//! \param seed Pseudorandom number seed pointer
//! \return Direction sampled
Expand Down
15 changes: 14 additions & 1 deletion include/openmc/distribution_spatial.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class SpatialDistribution {

//! Sample a position from the distribution
virtual Position sample(uint64_t* seed) const = 0;

static unique_ptr<SpatialDistribution> create(pugi::xml_node node);
};

//==============================================================================
Expand Down Expand Up @@ -102,16 +104,27 @@ class SphericalIndependent : public SpatialDistribution {
class MeshSpatial : public SpatialDistribution {
public:
explicit MeshSpatial(pugi::xml_node node);
explicit MeshSpatial(int32_t mesh_id, gsl::span<const double> strengths);

//! Sample a position from the distribution
//! \param seed Pseudorandom number seed pointer
//! \return Sampled position
Position sample(uint64_t* seed) const override;

const Mesh* mesh() const { return model::meshes.at(mesh_idx_).get(); }
//! Sample the mesh for an element and position within that element
//! \param seed Pseudorandom number seed pointer
//! \return Sampled element index and position within that element
std::pair<int32_t, Position> sample_mesh(uint64_t* seed) const;

//! For unstructured meshes, ensure that elements are all linear tetrahedra
void check_element_types() const;

// Accessors
const Mesh* mesh() const { return model::meshes.at(mesh_idx_).get(); }
int32_t n_sources() const { return this->mesh()->n_bins(); }

double total_strength() { return this->elem_idx_dist_.integral(); }

private:
int32_t mesh_idx_ {C_NONE};
DiscreteIndex elem_idx_dist_; //!< Distribution of
Expand Down
62 changes: 51 additions & 11 deletions include/openmc/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "pugixml.hpp"
#include "xtensor/xtensor.hpp"

#include "openmc/error.h"
#include "openmc/memory.h" // for unique_ptr
#include "openmc/particle.h"
#include "openmc/position.h"
Expand Down Expand Up @@ -81,12 +82,12 @@ class Mesh {
//! Return a position in the local coordinates of the mesh
virtual Position local_coords(const Position& r) const { return r; };

//! Sample a mesh volume using a certain seed
//! Sample mesh element
//
//! \param[in] seed Seed to use for random sampling
//! \param[in] bin Bin value of the tet sampled
//! \return sampled position within tet
virtual Position sample(uint64_t* seed, int32_t bin) const = 0;
virtual Position sample_element(uint64_t* seed, int32_t bin) const = 0;

//! Determine which bins were crossed by a particle
//
Expand Down Expand Up @@ -183,7 +184,12 @@ class StructuredMesh : public Mesh {
}
};

Position sample(uint64_t* seed, int32_t bin) const override;
Position sample_element(uint64_t* seed, int32_t bin) const override
{
return sample_element(seed, get_indices_from_bin(bin));
};

virtual Position sample_element(uint64_t* seed, const MeshIndex& ijk) const;

int get_bin(Position r) const override;

Expand Down Expand Up @@ -240,6 +246,30 @@ class StructuredMesh : public Mesh {
//! \param[in] i Direction index
virtual int get_index_in_direction(double r, int i) const = 0;

//! Get the coordinate for the mesh grid boundary in the positive direction
//!
//! \param[in] ijk Array of mesh indices
//! \param[in] i Direction index
virtual double positive_grid_boundary(const MeshIndex& ijk, int i) const
{
auto msg =
fmt::format("Attempting to call positive_grid_boundary on a {} mesh.",
get_mesh_type());
fatal_error(msg);
};

//! Get the coordinate for the mesh grid boundary in the negative direction
//!
//! \param[in] ijk Array of mesh indices
//! \param[in] i Direction index
virtual double negative_grid_boundary(const MeshIndex& ijk, int i) const
{
auto msg =
fmt::format("Attempting to call negative_grid_boundary on a {} mesh.",
get_mesh_type());
fatal_error(msg);
};

//! Get the closest distance from the coordinate r to the grid surface
//! in i direction that bounds mesh cell ijk and that is larger than l
//! The coordinate r does not have to be inside the mesh cell ijk. In
Expand Down Expand Up @@ -322,18 +352,17 @@ class RegularMesh : public StructuredMesh {

void to_hdf5(hid_t group) const override;

// New methods
//! Get the coordinate for the mesh grid boundary in the positive direction
//!
//! \param[in] ijk Array of mesh indices
//! \param[in] i Direction index
double positive_grid_boundary(const MeshIndex& ijk, int i) const;
double positive_grid_boundary(const MeshIndex& ijk, int i) const override;

//! Get the coordinate for the mesh grid boundary in the negative direction
//!
//! \param[in] ijk Array of mesh indices
//! \param[in] i Direction index
double negative_grid_boundary(const MeshIndex& ijk, int i) const;
double negative_grid_boundary(const MeshIndex& ijk, int i) const override;

//! Count number of bank sites in each mesh bin / energy bin
//
Expand Down Expand Up @@ -373,18 +402,17 @@ class RectilinearMesh : public StructuredMesh {

void to_hdf5(hid_t group) const override;

// New methods
//! Get the coordinate for the mesh grid boundary in the positive direction
//!
//! \param[in] ijk Array of mesh indices
//! \param[in] i Direction index
double positive_grid_boundary(const MeshIndex& ijk, int i) const;
double positive_grid_boundary(const MeshIndex& ijk, int i) const override;

//! Get the coordinate for the mesh grid boundary in the negative direction
//!
//! \param[in] ijk Array of mesh indices
//! \param[in] i Direction index
double negative_grid_boundary(const MeshIndex& ijk, int i) const;
double negative_grid_boundary(const MeshIndex& ijk, int i) const override;

//! Return the volume for a given mesh index
double volume(const MeshIndex& ijk) const override;
Expand All @@ -410,6 +438,8 @@ class CylindricalMesh : public PeriodicStructuredMesh {

static const std::string mesh_type;

Position sample_element(uint64_t* seed, const MeshIndex& ijk) const override;

MeshDistance distance_to_grid_boundary(const MeshIndex& ijk, int i,
const Position& r0, const Direction& u, double l) const override;

Expand All @@ -422,6 +452,11 @@ class CylindricalMesh : public PeriodicStructuredMesh {

array<vector<double>, 3> grid_;

// grid accessors
double r(int i) const { return grid_[0][i]; }
double phi(int i) const { return grid_[1][i]; }
double z(int i) const { return grid_[2][i]; }

int set_grid();

private:
Expand Down Expand Up @@ -466,6 +501,8 @@ class SphericalMesh : public PeriodicStructuredMesh {

static const std::string mesh_type;

Position sample_element(uint64_t* seed, const MeshIndex& ijk) const override;

MeshDistance distance_to_grid_boundary(const MeshIndex& ijk, int i,
const Position& r0, const Direction& u, double l) const override;

Expand All @@ -474,6 +511,9 @@ class SphericalMesh : public PeriodicStructuredMesh {

void to_hdf5(hid_t group) const override;

double r(int i) const { return grid_[0][i]; }
double theta(int i) const { return grid_[1][i]; }
double phi(int i) const { return grid_[2][i]; }
array<vector<double>, 3> grid_;

int set_grid();
Expand Down Expand Up @@ -621,7 +661,7 @@ class MOABMesh : public UnstructuredMesh {

// Overridden Methods

Position sample(uint64_t* seed, int32_t bin) const override;
Position sample_element(uint64_t* seed, int32_t bin) const override;

void bins_crossed(Position r0, Position r1, const Direction& u,
vector<int>& bins, vector<double>& lengths) const override;
Expand Down Expand Up @@ -789,7 +829,7 @@ class LibMesh : public UnstructuredMesh {
void bins_crossed(Position r0, Position r1, const Direction& u,
vector<int>& bins, vector<double>& lengths) const override;

Position sample(uint64_t* seed, int32_t bin) const override;
Position sample_element(uint64_t* seed, int32_t bin) const override;

int get_bin(Position r) const override;

Expand Down
47 changes: 43 additions & 4 deletions include/openmc/source.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class Source {

// Methods that can be overridden
virtual double strength() const { return 1.0; }

static unique_ptr<Source> create(pugi::xml_node node);
};

//==============================================================================
Expand Down Expand Up @@ -101,12 +103,13 @@ class IndependentSource : public Source {
class FileSource : public Source {
public:
// Constructors
explicit FileSource(std::string path);
explicit FileSource(const vector<SourceSite>& sites) : sites_ {sites} {}
explicit FileSource(pugi::xml_node node);
explicit FileSource(const std::string& path);

// Methods
SourceSite sample(uint64_t* seed) const override;

void load_sites_from_file(
const std::string& path); //!< Load source sites from file
private:
vector<SourceSite> sites_; //!< Source sites from a file
};
Expand All @@ -118,7 +121,7 @@ class FileSource : public Source {
class CompiledSourceWrapper : public Source {
public:
// Constructors, destructors
CompiledSourceWrapper(std::string path, std::string parameters);
CompiledSourceWrapper(pugi::xml_node node);
~CompiledSourceWrapper();

// Defer implementation to custom source library
Expand All @@ -129,13 +132,49 @@ class CompiledSourceWrapper : public Source {

double strength() const override { return compiled_source_->strength(); }

void setup(const std::string& path, const std::string& parameters);

private:
void* shared_library_; //!< library from dlopen
unique_ptr<Source> compiled_source_;
};

typedef unique_ptr<Source> create_compiled_source_t(std::string parameters);

//==============================================================================
//! Mesh-based source with different distributions for each element
//==============================================================================

class MeshSource : public Source {
public:
// Constructors
explicit MeshSource(pugi::xml_node node);

//! Sample from the external source distribution
//! \param[inout] seed Pseudorandom seed pointer
//! \return Sampled site
SourceSite sample(uint64_t* seed) const override;

// Properties
ParticleType particle_type() const { return particle_; }
double strength() const
{
return space_->total_strength();
} //!< Total source strength

// Accessors
const IndependentSource& source(int32_t i) const
{
return sources_.size() == 1 ? sources_[0] : sources_[i];
}

private:
// Data members
ParticleType particle_ {ParticleType::neutron}; //!< Type of particle emitted
unique_ptr<MeshSpatial> space_; //!< Mesh spatial
vector<IndependentSource> sources_; //!< Source distributions
pshriwise marked this conversation as resolved.
Show resolved Hide resolved
};

//==============================================================================
// Functions
//==============================================================================
Expand Down
Loading