BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
FTDistributions2D.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Sample/Correlations/FTDistributions2D.cpp
6 //! @brief Implements interface class IFTDistribution2D and children thereof.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
16 #include "Base/Math/Bessel.h"
17 #include "Base/Math/IntegratorGK.h"
18 #include <limits>
19 
20 // ************************************************************************************************
21 // interface IFTDistribution1D
22 // ************************************************************************************************
23 
24 IFTDistribution2D::IFTDistribution2D(const NodeMeta& meta, const std::vector<double>& PValues)
25  : INode(nodeMetaUnion({{"OmegaX", "nm", "Half-width along x axis", 0, INF, 1.},
26  {"OmegaY", "nm", "Half-width along y axis", 0, INF, 1.},
27  {"Gamma", "rad",
28  "direct-space orientation with respect to the first lattice vector",
29  -M_PI_2, +M_PI_2, 0}},
30  meta),
31  PValues)
32  , m_omega_x(m_P[0])
33  , m_omega_y(m_P[1])
34  , m_gamma(m_P[2])
35 {
36 }
37 
38 double IFTDistribution2D::sumsq(double qx, double qy) const
39 {
40  return qx * qx * m_omega_x * m_omega_x + qy * qy * m_omega_y * m_omega_y;
41 }
42 
43 // ************************************************************************************************
44 // class FTDistribution2DCauchy
45 // ************************************************************************************************
46 
48  : IFTDistribution2D({"FTDistribution2DCauchy", "class_tooltip", {}}, P)
49 {
50 }
51 
52 FTDistribution2DCauchy::FTDistribution2DCauchy(double omega_x, double omega_y, double gamma)
53  : FTDistribution2DCauchy(std::vector<double>{omega_x, omega_y, gamma})
54 {
55 }
56 
58 {
60 }
61 
62 double FTDistribution2DCauchy::evaluate(double qx, double qy) const
63 {
64  return std::pow(1.0 + sumsq(qx, qy), -1.5);
65 }
66 
67 std::unique_ptr<IDistribution2DSampler> FTDistribution2DCauchy::createSampler() const
68 {
69  return std::make_unique<Distribution2DCauchySampler>(m_omega_x, m_omega_y);
70 }
71 
72 // ************************************************************************************************
73 // class FTDistribution2DGauss
74 // ************************************************************************************************
75 
77  : IFTDistribution2D({"FTDistribution2DGauss", "class_tooltip", {}}, P)
78 {
79 }
80 
81 FTDistribution2DGauss::FTDistribution2DGauss(double omega_x, double omega_y, double gamma)
82  : FTDistribution2DGauss(std::vector<double>{omega_x, omega_y, gamma})
83 {
84 }
85 
87 {
89 }
90 
91 double FTDistribution2DGauss::evaluate(double qx, double qy) const
92 {
93  return std::exp(-sumsq(qx, qy) / 2);
94 }
95 
96 std::unique_ptr<IDistribution2DSampler> FTDistribution2DGauss::createSampler() const
97 {
98  return std::make_unique<Distribution2DGaussSampler>(m_omega_x, m_omega_y);
99 }
100 
101 // ************************************************************************************************
102 // class FTDistribution2DGate
103 // ************************************************************************************************
104 
105 FTDistribution2DGate::FTDistribution2DGate(const std::vector<double> P)
106  : IFTDistribution2D({"FTDistribution2DGate", "class_tooltip", {}}, P)
107 {
108 }
109 
110 FTDistribution2DGate::FTDistribution2DGate(double omega_x, double omega_y, double gamma)
111  : FTDistribution2DGate(std::vector<double>{omega_x, omega_y, gamma})
112 {
113 }
114 
116 {
118 }
119 
120 double FTDistribution2DGate::evaluate(double qx, double qy) const
121 {
122  double scaled_q = std::sqrt(sumsq(qx, qy));
123  return Math::Bessel::J1c(scaled_q) * 2.0;
124 }
125 
126 std::unique_ptr<IDistribution2DSampler> FTDistribution2DGate::createSampler() const
127 {
128  return std::make_unique<Distribution2DGateSampler>(m_omega_x, m_omega_y);
129 }
130 
131 // ************************************************************************************************
132 // class FTDistribution2DCone
133 // ************************************************************************************************
134 
135 FTDistribution2DCone::FTDistribution2DCone(const std::vector<double> P)
136  : IFTDistribution2D({"FTDistribution2DCone", "class_tooltip", {}}, P)
137 {
138 }
139 
140 FTDistribution2DCone::FTDistribution2DCone(double omega_x, double omega_y, double gamma)
141  : FTDistribution2DCone(std::vector<double>{omega_x, omega_y, gamma})
142 {
143 }
144 
146 {
148 }
149 
150 double FTDistribution2DCone::evaluate(double qx, double qy) const
151 {
152  double scaled_q = std::sqrt(sumsq(qx, qy));
153  if (scaled_q < std::numeric_limits<double>::epsilon())
154  return 1.0 - 3.0 * scaled_q * scaled_q / 40.0;
155  // second part of the integrand: \f$u^2\cdot J_0(u)\f$
156  double integral = RealIntegrator().integrate(
157  [](double x) -> double { return x * x * Math::Bessel::J0(x); }, 0.0, scaled_q);
158  return 6.0 * (Math::Bessel::J1c(scaled_q) - integral / scaled_q / scaled_q / scaled_q);
159 }
160 
161 std::unique_ptr<IDistribution2DSampler> FTDistribution2DCone::createSampler() const
162 {
163  return std::make_unique<Distribution2DConeSampler>(m_omega_x, m_omega_y);
164 }
165 
166 // ************************************************************************************************
167 // class FTDistribution2DVoigt
168 // ************************************************************************************************
169 
172  {"FTDistribution2DVoigt",
173  "class_tooltip",
174  {{"Eta", "", "balances between Gauss (eta=0) and Cauchy (eta=1) limiting cases", -INF,
175  +INF, 0}}},
176  P)
177  , m_eta(m_P[3])
178 {
179 }
180 
181 FTDistribution2DVoigt::FTDistribution2DVoigt(double omega_x, double omega_y, double gamma,
182  double eta)
183  : FTDistribution2DVoigt(std::vector<double>{omega_x, omega_y, gamma, eta})
184 {
185 }
186 
188 {
190 }
191 
192 double FTDistribution2DVoigt::evaluate(double qx, double qy) const
193 {
194  double sum_sq = sumsq(qx, qy);
195  return m_eta * std::exp(-sum_sq / 2) + (1.0 - m_eta) * std::pow(1.0 + sum_sq, -1.5);
196 }
197 
198 std::unique_ptr<IDistribution2DSampler> FTDistribution2DVoigt::createSampler() const
199 {
200  // TODO Need to implement 2D Voigt
201 
202  std::ostringstream ostr;
203  ostr << "FTDistribution2DVoigt::createSampler() -> Error in class initialization";
204  ostr << "\n\n Has not been implemented yet...stay tuned!";
205  throw std::runtime_error(ostr.str());
206 }
Defines Bessel functions in namespace Math.
#define M_PI_2
Definition: Constants.h:45
Defines interface class IFTDistribution2D, and children thereof.
NodeMeta nodeMetaUnion(const std::vector< ParaMeta > &base, const NodeMeta &other)
Definition: INode.cpp:23
const double INF
Definition: INode.h:25
Defines classes RealIntegrator, ComplexIntegrator.
Two-dimensional Cauchy distribution in Fourier space; corresponds to a normalized exp(-r) in real spa...
FTDistribution2DCauchy(const std::vector< double > P)
double evaluate(double qx, double qy) const final
evaluate Fourier transformed distribution for q in X,Y coordinates the original distribution (in real...
FTDistribution2DCauchy * clone() const final
std::unique_ptr< IDistribution2DSampler > createSampler() const final
Two-dimensional cone distribution in Fourier space; corresponds to 1-r if r<1 (and 0 otherwise) in re...
std::unique_ptr< IDistribution2DSampler > createSampler() const final
FTDistribution2DCone(const std::vector< double > P)
FTDistribution2DCone * clone() const final
double evaluate(double qx, double qy) const final
evaluate Fourier transformed distribution for q in X,Y coordinates the original distribution (in real...
Two-dimensional gate distribution in Fourier space; corresponds to normalized constant if r<1 (and 0 ...
FTDistribution2DGate(const std::vector< double > P)
FTDistribution2DGate * clone() const final
double evaluate(double qx, double qy) const final
evaluate Fourier transformed distribution for q in X,Y coordinates the original distribution (in real...
std::unique_ptr< IDistribution2DSampler > createSampler() const final
Two-dimensional Gauss distribution in Fourier space; corresponds to normalized exp(-r^2/2) in real sp...
FTDistribution2DGauss(const std::vector< double > P)
std::unique_ptr< IDistribution2DSampler > createSampler() const final
FTDistribution2DGauss * clone() const final
double evaluate(double qx, double qy) const final
evaluate Fourier transformed distribution for q in X,Y coordinates the original distribution (in real...
Two-dimensional Voigt distribution in Fourier space; corresponds to eta*Gauss + (1-eta)*Cauchy.
FTDistribution2DVoigt(const std::vector< double > P)
double evaluate(double qx, double qy) const final
evaluate Fourier transformed distribution for q in X,Y coordinates the original distribution (in real...
FTDistribution2DVoigt * clone() const final
std::unique_ptr< IDistribution2DSampler > createSampler() const final
Interface for two-dimensional distributions in Fourier space.
const double & m_gamma
const double & m_omega_y
const double & m_omega_x
IFTDistribution2D(const NodeMeta &meta, const std::vector< double > &PValues)
double sumsq(double qx, double qy) const
double gamma() const
Base class for tree-like structures containing parameterized objects.
Definition: INode.h:49
To integrate a real function of a real variable.
Definition: IntegratorGK.h:28
double integrate(const std::function< double(double)> &f, double lmin, double lmax)
double J0(double x)
Bessel function of the first kind and order 0.
Definition: Bessel.cpp:162
double J1c(double x)
Bessel function J1(x)/x.
Definition: Bessel.cpp:172
Definition: filesystem.h:81
Metadata of one model node.
Definition: INode.h:38