BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
KzComputation.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Resample/Slice/KzComputation.cpp
6 //! @brief Implements functions in namespace Compute::Kz.
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/Const/Units.h"
17 #include "Base/Math/Constants.h"
19 
20 namespace {
21 
22 complex_t normalizedSLD(const Material& material)
23 {
24  if (material.typeID() != MATERIAL_TYPES::MaterialBySLD)
25  throw std::runtime_error("Error in normalizedSLD: passed material has wrong type");
26 
27  complex_t sld = std::conj(material.materialData()) / (Units::angstrom * Units::angstrom);
28  sld *= 4.0 * M_PI;
29  return sld;
30 }
31 
32 complex_t checkForUnderflow(complex_t val)
33 {
34  return std::norm(val) < 1e-80 ? complex_t(0.0, 1e-40) : val;
35 }
36 
37 } // namespace
38 
39 // ************************************************************************************************
40 // namespace KzComputation
41 // ************************************************************************************************
42 
43 std::vector<complex_t> Compute::Kz::computeReducedKz(const SliceStack& slices, R3 k)
44 {
45  const size_t N = slices.size();
46 
47  const size_t i_ref = k.z() > 0. ? N - 1 : 0;
48  const double n_ref = slices[i_ref].material().refractiveIndex(M_TWOPI / k.mag()).real();
49  const double k_base = k.mag() * (k.z() > 0.0 ? -1 : 1);
50 
51  std::vector<complex_t> result(N);
52  // Calculate refraction angle, expressed as k_z, for each layer.
53  for (size_t i = 0; i < N; ++i) {
54  complex_t rad = slices[i].scalarReducedPotential(k, n_ref);
55  if (i != i_ref)
56  rad = checkForUnderflow(rad);
57  result[i] = k_base * std::sqrt(rad);
58  }
59  return result;
60 }
61 
62 std::vector<complex_t> Compute::Kz::computeKzFromSLDs(const SliceStack& slices, double kz)
63 {
64  const size_t N = slices.size();
65  const double k_sign = kz > 0.0 ? -1 : 1;
66  complex_t kz2_base = kz * kz + normalizedSLD(slices[0].material());
67 
68  std::vector<complex_t> result(N);
69  result[0] = -kz;
70  // Calculate refraction angle, expressed as k_z, for each layer.
71  for (size_t i = 1; i < N; ++i) {
72  complex_t kz2 = checkForUnderflow(kz2_base - normalizedSLD(slices[i].material()));
73  result[i] = k_sign * std::sqrt(kz2);
74  }
75  return result;
76 }
77 
78 std::vector<complex_t> Compute::Kz::computeKzFromRefIndices(const SliceStack& slices, R3 k)
79 {
80  const size_t N = slices.size();
81  const double kz = k.z();
82  const double k_sign = kz > 0.0 ? -1 : 1;
83  const double k2 = k.mag2();
84  const double kz2 = kz * kz;
85  const double wl = M_TWOPI / std::sqrt(k2);
86  const complex_t n2_ref = slices[0].material().refractiveIndex2(wl);
87 
88  std::vector<complex_t> result(N);
89  result[0] = -kz;
90  for (size_t i = 1; i < N; ++i) {
91  const complex_t n2_norm = slices[i].material().refractiveIndex2(wl) - n2_ref;
92  result[i] = k_sign * std::sqrt(checkForUnderflow(k2 * n2_norm + kz2));
93  }
94  return result;
95 }
Defines M_PI and some more mathematical constants.
#define M_TWOPI
Definition: Constants.h:54
#define M_PI
Definition: Constants.h:44
Declares functions in namespace ComputateKz.
Defines class SliceStack.
Defines some unit conversion factors and other constants in namespace Units.
A wrapper for underlying material implementation.
Definition: Material.h:35
MATERIAL_TYPES typeID() const
Returns the type of underlying material implementation.
Definition: Material.cpp:73
complex_t materialData() const
Returns delta + i beta.
Definition: Material.cpp:83
A stack of Slices.
Definition: SliceStack.h:38
#define N
Definition: mixmax.h:31
std::vector< complex_t > computeReducedKz(const SliceStack &slices, R3 k)
Computes kz values from known k vector and slices with the following assumptions:
std::vector< complex_t > computeKzFromSLDs(const SliceStack &slices, double kz)
Computes kz values from kz of the incoming beam known at a distant point in vacuum....
std::vector< complex_t > computeKzFromRefIndices(const SliceStack &slices, R3 k)
Computes kz values from k-vector of the incoming beam known at a distant point in vacuum....
static constexpr double rad
Radian, internal unit for angles.
Definition: Units.h:45
static constexpr double angstrom
Definition: Units.h:34