BornAgain  1.18.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 scattering at grazing incidence
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 
17 #include "Base/Utils/Integrator.h"
19 
21 {
22  return r * MathFunctions::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).
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) * MathFunctions::sinc(qyWdiv2)
42  * MathFunctions::sinc(qzHdiv2);
43 }
44 
45 //! Complex form factor of triangular ripple.
47 {
48  complex_t factor = width / M_PI;
49 
50  // analytical expressions for some particular cases
51  if (qz == 0.) {
52  if (qy == 0.)
53  return factor * M_PI_2 * height;
54  complex_t aaa = qy * width / (M_TWOPI);
55  complex_t aaa2 = aaa * aaa;
56  if (aaa2 == 1.)
57  return factor * M_PI_4 * height;
58  return factor * M_PI_2 * height * MathFunctions::sinc(qy * width * 0.5) / (1.0 - aaa2);
59  }
60 
61  // numerical integration otherwise
62  const complex_t ay = qy * width / M_TWOPI;
63  const complex_t az = qz * (height / 2);
64 
65  const auto integrand = [&](double u) -> complex_t {
66  return sin(u) * exp_I(az * std::cos(u)) * (ay == 0. ? u : sin(ay * u) / ay);
67  };
68  complex_t integral = ComplexIntegrator().integrate(integrand, 0, M_PI);
69  return factor * integral * exp_I(az) * (height / 2);
70 }
71 
72 //! Complex form factor of triangular ripple.
74  double asymmetry)
75 {
76  complex_t result;
77  const complex_t factor = height * width;
78  const complex_t qyW2 = qy * width * 0.5;
79  const complex_t qyd = qy * asymmetry;
80  const complex_t qzH = qz * height;
81  const complex_t a = qzH + qyd;
82  // dimensionless scale factors
83  const double a_scale = std::abs(a);
84  const double w_scale = std::abs(qyW2);
85 
86  if (w_scale < 1.e-5) { // |q_y*W| << 1
87  if (a_scale < 1e-5) { // |q_y*W| << 1 && |q_z*H + q_y*d| << 1
88  // relative error is O((q_y*W)^2) and O((q_z*H + q_y*d)^2)
89  result = exp_I(-qyd) * (0.5 + mul_I(a) / 6.);
90  } else {
91  // relative error is O((q_y*W)^2)
92  result = exp_I(-qyd) * (1.0 + mul_I(a) - exp_I(a)) / (a * a);
93  }
94  } else {
95  const complex_t gamma_p = (a + qyW2) * 0.5;
96  const complex_t gamma_m = (a - qyW2) * 0.5;
97  result = exp_I(gamma_m) * MathFunctions::sinc(gamma_p)
98  - exp_I(gamma_p) * MathFunctions::sinc(gamma_m);
99  result = mul_I(exp_I(-qyd) * result / (qyW2 * 2.));
100  }
101  return factor * result;
102 }
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 classes RealIntegrator, ComplexIntegrator.
Defines M_PI and some more mathematical constants.
#define M_TWOPI
Definition: MathConstants.h:49
#define M_PI_2
Definition: MathConstants.h:40
#define M_PI
Definition: MathConstants.h:39
#define M_PI_4
Definition: MathConstants.h:41
Defines namespace MathFunctions.
Declares computations in namespace ripples.
To integrate a complex function of a real variable.
Definition: Integrator.h:41
complex_t integrate(const std::function< complex_t(double)> &f, double lmin, double lmax)
Definition: Integrator.cpp:36
double sinc(double x)
sinc function:
complex_t profile_yz_cosine(complex_t qy, complex_t qz, double width, double height)
Complex form factor of triangular ripple.
Definition: Ripples.cpp:46
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:73
complex_t factor_x_Gauss(complex_t q, double l)
Definition: Ripples.cpp:25