BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
SumDWBA Class Reference

Description

Computes coherent sum of the four DWBA terms. Wraps an IReParticle, and provides functions evaluate or evaluatePol. Used from CoherentFFSum.

Definition at line 37 of file SumDWBA.h.

Collaboration diagram for SumDWBA:
[legend]

Public Member Functions

 SumDWBA (const IReParticle &ff)
 
 SumDWBA (const IReParticle &ff, size_t i_layer)
 
virtual ~SumDWBA ()
 
complex_t coherentFF (const DiffuseElement &ele) const
 Returns the coherent sum of the four DWBA terms for scalar scattering. More...
 
SpinMatrix coherentPolFF (const DiffuseElement &ele) const
 Returns the coherent sum of the four DWBA terms for polarized scattering. More...
 
const IReParticleff () const
 
size_t iLayer () const
 

Private Attributes

const std::unique_ptr< const IReParticlem_ff
 
const std::optional< size_t > m_i_layer
 

Friends

class TestPolarizedDWBATerm
 

Constructor & Destructor Documentation

◆ SumDWBA() [1/2]

SumDWBA::SumDWBA ( const IReParticle ff,
size_t  i_layer 
)

Definition at line 23 of file SumDWBA.cpp.

24  : m_ff(ff.clone())
25  , m_i_layer(i_layer)
26 {
27 }
const std::optional< size_t > m_i_layer
Definition: SumDWBA.h:55
const std::unique_ptr< const IReParticle > m_ff
Definition: SumDWBA.h:54

◆ SumDWBA() [2/2]

SumDWBA::SumDWBA ( const IReParticle ff)

Definition at line 29 of file SumDWBA.cpp.

30  : m_ff(ff.clone())
31  , m_i_layer()
32 {
33 }

◆ ~SumDWBA()

SumDWBA::~SumDWBA ( )
virtualdefault

Member Function Documentation

◆ coherentFF()

complex_t SumDWBA::coherentFF ( const DiffuseElement ele) const

Returns the coherent sum of the four DWBA terms for scalar scattering.

Definition at line 43 of file SumDWBA.cpp.

44 {
45  const WavevectorInfo& wavevectors = ele.wavevectorInfo();
46 
47  if (!m_i_layer.has_value())
48  // no slicing, pure Born approximation
49  return m_ff->theFF(wavevectors);
50 
51  const auto* inFlux = dynamic_cast<const ScalarFlux*>(ele.fluxIn(iLayer()));
52  const auto* outFlux = dynamic_cast<const ScalarFlux*>(ele.fluxOut(iLayer()));
53 
54  // Retrieve the two different incoming wavevectors in the layer
55  const C3& ki = wavevectors.getKi();
56  const complex_t kiz = inFlux->getScalarKz();
57  const C3 k_i_T{ki.x(), ki.y(), -kiz};
58  const C3 k_i_R{ki.x(), ki.y(), +kiz};
59 
60  // Retrieve the two different outgoing wavevector bins in the layer
61  const C3& kf = wavevectors.getKf();
62  const complex_t kfz = outFlux->getScalarKz();
63  const C3 k_f_T{kf.x(), kf.y(), +kfz};
64  const C3 k_f_R{kf.x(), kf.y(), -kfz};
65 
66  // Construct the four different scattering contributions wavevector infos
67  const double wavelength = wavevectors.vacuumLambda();
68  const WavevectorInfo q_TT(k_i_T, k_f_T, wavelength);
69  const WavevectorInfo q_RT(k_i_R, k_f_T, wavelength);
70  const WavevectorInfo q_TR(k_i_T, k_f_R, wavelength);
71  const WavevectorInfo q_RR(k_i_R, k_f_R, wavelength);
72 
73  // Get the four R,T coefficients
74  const complex_t T_in = inFlux->getScalarT();
75  const complex_t R_in = inFlux->getScalarR();
76  const complex_t T_out = outFlux->getScalarT();
77  const complex_t R_out = outFlux->getScalarR();
78 
79  // The four different scattering contributions;
80  // S stands for scattering off the particle,
81  // R for reflection off the layer interface.
82 
83  // Note that the order of multiplication matters:
84  // If a prefactor is 0, then theFF() won't be called.
85 
86  const complex_t term_S = T_in * T_out * m_ff->theFF(q_TT);
87  const complex_t term_RS = R_in * T_out * m_ff->theFF(q_RT);
88  const complex_t term_SR = T_in * R_out * m_ff->theFF(q_TR);
89  const complex_t term_RSR = R_in * R_out * m_ff->theFF(q_RR);
90 
91  return term_S + term_RS + term_SR + term_RSR;
92 }
const IFlux * fluxIn(size_t i_layer) const
const IFlux * fluxOut(size_t i_layer) const
WavevectorInfo wavevectorInfo() const
Specular reflection and transmission coefficients in a layer in case of scalar interactions between t...
Definition: ScalarFlux.h:29
size_t iLayer() const
Definition: SumDWBA.cpp:37
Holds all wavevector information relevant for calculating form factors.
C3 getKi() const
C3 getKf() const
double vacuumLambda() const

References DiffuseElement::fluxIn(), DiffuseElement::fluxOut(), WavevectorInfo::getKf(), WavevectorInfo::getKi(), iLayer(), m_ff, m_i_layer, WavevectorInfo::vacuumLambda(), and DiffuseElement::wavevectorInfo().

Here is the call graph for this function:

◆ coherentPolFF()

SpinMatrix SumDWBA::coherentPolFF ( const DiffuseElement ele) const

Returns the coherent sum of the four DWBA terms for polarized scattering.

Definition at line 94 of file SumDWBA.cpp.

95 {
96  const WavevectorInfo& wavevectors = ele.wavevectorInfo();
97 
98  if (!m_i_layer.has_value()) {
99  // no slicing, pure Born approximation
100  SpinMatrix o = m_ff->thePolFF(wavevectors);
101  return {-o.c, +o.a, -o.d, +o.b};
102  }
103 
104  const auto* inFlux = dynamic_cast<const MatrixFlux*>(ele.fluxIn(iLayer()));
105  const auto* outFlux = dynamic_cast<const MatrixFlux*>(ele.fluxOut(iLayer()));
106 
107  // the required wavevectors inside the layer for
108  // different eigenmodes and in- and outgoing wavevector;
109  const complex_t kix = wavevectors.getKi().x();
110  const complex_t kiy = wavevectors.getKi().y();
111  const Spinor& kiz = inFlux->getKz();
112  const C3 ki_1R{kix, kiy, +kiz.u};
113  const C3 ki_1T{kix, kiy, -kiz.u};
114  const C3 ki_2R{kix, kiy, +kiz.v};
115  const C3 ki_2T{kix, kiy, -kiz.v};
116 
117  const complex_t kfx = wavevectors.getKf().x();
118  const complex_t kfy = wavevectors.getKf().y();
119  const Spinor& kfz = outFlux->getKz();
120  const C3 kf_1R{kfx, kfy, -kfz.u};
121  const C3 kf_1T{kfx, kfy, +kfz.u};
122  const C3 kf_2R{kfx, kfy, -kfz.v};
123  const C3 kf_2T{kfx, kfy, +kfz.v};
124 
125  // now each of the 16 matrix terms of the polarized DWBA is calculated:
126  // NOTE: when the underlying reflection/transmission coefficients are
127  // scalar, the eigenmodes have identical eigenvalues and spin polarization
128  // is used as a basis; in this case however the matrices get mixed:
129  // real m_M11 = calculated m_M12
130  // real m_M12 = calculated m_M11
131  // real m_M21 = calculated m_M22
132  // real m_M22 = calculated m_M21
133  // since both eigenvalues are identical, this does not influence the result.
134  SpinMatrix ff_BA; // will be overwritten
135 
136  double wavelength = wavevectors.vacuumLambda();
137 
138  // The following matrices each contain the four polarization conditions
139  // (p->p, p->m, m->p, m->m)
140  // The first two indices indicate a scattering from the 1/2 eigenstate into
141  // the 1/2 eigenstate, while the capital indices indicate a reflection
142  // before and/or after the scattering event (first index is in-state,
143  // second is out-state; this also applies to the internal matrix indices)
144 
145  // eigenmode 1 -> eigenmode 1: direct scattering
146  ff_BA = m_ff->thePolFF({ki_1T, kf_1T, wavelength});
147  SpinMatrix M11_S(-DotProduct(outFlux->T1min(), ff_BA * inFlux->T1plus()),
148  +DotProduct(outFlux->T1plus(), ff_BA * inFlux->T1plus()),
149  -DotProduct(outFlux->T1min(), ff_BA * inFlux->T1min()),
150  +DotProduct(outFlux->T1plus(), ff_BA * inFlux->T1min()));
151  // eigenmode 1 -> eigenmode 1: reflection and then scattering
152  ff_BA = m_ff->thePolFF({ki_1R, kf_1T, wavelength});
153  SpinMatrix M11_RS(-DotProduct(outFlux->T1min(), ff_BA * inFlux->R1plus()),
154  +DotProduct(outFlux->T1plus(), ff_BA * inFlux->R1plus()),
155  -DotProduct(outFlux->T1min(), ff_BA * inFlux->R1min()),
156  +DotProduct(outFlux->T1plus(), ff_BA * inFlux->R1min()));
157  // eigenmode 1 -> eigenmode 1: scattering and then reflection
158  ff_BA = m_ff->thePolFF({ki_1T, kf_1R, wavelength});
159  SpinMatrix M11_SR(-DotProduct(outFlux->R1min(), ff_BA * inFlux->T1plus()),
160  +DotProduct(outFlux->R1plus(), ff_BA * inFlux->T1plus()),
161  -DotProduct(outFlux->R1min(), ff_BA * inFlux->T1min()),
162  +DotProduct(outFlux->R1plus(), ff_BA * inFlux->T1min()));
163  // eigenmode 1 -> eigenmode 1: reflection, scattering and again reflection
164  ff_BA = m_ff->thePolFF({ki_1R, kf_1R, wavelength});
165  SpinMatrix M11_RSR(-DotProduct(outFlux->R1min(), ff_BA * inFlux->R1plus()),
166  +DotProduct(outFlux->R1plus(), ff_BA * inFlux->R1plus()),
167  -DotProduct(outFlux->R1min(), ff_BA * inFlux->R1min()),
168  +DotProduct(outFlux->R1plus(), ff_BA * inFlux->R1min()));
169 
170  // eigenmode 1 -> eigenmode 2: direct scattering
171  ff_BA = m_ff->thePolFF({ki_1T, kf_2T, wavelength});
172  SpinMatrix M12_S(-DotProduct(outFlux->T2min(), ff_BA * inFlux->T1plus()),
173  +DotProduct(outFlux->T2plus(), ff_BA * inFlux->T1plus()),
174  -DotProduct(outFlux->T2min(), ff_BA * inFlux->T1min()),
175  +DotProduct(outFlux->T2plus(), ff_BA * inFlux->T1min()));
176  // eigenmode 1 -> eigenmode 2: reflection and then scattering
177  ff_BA = m_ff->thePolFF({ki_1R, kf_2T, wavelength});
178  SpinMatrix M12_RS(-DotProduct(outFlux->T2min(), ff_BA * inFlux->R1plus()),
179  +DotProduct(outFlux->T2plus(), ff_BA * inFlux->R1plus()),
180  -DotProduct(outFlux->T2min(), ff_BA * inFlux->R1min()),
181  +DotProduct(outFlux->T2plus(), ff_BA * inFlux->R1min()));
182  // eigenmode 1 -> eigenmode 2: scattering and then reflection
183  ff_BA = m_ff->thePolFF({ki_1T, kf_2R, wavelength});
184  SpinMatrix M12_SR(-DotProduct(outFlux->R2min(), ff_BA * inFlux->T1plus()),
185  +DotProduct(outFlux->R2plus(), ff_BA * inFlux->T1plus()),
186  -DotProduct(outFlux->R2min(), ff_BA * inFlux->T1min()),
187  +DotProduct(outFlux->R2plus(), ff_BA * inFlux->T1min()));
188  // eigenmode 1 -> eigenmode 2: reflection, scattering and again reflection
189  ff_BA = m_ff->thePolFF({ki_1R, kf_2R, wavelength});
190  SpinMatrix M12_RSR(-DotProduct(outFlux->R2min(), ff_BA * inFlux->R1plus()),
191  +DotProduct(outFlux->R2plus(), ff_BA * inFlux->R1plus()),
192  -DotProduct(outFlux->R2min(), ff_BA * inFlux->R1min()),
193  +DotProduct(outFlux->R2plus(), ff_BA * inFlux->R1min()));
194 
195  // eigenmode 2 -> eigenmode 1: direct scattering
196  ff_BA = m_ff->thePolFF({ki_2T, kf_1T, wavelength});
197  SpinMatrix M21_S(-DotProduct(outFlux->T1min(), ff_BA * inFlux->T2plus()),
198  +DotProduct(outFlux->T1plus(), ff_BA * inFlux->T2plus()),
199  -DotProduct(outFlux->T1min(), ff_BA * inFlux->T2min()),
200  +DotProduct(outFlux->T1plus(), ff_BA * inFlux->T2min()));
201  // eigenmode 2 -> eigenmode 1: reflection and then scattering
202  ff_BA = m_ff->thePolFF({ki_2R, kf_1T, wavelength});
203  SpinMatrix M21_RS(-DotProduct(outFlux->T1min(), ff_BA * inFlux->R2plus()),
204  +DotProduct(outFlux->T1plus(), ff_BA * inFlux->R2plus()),
205  -DotProduct(outFlux->T1min(), ff_BA * inFlux->R2min()),
206  +DotProduct(outFlux->T1plus(), ff_BA * inFlux->R2min()));
207  // eigenmode 2 -> eigenmode 1: scattering and then reflection
208  ff_BA = m_ff->thePolFF({ki_2T, kf_1R, wavelength});
209  SpinMatrix M21_SR(-DotProduct(outFlux->R1min(), ff_BA * inFlux->T2plus()),
210  +DotProduct(outFlux->R1plus(), ff_BA * inFlux->T2plus()),
211  -DotProduct(outFlux->R1min(), ff_BA * inFlux->T2min()),
212  +DotProduct(outFlux->R1plus(), ff_BA * inFlux->T2min()));
213  // eigenmode 2 -> eigenmode 1: reflection, scattering and again reflection
214  ff_BA = m_ff->thePolFF({ki_2R, kf_1R, wavelength});
215  SpinMatrix M21_RSR(-DotProduct(outFlux->R1min(), ff_BA * inFlux->R2plus()),
216  +DotProduct(outFlux->R1plus(), ff_BA * inFlux->R2plus()),
217  -DotProduct(outFlux->R1min(), ff_BA * inFlux->R2min()),
218  +DotProduct(outFlux->R1plus(), ff_BA * inFlux->R2min()));
219 
220  // eigenmode 2 -> eigenmode 2: direct scattering
221  ff_BA = m_ff->thePolFF({ki_2T, kf_2T, wavelength});
222  SpinMatrix M22_S(-DotProduct(outFlux->T2min(), ff_BA * inFlux->T2plus()),
223  +DotProduct(outFlux->T2plus(), ff_BA * inFlux->T2plus()),
224  -DotProduct(outFlux->T2min(), ff_BA * inFlux->T2min()),
225  +DotProduct(outFlux->T2plus(), ff_BA * inFlux->T2min()));
226  // eigenmode 2 -> eigenmode 2: reflection and then scattering
227  ff_BA = m_ff->thePolFF({ki_2R, kf_2T, wavelength});
228  SpinMatrix M22_RS(-DotProduct(outFlux->T2min(), ff_BA * inFlux->R2plus()),
229  +DotProduct(outFlux->T2plus(), ff_BA * inFlux->R2plus()),
230  -DotProduct(outFlux->T2min(), ff_BA * inFlux->R2min()),
231  +DotProduct(outFlux->T2plus(), ff_BA * inFlux->R2min()));
232  // eigenmode 2 -> eigenmode 2: scattering and then reflection
233  ff_BA = m_ff->thePolFF({ki_2T, kf_2R, wavelength});
234  SpinMatrix M22_SR(-DotProduct(outFlux->R2min(), ff_BA * inFlux->T2plus()),
235  +DotProduct(outFlux->R2plus(), ff_BA * inFlux->T2plus()),
236  -DotProduct(outFlux->R2min(), ff_BA * inFlux->T2min()),
237  +DotProduct(outFlux->R2plus(), ff_BA * inFlux->T2min()));
238  // eigenmode 2 -> eigenmode 2: reflection, scattering and again reflection
239  ff_BA = m_ff->thePolFF({ki_2R, kf_2R, wavelength});
240  SpinMatrix M22_RSR(-DotProduct(outFlux->R2min(), ff_BA * inFlux->R2plus()),
241  +DotProduct(outFlux->R2plus(), ff_BA * inFlux->R2plus()),
242  -DotProduct(outFlux->R2min(), ff_BA * inFlux->R2min()),
243  +DotProduct(outFlux->R2plus(), ff_BA * inFlux->R2min()));
244 
245  return M11_S + M11_RS + M11_SR + M11_RSR + M12_S + M12_RS + M12_SR + M12_RSR + M21_S + M21_RS
246  + M21_SR + M21_RSR + M22_S + M22_RS + M22_SR + M22_RSR;
247 }
complex_t DotProduct(const Spinor &r, const Spinor &t)
Definition: Spinor.cpp:55
Specular reflection and transmission coefficients in a layer in case of magnetic interactions between...
Definition: MatrixFlux.h:32
complex_t a
Definition: SpinMatrix.h:68
complex_t b
Definition: SpinMatrix.h:68
complex_t c
Definition: SpinMatrix.h:68
complex_t d
Definition: SpinMatrix.h:68
Definition: Spinor.h:20
complex_t v
Definition: Spinor.h:31
complex_t u
Definition: Spinor.h:31

References SpinMatrix::a, SpinMatrix::b, SpinMatrix::c, SpinMatrix::d, DotProduct(), DiffuseElement::fluxIn(), DiffuseElement::fluxOut(), WavevectorInfo::getKf(), WavevectorInfo::getKi(), iLayer(), m_ff, m_i_layer, Spinor::u, Spinor::v, WavevectorInfo::vacuumLambda(), and DiffuseElement::wavevectorInfo().

Here is the call graph for this function:

◆ ff()

const IReParticle& SumDWBA::ff ( ) const
inline

Definition at line 44 of file SumDWBA.h.

44 { return *m_ff; }

References m_ff.

◆ iLayer()

size_t SumDWBA::iLayer ( ) const

Definition at line 37 of file SumDWBA.cpp.

38 {
39  ASSERT(m_i_layer.has_value());
40  return m_i_layer.value();
41 }
#define ASSERT(condition)
Definition: Assert.h:45

References ASSERT, and m_i_layer.

Referenced by coherentFF(), and coherentPolFF().

Friends And Related Function Documentation

◆ TestPolarizedDWBATerm

friend class TestPolarizedDWBATerm
friend

Definition at line 57 of file SumDWBA.h.

Member Data Documentation

◆ m_ff

const std::unique_ptr<const IReParticle> SumDWBA::m_ff
private

Definition at line 54 of file SumDWBA.h.

Referenced by coherentFF(), coherentPolFF(), and ff().

◆ m_i_layer

const std::optional<size_t> SumDWBA::m_i_layer
private

Definition at line 55 of file SumDWBA.h.

Referenced by coherentFF(), coherentPolFF(), and iLayer().


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