BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
DecouplingApproximationStrategy.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Sample/Interference/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 
17 #include "Base/Types/Exceptions.h"
23 
26 
28  bool polarized)
29  : IInterferenceFunctionStrategy(sim_params, polarized)
30 {
31 }
32 
33 //! Returns the total incoherent and coherent scattering intensity for given kf and
34 //! for one particle layout (implied by the given particle form factors).
35 //! This is the scalar version
36 double
38 {
39  double intensity = 0.0;
40  complex_t amplitude = complex_t(0.0, 0.0);
41  auto precomputed_ff = PrecomputeScalarFormFactors(sim_element, m_formfactor_wrappers);
42  for (size_t i = 0; i < m_formfactor_wrappers.size(); ++i) {
43  complex_t ff = precomputed_ff[i];
44  if (std::isnan(ff.real()))
46  "DecouplingApproximationStrategy::scalarCalculation() -> Error! Amplitude is NaN");
47  double fraction = m_formfactor_wrappers[i].relativeAbundance();
48  amplitude += fraction * ff;
49  intensity += fraction * std::norm(ff);
50  }
51  double amplitude_norm = std::norm(amplitude);
52  double itf_function = mP_iff->evaluate(sim_element.getMeanQ());
53  return intensity + amplitude_norm * (itf_function - 1.0);
54 }
55 
56 //! This is the polarized version
57 double
59 {
60  Eigen::Matrix2cd mean_intensity = Eigen::Matrix2cd::Zero();
61  Eigen::Matrix2cd mean_amplitude = Eigen::Matrix2cd::Zero();
62 
63  auto precomputed_ff = PrecomputePolarizedFormFactors(sim_element, m_formfactor_wrappers);
64  const auto& polarization_handler = sim_element.polarizationHandler();
65  for (size_t i = 0; i < m_formfactor_wrappers.size(); ++i) {
66  Eigen::Matrix2cd ff = precomputed_ff[i];
67  if (!ff.allFinite())
69  "DecouplingApproximationStrategy::polarizedCalculation() -> "
70  "Error! Form factor contains NaN or infinite");
71  double fraction = m_formfactor_wrappers[i].relativeAbundance();
72  mean_amplitude += fraction * ff;
73  mean_intensity += fraction * (ff * polarization_handler.getPolarization() * ff.adjoint());
74  }
75  Eigen::Matrix2cd amplitude_matrix = polarization_handler.getAnalyzerOperator() * mean_amplitude
76  * polarization_handler.getPolarization()
77  * mean_amplitude.adjoint();
78  Eigen::Matrix2cd intensity_matrix = polarization_handler.getAnalyzerOperator() * mean_intensity;
79  double amplitude_trace = std::abs(amplitude_matrix.trace());
80  double intensity_trace = std::abs(intensity_matrix.trace());
81  double itf_function = mP_iff->evaluate(sim_element.getMeanQ());
82  return intensity_trace + amplitude_trace * (itf_function - 1.0);
83 }
std::complex< double > complex_t
Definition: Complex.h:20
Defines class DecouplingApproximationStrategy.
Defines many exception classes in namespace Exceptionss.
Defines class FormFactorCoherentSum.
Defines and implements the interface class IInterferenceFunction.
Defines helper functions for InterferenceFunctions and Strategies.
Defines namespace MathFunctions.
Defines class RealParameter.
Defines class SimulationElement.
double scalarCalculation(const SimulationElement &sim_element) const override
Returns the total incoherent and coherent scattering intensity for given kf and for one particle layo...
double polarizedCalculation(const SimulationElement &sim_element) const override
This is the polarized version.
DecouplingApproximationStrategy(SimulationOptions sim_params, bool polarized)
Base class of all interference function strategy classes.
std::vector< FormFactorCoherentSum > m_formfactor_wrappers
std::unique_ptr< IInterferenceFunction > mP_iff
Data stucture containing both input and output of a single detector cell.
kvector_t getMeanQ() const
const PolarizationHandler & polarizationHandler() const
Returns assigned PolarizationHandler.
Collect the different options for simulation.
std::vector< complex_t > PrecomputeScalarFormFactors(const SimulationElement &sim_element, const std::vector< FormFactorCoherentSum > &ff_wrappers)
matrixFFVector_t PrecomputePolarizedFormFactors(const SimulationElement &sim_element, const std::vector< FormFactorCoherentSum > &ff_wrappers)