From 285ff1dbcc3450d38b8b6a00f81c3cf03db8764b Mon Sep 17 00:00:00 2001 From: Michael Wedel <michael.wedel@psi.ch> Date: Mon, 8 Jun 2015 17:03:33 +0200 Subject: [PATCH] Refs #12749. Using reduced translation vector in reflection conditions --- .../Crystal/SymmetryOperation.h | 5 +- .../src/Crystal/SymmetryElementFactory.cpp | 26 +------- .../src/Crystal/SymmetryOperation.cpp | 62 +++++++++++++++---- .../test/SymmetryElementFactoryTest.h | 5 ++ .../Geometry/test/SymmetryOperationTest.h | 15 +++++ 5 files changed, 74 insertions(+), 39 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h index b89acd6824f..fdb10b8f6c0 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h @@ -129,7 +129,7 @@ public: const Kernel::IntMatrix &matrix() const; const V3R &vector() const; - V3R reducedVector() const; + const V3R &reducedVector() const; size_t order() const; std::string identifier() const; @@ -163,11 +163,14 @@ protected: void init(const Kernel::IntMatrix &matrix, const V3R &vector); size_t getOrderFromMatrix(const Kernel::IntMatrix &matrix) const; + V3R getReducedVector(const Kernel::IntMatrix &matrix, + const V3R &vector) const; size_t m_order; Kernel::IntMatrix m_matrix; Kernel::IntMatrix m_inverseMatrix; V3R m_vector; + V3R m_reducedVector; std::string m_identifier; }; diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElementFactory.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElementFactory.cpp index bca48f4c68e..6c98097cca3 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElementFactory.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElementFactory.cpp @@ -56,31 +56,7 @@ bool SymmetryElementInversionGenerator::canProcess( return operation.matrix() == inversionMatrix; } -/** - * @brief SymmetryElementWithAxisGenerator::determineTranslation - * - * According to ITA, 11.2, the translation component of a symmetry operation - * can be termined with the following algorithm. First, a matrix \f$W\f$ is - * calculated using the symmetry operation \f$S\f$ and its powers up to its - * order \f$k\f$, adding the matrices of the resulting operations: - * - * \f[ - * W = W_1(S^0) + W_2(S^1) + \dots + W_k(S^{k-1}) - * \f] - * - * The translation vector is then calculation from the vector \f$w\f$ of the - * operation: - * - * \f[ - * t = \frac{1}{k}\cdot (W \times w) - * \f] - * - * For operations which do not have translation components, this algorithm - * returns a 0-vector. - * - * @param operation :: Symmetry operation, possibly with translation vector. - * @return Translation vector. - */ +/// Returns the reduced vector of the operation. V3R SymmetryElementWithAxisGenerator::determineTranslation( const SymmetryOperation &operation) const { return operation.reducedVector(); diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp index 2aa2da30741..86b49b05879 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp @@ -11,7 +11,7 @@ namespace Geometry { SymmetryOperation::SymmetryOperation() : m_order(1), m_matrix(Kernel::IntMatrix(3, 3, true)), m_inverseMatrix(Kernel::IntMatrix(3, 3, true)), m_vector(), - m_identifier() { + m_reducedVector(), m_identifier() { m_identifier = SymmetryOperationSymbolParser::getNormalizedIdentifier( m_matrix, m_vector); } @@ -44,7 +44,8 @@ SymmetryOperation::SymmetryOperation(const Kernel::IntMatrix &matrix, SymmetryOperation::SymmetryOperation(const SymmetryOperation &other) : m_order(other.m_order), m_matrix(other.m_matrix), m_inverseMatrix(other.m_inverseMatrix), m_vector(other.m_vector), - m_identifier(other.m_identifier) {} + m_reducedVector(other.m_reducedVector), m_identifier(other.m_identifier) { +} /// Assignment operator SymmetryOperation &SymmetryOperation:: @@ -53,6 +54,7 @@ operator=(const SymmetryOperation &other) { m_matrix = other.m_matrix; m_inverseMatrix = other.m_inverseMatrix; m_vector = other.m_vector; + m_reducedVector = other.m_reducedVector; m_identifier = other.m_identifier; return *this; @@ -69,10 +71,11 @@ void SymmetryOperation::init(const Kernel::IntMatrix &matrix, m_inverseMatrix = m_inverseMatrix.Transpose(); m_vector = getWrappedVector(vector); - m_order = getOrderFromMatrix(m_matrix); m_identifier = SymmetryOperationSymbolParser::getNormalizedIdentifier( m_matrix, m_vector); + + m_reducedVector = getReducedVector(m_matrix, m_vector); } /// Returns a const reference to the internally stored matrix @@ -81,16 +84,31 @@ const Kernel::IntMatrix &SymmetryOperation::matrix() const { return m_matrix; } /// Returns a const reference to the internall stored vector const V3R &SymmetryOperation::vector() const { return m_vector; } -V3R SymmetryOperation::reducedVector() const { - Kernel::IntMatrix translationMatrix(3, 3, false); - - for (size_t i = 0; i < order(); ++i) { - translationMatrix += ((*this) ^ i).matrix(); - } - - return (translationMatrix * m_vector) * - RationalNumber(1, static_cast<int>(order())); -} +/** + * @brief SymmetryOperation::reducedVector + * + * According to ITA, 11.2, the translation component of a symmetry operation + * can be termined with the following algorithm. First, a matrix \f$W\f$ is + * calculated using the symmetry operation \f$S\f$ and its powers up to its + * order \f$k\f$, adding the matrices of the resulting operations: + * + * \f[ + * W = W_1(S^0) + W_2(S^1) + \dots + W_k(S^{k-1}) + * \f] + * + * The translation vector is then calculation from the vector \f$w\f$ of the + * operation: + * + * \f[ + * t = \frac{1}{k}\cdot (W \times w) + * \f] + * + * For operations which do not have translation components, this algorithm + * returns a 0-vector. + * + * @return Translation vector. + */ +const V3R &SymmetryOperation::reducedVector() const { return m_reducedVector; } /** * Returns the order of the symmetry operation @@ -242,6 +260,24 @@ SymmetryOperation::getOrderFromMatrix(const Kernel::IntMatrix &matrix) const { throw std::runtime_error("There is something wrong with supplied matrix."); } +V3R SymmetryOperation::getReducedVector(const Kernel::IntMatrix &matrix, + const V3R &vector) const { + Kernel::IntMatrix translationMatrix(3, 3, false); + + for (size_t i = 0; i < order(); ++i) { + Kernel::IntMatrix tempMatrix(3, 3, true); + + for (size_t j = 0; j < i; ++j) { + tempMatrix *= matrix; + } + + translationMatrix += tempMatrix; + } + + return (translationMatrix * vector) * + RationalNumber(1, static_cast<int>(order())); +} + /** * Wraps a V3R to the interval (0, 1] * diff --git a/Code/Mantid/Framework/Geometry/test/SymmetryElementFactoryTest.h b/Code/Mantid/Framework/Geometry/test/SymmetryElementFactoryTest.h index 35991f81e70..74a8017f832 100644 --- a/Code/Mantid/Framework/Geometry/test/SymmetryElementFactoryTest.h +++ b/Code/Mantid/Framework/Geometry/test/SymmetryElementFactoryTest.h @@ -199,6 +199,11 @@ public: V3R glideVectorC = V3R(0, 0, 1) / 2; SymmetryOperation glidePlaneC("x,-y,z+1/2"); TS_ASSERT_EQUALS(generator.determineTranslation(glidePlaneC), glideVectorC); + + V3R screwVectorThreeFourth = V3R(3, 0, 0) / 4; + SymmetryOperation fourThreeScrewAxis("x+3/4,-z+3/4,y+1/4"); + TS_ASSERT_EQUALS(generator.determineTranslation(fourThreeScrewAxis), + screwVectorThreeFourth); } void testSymmetryElementRotationDetermineRotationSense() { diff --git a/Code/Mantid/Framework/Geometry/test/SymmetryOperationTest.h b/Code/Mantid/Framework/Geometry/test/SymmetryOperationTest.h index 6eb759f2bea..79c338cd527 100644 --- a/Code/Mantid/Framework/Geometry/test/SymmetryOperationTest.h +++ b/Code/Mantid/Framework/Geometry/test/SymmetryOperationTest.h @@ -260,6 +260,21 @@ public: } + void testReducedVector() + { + SymmetryOperation fourThreeScrewAxis("x+3/4,-z+3/4,y+1/4"); + TS_ASSERT_EQUALS(fourThreeScrewAxis.reducedVector(), V3R(3, 0, 0) / 4); + + SymmetryOperation glidePlaneC("x,-y,z+1/2"); + TS_ASSERT_EQUALS(glidePlaneC.reducedVector(), V3R(0, 0, 1) / 2); + + SymmetryOperation noTranslation("-x,-y,-z"); + TS_ASSERT_EQUALS(noTranslation.reducedVector(), V3R(0, 0, 0)); + + SymmetryOperation noTranslationShifted("-x+1/8,-y+1/8,-z+1/8"); + TS_ASSERT_EQUALS(noTranslationShifted.reducedVector(), V3R(0, 0, 0)); + } + void testPower() { SymmetryOperation mirror("x,-y,z"); -- GitLab