BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
SpecularMagneticNewTanhStrategy.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Sample/Specular/SpecularMagneticNewTanhStrategy.cpp
6 //! @brief Implements class SpecularMagneticNewTanhStrategy.
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 
18 
19 namespace
20 {
21 const double pi2_15 = std::pow(M_PI_2, 1.5);
22 } // namespace
23 
24 Eigen::Matrix2cd
26  double sigma, bool inverse) const
27 {
28  if (sigma < 10 * std::numeric_limits<double>::epsilon())
29  return Eigen::Matrix2cd{Eigen::Matrix2cd::Identity()};
30 
31  const double sigeff = pi2_15 * sigma;
32  const auto b = coeff.m_b;
33 
34  if (std::abs(b.mag() - 1.) < std::numeric_limits<double>::epsilon() * 10.) {
35  Eigen::Matrix2cd Q;
36  const double factor1 = 2. * (1. + b.z());
37  Q << (1. + b.z()), (I * b.y() - b.x()), (b.x() + I * b.y()), (b.z() + 1.);
38 
39  complex_t l1 = std::sqrt(MathFunctions::tanhc(sigeff * coeff.m_lambda(1)));
40  complex_t l2 = std::sqrt(MathFunctions::tanhc(sigeff * coeff.m_lambda(0)));
41 
42  if (inverse) {
43  l1 = 1. / l1;
44  l2 = 1. / l2;
45  }
46 
47  const Eigen::Matrix2cd lambda = Eigen::DiagonalMatrix<complex_t, 2>({l1, l2});
48 
49  return Q * lambda * Q.adjoint() / factor1;
50 
51  } else if (b.mag() < 10 * std::numeric_limits<double>::epsilon()) {
52  complex_t alpha =
53  std::sqrt(MathFunctions::tanhc(0.5 * sigeff * (coeff.m_lambda(1) + coeff.m_lambda(0))));
54  if (inverse)
55  alpha = 1. / alpha;
56  const Eigen::Matrix2cd lambda = Eigen::DiagonalMatrix<complex_t, 2>({alpha, alpha});
57 
58  return lambda;
59  }
60 
61  throw std::runtime_error("Broken magnetic field vector");
62 }
63 
64 std::pair<Eigen::Matrix2cd, Eigen::Matrix2cd>
66  const MatrixRTCoefficients_v3& coeff_i, const MatrixRTCoefficients_v3& coeff_i1,
67  double sigma) const
68 {
69  Eigen::Matrix2cd R{Eigen::Matrix2cd::Identity()};
70  Eigen::Matrix2cd RInv{Eigen::Matrix2cd::Identity()};
71 
72  if (sigma != 0.) {
73  R = computeRoughnessMatrix(coeff_i1, sigma, false)
74  * computeRoughnessMatrix(coeff_i, sigma, true);
75 
76  RInv = computeRoughnessMatrix(coeff_i, sigma, false)
77  * computeRoughnessMatrix(coeff_i1, sigma, true);
78  }
79 
80  const Eigen::Matrix2cd mproduct = coeff_i.computeInverseP() * coeff_i1.computeP();
81  const Eigen::Matrix2cd mp = 0.5 * (RInv + mproduct * R);
82  const Eigen::Matrix2cd mm = 0.5 * (RInv - mproduct * R);
83 
84  return {mp, mm};
85 }
constexpr complex_t I
Definition: Complex.h:21
std::complex< double > complex_t
Definition: Complex.h:20
Defines M_PI and some more mathematical constants.
#define M_PI_2
Definition: MathConstants.h:40
Defines namespace MathFunctions.
Defines class SpecularMagneticNewTanhStrategy.
Specular reflection and transmission coefficients in a layer in case of magnetic interactions between...
Eigen::Vector2cd m_lambda
wave propagation direction (-1 for direct one, 1 for time reverse)
Eigen::Matrix2cd computeInverseP() const
Eigen::Matrix2cd computeP() const
kvector_t m_b
unit magnetic field vector
Eigen::Matrix2cd computeRoughnessMatrix(const MatrixRTCoefficients_v3 &coeff, double sigma, bool inverse=false) const
virtual std::pair< Eigen::Matrix2cd, Eigen::Matrix2cd > computeBackwardsSubmatrices(const MatrixRTCoefficients_v3 &coeff_i, const MatrixRTCoefficients_v3 &coeff_i1, double sigma) const
complex_t tanhc(const complex_t z)
Complex tanhc function: .