OpenMC/include/openmc/distribution_spatial.h
Patrick Shriwise e0d03812b9
Mesh Source Class (#2759)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
Co-authored-by: Jonathan Shimwell <drshimwell@gmail.com>
2023-12-02 17:35:23 +00:00

183 lines
6.4 KiB
C++

#ifndef OPENMC_DISTRIBUTION_SPATIAL_H
#define OPENMC_DISTRIBUTION_SPATIAL_H
#include "pugixml.hpp"
#include "openmc/distribution.h"
#include "openmc/mesh.h"
#include "openmc/position.h"
namespace openmc {
//==============================================================================
//! Probability density function for points in Euclidean space
//==============================================================================
class SpatialDistribution {
public:
virtual ~SpatialDistribution() = default;
//! Sample a position from the distribution
virtual Position sample(uint64_t* seed) const = 0;
static unique_ptr<SpatialDistribution> create(pugi::xml_node node);
};
//==============================================================================
//! Distribution of points specified by independent distributions in x,y,z
//==============================================================================
class CartesianIndependent : public SpatialDistribution {
public:
explicit CartesianIndependent(pugi::xml_node node);
//! Sample a position from the distribution
//! \param seed Pseudorandom number seed pointer
//! \return Sampled position
Position sample(uint64_t* seed) const override;
// Observer pointers
Distribution* x() const { return x_.get(); }
Distribution* y() const { return y_.get(); }
Distribution* z() const { return z_.get(); }
private:
UPtrDist x_; //!< Distribution of x coordinates
UPtrDist y_; //!< Distribution of y coordinates
UPtrDist z_; //!< Distribution of z coordinates
};
//==============================================================================
//! Distribution of points specified by cylindrical coordinates r,phi,z
//==============================================================================
class CylindricalIndependent : public SpatialDistribution {
public:
explicit CylindricalIndependent(pugi::xml_node node);
//! Sample a position from the distribution
//! \param seed Pseudorandom number seed pointer
//! \return Sampled position
Position sample(uint64_t* seed) const override;
Distribution* r() const { return r_.get(); }
Distribution* phi() const { return phi_.get(); }
Distribution* z() const { return z_.get(); }
Position origin() const { return origin_; }
private:
UPtrDist r_; //!< Distribution of r coordinates
UPtrDist phi_; //!< Distribution of phi coordinates
UPtrDist z_; //!< Distribution of z coordinates
Position origin_; //!< Cartesian coordinates of the cylinder center
};
//==============================================================================
//! Distribution of points specified by spherical coordinates r,cos_theta,phi
//==============================================================================
class SphericalIndependent : public SpatialDistribution {
public:
explicit SphericalIndependent(pugi::xml_node node);
//! Sample a position from the distribution
//! \param seed Pseudorandom number seed pointer
//! \return Sampled position
Position sample(uint64_t* seed) const override;
Distribution* r() const { return r_.get(); }
Distribution* cos_theta() const { return cos_theta_.get(); }
Distribution* phi() const { return phi_.get(); }
Position origin() const { return origin_; }
private:
UPtrDist r_; //!< Distribution of r coordinates
UPtrDist cos_theta_; //!< Distribution of cos_theta coordinates
UPtrDist phi_; //!< Distribution of phi coordinates
Position origin_; //!< Cartesian coordinates of the sphere center
};
//==============================================================================
//! Distribution of points within a mesh
//==============================================================================
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;
//! 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
//!< mesh element indices
};
//==============================================================================
//! Uniform distribution of points over a box
//==============================================================================
class SpatialBox : public SpatialDistribution {
public:
explicit SpatialBox(pugi::xml_node node, bool fission = false);
//! Sample a position from the distribution
//! \param seed Pseudorandom number seed pointer
//! \return Sampled position
Position sample(uint64_t* seed) const override;
// Properties
bool only_fissionable() const { return only_fissionable_; }
Position lower_left() const { return lower_left_; }
Position upper_right() const { return upper_right_; }
private:
Position lower_left_; //!< Lower-left coordinates of box
Position upper_right_; //!< Upper-right coordinates of box
bool only_fissionable_ {false}; //!< Only accept sites in fissionable region?
};
//==============================================================================
//! Distribution at a single point
//==============================================================================
class SpatialPoint : public SpatialDistribution {
public:
SpatialPoint() : r_ {} {};
SpatialPoint(Position r) : r_ {r} {};
explicit SpatialPoint(pugi::xml_node node);
//! Sample a position from the distribution
//! \param seed Pseudorandom number seed pointer
//! \return Sampled position
Position sample(uint64_t* seed) const override;
Position r() const { return r_; }
private:
Position r_; //!< Single position at which sites are generated
};
using UPtrSpace = unique_ptr<SpatialDistribution>;
} // namespace openmc
#endif // OPENMC_DISTRIBUTION_SPATIAL_H