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 
24 using InterferenceFunctionUtils::PrecomputePolarizedFormFactors;
25 using InterferenceFunctionUtils::PrecomputeScalarFormFactors;
26 
27 DecouplingApproximationStrategy::DecouplingApproximationStrategy(SimulationOptions sim_params,
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
37 DecouplingApproximationStrategy::scalarCalculation(const SimulationElement& sim_element) const
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
58 DecouplingApproximationStrategy::polarizedCalculation(const SimulationElement& sim_element) const
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 }
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.
Base class of all interference function strategy classes.
Data stucture containing both input and output of a single detector cell.
const PolarizationHandler & polarizationHandler() const
Returns assigned PolarizationHandler.
Collect the different options for simulation.