BornAgain  1.18.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 scattering at grazing incidence
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/Types/Exceptions.h"
17 #include "Base/Utils/Integrator.h"
19 #include <limits>
20 
21 // ************************************************************************** //
22 // interface IFTDistribution1D
23 // ************************************************************************** //
24 
25 IFTDistribution2D::IFTDistribution2D(const NodeMeta& meta, const std::vector<double>& PValues)
26  : INode(nodeMetaUnion({{"OmegaX", "nm", "Half-width along x axis", 0, INF, 1.},
27  {"OmegaY", "nm", "Half-width along y axis", 0, INF, 1.},
28  {"Gamma", "rad",
29  "direct-space orientation with respect to the first lattice vector",
30  -M_PI_2, +M_PI_2, 0}},
31  meta),
32  PValues),
33  m_omega_x(m_P[0]), m_omega_y(m_P[1]), m_gamma(m_P[2])
34 {
35 }
36 
37 double IFTDistribution2D::sumsq(double qx, double qy) const
38 {
39  return qx * qx * m_omega_x * m_omega_x + qy * qy * m_omega_y * m_omega_y;
40 }
41 
42 // ************************************************************************** //
43 // class FTDistribution2DCauchy
44 // ************************************************************************** //
45 
47  : IFTDistribution2D({"FTDistribution2DCauchy", "class_tooltip", {}}, P)
48 {
49 }
50 
51 FTDistribution2DCauchy::FTDistribution2DCauchy(double omega_x, double omega_y, double gamma)
52  : FTDistribution2DCauchy(std::vector<double>{omega_x, omega_y, gamma})
53 {
54 }
55 
57 {
59 }
60 
61 double FTDistribution2DCauchy::evaluate(double qx, double qy) const
62 {
63  return std::pow(1.0 + sumsq(qx, qy), -1.5);
64 }
65 
66 std::unique_ptr<IDistribution2DSampler> FTDistribution2DCauchy::createSampler() const
67 {
68  return std::make_unique<Distribution2DCauchySampler>(m_omega_x, m_omega_y);
69 }
70 
71 // ************************************************************************** //
72 // class FTDistribution2DGauss
73 // ************************************************************************** //
74 
76  : IFTDistribution2D({"FTDistribution2DGauss", "class_tooltip", {}}, P)
77 {
78 }
79 
80 FTDistribution2DGauss::FTDistribution2DGauss(double omega_x, double omega_y, double gamma)
81  : FTDistribution2DGauss(std::vector<double>{omega_x, omega_y, gamma})
82 {
83 }
84 
86 {
88 }
89 
90 double FTDistribution2DGauss::evaluate(double qx, double qy) const
91 {
92  return std::exp(-sumsq(qx, qy) / 2);
93 }
94 
95 std::unique_ptr<IDistribution2DSampler> FTDistribution2DGauss::createSampler() const
96 {
97  return std::make_unique<Distribution2DGaussSampler>(m_omega_x, m_omega_y);
98 }
99 
100 // ************************************************************************** //
101 // class FTDistribution2DGate
102 // ************************************************************************** //
103 
104 FTDistribution2DGate::FTDistribution2DGate(const std::vector<double> P)
105  : IFTDistribution2D({"FTDistribution2DGate", "class_tooltip", {}}, P)
106 {
107 }
108 
109 FTDistribution2DGate::FTDistribution2DGate(double omega_x, double omega_y, double gamma)
110  : FTDistribution2DGate(std::vector<double>{omega_x, omega_y, gamma})
111 {
112 }
113 
115 {
117 }
118 
119 double FTDistribution2DGate::evaluate(double qx, double qy) const
120 {
121  double scaled_q = std::sqrt(sumsq(qx, qy));
122  return MathFunctions::Bessel_J1c(scaled_q) * 2.0;
123 }
124 
125 std::unique_ptr<IDistribution2DSampler> FTDistribution2DGate::createSampler() const
126 {
127  return std::make_unique<Distribution2DGateSampler>(m_omega_x, m_omega_y);
128 }
129 
130 // ************************************************************************** //
131 // class FTDistribution2DCone
132 // ************************************************************************** //
133 
134 FTDistribution2DCone::FTDistribution2DCone(const std::vector<double> P)
135  : IFTDistribution2D({"FTDistribution2DCone", "class_tooltip", {}}, P)
136 {
137 }
138 
139 FTDistribution2DCone::FTDistribution2DCone(double omega_x, double omega_y, double gamma)
140  : FTDistribution2DCone(std::vector<double>{omega_x, omega_y, gamma})
141 {
142 }
143 
145 {
147 }
148 
149 double FTDistribution2DCone::evaluate(double qx, double qy) const
150 {
151  double scaled_q = std::sqrt(sumsq(qx, qy));
152  if (scaled_q < std::numeric_limits<double>::epsilon())
153  return 1.0 - 3.0 * scaled_q * scaled_q / 40.0;
154  // second part of the integrand: \f$u^2\cdot J_0(u)\f$
155  double integral = RealIntegrator().integrate(
156  [](double x) -> double { return x * x * MathFunctions::Bessel_J0(x); }, 0.0, scaled_q);
157  return 6.0 * (MathFunctions::Bessel_J1c(scaled_q) - integral / scaled_q / scaled_q / scaled_q);
158 }
159 
160 std::unique_ptr<IDistribution2DSampler> FTDistribution2DCone::createSampler() const
161 {
162  return std::make_unique<Distribution2DConeSampler>(m_omega_x, m_omega_y);
163 }
164 
165 // ************************************************************************** //
166 // class FTDistribution2DVoigt
167 // ************************************************************************** //
168 
171  {"FTDistribution2DVoigt",
172  "class_tooltip",
173  {{"Eta", "", "balances between Gauss (eta=0) and Cauchy (eta=1) limiting cases", -INF,
174  +INF, 0}}},
175  P),
176  m_eta(m_P[3])
177 {
178 }
179 
180 FTDistribution2DVoigt::FTDistribution2DVoigt(double omega_x, double omega_y, double gamma,
181  double eta)
182  : FTDistribution2DVoigt(std::vector<double>{omega_x, omega_y, gamma, eta})
183 {
184 }
185 
187 {
189 }
190 
191 double FTDistribution2DVoigt::evaluate(double qx, double qy) const
192 {
193  double sum_sq = sumsq(qx, qy);
194  return m_eta * std::exp(-sum_sq / 2) + (1.0 - m_eta) * std::pow(1.0 + sum_sq, -1.5);
195 }
196 
197 std::unique_ptr<IDistribution2DSampler> FTDistribution2DVoigt::createSampler() const
198 {
199  // TODO Need to implement 2D Voigt
200 
201  std::ostringstream ostr;
202  ostr << "FTDistribution2DVoigt::createSampler() -> Error in class initialization";
203  ostr << "\n\n Has not been implemented yet...stay tuned!";
205 }
Defines many exception classes in namespace Exceptionss.
Defines interface class IFTDistribution2D, and children thereof.
NodeMeta nodeMetaUnion(const std::vector< ParaMeta > &base, const NodeMeta &other)
Definition: INode.cpp:24
const double INF
Definition: INode.h:24
Defines classes RealIntegrator, ComplexIntegrator.
#define M_PI_2
Definition: MathConstants.h:40
Defines namespace MathFunctions.
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: Integrator.h:24
double integrate(const std::function< double(double)> &f, double lmin, double lmax)
Definition: Integrator.cpp:27
double Bessel_J0(double x)
Bessel function of the first kind and order 0.
double Bessel_J1c(double x)
Bessel function Bessel_J1(x)/x.
Metadata of one model node.
Definition: INode.h:37