Repository navigation
Expand file tree
/
Copy pathdistribution_multi.h
More file actions
142 lines (110 loc) · 4.96 KB
/
Copy pathdistribution_multi.h
File metadata and controls
142 lines (110 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef DISTRIBUTION_MULTI_H
#define DISTRIBUTION_MULTI_H
#include "openmc/memory.h"
#include "pugixml.hpp"
#include "openmc/distribution.h"
#include "openmc/error.h"
#include "openmc/position.h"
namespace openmc {
//==============================================================================
//! Probability density function for points on the unit sphere. Extensions of
//! this type are used to sample angular distributions for starting sources
//==============================================================================
class UnitSphereDistribution {
public:
UnitSphereDistribution() {};
explicit UnitSphereDistribution(Direction u) : u_ref_ {u} {};
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 (sampled Direction, sample weight)
virtual std::pair<Direction, double> sample(uint64_t* seed) const = 0;
//! Evaluate the probability density for a given direction
//! \param[in] u Direction on the unit sphere
//! \return Probability density at the given direction
virtual double evaluate(Direction u) const
{
fatal_error("evaluate not available for this UnitSphereDistribution type");
}
Direction u_ref_ {0.0, 0.0, 1.0}; //!< reference direction
};
//==============================================================================
//! Explicit distribution of polar and azimuthal angles
//==============================================================================
class PolarAzimuthal : public UnitSphereDistribution {
public:
PolarAzimuthal(Direction u, UPtrDist mu, UPtrDist phi);
explicit PolarAzimuthal(pugi::xml_node node);
//! Sample a direction from the distribution
//! \param seed Pseudorandom number seed pointer
//! \return (sampled Direction, sample weight)
std::pair<Direction, double> sample(uint64_t* seed) const override;
//! Sample a direction and return evaluation of the PDF for biased sampling.
//! Note that bias distributions are intended to return unit-weight samples.
//! \param seed Pseudorandom number seed points
//! \return (sampled Direction, value of the PDF at this Direction)
std::pair<Direction, double> sample_as_bias(uint64_t* seed) const;
//! Evaluate the probability density for a given direction
//! \param[in] u Direction on the unit sphere
//! \return Probability density at the given direction
double evaluate(Direction u) const override;
// Observing pointers
Distribution* mu() const { return mu_.get(); }
Distribution* phi() const { return phi_.get(); }
private:
//! Common sampling implementation
//! \param seed Pseudorandom number seed pointer
//! \param return_pdf If true, return PDF evaluation; if false, return
//! importance weight
//! \return (sampled Direction, weight or PDF value)
std::pair<Direction, double> sample_impl(
uint64_t* seed, bool return_pdf) const;
Direction v_ref_ {1.0, 0.0, 0.0}; //!< reference direction
Direction w_ref_;
UPtrDist mu_; //!< Distribution of polar angle
UPtrDist phi_; //!< Distribution of azimuthal angle
};
//==============================================================================
//! Uniform distribution on the unit sphere
//==============================================================================
Direction isotropic_direction(uint64_t* seed);
class Isotropic : public UnitSphereDistribution {
public:
Isotropic() {};
explicit Isotropic(pugi::xml_node node);
//! Sample a direction from the distribution
//! \param seed Pseudorandom number seed pointer
//! \return (sampled direction, sample weight)
std::pair<Direction, double> sample(uint64_t* seed) const override;
//! Evaluate the probability density for a given direction
//! \param[in] u Direction on the unit sphere
//! \return Probability density at the given direction
double evaluate(Direction u) const override;
// Set or get bias distribution
void set_bias(std::unique_ptr<PolarAzimuthal> bias)
{
bias_ = std::move(bias);
}
const PolarAzimuthal* bias() const { return bias_.get(); }
protected:
// Biasing distribution
unique_ptr<PolarAzimuthal> bias_;
};
//==============================================================================
//! Monodirectional distribution
//==============================================================================
class Monodirectional : public UnitSphereDistribution {
public:
Monodirectional(Direction u) : UnitSphereDistribution {u} {};
explicit Monodirectional(pugi::xml_node node)
: UnitSphereDistribution {node} {};
//! Sample a direction from the distribution
//! \param seed Pseudorandom number seed pointer
//! \return (sampled direction, sample weight)
std::pair<Direction, double> sample(uint64_t* seed) const override;
};
using UPtrAngle = unique_ptr<UnitSphereDistribution>;
} // namespace openmc
#endif // DISTRIBUTION_MULTI_H