BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
RoughMultiLayerComputation Class Referencefinal
Collaboration diagram for RoughMultiLayerComputation:

Public Member Functions

 RoughMultiLayerComputation (const ProcessedSample *p_sample)
 
void compute (SimulationElement &elem) const
 

Private Member Functions

complex_t get_refractive_term (size_t ilayer, double wavelength) const
 
complex_t get_sum8terms (size_t ilayer, const SimulationElement &sim_element) const
 

Private Attributes

const ProcessedSamplemp_sample
 

Detailed Description

Computes the diffuse reflection from the rough interfaces of a multilayer.

Used by DWBAComputation.

Definition at line 27 of file RoughMultiLayerComputation.h.

Constructor & Destructor Documentation

◆ RoughMultiLayerComputation()

RoughMultiLayerComputation::RoughMultiLayerComputation ( const ProcessedSample p_sample)

Definition at line 43 of file RoughMultiLayerComputation.cpp.

44  : mp_sample{p_sample}
45 {
46 }

Member Function Documentation

◆ compute()

void RoughMultiLayerComputation::compute ( SimulationElement elem) const

Definition at line 48 of file RoughMultiLayerComputation.cpp.

49 {
50  if (elem.getAlphaMean() < 0.0)
51  return;
53  kvector_t q = elem.getMeanQ();
54  double wavelength = elem.getWavelength();
55  double autocorr(0.0);
56  complex_t crosscorr(0.0, 0.0);
57 
58  std::vector<complex_t> rterm(n_slices - 1);
59  std::vector<complex_t> sterm(n_slices - 1);
60 
61  for (size_t i = 0; i + 1 < n_slices; i++) {
62  rterm[i] = get_refractive_term(i, wavelength);
63  sterm[i] = get_sum8terms(i, elem);
64  }
65  for (size_t i = 0; i + 1 < n_slices; i++) {
66  const LayerRoughness* rough = mp_sample->bottomRoughness(i);
67  if (rough)
68  autocorr += std::norm(rterm[i]) * std::norm(sterm[i]) * rough->getSpectralFun(q);
69  }
70  // cross correlation between layers
71  if (mp_sample->crossCorrelationLength() != 0.0) {
72  for (size_t j = 0; j < n_slices - 1; j++) {
73  for (size_t k = 0; k < n_slices - 1; k++) {
74  if (j == k)
75  continue;
76  crosscorr += rterm[j] * sterm[j] * mp_sample->crossCorrSpectralFun(q, j, k)
77  * std::conj(rterm[k]) * std::conj(sterm[k]);
78  }
79  }
80  }
81  //! @TODO clarify complex vs double
82  elem.addIntensity((autocorr + crosscorr.real()) * M_PI / 4. / wavelength / wavelength);
83 }
std::complex< double > complex_t
Definition: Complex.h:20
#define M_PI
Definition: MathConstants.h:39
A roughness of interface between two layers.
double getSpectralFun(const kvector_t kvec) const
Returns power spectral density of the surface roughness.
size_t numberOfSlices() const
double crossCorrSpectralFun(const kvector_t kvec, size_t j, size_t k) const
Fourier transform of the correlation function of roughnesses between the interfaces.
double crossCorrelationLength() const
const LayerRoughness * bottomRoughness(size_t i) const
complex_t get_sum8terms(size_t ilayer, const SimulationElement &sim_element) const
complex_t get_refractive_term(size_t ilayer, double wavelength) const
void addIntensity(double intensity)
double getWavelength() const
kvector_t getMeanQ() const
double getAlphaMean() const

References SimulationElement::addIntensity(), ProcessedSample::bottomRoughness(), ProcessedSample::crossCorrelationLength(), ProcessedSample::crossCorrSpectralFun(), get_refractive_term(), get_sum8terms(), SimulationElement::getAlphaMean(), SimulationElement::getMeanQ(), LayerRoughness::getSpectralFun(), SimulationElement::getWavelength(), M_PI, mp_sample, anonymous_namespace{SlicedCylindersBuilder.cpp}::n_slices(), ProcessedSample::numberOfSlices(), and anonymous_namespace{SlicedCylindersBuilder.cpp}::wavelength().

Here is the call graph for this function:

◆ get_refractive_term()

complex_t RoughMultiLayerComputation::get_refractive_term ( size_t  ilayer,
double  wavelength 
) const
private

Definition at line 85 of file RoughMultiLayerComputation.cpp.

86 {
87  auto& slices = mp_sample->slices();
88  return slices[ilayer].material().refractiveIndex2(wavelength)
89  - slices[ilayer + 1].material().refractiveIndex2(wavelength);
90 }
const std::vector< Slice > & slices() const

References mp_sample, ProcessedSample::slices(), and anonymous_namespace{SlicedCylindersBuilder.cpp}::wavelength().

Referenced by compute().

Here is the call graph for this function:

◆ get_sum8terms()

complex_t RoughMultiLayerComputation::get_sum8terms ( size_t  ilayer,
const SimulationElement sim_element 
) const
private

Definition at line 92 of file RoughMultiLayerComputation.cpp.

94 {
95  auto& slices = mp_sample->slices();
96  auto p_fresnel_map = mp_sample->fresnelMap();
97  const auto P_in_plus = p_fresnel_map->getInCoefficients(sim_element, ilayer);
98  const auto P_out_plus = p_fresnel_map->getOutCoefficients(sim_element, ilayer);
99 
100  const auto P_in_minus = p_fresnel_map->getInCoefficients(sim_element, ilayer + 1);
101  const auto P_out_minus = p_fresnel_map->getOutCoefficients(sim_element, ilayer + 1);
102 
103  complex_t kiz_plus = P_in_plus->getScalarKz();
104  complex_t kfz_plus = P_out_plus->getScalarKz();
105  complex_t qz1_plus = -kiz_plus - kfz_plus;
106  complex_t qz2_plus = -kiz_plus + kfz_plus;
107  complex_t qz3_plus = -qz2_plus;
108  complex_t qz4_plus = -qz1_plus;
109  double thickness = slices[ilayer].thickness();
110  complex_t T_in_plus = P_in_plus->getScalarT() * exp_I(kiz_plus * thickness);
111  complex_t R_in_plus = P_in_plus->getScalarR() * exp_I(-kiz_plus * thickness);
112  complex_t T_out_plus = P_out_plus->getScalarT() * exp_I(kfz_plus * thickness);
113  complex_t R_out_plus = P_out_plus->getScalarR() * exp_I(-kfz_plus * thickness);
114 
115  complex_t kiz_minus = P_in_minus->getScalarKz();
116  complex_t kfz_minus = P_out_minus->getScalarKz();
117  complex_t qz1_minus = -kiz_minus - kfz_minus;
118  complex_t qz2_minus = -kiz_minus + kfz_minus;
119  complex_t qz3_minus = -qz2_minus;
120  complex_t qz4_minus = -qz1_minus;
121 
122  double sigma(0.0);
123  if (const LayerRoughness* roughness = mp_sample->bottomRoughness(ilayer))
124  sigma = roughness->getSigma();
125  complex_t term1 = T_in_plus * T_out_plus * h_plus(qz1_plus * sigma);
126  complex_t term2 = T_in_plus * R_out_plus * h_plus(qz2_plus * sigma);
127  complex_t term3 = R_in_plus * T_out_plus * h_plus(qz3_plus * sigma);
128  complex_t term4 = R_in_plus * R_out_plus * h_plus(qz4_plus * sigma);
129  complex_t term5 =
130  P_in_minus->getScalarT() * P_out_minus->getScalarT() * h_min(qz1_minus * sigma);
131  complex_t term6 =
132  P_in_minus->getScalarT() * P_out_minus->getScalarR() * h_min(qz2_minus * sigma);
133  complex_t term7 =
134  P_in_minus->getScalarR() * P_out_minus->getScalarT() * h_min(qz3_minus * sigma);
135  complex_t term8 =
136  P_in_minus->getScalarR() * P_out_minus->getScalarR() * h_min(qz4_minus * sigma);
137 
138  return term1 + term2 + term3 + term4 + term5 + term6 + term7 + term8;
139 }
complex_t exp_I(complex_t z)
Returns exp(I*z), where I is the imaginary unit.
Definition: Complex.h:30
std::unique_ptr< const ILayerRTCoefficients > getInCoefficients(const T &sim_element, size_t layer_index) const
Retrieves the amplitude coefficients for an incoming wavevector.
Definition: IFresnelMap.h:41
const IFresnelMap * fresnelMap() const

References ProcessedSample::bottomRoughness(), exp_I(), ProcessedSample::fresnelMap(), IFresnelMap::getInCoefficients(), anonymous_namespace{RoughMultiLayerComputation.cpp}::h_min(), anonymous_namespace{RoughMultiLayerComputation.cpp}::h_plus(), mp_sample, and ProcessedSample::slices().

Referenced by compute().

Here is the call graph for this function:

Member Data Documentation

◆ mp_sample

const ProcessedSample* RoughMultiLayerComputation::mp_sample
private

Definition at line 35 of file RoughMultiLayerComputation.h.

Referenced by compute(), get_refractive_term(), and get_sum8terms().


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