BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
ComputeDWBAPol.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Sample/FFCompute/ComputeDWBAPol.cpp
6 //! @brief Defines class ComputeDWBAPol.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
19 
20 namespace {
21 complex_t VecMatVecProduct(const Eigen::Vector2cd& vec1, const Eigen::Matrix2cd& ff,
22  const Eigen::Vector2cd& vec2)
23 {
24  return vec1.transpose() * ff * vec2;
25 }
26 } // namespace
27 
29 
31 
33 {
34  ComputeDWBAPol* p_result = new ComputeDWBAPol(*m_ff);
35  std::unique_ptr<const ILayerRTCoefficients> p_in_coefs =
36  m_in_coeffs ? std::unique_ptr<const ILayerRTCoefficients>(m_in_coeffs->clone()) : nullptr;
37  std::unique_ptr<const ILayerRTCoefficients> p_out_coefs =
38  m_out_coeffs ? std::unique_ptr<const ILayerRTCoefficients>(m_out_coeffs->clone()) : nullptr;
39  p_result->setSpecularInfo(std::move(p_in_coefs), std::move(p_out_coefs));
40  return p_result;
41 }
42 
44 {
45  throw std::runtime_error("Bug: forbidden call of ComputeDWBAPol::evaluate");
46 }
47 
48 Eigen::Matrix2cd ComputeDWBAPol::evaluatePol(const WavevectorInfo& wavevectors) const
49 {
50  // the required wavevectors inside the layer for
51  // different eigenmodes and in- and outgoing wavevector;
52  complex_t kix = wavevectors.getKi().x();
53  complex_t kiy = wavevectors.getKi().y();
54  cvector_t ki_1R(kix, kiy, m_in_coeffs->getKz()(0));
55  cvector_t ki_1T(kix, kiy, -m_in_coeffs->getKz()(0));
56  cvector_t ki_2R(kix, kiy, m_in_coeffs->getKz()(1));
57  cvector_t ki_2T(kix, kiy, -m_in_coeffs->getKz()(1));
58 
59  cvector_t kf_1R = wavevectors.getKf();
60  kf_1R.setZ(-(complex_t)m_out_coeffs->getKz()(0));
61  cvector_t kf_1T = kf_1R;
62  kf_1T.setZ((complex_t)m_out_coeffs->getKz()(0));
63  cvector_t kf_2R = kf_1R;
64  kf_2R.setZ(-(complex_t)m_out_coeffs->getKz()(1));
65  cvector_t kf_2T = kf_1R;
66  kf_2T.setZ((complex_t)m_out_coeffs->getKz()(1));
67  // now each of the 16 matrix terms of the polarized DWBA is calculated:
68  // NOTE: when the underlying reflection/transmission coefficients are
69  // scalar, the eigenmodes have identical eigenvalues and spin polarization
70  // is used as a basis; in this case however the matrices get mixed:
71  // real m_M11 = calculated m_M12
72  // real m_M12 = calculated m_M11
73  // real m_M21 = calculated m_M22
74  // real m_M22 = calculated m_M21
75  // since both eigenvalues are identical, this does not influence the result.
76  Eigen::Matrix2cd ff_BA;
77 
78  double wavelength = wavevectors.wavelength();
79 
80  // The following matrices each contain the four polarization conditions
81  // (p->p, p->m, m->p, m->m)
82  // The first two indices indicate a scattering from the 1/2 eigenstate into
83  // the 1/2 eigenstate, while the capital indices indicate a reflection
84  // before and/or after the scattering event (first index is in-state,
85  // second is out-state; this also applies to the internal matrix indices)
86  Eigen::Matrix2cd M11_S, M11_RS, M11_SR, M11_RSR, M12_S, M12_RS, M12_SR, M12_RSR, M21_S, M21_RS,
87  M21_SR, M21_RSR, M22_S, M22_RS, M22_SR, M22_RSR;
88 
89  // eigenmode 1 -> eigenmode 1: direct scattering
90  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_1T, kf_1T, wavelength));
91  M11_S(0, 0) = -VecMatVecProduct(m_out_coeffs->T1min(), ff_BA, m_in_coeffs->T1plus());
92  M11_S(0, 1) = VecMatVecProduct(m_out_coeffs->T1plus(), ff_BA, m_in_coeffs->T1plus());
93  M11_S(1, 0) = -VecMatVecProduct(m_out_coeffs->T1min(), ff_BA, m_in_coeffs->T1min());
94  M11_S(1, 1) = VecMatVecProduct(m_out_coeffs->T1plus(), ff_BA, m_in_coeffs->T1min());
95  // eigenmode 1 -> eigenmode 1: reflection and then scattering
96  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_1R, kf_1T, wavelength));
97  M11_RS(0, 0) = -VecMatVecProduct(m_out_coeffs->T1min(), ff_BA, m_in_coeffs->R1plus());
98  M11_RS(0, 1) = VecMatVecProduct(m_out_coeffs->T1plus(), ff_BA, m_in_coeffs->R1plus());
99  M11_RS(1, 0) = -VecMatVecProduct(m_out_coeffs->T1min(), ff_BA, m_in_coeffs->R1min());
100  M11_RS(1, 1) = VecMatVecProduct(m_out_coeffs->T1plus(), ff_BA, m_in_coeffs->R1min());
101  // eigenmode 1 -> eigenmode 1: scattering and then reflection
102  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_1T, kf_1R, wavelength));
103  M11_SR(0, 0) = -VecMatVecProduct(m_out_coeffs->R1min(), ff_BA, m_in_coeffs->T1plus());
104  M11_SR(0, 1) = VecMatVecProduct(m_out_coeffs->R1plus(), ff_BA, m_in_coeffs->T1plus());
105  M11_SR(1, 0) = -VecMatVecProduct(m_out_coeffs->R1min(), ff_BA, m_in_coeffs->T1min());
106  M11_SR(1, 1) = VecMatVecProduct(m_out_coeffs->R1plus(), ff_BA, m_in_coeffs->T1min());
107  // eigenmode 1 -> eigenmode 1: reflection, scattering and again reflection
108  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_1R, kf_1R, wavelength));
109  M11_RSR(0, 0) = -VecMatVecProduct(m_out_coeffs->R1min(), ff_BA, m_in_coeffs->R1plus());
110  M11_RSR(0, 1) = VecMatVecProduct(m_out_coeffs->R1plus(), ff_BA, m_in_coeffs->R1plus());
111  M11_RSR(1, 0) = -VecMatVecProduct(m_out_coeffs->R1min(), ff_BA, m_in_coeffs->R1min());
112  M11_RSR(1, 1) = VecMatVecProduct(m_out_coeffs->R1plus(), ff_BA, m_in_coeffs->R1min());
113 
114  // eigenmode 1 -> eigenmode 2: direct scattering
115  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_1T, kf_2T, wavelength));
116  M12_S(0, 0) = -VecMatVecProduct(m_out_coeffs->T2min(), ff_BA, m_in_coeffs->T1plus());
117  M12_S(0, 1) = VecMatVecProduct(m_out_coeffs->T2plus(), ff_BA, m_in_coeffs->T1plus());
118  M12_S(1, 0) = -VecMatVecProduct(m_out_coeffs->T2min(), ff_BA, m_in_coeffs->T1min());
119  M12_S(1, 1) = VecMatVecProduct(m_out_coeffs->T2plus(), ff_BA, m_in_coeffs->T1min());
120  // eigenmode 1 -> eigenmode 2: reflection and then scattering
121  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_1R, kf_2T, wavelength));
122  M12_RS(0, 0) = -VecMatVecProduct(m_out_coeffs->T2min(), ff_BA, m_in_coeffs->R1plus());
123  M12_RS(0, 1) = VecMatVecProduct(m_out_coeffs->T2plus(), ff_BA, m_in_coeffs->R1plus());
124  M12_RS(1, 0) = -VecMatVecProduct(m_out_coeffs->T2min(), ff_BA, m_in_coeffs->R1min());
125  M12_RS(1, 1) = VecMatVecProduct(m_out_coeffs->T2plus(), ff_BA, m_in_coeffs->R1min());
126  // eigenmode 1 -> eigenmode 2: scattering and then reflection
127  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_1T, kf_2R, wavelength));
128  M12_SR(0, 0) = -VecMatVecProduct(m_out_coeffs->R2min(), ff_BA, m_in_coeffs->T1plus());
129  M12_SR(0, 1) = VecMatVecProduct(m_out_coeffs->R2plus(), ff_BA, m_in_coeffs->T1plus());
130  M12_SR(1, 0) = -VecMatVecProduct(m_out_coeffs->R2min(), ff_BA, m_in_coeffs->T1min());
131  M12_SR(1, 1) = VecMatVecProduct(m_out_coeffs->R2plus(), ff_BA, m_in_coeffs->T1min());
132  // eigenmode 1 -> eigenmode 2: reflection, scattering and again reflection
133  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_1R, kf_2R, wavelength));
134  M12_RSR(0, 0) = -VecMatVecProduct(m_out_coeffs->R2min(), ff_BA, m_in_coeffs->R1plus());
135  M12_RSR(0, 1) = VecMatVecProduct(m_out_coeffs->R2plus(), ff_BA, m_in_coeffs->R1plus());
136  M12_RSR(1, 0) = -VecMatVecProduct(m_out_coeffs->R2min(), ff_BA, m_in_coeffs->R1min());
137  M12_RSR(1, 1) = VecMatVecProduct(m_out_coeffs->R2plus(), ff_BA, m_in_coeffs->R1min());
138 
139  // eigenmode 2 -> eigenmode 1: direct scattering
140  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_2T, kf_1T, wavelength));
141  M21_S(0, 0) = -VecMatVecProduct(m_out_coeffs->T1min(), ff_BA, m_in_coeffs->T2plus());
142  M21_S(0, 1) = VecMatVecProduct(m_out_coeffs->T1plus(), ff_BA, m_in_coeffs->T2plus());
143  M21_S(1, 0) = -VecMatVecProduct(m_out_coeffs->T1min(), ff_BA, m_in_coeffs->T2min());
144  M21_S(1, 1) = VecMatVecProduct(m_out_coeffs->T1plus(), ff_BA, m_in_coeffs->T2min());
145  // eigenmode 2 -> eigenmode 1: reflection and then scattering
146  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_2R, kf_1T, wavelength));
147  M21_RS(0, 0) = -VecMatVecProduct(m_out_coeffs->T1min(), ff_BA, m_in_coeffs->R2plus());
148  M21_RS(0, 1) = VecMatVecProduct(m_out_coeffs->T1plus(), ff_BA, m_in_coeffs->R2plus());
149  M21_RS(1, 0) = -VecMatVecProduct(m_out_coeffs->T1min(), ff_BA, m_in_coeffs->R2min());
150  M21_RS(1, 1) = VecMatVecProduct(m_out_coeffs->T1plus(), ff_BA, m_in_coeffs->R2min());
151  // eigenmode 2 -> eigenmode 1: scattering and then reflection
152  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_2T, kf_1R, wavelength));
153  M21_SR(0, 0) = -VecMatVecProduct(m_out_coeffs->R1min(), ff_BA, m_in_coeffs->T2plus());
154  M21_SR(0, 1) = VecMatVecProduct(m_out_coeffs->R1plus(), ff_BA, m_in_coeffs->T2plus());
155  M21_SR(1, 0) = -VecMatVecProduct(m_out_coeffs->R1min(), ff_BA, m_in_coeffs->T2min());
156  M21_SR(1, 1) = VecMatVecProduct(m_out_coeffs->R1plus(), ff_BA, m_in_coeffs->T2min());
157  // eigenmode 2 -> eigenmode 1: reflection, scattering and again reflection
158  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_2R, kf_1R, wavelength));
159  M21_RSR(0, 0) = -VecMatVecProduct(m_out_coeffs->R1min(), ff_BA, m_in_coeffs->R2plus());
160  M21_RSR(0, 1) = VecMatVecProduct(m_out_coeffs->R1plus(), ff_BA, m_in_coeffs->R2plus());
161  M21_RSR(1, 0) = -VecMatVecProduct(m_out_coeffs->R1min(), ff_BA, m_in_coeffs->R2min());
162  M21_RSR(1, 1) = VecMatVecProduct(m_out_coeffs->R1plus(), ff_BA, m_in_coeffs->R2min());
163 
164  // eigenmode 2 -> eigenmode 2: direct scattering
165  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_2T, kf_2T, wavelength));
166  M22_S(0, 0) = -VecMatVecProduct(m_out_coeffs->T2min(), ff_BA, m_in_coeffs->T2plus());
167  M22_S(0, 1) = VecMatVecProduct(m_out_coeffs->T2plus(), ff_BA, m_in_coeffs->T2plus());
168  M22_S(1, 0) = -VecMatVecProduct(m_out_coeffs->T2min(), ff_BA, m_in_coeffs->T2min());
169  M22_S(1, 1) = VecMatVecProduct(m_out_coeffs->T2plus(), ff_BA, m_in_coeffs->T2min());
170  // eigenmode 2 -> eigenmode 2: reflection and then scattering
171  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_2R, kf_2T, wavelength));
172  M22_RS(0, 0) = -VecMatVecProduct(m_out_coeffs->T2min(), ff_BA, m_in_coeffs->R2plus());
173  M22_RS(0, 1) = VecMatVecProduct(m_out_coeffs->T2plus(), ff_BA, m_in_coeffs->R2plus());
174  M22_RS(1, 0) = -VecMatVecProduct(m_out_coeffs->T2min(), ff_BA, m_in_coeffs->R2min());
175  M22_RS(1, 1) = VecMatVecProduct(m_out_coeffs->T2plus(), ff_BA, m_in_coeffs->R2min());
176  // eigenmode 2 -> eigenmode 2: scattering and then reflection
177  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_2T, kf_2R, wavelength));
178  M22_SR(0, 0) = -VecMatVecProduct(m_out_coeffs->R2min(), ff_BA, m_in_coeffs->T2plus());
179  M22_SR(0, 1) = VecMatVecProduct(m_out_coeffs->R2plus(), ff_BA, m_in_coeffs->T2plus());
180  M22_SR(1, 0) = -VecMatVecProduct(m_out_coeffs->R2min(), ff_BA, m_in_coeffs->T2min());
181  M22_SR(1, 1) = VecMatVecProduct(m_out_coeffs->R2plus(), ff_BA, m_in_coeffs->T2min());
182  // eigenmode 2 -> eigenmode 2: reflection, scattering and again reflection
183  ff_BA = m_ff->evaluatePol(WavevectorInfo(ki_2R, kf_2R, wavelength));
184  M22_RSR(0, 0) = -VecMatVecProduct(m_out_coeffs->R2min(), ff_BA, m_in_coeffs->R2plus());
185  M22_RSR(0, 1) = VecMatVecProduct(m_out_coeffs->R2plus(), ff_BA, m_in_coeffs->R2plus());
186  M22_RSR(1, 0) = -VecMatVecProduct(m_out_coeffs->R2min(), ff_BA, m_in_coeffs->R2min());
187  M22_RSR(1, 1) = VecMatVecProduct(m_out_coeffs->R2plus(), ff_BA, m_in_coeffs->R2min());
188 
189  return M11_S + M11_RS + M11_SR + M11_RSR + M12_S + M12_RS + M12_SR + M12_RSR + M21_S + M21_RS
190  + M21_SR + M21_RSR + M22_S + M22_RS + M22_SR + M22_RSR;
191 }
192 
193 void ComputeDWBAPol::setSpecularInfo(std::unique_ptr<const ILayerRTCoefficients> p_in_coeffs,
194  std::unique_ptr<const ILayerRTCoefficients> p_out_coeffs)
195 {
196  m_in_coeffs = std::move(p_in_coeffs);
197  m_out_coeffs = std::move(p_out_coeffs);
198 }
std::complex< double > complex_t
Definition: Complex.h:20
Defines class ComputeDWBAPol.
Defines and implements interface IFormFactor.
Defines and implements class ILayerRTCoefficients.
Defines WavevectorInfo.
T y() const
Returns y-component in cartesian coordinate system.
Definition: BasicVector3D.h:65
T x() const
Returns x-component in cartesian coordinate system.
Definition: BasicVector3D.h:63
void setZ(const T &a)
Sets z-component in cartesian coordinate system.
Definition: BasicVector3D.h:74
Provides polarized DWBA computation for given IFormFactor.
ComputeDWBAPol * clone() const override
Eigen::Matrix2cd evaluatePol(const WavevectorInfo &wavevectors) const override
Returns the coherent sum of the four DWBA terms for polarized scattering.
void setSpecularInfo(std::unique_ptr< const ILayerRTCoefficients > p_in_coeffs, std::unique_ptr< const ILayerRTCoefficients > p_out_coeffs) override
Sets reflection/transmission info.
std::unique_ptr< const ILayerRTCoefficients > m_in_coeffs
complex_t evaluate(const WavevectorInfo &wavevectors) const override
Throws not-implemented exception.
~ComputeDWBAPol() override
std::unique_ptr< const ILayerRTCoefficients > m_out_coeffs
ComputeDWBAPol(const IFormFactor &ff)
Abstract base class for form factor evaluations.
Definition: IComputeFF.h:39
std::unique_ptr< IFormFactor > m_ff
Definition: IComputeFF.h:64
Abstract base class for all form factors.
Definition: IFormFactor.h:36
Holds all wavevector information relevant for calculating form factors.
cvector_t getKf() const
cvector_t getKi() const
double wavelength() const