BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
Ripples.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Sample/HardParticle/Ripples.cpp
6 //! @brief Implements computations in namespace ripples.
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/Constants.h"
17 #include "Base/Math/Functions.h"
18 #include "Base/Math/IntegratorGK.h"
19 
21 {
22  return r * Math::sinc(q * r / 2.0);
23 }
24 
26 {
27  return r * exp(-q * r / 8.0);
28 }
29 
31 {
32  return r / (1.0 + (q * r) * (q * r));
33 }
34 
35 //! Complex form factor of rectangular ripple (bar).
36 complex_t ripples::profile_yz_bar(complex_t qy, complex_t qz, double width, double height)
37 {
38  const complex_t qyWdiv2 = width * qy / 2.0;
39  const complex_t qzHdiv2 = height * qz / 2.0;
40 
41  return height * width * exp_I(qzHdiv2) * Math::sinc(qyWdiv2) * Math::sinc(qzHdiv2);
42 }
43 
44 //! Complex form factor of cosine ripple.
45 complex_t ripples::profile_yz_cosine(complex_t qy, complex_t qz, double width, double height)
46 {
47  complex_t factor = width / M_PI;
48 
49  // analytical expressions for some particular cases
50  if (qz == 0.) {
51  if (qy == 0.)
52  return factor * M_PI_2 * height;
53  complex_t aaa = qy * width / (M_TWOPI);
54  complex_t aaa2 = aaa * aaa;
55  if (aaa2 == 1.)
56  return factor * M_PI_4 * height;
57  return factor * M_PI_2 * height * Math::sinc(qy * width * 0.5) / (1.0 - aaa2);
58  }
59 
60  // numerical integration otherwise
61  const complex_t ay = qy * width / M_TWOPI;
62  const complex_t az = qz * (height / 2);
63 
64  const auto integrand = [&](double u) -> complex_t {
65  return sin(u) * exp_I(az * std::cos(u)) * (ay == 0. ? u : sin(ay * u) / ay);
66  };
67  complex_t integral = ComplexIntegrator().integrate(integrand, 0, M_PI);
68  return factor * integral * exp_I(az) * (height / 2);
69 }
70 
71 //! Complex form factor of triangular ripple.
72 complex_t ripples::profile_yz_triangular(complex_t qy, complex_t qz, double width, double height,
73  double asymmetry)
74 {
75  complex_t result;
76  const complex_t factor = height * width;
77  const complex_t qyW2 = qy * width * 0.5;
78  const complex_t qyd = qy * asymmetry;
79  const complex_t qzH = qz * height;
80  const complex_t a = qzH + qyd;
81  // dimensionless scale factors
82  const double a_scale = std::abs(a);
83  const double w_scale = std::abs(qyW2);
84 
85  if (w_scale < 1.e-5) { // |q_y*W| << 1
86  if (a_scale < 1e-5) { // |q_y*W| << 1 && |q_z*H + q_y*d| << 1
87  // relative error is O((q_y*W)^2) and O((q_z*H + q_y*d)^2)
88  result = exp_I(-qyd) * (0.5 + mul_I(a) / 6.);
89  } else {
90  // relative error is O((q_y*W)^2)
91  result = exp_I(-qyd) * (1.0 + mul_I(a) - exp_I(a)) / (a * a);
92  }
93  } else {
94  const complex_t gamma_p = (a + qyW2) * 0.5;
95  const complex_t gamma_m = (a - qyW2) * 0.5;
96  result = exp_I(gamma_m) * Math::sinc(gamma_p) - exp_I(gamma_p) * Math::sinc(gamma_m);
97  result = mul_I(exp_I(-qyd) * result / (qyW2 * 2.));
98  }
99  return factor * result;
100 }
complex_t mul_I(complex_t z)
Returns product I*z, where I is the imaginary unit.
Definition: Complex.h:24
std::complex< double > complex_t
Definition: Complex.h:20
complex_t exp_I(complex_t z)
Returns exp(I*z), where I is the imaginary unit.
Definition: Complex.h:30
Defines M_PI and some more mathematical constants.
#define M_TWOPI
Definition: Constants.h:54
#define M_PI_2
Definition: Constants.h:45
#define M_PI
Definition: Constants.h:44
#define M_PI_4
Definition: Constants.h:46
Defines functions in namespace Math.
Defines classes RealIntegrator, ComplexIntegrator.
Declares computations in namespace ripples.
To integrate a complex function of a real variable.
Definition: IntegratorGK.h:44
complex_t integrate(const std::function< complex_t(double)> &f, double lmin, double lmax)
double sinc(double x)
sinc function:
Definition: Functions.cpp:53
complex_t profile_yz_cosine(complex_t qy, complex_t qz, double width, double height)
Complex form factor of cosine ripple.
Definition: Ripples.cpp:45
complex_t profile_yz_bar(complex_t qy, complex_t qz, double width, double height)
Complex form factor of rectangular ripple (bar).
Definition: Ripples.cpp:36
complex_t factor_x_box(complex_t q, double l)
Definition: Ripples.cpp:20
complex_t factor_x_Lorentz(complex_t q, double l)
Definition: Ripples.cpp:30
complex_t profile_yz_triangular(complex_t qy, complex_t qz, double width, double height, double asymmetry)
Complex form factor of triangular ripple.
Definition: Ripples.cpp:72
complex_t factor_x_Gauss(complex_t q, double l)
Definition: Ripples.cpp:25