BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
DecouplingApproximationStrategy.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Resample/Interparticle/DecouplingApproximationStrategy.cpp
6 //! @brief Implements class DecouplingApproximationStrategy.
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 
16 #include "Base/Math/Functions.h"
20 
22  const std::vector<std::unique_ptr<const CoherentFFSum>>& weighted_formfactors,
23  const IInterference* iff, SimulationOptions sim_params, bool polarized)
24  : IInterparticleStrategy(weighted_formfactors, sim_params, polarized)
25  , m_iff(iff ? iff->clone() : new InterferenceNone())
26 
27 {
28 }
29 
30 //! Returns the total incoherent and coherent scattering intensity for given kf and
31 //! for one particle layout (implied by the given particle form factors).
32 //! This is the scalar version
34 {
35  double intensity = 0.0;
36  complex_t amplitude = complex_t(0.0, 0.0);
37  for (const auto& ffw : m_weighted_formfactors) {
38  const complex_t ff = ffw->summedFF(ele);
39  if (std::isnan(ff.real()))
40  throw std::runtime_error(
41  "numerical error in coherent sum (scalar, DA): amplitude is NaN");
42  const double fraction = ffw->relativeAbundance();
43  amplitude += fraction * ff;
44  intensity += fraction * std::norm(ff);
45  }
46  const double amplitude_norm = std::norm(amplitude); // squared magnitude
47  const double coherence_factor = m_iff->structureFactor(ele.meanQ());
48  return intensity + amplitude_norm * (coherence_factor - 1.0);
49 }
50 
51 //! This is the polarized version
53 {
54  SpinMatrix mean_intensity;
55  SpinMatrix mean_amplitude;
56 
57  const auto& polarization_handler = ele.polMatrices();
58  for (const auto& ffw : m_weighted_formfactors) {
59  const SpinMatrix ff = ffw->summedPolFF(ele);
60  if (!ff.allFinite())
61  throw std::runtime_error(
62  "numerical error in coherent sum (polarized, DA): amplitude is NaN");
63  const double fraction = ffw->relativeAbundance();
64  mean_amplitude += fraction * ff;
65  mean_intensity += fraction * (ff * polarization_handler.polarizerMatrix() * ff.adjoint());
66  }
67  const SpinMatrix amplitude_matrix = polarization_handler.analyzerMatrix() * mean_amplitude
68  * polarization_handler.polarizerMatrix()
69  * mean_amplitude.adjoint();
70  const SpinMatrix intensity_matrix = polarization_handler.analyzerMatrix() * mean_intensity;
71  const double amplitude_trace = std::abs(amplitude_matrix.trace());
72  const double intensity_trace = std::abs(intensity_matrix.trace());
73  const double coherence_factor = m_iff->structureFactor(ele.meanQ());
74  return intensity_trace + amplitude_trace * (coherence_factor - 1.0);
75 }
Defines class CoherentFFSum.
Defines class DecouplingApproximationStrategy.
Defines class DiffuseElement.
Defines namespace Math.
Defines class InterferenceNone.
double polarizedCalculation(const DiffuseElement &ele) const override
This is the polarized version.
const std::unique_ptr< IInterference > m_iff
double scalarCalculation(const DiffuseElement &ele) const override
Returns the total incoherent and coherent scattering intensity for given kf and for one particle layo...
DecouplingApproximationStrategy(const std::vector< std::unique_ptr< const CoherentFFSum >> &weighted_formfactors, const IInterference *iff, SimulationOptions sim_params, bool polarized)
Data stucture containing both input and output of a single detector cell.
const PolMatrices & polMatrices() const
Returns polarizer and analyzer matrices.
Definition: IElement.h:37
Abstract base class of interference functions.
Definition: IInterference.h:24
Abstract base class of DecouplingApproximationStrategy, SSCAStrategy. Provides function 'evaluate' th...
const std::vector< std::unique_ptr< const CoherentFFSum > > & m_weighted_formfactors
Default interference function (i.e. absence of any interference).
Collect the different options for simulation.SimulationOptions.
SpinMatrix adjoint() const
Definition: SpinMatrix.cpp:180
complex_t trace() const
Definition: SpinMatrix.cpp:165