Skip to content

Commit

Permalink
Refs #10305. Draft of symbol determination algorithm for rotations.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Wedel committed Feb 6, 2015
1 parent 2f4d3a6 commit f3d2cfc
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ class MANTID_GEOMETRY_DLL SymmetryElementRotation
RotationSense determineRotationSense(const SymmetryOperation &operation,
const V3R &rotationAxis) const;

bool isNotRotation(int determinant, int trace) const;
std::string determineSymbol(const SymmetryOperation &operation) const;

RotationSense m_rotationSense;
};

Expand Down
61 changes: 57 additions & 4 deletions Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <gsl/gsl_eigen.h>
#include <gsl/gsl_complex_math.h>
#include <boost/lexical_cast.hpp>

namespace Mantid {
namespace Geometry {
Expand Down Expand Up @@ -149,7 +150,14 @@ SymmetryElementRotation::SymmetryElementRotation()
: SymmetryElementWithAxis() {}

void SymmetryElementRotation::init(const SymmetryOperation &operation) {
UNUSED_ARG(operation);
int determinant = operation.matrix().determinant();
int trace = operation.matrix().Trace();

if (isNotRotation(determinant, trace)) {
throw std::invalid_argument(
"SymmetryOperation " + operation.identifier() +
" cannot be used to construct SymmetryElementRotation.");
}
}

SymmetryElementRotation::RotationSense
Expand All @@ -168,11 +176,56 @@ SymmetryElementRotation::determineRotationSense(

double determinant = matrix.determinant() * operation.matrix().determinant();

if(determinant < 0) {
return Negative;
if (determinant < 0) {
return Negative;
} else {
return Positive;
return Positive;
}
}

bool SymmetryElementRotation::isNotRotation(int determinant, int trace) const {
// It's an inversion or identity
if (abs(trace) == 3) {
return true;
}

// It's a mirror
if (trace == 1 && determinant == -1) {
return true;
}

return false;
}

std::string SymmetryElementRotation::determineSymbol(
const SymmetryOperation &operation) const {

const Kernel::IntMatrix &matrix = operation.matrix();

int trace = matrix.Trace();
int determinant = matrix.determinant();

if (trace == 0 && determinant == -1) {
return "-3";
}

std::string symbol;

if (determinant < 0) {
symbol += "-";
}

symbol += boost::lexical_cast<std::string>(operation.order());

int translation =
static_cast<int>(static_cast<double>(operation.order()) *
Kernel::V3D(determineTranslation(operation)).norm());

if (translation != 0) {
symbol += boost::lexical_cast<std::string>(translation);
}

return symbol;
}

SymmetryElementMirror::SymmetryElementMirror() : SymmetryElementWithAxis() {}
Expand Down
43 changes: 30 additions & 13 deletions Code/Mantid/Framework/Geometry/test/SymmetryElementTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "MantidGeometry/Crystal/SymmetryElement.h"
#include "MantidGeometry/Crystal/SpaceGroupFactory.h"
#include "MantidGeometry/Crystal/PointGroupFactory.h"

using namespace Mantid::Geometry;
using namespace Mantid::Kernel;
Expand Down Expand Up @@ -206,33 +207,49 @@ class SymmetryElementTest : public CxxTest::TestSuite {

// Test case 2: 6 [0 0 1] (Positive/Negative) in hexagonal system
SymmetryOperation sixFoldRotationZPlus("x-y,x,z");
V3R rotationAxisZ =
element.determineAxis(sixFoldRotationZPlus.matrix());
TS_ASSERT_EQUALS(element.determineRotationSense(
sixFoldRotationZPlus, rotationAxisZ),
SymmetryElementRotation::Positive);
V3R rotationAxisZ = element.determineAxis(sixFoldRotationZPlus.matrix());
TS_ASSERT_EQUALS(
element.determineRotationSense(sixFoldRotationZPlus, rotationAxisZ),
SymmetryElementRotation::Positive);

SymmetryOperation sixFoldRotationZMinus("y,y-x,z");
V3R rotationAxisZ2 =
element.determineAxis(sixFoldRotationZMinus.matrix());
V3R rotationAxisZ2 = element.determineAxis(sixFoldRotationZMinus.matrix());

TS_ASSERT_EQUALS(rotationAxisZ, rotationAxisZ2);

TS_ASSERT_EQUALS(element.determineRotationSense(
sixFoldRotationZMinus, rotationAxisZ2),
SymmetryElementRotation::Negative);
TS_ASSERT_EQUALS(
element.determineRotationSense(sixFoldRotationZMinus, rotationAxisZ2),
SymmetryElementRotation::Negative);
}

void xtestSymmetryElementWithAxisSpaceGroup() {
MockSymmetryElementWithAxis element;
void testSymmetryElementRotationDetermineSymbol() {
TestableSymmetryElementRotation element;

SymmetryOperation sixFoldRotationZMinus("y,y-x,z");

std::cout << element.determineSymbol(sixFoldRotationZMinus) << std::endl;
}

void testSymmetryElementWithAxisSpaceGroup() {
TestableSymmetryElementRotation element;

SpaceGroup_const_sptr sg =
SpaceGroupFactory::Instance().createSpaceGroup("P m -3");

PointGroup_sptr pg =
PointGroupFactory::Instance().createPointGroupFromSpaceGroupSymbol(
sg->hmSymbol());

std::vector<SymmetryOperation> ops = sg->getSymmetryOperations();
for (auto it = ops.begin(); it != ops.end(); ++it) {
V3R axis = element.determineAxis((*it).matrix());
SymmetryElementRotation::RotationSense sense =
element.determineRotationSense(*it, axis);
std::cout << (*it).identifier() << ": " << (*it).order() << " "
<< element.determineAxis((*it).matrix()) << std::endl;
<< pg->getReflectionFamily(axis) << " "
<< element.determineSymbol(*it)
<< (sense == SymmetryElementRotation::Positive ? "+" : "-")
<< std::endl;
}
}

Expand Down

0 comments on commit f3d2cfc

Please sign in to comment.