Mantid
Loading...
Searching...
No Matches
SymmetryOperation.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
9#include <memory>
10
11#include <boost/algorithm/string.hpp>
12
13namespace Mantid::Geometry {
14
17 : m_order(1), m_transposedInverseMatrix(Kernel::IntMatrix(3, 3, true)), m_reducedVector(), m_identifier(),
18 m_matrixVectorPair() {
20}
21
33SymmetryOperation::SymmetryOperation(const std::string &identifier) {
35}
36
41}
42
45 init(MatrixVectorPair<int, V3R>(convertMatrix<int>(matrix), vector));
46}
47
50 m_matrixVectorPair = matrixVectorPair;
51
52 // Inverse matrix for HKL operations.
56
59
61}
62
65
67const V3R &SymmetryOperation::vector() const { return m_matrixVectorPair.getVector(); }
68
94
100size_t SymmetryOperation::order() const { return m_order; }
101
107std::string SymmetryOperation::identifier() const { return m_identifier; }
108
111 return !hasTranslation() && m_matrixVectorPair.getMatrix() == Kernel::IntMatrix(3, 3, true);
112}
113
115bool SymmetryOperation::hasTranslation() const { return m_matrixVectorPair.getVector() != 0; }
116
128
150 return SymmetryOperation(result.getMatrix(), result.getVector());
151}
152
156
157 return SymmetryOperation(inverse.getMatrix(), inverse.getVector());
158}
159
162 // If the exponent is 1, no calculations are necessary.
163 if (exponent == 1) {
164 return SymmetryOperation(*this);
165 }
166
168
169 // The same for 0, which means identity in every case.
170 if (exponent == 0) {
171 return op;
172 }
173
174 for (size_t i = 0; i < exponent; ++i) {
175 op = (*this) * op;
176 }
177
178 return op;
179}
180
183 return m_matrixVectorPair == other.m_matrixVectorPair;
184}
185
188bool SymmetryOperation::operator<(const SymmetryOperation &other) const { return m_identifier < other.m_identifier; }
189
191bool SymmetryOperation::operator!=(const SymmetryOperation &other) const { return !(this->operator==(other)); }
192
197 int trace = matrix.Trace();
198 int determinant = matrix.determinant();
199
200 if (determinant == 1) {
201 switch (trace) {
202 case 3:
203 return 1;
204 case 2:
205 return 6;
206 case 1:
207 return 4;
208 case 0:
209 return 3;
210 case -1:
211 return 2;
212 default:
213 break;
214 }
215 } else if (determinant == -1) {
216 switch (trace) {
217 case -3:
218 return 2;
219 case -2:
220 return 6;
221 case -1:
222 return 4;
223 case 0:
224 return 6;
225 case 1:
226 return 2;
227 default:
228 break;
229 }
230 }
231
232 throw std::runtime_error("There is something wrong with supplied matrix.");
233}
234
236 Kernel::IntMatrix translationMatrix(3, 3, false);
237
238 for (size_t i = 0; i < order(); ++i) {
239 Kernel::IntMatrix tempMatrix(3, 3, true);
240
241 for (size_t j = 0; j < i; ++j) {
242 tempMatrix *= matrix;
243 }
244
245 translationMatrix += tempMatrix;
246 }
247
248 return (translationMatrix * vector) * RationalNumber(1, static_cast<int>(order()));
249}
250
262V3R getWrappedVector(const V3R &vector) {
263 V3R wrappedVector(vector);
264
265 for (size_t i = 0; i < 3; ++i) {
266 wrappedVector[i] -= (vector[i].numerator() / vector[i].denominator());
267
268 if (wrappedVector[i] < 0) {
269 wrappedVector[i] += 1;
270 }
271 }
272
273 return wrappedVector;
274}
275
279 Kernel::V3D wrappedVector;
280
281 for (size_t i = 0; i < 3; ++i) {
282 wrappedVector[i] = fmod(vector[i], 1.0);
283
284 if (wrappedVector[i] < 0) {
285 wrappedVector[i] += 1.0;
286 }
287 }
288
289 return wrappedVector;
290}
291
293std::ostream &operator<<(std::ostream &stream, const SymmetryOperation &operation) {
294 stream << "[" + operation.identifier() + "]";
295
296 return stream;
297}
298
300std::istream &operator>>(std::istream &stream, SymmetryOperation &operation) {
301 std::string identifier;
302 std::getline(stream, identifier);
303
304 size_t i = identifier.find_first_of('[');
305 size_t j = identifier.find_last_of(']');
306
307 if (i == std::string::npos || j == std::string::npos) {
308 throw std::runtime_error("Cannot construct SymmetryOperation from identifier: " + identifier);
309 }
310
311 operation = SymmetryOperation(identifier.substr(i + 1, j - i - 1));
312
313 return stream;
314}
315
318 return SymmetryOperation(symOp.matrix(), getWrappedVector(symOp.vector()));
319}
320
321} // namespace Mantid::Geometry
const VectorType & getVector() const
Returns a const reference to the stored vector.
const Kernel::Matrix< MatrixNumericType > & getMatrix() const
Returns a const reference to the internally stored matrix.
static std::string getNormalizedIdentifier(const MatrixVectorPair< int, V3R > &data)
Returns a Jones faithful representation of the symmetry operation characterized by the supplied matri...
static MatrixVectorPair< int, V3R > parseIdentifier(const std::string &identifier)
Tries to parse the given symbol.
Crystallographic symmetry operations are composed of a rotational component, which is represented by ...
SymmetryOperation inverse() const
Returns the inverse of the symmetry operation.
std::string identifier() const
Returns the string-identifier for this symmetry operation.
V3R getReducedVector(const Kernel::IntMatrix &matrix, const V3R &vector) const
size_t getOrderFromMatrix(const Kernel::IntMatrix &matrix) const
Returns the order of the symmetry operation based on the matrix.
void init(const MatrixVectorPair< int, V3R > &matrixVectorPair)
Initialize from matrix and vector.
bool operator==(const SymmetryOperation &other) const
Returns true if matrix and vector are equal.
bool isIdentity() const
Returns true if this is the identity operation.
const Kernel::IntMatrix & matrix() const
Returns a const reference to the internally stored matrix.
T operator*(const T &operand) const
Returns the transformed vector.
bool operator<(const SymmetryOperation &other) const
Returns true if SymmetryOperation is "smaller" than other, determined by using the identifier strings...
Kernel::V3D transformHKL(const Kernel::V3D &hkl) const
Transforms an index triplet hkl.
bool operator!=(const SymmetryOperation &other) const
Returns true if operatios are not equal.
SymmetryOperation operator^(size_t exponent) const
Returns the symmetry operation, applied to itself (exponent) times.
const V3R & reducedVector() const
SymmetryOperation::reducedVector.
bool hasTranslation() const
Returns true if the operation has a translational component.
SymmetryOperation()
Default constructor, results in identity.
MatrixVectorPair< int, V3R > m_matrixVectorPair
size_t order() const
Returns the order of the symmetry operation.
const V3R & vector() const
Returns a const reference to the internall stored vector.
T determinant() const
Calculate the determinant.
Definition: Matrix.cpp:1048
T Invert()
LU inversion routine.
Definition: Matrix.cpp:924
T Trace() const
Trace of the matrix.
Definition: Matrix.cpp:1280
Matrix< T > & Transpose()
Transpose the matrix.
Definition: Matrix.cpp:793
Class for 3D vectors.
Definition: V3D.h:34
MANTID_GEOMETRY_DLL std::istream & operator>>(std::istream &stream, SymmetryOperation &operation)
Reads identifier from stream and tries to parse as a symbol.
boost::rational< int > RationalNumber
V3R :
Definition: V3R.h:35
MANTID_GEOMETRY_DLL std::ostream & operator<<(std::ostream &stream, const PointGroup &self)
Returns a streamed representation of the PointGroup object.
Definition: PointGroup.cpp:312
MANTID_GEOMETRY_DLL V3R getWrappedVector(const V3R &vector)
Wraps a V3R to the interval (0, 1].
MANTID_GEOMETRY_DLL SymmetryOperation getUnitCellIntervalOperation(const SymmetryOperation &symOp)
Returns a SymmetryOperation with the vector wrapped to the interval (0, 1].
Mantid::Kernel::Matrix< int > IntMatrix
Definition: Matrix.h:207