BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
FormFactorCrystal.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Sample/Particle/FormFactorCrystal.cpp
6 //! @brief Implements class FormFactorCrystal.
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"
19 
20 FormFactorCrystal::FormFactorCrystal(const Lattice& lattice, const IFormFactor& basis_form_factor,
21  const IFormFactor& meso_form_factor, double position_variance)
22  : m_lattice(lattice), mp_basis_form_factor(basis_form_factor.clone()),
23  mp_meso_form_factor(meso_form_factor.clone()), m_position_variance(position_variance)
24 {
25  setName("FormFactorCrystal");
26  calculateLargestReciprocalDistance();
27 }
28 
29 FormFactorCrystal::~FormFactorCrystal()
30 {
31  delete mp_basis_form_factor;
32  delete mp_meso_form_factor;
33 }
34 
35 double FormFactorCrystal::bottomZ(const IRotation& rotation) const
36 {
37  return mp_meso_form_factor->bottomZ(rotation);
38 }
39 
40 double FormFactorCrystal::topZ(const IRotation& rotation) const
41 {
42  return mp_meso_form_factor->topZ(rotation);
43 }
44 
45 complex_t FormFactorCrystal::evaluate(const WavevectorInfo& wavevectors) const
46 {
47  // retrieve reciprocal lattice vectors within reasonable radius
48  cvector_t q = wavevectors.getQ();
49  double radius = 2.1 * m_max_rec_length;
50  std::vector<kvector_t> rec_vectors =
51  m_lattice.reciprocalLatticeVectorsWithinRadius(q.real(), radius);
52 
53  // perform convolution on these lattice vectors
54  complex_t result(0.0, 0.0);
55  for (const auto& rec : rec_vectors) {
56  auto dw_factor = debyeWallerFactor(rec);
57  WavevectorInfo basis_wavevectors(kvector_t(), -rec, wavevectors.getWavelength());
58  complex_t basis_factor = mp_basis_form_factor->evaluate(basis_wavevectors);
59  WavevectorInfo meso_wavevectors(cvector_t(), rec.complex() - q,
60  wavevectors.getWavelength());
61  complex_t meso_factor = mp_meso_form_factor->evaluate(meso_wavevectors);
62  result += dw_factor * basis_factor * meso_factor;
63  }
64  // the transformed delta train gets a factor of (2pi)^3/V, but the (2pi)^3
65  // is canceled by the convolution of Fourier transforms :
66  double volume = m_lattice.volume();
67  return result / volume;
68 }
69 
70 Eigen::Matrix2cd FormFactorCrystal::evaluatePol(const WavevectorInfo& wavevectors) const
71 {
72  // retrieve reciprocal lattice vectors within reasonable radius
73  cvector_t q = wavevectors.getQ();
74  double radius = 2.1 * m_max_rec_length;
75  std::vector<kvector_t> rec_vectors =
76  m_lattice.reciprocalLatticeVectorsWithinRadius(q.real(), radius);
77 
78  // perform convolution on these lattice vectors
79  Eigen::Matrix2cd result = Eigen::Matrix2cd::Zero();
80  for (const auto& rec : rec_vectors) {
81  auto dw_factor = debyeWallerFactor(rec);
82  WavevectorInfo basis_wavevectors(kvector_t(), -rec, wavevectors.getWavelength());
83  Eigen::Matrix2cd basis_factor = mp_basis_form_factor->evaluatePol(basis_wavevectors);
84  WavevectorInfo meso_wavevectors(cvector_t(), rec.complex() - q,
85  wavevectors.getWavelength());
86  complex_t meso_factor = mp_meso_form_factor->evaluate(meso_wavevectors);
87  result += dw_factor * basis_factor * meso_factor;
88  }
89  // the transformed delta train gets a factor of (2pi)^3/V, but the (2pi)^3
90  // is canceled by the convolution of Fourier transforms :
91  double volume = m_lattice.volume();
92  return result / volume;
93 }
94 
95 void FormFactorCrystal::calculateLargestReciprocalDistance()
96 {
97  kvector_t a1 = m_lattice.getBasisVectorA();
98  kvector_t a2 = m_lattice.getBasisVectorB();
99  kvector_t a3 = m_lattice.getBasisVectorC();
100 
101  m_max_rec_length = std::max(M_PI / a1.mag(), M_PI / a2.mag());
102  m_max_rec_length = std::max(m_max_rec_length, M_PI / a3.mag());
103 }
104 
105 complex_t FormFactorCrystal::debyeWallerFactor(const kvector_t& q_i) const
106 {
107  auto q2 = q_i.mag2();
108  return std::exp(-q2 * m_position_variance / 2.0);
109 }
Defines many exception classes in namespace Exceptionss.
Defines class FormFactorCrystal.
Defines M_PI and some more mathematical constants.
Defines WavevectorInfo.
double mag2() const
Returns magnitude squared of the vector.
double mag() const
Returns magnitude of the vector.
BasicVector3D< double > real() const
Returns real parts.
BasicVector3D< std::complex< double > > complex() const
Returns this, trivially converted to complex type.
Eigen::Matrix2cd evaluatePol(const WavevectorInfo &wavevectors) const override final
Returns scattering amplitude for matrix interactions.
double bottomZ(const IRotation &rotation) const override
Returns the z-coordinate of the lowest point in this shape after a given rotation.
complex_t evaluate(const WavevectorInfo &wavevectors) const override final
Returns scattering amplitude for complex wavevectors ki, kf.
double volume() const override final
Returns the total volume of the particle of this form factor's shape.
double topZ(const IRotation &rotation) const override final
Returns the z-coordinate of the lowest point in this shape after a given rotation.
Pure virtual base class for all form factors.
Definition: IFormFactor.h:40
virtual complex_t evaluate(const WavevectorInfo &wavevectors) const =0
Returns scattering amplitude for complex wavevectors ki, kf.
virtual double topZ(const IRotation &rotation) const =0
Returns the z-coordinate of the lowest point in this shape after a given rotation.
virtual double bottomZ(const IRotation &rotation) const =0
Returns the z-coordinate of the lowest point in this shape after a given rotation.
virtual Eigen::Matrix2cd evaluatePol(const WavevectorInfo &wavevectors) const
Returns scattering amplitude for matrix interactions.
Definition: IFormFactor.cpp:49
Pure virtual interface for rotations.
Definition: Rotations.h:27
A lattice with three basis vectors.
Definition: Lattice.h:28
kvector_t getBasisVectorB() const
Returns basis vector b.
Definition: Lattice.h:47
std::vector< kvector_t > reciprocalLatticeVectorsWithinRadius(const kvector_t input_vector, double radius) const
Computes a list of reciprocal lattice vectors within a specified distance of a given vector.
Definition: Lattice.cpp:126
kvector_t getBasisVectorC() const
Returns basis vector c.
Definition: Lattice.h:50
double volume() const
Returns the volume of the unit cell.
Definition: Lattice.cpp:88
kvector_t getBasisVectorA() const
Returns basis vector a.
Definition: Lattice.h:44
Holds all wavevector information relevant for calculating form factors.