BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
FormFactorDWBAPol.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Sample/Scattering/FormFactorDWBAPol.cpp
6 //! @brief Defines class FormFactorDWBAPol.
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 
18 
19 namespace
20 {
21 std::complex<double> 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  : mP_form_factor(form_factor.clone())
30 {
31  setName("FormFactorDWBAPol");
32 }
33 
35 
37 {
39  std::unique_ptr<const ILayerRTCoefficients> p_in_coefs =
40  mp_in_coeffs ? std::unique_ptr<const ILayerRTCoefficients>(mp_in_coeffs->clone()) : nullptr;
41  std::unique_ptr<const ILayerRTCoefficients> p_out_coefs =
42  mp_out_coeffs ? std::unique_ptr<const ILayerRTCoefficients>(mp_out_coeffs->clone())
43  : nullptr;
44  p_result->setSpecularInfo(std::move(p_in_coefs), std::move(p_out_coefs));
45  return p_result;
46 }
47 
49 {
51  "FormFactorDWBAPol::evaluate: should never be called for matrix interactions");
52 }
53 
54 Eigen::Matrix2cd FormFactorDWBAPol::evaluatePol(const WavevectorInfo& wavevectors) const
55 {
56  // the required wavevectors inside the layer for
57  // different eigenmodes and in- and outgoing wavevector;
58  complex_t kix = wavevectors.getKi().x();
59  complex_t kiy = wavevectors.getKi().y();
60  cvector_t ki_1R(kix, kiy, mp_in_coeffs->getKz()(0));
61  cvector_t ki_1T(kix, kiy, -mp_in_coeffs->getKz()(0));
62  cvector_t ki_2R(kix, kiy, mp_in_coeffs->getKz()(1));
63  cvector_t ki_2T(kix, kiy, -mp_in_coeffs->getKz()(1));
64 
65  cvector_t kf_1R = wavevectors.getKf();
66  kf_1R.setZ(-(complex_t)mp_out_coeffs->getKz()(0));
67  cvector_t kf_1T = kf_1R;
68  kf_1T.setZ((complex_t)mp_out_coeffs->getKz()(0));
69  cvector_t kf_2R = kf_1R;
70  kf_2R.setZ(-(complex_t)mp_out_coeffs->getKz()(1));
71  cvector_t kf_2T = kf_1R;
72  kf_2T.setZ((complex_t)mp_out_coeffs->getKz()(1));
73  // now each of the 16 matrix terms of the polarized DWBA is calculated:
74  // NOTE: when the underlying reflection/transmission coefficients are
75  // scalar, the eigenmodes have identical eigenvalues and spin polarization
76  // is used as a basis; in this case however the matrices get mixed:
77  // real m_M11 = calculated m_M12
78  // real m_M12 = calculated m_M11
79  // real m_M21 = calculated m_M22
80  // real m_M22 = calculated m_M21
81  // since both eigenvalues are identical, this does not influence the result.
82  Eigen::Matrix2cd ff_BA;
83 
84  double wavelength = wavevectors.getWavelength();
85 
86  // The following matrices each contain the four polarization conditions
87  // (p->p, p->m, m->p, m->m)
88  // The first two indices indicate a scattering from the 1/2 eigenstate into
89  // the 1/2 eigenstate, while the capital indices indicate a reflection
90  // before and/or after the scattering event (first index is in-state,
91  // second is out-state; this also applies to the internal matrix indices)
92  Eigen::Matrix2cd M11_S, M11_RS, M11_SR, M11_RSR, M12_S, M12_RS, M12_SR, M12_RSR, M21_S, M21_RS,
93  M21_SR, M21_RSR, M22_S, M22_RS, M22_SR, M22_RSR;
94 
95  // eigenmode 1 -> eigenmode 1: direct scattering
96  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_1T, kf_1T, wavelength));
97  M11_S(0, 0) = -VecMatVecProduct(mp_out_coeffs->T1min(), ff_BA, mp_in_coeffs->T1plus());
98  M11_S(0, 1) = VecMatVecProduct(mp_out_coeffs->T1plus(), ff_BA, mp_in_coeffs->T1plus());
99  M11_S(1, 0) = -VecMatVecProduct(mp_out_coeffs->T1min(), ff_BA, mp_in_coeffs->T1min());
100  M11_S(1, 1) = VecMatVecProduct(mp_out_coeffs->T1plus(), ff_BA, mp_in_coeffs->T1min());
101  // eigenmode 1 -> eigenmode 1: reflection and then scattering
102  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_1R, kf_1T, wavelength));
103  M11_RS(0, 0) = -VecMatVecProduct(mp_out_coeffs->T1min(), ff_BA, mp_in_coeffs->R1plus());
104  M11_RS(0, 1) = VecMatVecProduct(mp_out_coeffs->T1plus(), ff_BA, mp_in_coeffs->R1plus());
105  M11_RS(1, 0) = -VecMatVecProduct(mp_out_coeffs->T1min(), ff_BA, mp_in_coeffs->R1min());
106  M11_RS(1, 1) = VecMatVecProduct(mp_out_coeffs->T1plus(), ff_BA, mp_in_coeffs->R1min());
107  // eigenmode 1 -> eigenmode 1: scattering and then reflection
108  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_1T, kf_1R, wavelength));
109  M11_SR(0, 0) = -VecMatVecProduct(mp_out_coeffs->R1min(), ff_BA, mp_in_coeffs->T1plus());
110  M11_SR(0, 1) = VecMatVecProduct(mp_out_coeffs->R1plus(), ff_BA, mp_in_coeffs->T1plus());
111  M11_SR(1, 0) = -VecMatVecProduct(mp_out_coeffs->R1min(), ff_BA, mp_in_coeffs->T1min());
112  M11_SR(1, 1) = VecMatVecProduct(mp_out_coeffs->R1plus(), ff_BA, mp_in_coeffs->T1min());
113  // eigenmode 1 -> eigenmode 1: reflection, scattering and again reflection
114  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_1R, kf_1R, wavelength));
115  M11_RSR(0, 0) = -VecMatVecProduct(mp_out_coeffs->R1min(), ff_BA, mp_in_coeffs->R1plus());
116  M11_RSR(0, 1) = VecMatVecProduct(mp_out_coeffs->R1plus(), ff_BA, mp_in_coeffs->R1plus());
117  M11_RSR(1, 0) = -VecMatVecProduct(mp_out_coeffs->R1min(), ff_BA, mp_in_coeffs->R1min());
118  M11_RSR(1, 1) = VecMatVecProduct(mp_out_coeffs->R1plus(), ff_BA, mp_in_coeffs->R1min());
119 
120  // eigenmode 1 -> eigenmode 2: direct scattering
121  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_1T, kf_2T, wavelength));
122  M12_S(0, 0) = -VecMatVecProduct(mp_out_coeffs->T2min(), ff_BA, mp_in_coeffs->T1plus());
123  M12_S(0, 1) = VecMatVecProduct(mp_out_coeffs->T2plus(), ff_BA, mp_in_coeffs->T1plus());
124  M12_S(1, 0) = -VecMatVecProduct(mp_out_coeffs->T2min(), ff_BA, mp_in_coeffs->T1min());
125  M12_S(1, 1) = VecMatVecProduct(mp_out_coeffs->T2plus(), ff_BA, mp_in_coeffs->T1min());
126  // eigenmode 1 -> eigenmode 2: reflection and then scattering
127  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_1R, kf_2T, wavelength));
128  M12_RS(0, 0) = -VecMatVecProduct(mp_out_coeffs->T2min(), ff_BA, mp_in_coeffs->R1plus());
129  M12_RS(0, 1) = VecMatVecProduct(mp_out_coeffs->T2plus(), ff_BA, mp_in_coeffs->R1plus());
130  M12_RS(1, 0) = -VecMatVecProduct(mp_out_coeffs->T2min(), ff_BA, mp_in_coeffs->R1min());
131  M12_RS(1, 1) = VecMatVecProduct(mp_out_coeffs->T2plus(), ff_BA, mp_in_coeffs->R1min());
132  // eigenmode 1 -> eigenmode 2: scattering and then reflection
133  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_1T, kf_2R, wavelength));
134  M12_SR(0, 0) = -VecMatVecProduct(mp_out_coeffs->R2min(), ff_BA, mp_in_coeffs->T1plus());
135  M12_SR(0, 1) = VecMatVecProduct(mp_out_coeffs->R2plus(), ff_BA, mp_in_coeffs->T1plus());
136  M12_SR(1, 0) = -VecMatVecProduct(mp_out_coeffs->R2min(), ff_BA, mp_in_coeffs->T1min());
137  M12_SR(1, 1) = VecMatVecProduct(mp_out_coeffs->R2plus(), ff_BA, mp_in_coeffs->T1min());
138  // eigenmode 1 -> eigenmode 2: reflection, scattering and again reflection
139  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_1R, kf_2R, wavelength));
140  M12_RSR(0, 0) = -VecMatVecProduct(mp_out_coeffs->R2min(), ff_BA, mp_in_coeffs->R1plus());
141  M12_RSR(0, 1) = VecMatVecProduct(mp_out_coeffs->R2plus(), ff_BA, mp_in_coeffs->R1plus());
142  M12_RSR(1, 0) = -VecMatVecProduct(mp_out_coeffs->R2min(), ff_BA, mp_in_coeffs->R1min());
143  M12_RSR(1, 1) = VecMatVecProduct(mp_out_coeffs->R2plus(), ff_BA, mp_in_coeffs->R1min());
144 
145  // eigenmode 2 -> eigenmode 1: direct scattering
146  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_2T, kf_1T, wavelength));
147  M21_S(0, 0) = -VecMatVecProduct(mp_out_coeffs->T1min(), ff_BA, mp_in_coeffs->T2plus());
148  M21_S(0, 1) = VecMatVecProduct(mp_out_coeffs->T1plus(), ff_BA, mp_in_coeffs->T2plus());
149  M21_S(1, 0) = -VecMatVecProduct(mp_out_coeffs->T1min(), ff_BA, mp_in_coeffs->T2min());
150  M21_S(1, 1) = VecMatVecProduct(mp_out_coeffs->T1plus(), ff_BA, mp_in_coeffs->T2min());
151  // eigenmode 2 -> eigenmode 1: reflection and then scattering
152  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_2R, kf_1T, wavelength));
153  M21_RS(0, 0) = -VecMatVecProduct(mp_out_coeffs->T1min(), ff_BA, mp_in_coeffs->R2plus());
154  M21_RS(0, 1) = VecMatVecProduct(mp_out_coeffs->T1plus(), ff_BA, mp_in_coeffs->R2plus());
155  M21_RS(1, 0) = -VecMatVecProduct(mp_out_coeffs->T1min(), ff_BA, mp_in_coeffs->R2min());
156  M21_RS(1, 1) = VecMatVecProduct(mp_out_coeffs->T1plus(), ff_BA, mp_in_coeffs->R2min());
157  // eigenmode 2 -> eigenmode 1: scattering and then reflection
158  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_2T, kf_1R, wavelength));
159  M21_SR(0, 0) = -VecMatVecProduct(mp_out_coeffs->R1min(), ff_BA, mp_in_coeffs->T2plus());
160  M21_SR(0, 1) = VecMatVecProduct(mp_out_coeffs->R1plus(), ff_BA, mp_in_coeffs->T2plus());
161  M21_SR(1, 0) = -VecMatVecProduct(mp_out_coeffs->R1min(), ff_BA, mp_in_coeffs->T2min());
162  M21_SR(1, 1) = VecMatVecProduct(mp_out_coeffs->R1plus(), ff_BA, mp_in_coeffs->T2min());
163  // eigenmode 2 -> eigenmode 1: reflection, scattering and again reflection
164  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_2R, kf_1R, wavelength));
165  M21_RSR(0, 0) = -VecMatVecProduct(mp_out_coeffs->R1min(), ff_BA, mp_in_coeffs->R2plus());
166  M21_RSR(0, 1) = VecMatVecProduct(mp_out_coeffs->R1plus(), ff_BA, mp_in_coeffs->R2plus());
167  M21_RSR(1, 0) = -VecMatVecProduct(mp_out_coeffs->R1min(), ff_BA, mp_in_coeffs->R2min());
168  M21_RSR(1, 1) = VecMatVecProduct(mp_out_coeffs->R1plus(), ff_BA, mp_in_coeffs->R2min());
169 
170  // eigenmode 2 -> eigenmode 2: direct scattering
171  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_2T, kf_2T, wavelength));
172  M22_S(0, 0) = -VecMatVecProduct(mp_out_coeffs->T2min(), ff_BA, mp_in_coeffs->T2plus());
173  M22_S(0, 1) = VecMatVecProduct(mp_out_coeffs->T2plus(), ff_BA, mp_in_coeffs->T2plus());
174  M22_S(1, 0) = -VecMatVecProduct(mp_out_coeffs->T2min(), ff_BA, mp_in_coeffs->T2min());
175  M22_S(1, 1) = VecMatVecProduct(mp_out_coeffs->T2plus(), ff_BA, mp_in_coeffs->T2min());
176  // eigenmode 2 -> eigenmode 2: reflection and then scattering
177  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_2R, kf_2T, wavelength));
178  M22_RS(0, 0) = -VecMatVecProduct(mp_out_coeffs->T2min(), ff_BA, mp_in_coeffs->R2plus());
179  M22_RS(0, 1) = VecMatVecProduct(mp_out_coeffs->T2plus(), ff_BA, mp_in_coeffs->R2plus());
180  M22_RS(1, 0) = -VecMatVecProduct(mp_out_coeffs->T2min(), ff_BA, mp_in_coeffs->R2min());
181  M22_RS(1, 1) = VecMatVecProduct(mp_out_coeffs->T2plus(), ff_BA, mp_in_coeffs->R2min());
182  // eigenmode 2 -> eigenmode 2: scattering and then reflection
183  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_2T, kf_2R, wavelength));
184  M22_SR(0, 0) = -VecMatVecProduct(mp_out_coeffs->R2min(), ff_BA, mp_in_coeffs->T2plus());
185  M22_SR(0, 1) = VecMatVecProduct(mp_out_coeffs->R2plus(), ff_BA, mp_in_coeffs->T2plus());
186  M22_SR(1, 0) = -VecMatVecProduct(mp_out_coeffs->R2min(), ff_BA, mp_in_coeffs->T2min());
187  M22_SR(1, 1) = VecMatVecProduct(mp_out_coeffs->R2plus(), ff_BA, mp_in_coeffs->T2min());
188  // eigenmode 2 -> eigenmode 2: reflection, scattering and again reflection
189  ff_BA = mP_form_factor->evaluatePol(WavevectorInfo(ki_2R, kf_2R, wavelength));
190  M22_RSR(0, 0) = -VecMatVecProduct(mp_out_coeffs->R2min(), ff_BA, mp_in_coeffs->R2plus());
191  M22_RSR(0, 1) = VecMatVecProduct(mp_out_coeffs->R2plus(), ff_BA, mp_in_coeffs->R2plus());
192  M22_RSR(1, 0) = -VecMatVecProduct(mp_out_coeffs->R2min(), ff_BA, mp_in_coeffs->R2min());
193  M22_RSR(1, 1) = VecMatVecProduct(mp_out_coeffs->R2plus(), ff_BA, mp_in_coeffs->R2min());
194 
195  return M11_S + M11_RS + M11_SR + M11_RSR + M12_S + M12_RS + M12_SR + M12_RSR + M21_S + M21_RS
196  + M21_SR + M21_RSR + M22_S + M22_RS + M22_SR + M22_RSR;
197 }
198 
199 double FormFactorDWBAPol::bottomZ(const IRotation& rotation) const
200 {
201  return mP_form_factor->bottomZ(rotation);
202 }
203 
204 double FormFactorDWBAPol::topZ(const IRotation& rotation) const
205 {
206  return mP_form_factor->topZ(rotation);
207 }
208 
209 void FormFactorDWBAPol::setSpecularInfo(std::unique_ptr<const ILayerRTCoefficients> p_in_coeffs,
210  std::unique_ptr<const ILayerRTCoefficients> p_out_coeffs)
211 {
212  mp_in_coeffs = std::move(p_in_coeffs);
213  mp_out_coeffs = std::move(p_out_coeffs);
214 }
std::complex< double > complex_t
Definition: Complex.h:20
Defines class FormFactorDWBAPol.
Defines and implements class ILayerRTCoefficients.
Defines WavevectorInfo.
T y() const
Returns y-component in cartesian coordinate system.
Definition: BasicVector3D.h:66
T x() const
Returns x-component in cartesian coordinate system.
Definition: BasicVector3D.h:64
void setZ(const T &a)
Sets z-component in cartesian coordinate system.
Definition: BasicVector3D.h:75
Evaluates the coherent sum of the 16 matrix DWBA terms in a polarized IFormFactor.
double bottomZ(const IRotation &rotation) const override
Returns the z-coordinate of the lowest point in this shape after a given rotation.
std::unique_ptr< const ILayerRTCoefficients > mp_in_coeffs
Eigen::Matrix2cd evaluatePol(const WavevectorInfo &wavevectors) const override
Calculates and returns a polarized form factor calculation in DWBA.
std::unique_ptr< IFormFactor > mP_form_factor
The form factor for BA.
double topZ(const IRotation &rotation) const override
Returns the z-coordinate of the lowest point in this shape after a given rotation.
std::unique_ptr< const ILayerRTCoefficients > mp_out_coeffs
FormFactorDWBAPol(const IFormFactor &form_factor)
complex_t evaluate(const WavevectorInfo &wavevectors) const override
Throws not-implemented exception.
~FormFactorDWBAPol() override
void setSpecularInfo(std::unique_ptr< const ILayerRTCoefficients > p_in_coeffs, std::unique_ptr< const ILayerRTCoefficients > p_out_coeffs) override
Sets reflection/transmission info.
FormFactorDWBAPol * clone() const override
Returns a clone of this ISample object.
Pure virtual base class for all form factors.
Definition: IFormFactor.h:40
void setName(const std::string &name)
Pure virtual interface for rotations.
Definition: Rotations.h:27
Holds all wavevector information relevant for calculating form factors.
cvector_t getKf() const
cvector_t getKi() const
double getWavelength() const
std::complex< double > VecMatVecProduct(const Eigen::Vector2cd &vec1, const Eigen::Matrix2cd &ff, const Eigen::Vector2cd &vec2)