diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h index b89acd6824f2e13a5056bd340b57dc281d13457c..fdb10b8f6c03afc9ac9164d535901aff8a658283 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 bca48f4c68e499cb824cda9236b241404cf7db78..6c98097cca3110ee8ad5c1a7256b01fbd9965025 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 2aa2da307419ed1d9d98fb7b640af63cebc43d68..86b49b05879d9d30e42d3d5c2a0c4794857f07d8 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 35991f81e7058ffa9a0dd23b63ba7a691d34eae7..74a8017f8329752d9eb9f6ab9cd490a50453a178 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 6eb759f2bea15be875837d487714a67da3df0b60..79c338cd527efdc5a78a997944e7e35694a4e10d 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");