BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
TransitionMagneticNevot.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Resample/Specular/TransitionMagneticNevot.cpp
6 //! @brief Implements namespace MagneticNevotCroceTransition.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2020
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
17 
18 namespace {
19 
20 complex_t checkForUnderflow(complex_t val)
21 {
22  return std::abs(val.imag()) < 1e-80 && val.real() < 0 ? complex_t(val.real(), 1e-40) : val;
23 }
24 
25 std::pair<SpinMatrix, SpinMatrix> computeRoughnessMatrices(const MatrixFlux& coeff_i,
26  const MatrixFlux& coeff_i1, double sigma)
27 {
28  complex_t beta_i = coeff_i.m_lambda.v - coeff_i.m_lambda.u;
29  complex_t beta_i1 = coeff_i1.m_lambda.v - coeff_i1.m_lambda.u;
30 
31  auto roughness_matrix = [sigma, &coeff_i, &coeff_i1, beta_i, beta_i1](double sign) {
32  const complex_t alpha_p = coeff_i1.m_lambda.u + coeff_i1.m_lambda.v
33  + sign * (coeff_i.m_lambda.u + coeff_i.m_lambda.v);
34  auto b_p_vec = beta_i1 * coeff_i1.m_b + sign * beta_i * coeff_i.m_b;
35 
36  auto square = [](auto& v) { return v.x() * v.x() + v.y() * v.y() + v.z() * v.z(); };
37  complex_t beta_p = std::sqrt(checkForUnderflow(square(b_p_vec)));
38  b_p_vec /= beta_p;
39 
40  const complex_t alpha_pp = -(alpha_p * alpha_p + beta_p * beta_p) * sigma * sigma / 8.;
41  const complex_t beta_pp = -alpha_p * beta_p * sigma * sigma / 4.;
42 
43  const complex_t factor1 = std::sqrt(2. * (1. + b_p_vec.z()));
44  const complex_t factor2 = std::sqrt(2. * (1. - b_p_vec.z()));
45  SpinMatrix QL((b_p_vec.z() + 1.) / factor1, (b_p_vec.z() - 1.) / factor2,
46  (b_p_vec.x() + I * b_p_vec.y()) / factor1,
47  (b_p_vec.x() + I * b_p_vec.y()) / factor2);
48  SpinMatrix QR((b_p_vec.z() + 1.) / factor1, (b_p_vec.x() - I * b_p_vec.y()) / factor1,
49  (b_p_vec.z() - 1.) / factor2, (b_p_vec.x() - I * b_p_vec.y()) / factor2);
50 
51  const SpinMatrix exp1(std::exp(alpha_pp), 0, 0, std::exp(alpha_pp));
52 
53  if (std::abs(beta_p) > std::numeric_limits<double>::epsilon() * 10.) {
54  SpinMatrix exp2(std::exp(beta_pp), 0, 0, std::exp(-beta_pp));
55  return SpinMatrix{exp1 * QL * exp2 * QR};
56  }
57 
58  return exp1;
59  };
60 
61  const SpinMatrix roughness_sum = roughness_matrix(1.);
62  const SpinMatrix roughness_diff = roughness_matrix(-1.);
63 
64  return {roughness_sum, roughness_diff};
65 }
66 
67 } // namespace
68 
69 
71  const MatrixFlux& coeff_i, const MatrixFlux& coeff_i1, double sigma)
72 {
73  SpinMatrix roughness_sum = SpinMatrix::One();
74  SpinMatrix roughness_diff = SpinMatrix::One();
75  if (sigma != 0.) {
76  const auto ret = computeRoughnessMatrices(coeff_i, coeff_i1, sigma);
77  roughness_sum = std::get<0>(ret);
78  roughness_diff = std::get<1>(ret);
79  }
80 
81  const auto P = SpinMatrix(coeff_i.computeInverseP() * coeff_i1.computeP());
82  const auto mp = 0.5 * (SpinMatrix::One() + P) * roughness_diff;
83  const auto mm = 0.5 * (SpinMatrix::One() - P) * roughness_sum;
84 
85  return {mp, mm};
86 }
Defines class MatrixFlux.
Defines namespace MagneticNevotCroceTransition.
Specular reflection and transmission coefficients in a layer in case of magnetic interactions between...
Definition: MatrixFlux.h:32
SpinMatrix computeP() const
Definition: MatrixFlux.cpp:124
Spinor m_lambda
eigenvalues for wave propagation
Definition: MatrixFlux.h:55
SpinMatrix computeInverseP() const
Definition: MatrixFlux.cpp:132
R3 m_b
unit magnetic field vector
Definition: MatrixFlux.h:60
static SpinMatrix One()
Definition: SpinMatrix.cpp:36
complex_t v
Definition: Spinor.h:31
complex_t u
Definition: Spinor.h:31
std::pair< SpinMatrix, SpinMatrix > backwardsSubmatrices(const MatrixFlux &coeff_i, const MatrixFlux &coeff_i1, double sigma)