BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
ScalarFresnelMap.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Sample/Fresnel/ScalarFresnelMap.cpp
6 //! @brief Implements class ScalarFresnelMap.
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 <functional>
18 
19 ScalarFresnelMap::ScalarFresnelMap(std::unique_ptr<ISpecularStrategy> strategy)
20  : IFresnelMap(std::move(strategy))
21 {
22 }
23 
25 
26 //! Returns hash value of a pair of doubles, computed by exclusive-or of the component hash values.
27 size_t ScalarFresnelMap::Hash2Doubles::operator()(const std::pair<double, double>& doubles) const
28  noexcept
29 {
30  return std::hash<double>{}(doubles.first) ^ std::hash<double>{}(doubles.second);
31 }
32 
33 std::unique_ptr<const ILayerRTCoefficients>
34 ScalarFresnelMap::getOutCoefficients(const SimulationElement& sim_element, size_t layer_index) const
35 {
36  return getCoefficients(-sim_element.getMeanKf(), layer_index);
37 }
38 
39 std::unique_ptr<const ILayerRTCoefficients>
40 ScalarFresnelMap::getCoefficients(const kvector_t& kvec, size_t layer_index) const
41 {
42  if (!m_use_cache) {
43  auto coeffs = m_Strategy->Execute(m_slices, kvec);
44  return std::unique_ptr<const ILayerRTCoefficients>(coeffs[layer_index]->clone());
45  }
46  const auto& coef_vector = getCoefficientsFromCache(kvec);
47  return std::unique_ptr<const ILayerRTCoefficients>(coef_vector[layer_index]->clone());
48 }
49 
51 {
52  std::pair<double, double> k2_theta(kvec.mag2(), kvec.theta());
53  auto it = m_cache.find(k2_theta);
54  if (it == m_cache.end()) {
55  it = m_cache.emplace(k2_theta, m_Strategy->Execute(m_slices, kvec)).first;
56  }
57  return it->second;
58 }
Defines class ScalarFresnelMap.
Defines class SimulationElement.
double mag2() const
Returns magnitude squared of the vector.
double theta() const
Returns polar angle.
Holds the necessary information to calculate the radiation wavefunction in every layer for different ...
Definition: IFresnelMap.h:30
std::vector< Slice > m_slices
Definition: IFresnelMap.h:57
std::unique_ptr< ISpecularStrategy > m_Strategy
Definition: IFresnelMap.h:60
bool m_use_cache
Definition: IFresnelMap.h:58
std::vector< std::unique_ptr< const ILayerRTCoefficients > > coeffs_t
size_t operator()(const std::pair< double, double > &doubles) const noexcept
Returns hash value of a pair of doubles, computed by exclusive-or of the component hash values.
std::unique_ptr< const ILayerRTCoefficients > getOutCoefficients(const SimulationElement &sim_element, size_t layer_index) const override
Retrieves the amplitude coefficients for a (time-reversed) outgoing wavevector.
ScalarFresnelMap(std::unique_ptr< ISpecularStrategy > strategy)
const ISpecularStrategy::coeffs_t & getCoefficientsFromCache(kvector_t kvec) const
std::unique_ptr< const ILayerRTCoefficients > getCoefficients(const kvector_t &kvec, size_t layer_index) const override
~ScalarFresnelMap() final
std::unordered_map< std::pair< double, double >, ISpecularStrategy::coeffs_t, Hash2Doubles > m_cache
Data stucture containing both input and output of a single detector cell.
kvector_t getMeanKf() const