BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
SpecularScalarTanhStrategy Class Reference
Inheritance diagram for SpecularScalarTanhStrategy:
Collaboration diagram for SpecularScalarTanhStrategy:

Public Types

using coeffs_t = std::vector< std::unique_ptr< const ILayerRTCoefficients > >
 

Public Member Functions

virtual ISpecularStrategy::coeffs_t Execute (const std::vector< Slice > &slices, const kvector_t &k) const override
 
virtual ISpecularStrategy::coeffs_t Execute (const std::vector< Slice > &slices, const std::vector< complex_t > &kz) const override
 

Private Member Functions

virtual std::pair< complex_t, complex_ttransition (complex_t kzi, complex_t kzi1, double sigma) const override
 
std::vector< ScalarRTCoefficientscomputeTR (const std::vector< Slice > &slices, const std::vector< complex_t > &kz) const
 
void calculateUpFromLayer (std::vector< ScalarRTCoefficients > &coeff, const std::vector< Slice > &slices, const std::vector< complex_t > &kz) const
 

Static Private Member Functions

static void setZeroBelow (std::vector< ScalarRTCoefficients > &coeff, size_t current_layer)
 

Detailed Description

Implements an tanh transition function to model roughness in a scaler computation.

Implements the transition function that includes the analytical roughness model of an tanh interface transition in the computation of the coefficients for coherent wave propagation in a multilayer by applying modified Fresnel coefficients.

Definition at line 29 of file SpecularScalarTanhStrategy.h.

Member Typedef Documentation

◆ coeffs_t

using ISpecularStrategy::coeffs_t = std::vector<std::unique_ptr<const ILayerRTCoefficients> >
inherited

Definition at line 40 of file ISpecularStrategy.h.

Member Function Documentation

◆ transition()

std::pair< complex_t, complex_t > SpecularScalarTanhStrategy::transition ( complex_t  kzi,
complex_t  kzi1,
double  sigma 
) const
overrideprivatevirtual

Roughness is modelled by tanh profile [see e.g. Phys. Rev. B, vol. 47 (8), p. 4385 (1993)].

Implements SpecularScalarStrategy.

Definition at line 26 of file SpecularScalarTanhStrategy.cpp.

27 {
28  complex_t roughness = 1;
29  if (sigma > 0.0) {
30  const double sigeff = pi2_15 * sigma;
31  roughness =
32  std::sqrt(MathFunctions::tanhc(sigeff * kzi1) / MathFunctions::tanhc(sigeff * kzi));
33  }
34  const complex_t inv_roughness = 1.0 / roughness;
35  const complex_t kz_ratio = kzi1 / kzi * roughness;
36 
37  const complex_t a00 = 0.5 * (inv_roughness + kz_ratio);
38  const complex_t a01 = 0.5 * (inv_roughness - kz_ratio);
39 
40  return {a00, a01};
41 }
std::complex< double > complex_t
Definition: Complex.h:20
complex_t tanhc(const complex_t z)
Complex tanhc function: .

References anonymous_namespace{SpecularScalarTanhStrategy.cpp}::pi2_15, and MathFunctions::tanhc().

Here is the call graph for this function:

◆ Execute() [1/2]

ISpecularStrategy::coeffs_t SpecularScalarStrategy::Execute ( const std::vector< Slice > &  slices,
const kvector_t k 
) const
overridevirtualinherited

Computes refraction angles and transmission/reflection coefficients for given coherent wave propagation in a multilayer.

Implements ISpecularStrategy.

Definition at line 29 of file SpecularScalarStrategy.cpp.

31 {
32  std::vector<complex_t> kz = KzComputation::computeReducedKz(slices, k);
33  return Execute(slices, kz);
34 }
virtual ISpecularStrategy::coeffs_t Execute(const std::vector< Slice > &slices, const kvector_t &k) const override
Computes refraction angles and transmission/reflection coefficients for given coherent wave propagati...
std::vector< complex_t > computeReducedKz(const std::vector< Slice > &slices, kvector_t k)

References KzComputation::computeReducedKz().

Here is the call graph for this function:

◆ Execute() [2/2]

ISpecularStrategy::coeffs_t SpecularScalarStrategy::Execute ( const std::vector< Slice > &  slices,
const std::vector< complex_t > &  kz 
) const
overridevirtualinherited

Implements ISpecularStrategy.

Definition at line 36 of file SpecularScalarStrategy.cpp.

38 {
39  if (slices.size() != kz.size())
40  throw std::runtime_error("Number of slices does not match the size of the kz-vector");
41 
43  for (auto& coeff : computeTR(slices, kz))
44  result.push_back(std::make_unique<ScalarRTCoefficients>(coeff));
45 
46  return result;
47 }
std::vector< std::unique_ptr< const ILayerRTCoefficients > > coeffs_t
std::vector< ScalarRTCoefficients > computeTR(const std::vector< Slice > &slices, const std::vector< complex_t > &kz) const

References SpecularScalarStrategy::computeTR().

Here is the call graph for this function:

◆ computeTR()

std::vector< ScalarRTCoefficients > SpecularScalarStrategy::computeTR ( const std::vector< Slice > &  slices,
const std::vector< complex_t > &  kz 
) const
privateinherited

Definition at line 50 of file SpecularScalarStrategy.cpp.

52 {
53  const size_t N = slices.size();
54  std::vector<ScalarRTCoefficients> coeff(N);
55 
56  for (size_t i = 0; i < N; ++i)
57  coeff[i].kz = kz[i];
58 
59  if (N == 1) { // If only one layer present, there's nothing left to calculate
60  coeff[0].t_r = {1.0, 0.0};
61  return coeff;
62  } else if (kz[0] == 0.0) { // If kz in layer 0 is zero, R0 = -T0 and all others equal to 0
63  coeff[0].t_r = {1.0, -1.0};
64  for (size_t i = 1; i < N; ++i)
65  coeff[i].t_r.setZero();
66  return coeff;
67  }
68 
69  // Calculate transmission/refraction coefficients t_r for each layer, from bottom to top.
70  calculateUpFromLayer(coeff, slices, kz);
71  return coeff;
72 }
void calculateUpFromLayer(std::vector< ScalarRTCoefficients > &coeff, const std::vector< Slice > &slices, const std::vector< complex_t > &kz) const

References SpecularScalarStrategy::calculateUpFromLayer().

Referenced by SpecularScalarStrategy::Execute().

Here is the call graph for this function:

◆ setZeroBelow()

void SpecularScalarStrategy::setZeroBelow ( std::vector< ScalarRTCoefficients > &  coeff,
size_t  current_layer 
)
staticprivateinherited

Definition at line 74 of file SpecularScalarStrategy.cpp.

76 {
77  size_t N = coeff.size();
78  for (size_t i = current_layer + 1; i < N; ++i) {
79  coeff[i].t_r.setZero();
80  }
81 }

◆ calculateUpFromLayer()

void SpecularScalarStrategy::calculateUpFromLayer ( std::vector< ScalarRTCoefficients > &  coeff,
const std::vector< Slice > &  slices,
const std::vector< complex_t > &  kz 
) const
privateinherited

Definition at line 83 of file SpecularScalarStrategy.cpp.

86 {
87  auto N = slices.size();
88 
89  coeff.back().t_r(0) = 1.0;
90  coeff.back().t_r(1) = 0.0;
91  std::vector<complex_t> factors(N - 1);
92  for (int i = N - 2; i >= 0; i--) {
93  double sigma = 0.0;
94  if (const auto roughness = GetBottomRoughness(slices, i))
95  sigma = roughness->getSigma();
96 
97  const auto mpmm = transition(kz[i], kz[i + 1], sigma);
98  const complex_t mp = mpmm.first;
99  const complex_t mm = mpmm.second;
100 
101  const complex_t delta = exp_I(kz[i] * slices[i].thickness());
102 
103  complex_t S = mp + mm * coeff[i + 1].t_r(1);
104  S = 1. / S * delta;
105  factors[i] = S;
106 
107  coeff[i].t_r(1) = delta * (mm + mp * coeff[i + 1].t_r(1)) * S;
108  }
109 
110  // now correct all amplitudes by dividing the with the remaining factors in forward direction
111  // at some point this divison underflows, which is the point when all further amplitudes are set
112  // to zero
113  complex_t dumpingFactor = 1;
114  for (size_t j = 1; j < N; ++j) {
115  dumpingFactor = dumpingFactor * factors[j - 1];
116 
117  coeff[j].t_r(0) = dumpingFactor;
118  coeff[j].t_r(1) *= dumpingFactor;
119  }
120 }
complex_t exp_I(complex_t z)
Returns exp(I*z), where I is the imaginary unit.
Definition: Complex.h:30
virtual std::pair< complex_t, complex_t > transition(complex_t kzi, complex_t kzi1, double sigma) const =0
const LayerRoughness * GetBottomRoughness(const std::vector< Slice > &slices, const size_t slice_index)

References exp_I(), anonymous_namespace{SpecularScalarStrategy.cpp}::GetBottomRoughness(), and SpecularScalarStrategy::transition().

Referenced by SpecularScalarStrategy::computeTR().

Here is the call graph for this function:

The documentation for this class was generated from the following files: