BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
Compute::SpecularMagnetic Namespace Reference

Description

Methods to compute polarized propagation directions and fluxes as function of slice.

Implements the transfer matrix formalism for the calculation of wave amplitudes of the coherent wave solution in a sample with magnetization. For a description, see internal document "Polarized Implementation of the Transfer Matrix Method"

Functions

Fluxes fluxes (const SliceStack &slices, const R3 &k, bool forward)
 Computes refraction angle reflection/transmission coefficients for given sliced sample and wavevector k. More...
 
SpinMatrix topLayerR (const SliceStack &slices, const std::vector< complex_t > &kzs, bool forward)
 Computes the Fresnel R coefficient for the top layer only Introduced in order to speed up pure reflectivity computations. More...
 

Function Documentation

◆ fluxes()

Fluxes Compute::SpecularMagnetic::fluxes ( const SliceStack slices,
const R3 &  k,
bool  forward 
)

Computes refraction angle reflection/transmission coefficients for given sliced sample and wavevector k.

Definition at line 176 of file ComputeFluxMagnetic.cpp.

177 {
178  if (slices.size() > 1 && k.z() > 0)
179  throw std::runtime_error(
180  "source or detector below horizon not yet implemented for polarized scattering");
181  std::vector<complex_t> kz = Compute::Kz::computeReducedKz(slices, k);
182  ASSERT(slices.size() == kz.size());
183 
184  Fluxes result;
185  for (auto& coeff : computeFlux(slices, kz, slices.roughnessModel(), forward))
186  result.emplace_back(std::make_unique<const MatrixFlux>(coeff));
187 
188  return result;
189 }
#define ASSERT(condition)
Definition: Assert.h:45
std::vector< std::unique_ptr< const IFlux > > Fluxes
RoughnessModel roughnessModel() const
Definition: SliceStack.h:57
std::vector< complex_t > computeReducedKz(const SliceStack &slices, R3 k)
Computes kz values from known k vector and slices with the following assumptions:

References ASSERT, Compute::Kz::computeReducedKz(), and SliceStack::roughnessModel().

Referenced by reSample::fluxesIn(), reSample::fluxesOut(), and DepthProbeComputation::runProtected().

Here is the call graph for this function:

◆ topLayerR()

SpinMatrix Compute::SpecularMagnetic::topLayerR ( const SliceStack slices,
const std::vector< complex_t > &  kzs,
bool  forward 
)

Computes the Fresnel R coefficient for the top layer only Introduced in order to speed up pure reflectivity computations.

Definition at line 191 of file ComputeFluxMagnetic.cpp.

193 {
194  const RoughnessModel& r_model = slices.roughnessModel();
195 
196  ASSERT(slices.size() == kzs.size());
197  const auto N = slices.size();
198  if (N == 1)
199  return SpinMatrix();
200  if (kzs[0] == 0.)
201  return -SpinMatrix::One();
202 
203  auto B_0 = slices.front().bField();
204  const double kz_sign = kzs.front().real() >= 0.0 ? 1.0 : -1.0; // save sign to restore it later
205 
206  auto createCoeff = [&slices, &kzs, kz_sign, B_0, forward](size_t i) {
207  const auto B = (forward ? +1 : -1) * (slices[i].bField() - B_0);
208  const auto magnetic_SLD = magneticSLD(B);
209 
210  return MatrixFlux(kz_sign, checkForUnderflow(eigenvalues(kzs[i], magnetic_SLD)),
211  B.mag() > eps ? B / B.mag() : R3{0.0, 0.0, 0.0}, magnetic_SLD);
212  };
213 
214  auto c_i1 = createCoeff(N - 1);
215 
216  // bottom boundary condition
217  c_i1.m_R = SpinMatrix();
218 
219  for (size_t i = N - 1; i > 0; --i) {
220  auto c_i = createCoeff(i - 1);
221 
222  double sigma = 0.;
223  if (const auto* const roughness = slices.bottomRoughness(i - 1))
224  sigma = roughness->sigma();
225 
226  // compute the 2x2 submatrices in the write-up denoted as P+, P- and delta
227  const auto [mp, mm] = computeBackwardsSubmatrices(c_i, c_i1, sigma, r_model);
228 
229  const SpinMatrix delta = c_i.computeDeltaMatrix(slices[i - 1].thicknessOr0());
230 
231  // compute the rotation matrix
232  SpinMatrix Si = mp + mm * c_i1.m_R;
233  SpinMatrix S(Si.d, -Si.b, -Si.c, Si.a);
234  const complex_t norm = S.determinant();
235  S = S * (delta / norm);
236 
237  c_i.m_R = delta * (mm + mp * c_i1.m_R) * S;
238  c_i1 = c_i;
239  }
240  return c_i1.m_R;
241 }
Specular reflection and transmission coefficients in a layer in case of magnetic interactions between...
Definition: MatrixFlux.h:32
const LayerRoughness * bottomRoughness(size_t i_slice) const
Definition: SliceStack.cpp:75
complex_t a
Definition: SpinMatrix.h:68
complex_t b
Definition: SpinMatrix.h:68
complex_t c
Definition: SpinMatrix.h:68
static SpinMatrix One()
Definition: SpinMatrix.cpp:36
complex_t d
Definition: SpinMatrix.h:68
#define N
Definition: mixmax.h:31

References SpinMatrix::a, ASSERT, SpinMatrix::b, SliceStack::bottomRoughness(), SpinMatrix::c, SpinMatrix::d, SpinMatrix::determinant(), N, SpinMatrix::One(), and SliceStack::roughnessModel().

Referenced by SpecularComputation::runProtected().

Here is the call graph for this function: