BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
ILatticeOrientation.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Sample/Lattice/ILatticeOrientation.cpp
6 //! @brief Implements subclasses of ILatticeOrientation.
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 
17 namespace
18 {
19 bool ValidMillerIndex(MillerIndex index);
20 bool ParallelMillerIndices(MillerIndex index1, MillerIndex index2);
25 void FillVectorInRow(Eigen::Matrix3d& matrix, kvector_t vec,
27 } // unnamed namespace
28 
30 
31 MillerIndex::MillerIndex(double h_, double k_, double l_) : h(h_), k(k_), l(l_) {}
32 
34  MillerIndex index1,
36  MillerIndex index2)
37  : m_prim_lattice(), m_q1(q1), m_q2(q2), m_ind1{index1}, m_ind2{index2}
38 {
39  if (!checkAlignment())
40  throw std::runtime_error("MillerIndexOrientation constructor: "
41  "invalid alignment parameters");
42 }
43 
45 {
46  auto* result = new MillerIndexOrientation(m_q1, m_ind1, m_q2, m_ind2);
47  result->usePrimitiveLattice(m_prim_lattice);
48  return result;
49 }
50 
52 
54 {
56  lattice.getBasisVectorC());
57 }
58 
60 {
63  auto dir_2_parallel = dir_2.project(dir_1);
64  dir_2 = (dir_2 - dir_2_parallel).unit();
65  auto dir_3 = SignForCrossProduct(m_q1, m_q2) * dir_1.cross(dir_2);
66  auto q3 = ThirdQComponent(m_q1, m_q2);
67  Eigen::Matrix3d rot_matrix;
68  FillVectorInRow(rot_matrix, dir_1, m_q1);
69  FillVectorInRow(rot_matrix, dir_2, m_q2);
70  FillVectorInRow(rot_matrix, dir_3, q3);
71  return Transform3D(rot_matrix);
72 }
73 
75 {
76  if (m_q1 == m_q2)
77  return false;
79  return false;
81  return false;
82  return true;
83 }
84 
85 namespace
86 {
88 {
89  return (index.h != 0.0 || index.k != 0.0 || index.l != 0.0);
90 }
92 {
93  double ratio = 0.0;
94  if (index2.h != 0.0) {
95  ratio = index1.h / index2.h;
96  } else if (index2.k != 0.0) {
97  ratio = index1.k / index2.k;
98  } else if (index2.l != 0.0) {
99  ratio = index1.l / index2.l;
100  }
101  if (ratio == 0.0)
102  return false;
103  return (index1.h == ratio * index2.h && index1.k == ratio * index2.k
104  && index1.l == ratio * index2.l);
105 }
108 {
112  return 1.0;
113  return -1.0;
114 }
117 {
123 }
125 {
126  int i = row == MillerIndexOrientation::QX ? 0 : row == MillerIndexOrientation::QY ? 1 : 2;
127  for (int j = 0; j < 3; ++j)
128  mat(i, j) = vec[j];
129 }
130 } // unnamed namespace
Defines interface ILatticeOrientation and subclasses.
BasicVector3D< T > project(const BasicVector3D< T > &v) const
Returns projection of this onto other vector: (this*v)*v/|v|^2.
virtual ~ILatticeOrientation()
A lattice with three basis vectors.
Definition: Lattice.h:28
void resetBasis(const kvector_t a1, const kvector_t a2, const kvector_t a3)
Resets the basis vectors.
Definition: Lattice.cpp:72
kvector_t getMillerDirection(double h, double k, double l) const
Returns normalized direction corresponding to the given Miller indices.
Definition: Lattice.cpp:80
kvector_t getBasisVectorB() const
Returns basis vector b.
Definition: Lattice.h:47
kvector_t getBasisVectorC() const
Returns basis vector c.
Definition: Lattice.h:50
kvector_t getBasisVectorA() const
Returns basis vector a.
Definition: Lattice.h:44
Specifies a rotation of a lattice through the Miller indices of two coordinate axes.
Transform3D transformationMatrix() const override
~MillerIndexOrientation() override
void usePrimitiveLattice(const Lattice &lattice) override
MillerIndexOrientation(QComponent q1, MillerIndex index1, QComponent q2, MillerIndex index2)
This constructor is best explained by an example.
MillerIndexOrientation * clone() const override
Vector transformations in three dimensions.
Definition: Transform3D.h:28
MillerIndexOrientation::QComponent ThirdQComponent(MillerIndexOrientation::QComponent q1, MillerIndexOrientation::QComponent q2)
bool ParallelMillerIndices(MillerIndex index1, MillerIndex index2)
double SignForCrossProduct(MillerIndexOrientation::QComponent q1, MillerIndexOrientation::QComponent q2)
void FillVectorInRow(Eigen::Matrix3d &matrix, kvector_t vec, MillerIndexOrientation::QComponent row)
A direction in reciprocal space, specified by double-valued indices hkl.
MillerIndex(double h_, double k_, double l_)