1 #ifndef OPENMC_DISTRIBUTION_SPATIAL_H
2 #define OPENMC_DISTRIBUTION_SPATIAL_H
3 
4 #include "pugixml.hpp"
5 
6 #include "openmc/distribution.h"
7 #include "openmc/position.h"
8 
9 namespace openmc {
10 
11 //==============================================================================
12 //! Probability density function for points in Euclidean space
13 //==============================================================================
14 
15 class SpatialDistribution {
16 public:
17   virtual ~SpatialDistribution() = default;
18 
19   //! Sample a position from the distribution
20   virtual Position sample(uint64_t* seed) const = 0;
21 };
22 
23 //==============================================================================
24 //! Distribution of points specified by independent distributions in x,y,z
25 //==============================================================================
26 
27 class CartesianIndependent : public SpatialDistribution {
28 public:
29   explicit CartesianIndependent(pugi::xml_node node);
30 
31   //! Sample a position from the distribution
32   //! \param seed Pseudorandom number seed pointer
33   //! \return Sampled position
34   Position sample(uint64_t* seed) const;
35 
36   // Observer pointers
x()37   Distribution* x() const { return x_.get(); }
y()38   Distribution* y() const { return y_.get(); }
z()39   Distribution* z() const { return z_.get(); }
40 private:
41   UPtrDist x_; //!< Distribution of x coordinates
42   UPtrDist y_; //!< Distribution of y coordinates
43   UPtrDist z_; //!< Distribution of z coordinates
44 };
45 
46 //==============================================================================
47 //! Distribution of points specified by cylindrical coordinates r,phi,z
48 //==============================================================================
49 
50 class CylindricalIndependent : public SpatialDistribution {
51 public:
52   explicit CylindricalIndependent(pugi::xml_node node);
53 
54   //! Sample a position from the distribution
55   //! \param seed Pseudorandom number seed pointer
56   //! \return Sampled position
57   Position sample(uint64_t* seed) const;
58 
r()59   Distribution* r() const { return r_.get(); }
phi()60   Distribution* phi() const { return phi_.get(); }
z()61   Distribution* z() const { return z_.get(); }
origin()62   Position origin() const { return origin_; }
63 private:
64   UPtrDist r_; //!< Distribution of r coordinates
65   UPtrDist phi_; //!< Distribution of phi coordinates
66   UPtrDist z_; //!< Distribution of z coordinates
67   Position origin_; //!< Cartesian coordinates of the cylinder center
68 };
69 
70 
71 //==============================================================================
72 //! Distribution of points specified by spherical coordinates r,theta,phi
73 //==============================================================================
74 
75 class SphericalIndependent : public SpatialDistribution {
76 public:
77   explicit SphericalIndependent(pugi::xml_node node);
78 
79   //! Sample a position from the distribution
80   //! \param seed Pseudorandom number seed pointer
81   //! \return Sampled position
82   Position sample(uint64_t* seed) const;
83 
r()84   Distribution* r() const { return r_.get(); }
theta()85   Distribution* theta() const { return theta_.get(); }
phi()86   Distribution* phi() const { return phi_.get(); }
origin()87   Position origin () const { return origin_; }
88 private:
89   UPtrDist r_; //!< Distribution of r coordinates
90   UPtrDist theta_; //!< Distribution of theta coordinates
91   UPtrDist phi_; //!< Distribution of phi coordinates
92   Position origin_; //!< Cartesian coordinates of the sphere center
93 };
94 
95 //==============================================================================
96 //! Uniform distribution of points over a box
97 //==============================================================================
98 
99 class SpatialBox : public SpatialDistribution {
100 public:
101   explicit SpatialBox(pugi::xml_node node, bool fission=false);
102 
103   //! Sample a position from the distribution
104   //! \param seed Pseudorandom number seed pointer
105   //! \return Sampled position
106   Position sample(uint64_t* seed) const;
107 
108   // Properties
only_fissionable()109   bool only_fissionable() const { return only_fissionable_; }
lower_left()110   Position lower_left() const { return lower_left_; }
upper_right()111   Position upper_right() const { return upper_right_; }
112 private:
113   Position lower_left_; //!< Lower-left coordinates of box
114   Position upper_right_; //!< Upper-right coordinates of box
115   bool only_fissionable_ {false}; //!< Only accept sites in fissionable region?
116 };
117 
118 //==============================================================================
119 //! Distribution at a single point
120 //==============================================================================
121 
122 class SpatialPoint : public SpatialDistribution {
123 public:
SpatialPoint()124   SpatialPoint() : r_{} { };
SpatialPoint(Position r)125   SpatialPoint(Position r) : r_{r} { };
126   explicit SpatialPoint(pugi::xml_node node);
127 
128   //! Sample a position from the distribution
129   //! \param seed Pseudorandom number seed pointer
130   //! \return Sampled position
131   Position sample(uint64_t* seed) const;
132 
r()133   Position r() const { return r_; }
134 private:
135   Position r_; //!< Single position at which sites are generated
136 };
137 
138 using UPtrSpace = unique_ptr<SpatialDistribution>;
139 
140 } // namespace openmc
141 
142 #endif // OPENMC_DISTRIBUTION_SPATIAL_H
143