BornAgain  1.19.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 reflection and scattering
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 
16 #include "Base/Math/Functions.h"
21 
23  const std::vector<FormFactorCoherentSum>& weighted_formfactors,
24  const IInterferenceFunction* iff, SimulationOptions sim_params, bool polarized)
25  : IInterferenceFunctionStrategy(weighted_formfactors, sim_params, polarized)
26  , m_iff(iff ? iff->clone() : new InterferenceFunctionNone())
27 
28 {
29 }
30 
31 //! Returns the total incoherent and coherent scattering intensity for given kf and
32 //! for one particle layout (implied by the given particle form factors).
33 //! This is the scalar version
34 double
36 {
37  double intensity = 0.0;
38  complex_t amplitude = complex_t(0.0, 0.0);
39  for (const auto& ffw : m_weighted_formfactors) {
40  const complex_t ff = ffw.evaluate(sim_element);
41  if (std::isnan(ff.real()))
42  throw std::runtime_error(
43  "DecouplingApproximationStrategy::scalarCalculation() -> Error! Amplitude is NaN");
44  double fraction = ffw.relativeAbundance();
45  amplitude += fraction * ff;
46  intensity += fraction * std::norm(ff);
47  }
48  const double amplitude_norm = std::norm(amplitude);
49  const double coherence_factor = m_iff->evaluate(sim_element.meanQ());
50  return intensity + amplitude_norm * (coherence_factor - 1.0);
51 }
52 
53 //! This is the polarized version
54 double
56 {
57  Eigen::Matrix2cd mean_intensity = Eigen::Matrix2cd::Zero();
58  Eigen::Matrix2cd mean_amplitude = Eigen::Matrix2cd::Zero();
59 
60  const auto& polarization_handler = sim_element.polarizationHandler();
61  for (const auto& ffw : m_weighted_formfactors) {
62  const Eigen::Matrix2cd ff = ffw.evaluatePol(sim_element);
63  if (!ff.allFinite())
64  throw std::runtime_error("DecouplingApproximationStrategy::polarizedCalculation() -> "
65  "Error! Form factor contains NaN or infinite");
66  const double fraction = ffw.relativeAbundance();
67  mean_amplitude += fraction * ff;
68  mean_intensity += fraction * (ff * polarization_handler.getPolarization() * ff.adjoint());
69  }
70  const Eigen::Matrix2cd amplitude_matrix =
71  polarization_handler.getAnalyzerOperator() * mean_amplitude
72  * polarization_handler.getPolarization() * mean_amplitude.adjoint();
73  const Eigen::Matrix2cd intensity_matrix =
74  polarization_handler.getAnalyzerOperator() * mean_intensity;
75  const double amplitude_trace = std::abs(amplitude_matrix.trace());
76  const double intensity_trace = std::abs(intensity_matrix.trace());
77  const double coherence_factor = m_iff->evaluate(sim_element.meanQ());
78  return intensity_trace + amplitude_trace * (coherence_factor - 1.0);
79 }
std::complex< double > complex_t
Definition: Complex.h:20
Defines class DecouplingApproximationStrategy.
Defines class FormFactorCoherentSum.
Defines functions in namespace Math.
Defines class InterferenceFunctionNone.
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...
DecouplingApproximationStrategy(const std::vector< FormFactorCoherentSum > &weighted_formfactors, const IInterferenceFunction *iff, SimulationOptions sim_params, bool polarized)
double polarizedCalculation(const SimulationElement &sim_element) const override
This is the polarized version.
std::unique_ptr< IInterferenceFunction > m_iff
Base class of all interference function strategy classes.
std::vector< FormFactorCoherentSum > m_weighted_formfactors
Abstract base class of interference functions.
Default interference function (i.e.
Data stucture containing both input and output of a single detector cell.
kvector_t meanQ() const
const PolarizationHandler & polarizationHandler() const
Returns assigned PolarizationHandler.
Collect the different options for simulation.
matrixFFVector_t polarized(const SimulationElement &sim_element, const std::vector< FormFactorCoherentSum > &ff_wrappers)