BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
TransitionMagneticTanh.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Resample/Specular/TransitionMagneticTanh.cpp
6 //! @brief Implements class SpecularMagneticTanhStrategy.
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 
16 #include "Base/Math/Constants.h"
17 #include "Base/Math/Functions.h"
19 
20 namespace {
21 
22 SpinMatrix computeRoughnessMatrix(const MatrixFlux& coeff, double sigma, bool inverse)
23 {
24  if (sigma < 10 * std::numeric_limits<double>::epsilon())
25  return SpinMatrix::One();
26 
27  const double sigeff = std::pow(M_PI_2, 1.5) * sigma;
28  const auto b = coeff.m_b;
29 
30  if (std::abs(b.mag() - 1.) < std::numeric_limits<double>::epsilon() * 10.) {
31  const double factor1 = 2. * (1. + b.z());
32  SpinMatrix Q((1. + b.z()), (I * b.y() - b.x()), (b.x() + I * b.y()), (b.z() + 1.));
33 
34  complex_t l1 = std::sqrt(Math::tanhc(sigeff * coeff.m_lambda.v));
35  complex_t l2 = std::sqrt(Math::tanhc(sigeff * coeff.m_lambda.u));
36 
37  if (inverse) {
38  l1 = 1. / l1;
39  l2 = 1. / l2;
40  }
41 
42  const SpinMatrix lambda(l1, 0, 0, l2);
43 
44  return Q * lambda * Q.adjoint() / factor1;
45  }
46 
47  if (b.mag() < 10 * std::numeric_limits<double>::epsilon()) {
48  complex_t alpha =
49  std::sqrt(Math::tanhc(0.5 * sigeff * (coeff.m_lambda.v + coeff.m_lambda.u)));
50  if (inverse)
51  alpha = 1. / alpha;
52  const SpinMatrix lambda(alpha, 0, 0, alpha);
53 
54  return lambda;
55  }
56 
57  throw std::runtime_error("Broken magnetic field vector");
58 }
59 
60 } // namespace
61 
62 
63 std::pair<SpinMatrix, SpinMatrix>
65  const MatrixFlux& coeff_i1, double sigma)
66 {
69 
70  if (sigma != 0.) {
71  R = computeRoughnessMatrix(coeff_i1, sigma, false)
72  * computeRoughnessMatrix(coeff_i, sigma, true);
73 
74  RInv = computeRoughnessMatrix(coeff_i, sigma, false)
75  * computeRoughnessMatrix(coeff_i1, sigma, true);
76  }
77 
78  const SpinMatrix mproduct = coeff_i.computeInverseP() * coeff_i1.computeP();
79  const SpinMatrix mp = 0.5 * (RInv + mproduct * R);
80  const SpinMatrix mm = 0.5 * (RInv - mproduct * R);
81 
82  return {mp, mm};
83 }
Defines M_PI and some more mathematical constants.
#define M_PI_2
Definition: Constants.h:45
Defines namespace Math.
Defines class MatrixFlux.
Defines namespace TransitionMagneticTanh.
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)
complex_t tanhc(complex_t z)
Complex tanhc function: .
Definition: Functions.cpp:70
constexpr Double_t R()
Definition: TMath.h:213