diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h index 35c4879f71fe702b7391ead9b3b9e545bd07ec85..f3a0860f1a926d3ed2de26b8698aa8945ec9120d 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h @@ -46,7 +46,7 @@ public: /// Hermann-Mauguin symbol std::string getSymbol() const; - CrystalSystem crystalSystem() const { return Cubic; } + CrystalSystem crystalSystem() const { return m_crystalSystem; } /// Return true if the hkls are in same group bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; @@ -56,14 +56,16 @@ public: /// Returns the same hkl for all equivalent hkls Kernel::V3D getReflectionFamily(const Kernel::V3D &hkl) const; - protected: bool groupHasNoTranslations(const Group &group) const; std::vector<Kernel::V3D> getEquivalentSet(const Kernel::V3D &hkl) const; + CrystalSystem getCrystalSystemFromGroup() const; + std::string m_symbolHM; std::string m_name; + CrystalSystem m_crystalSystem; }; /// Shared pointer to a PointGroup diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h index 36c9c583dbea2ff8d866ea1fdc32a1345d414fcf..ed748f1d82cc1a460333f8530a15b0d853da66d9 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h @@ -87,7 +87,7 @@ public: std::vector<std::string> getAllPointGroupSymbols() const; std::vector<std::string> - getPointGroupSymbols(const PointGroup::CrystalSystem &crystalSystem) const; + getPointGroupSymbols(const PointGroup::CrystalSystem &crystalSystem); void subscribePointGroup(const std::string &hmSymbol, const std::string &generatorString, diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/PointGroup.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/PointGroup.cpp index ecbe2174f8dddfcd11dac99450e73bb156ee666a..81180588d552b1ea2d2bde8e2b6767f9b005540c 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/PointGroup.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/PointGroup.cpp @@ -7,6 +7,7 @@ #include "MantidGeometry/Crystal/PointGroupFactory.h" #include "MantidGeometry/Crystal/SymmetryOperationFactory.h" +#include "MantidGeometry/Crystal/SymmetryElementFactory.h" namespace Mantid { namespace Geometry { @@ -49,7 +50,7 @@ std::vector<V3D> PointGroup::getEquivalents(const V3D &hkl) const { * @return :: hkl specific to a family of index-triplets */ V3D PointGroup::getReflectionFamily(const Kernel::V3D &hkl) const { - return *getEquivalentSet(hkl).rbegin(); + return *getEquivalentSet(hkl).begin(); } bool PointGroup::groupHasNoTranslations(const Group &group) const { @@ -68,16 +69,20 @@ bool PointGroup::groupHasNoTranslations(const Group &group) const { PointGroup::PointGroup(const std::string &symbolHM, const Group &group, const std::string &description) : Group(group), m_symbolHM(symbolHM), - m_name(symbolHM + " (" + description + ")") {} + m_name(symbolHM + " (" + description + ")") { + m_crystalSystem = getCrystalSystemFromGroup(); +} PointGroup::PointGroup(const PointGroup &other) - : Group(other), m_symbolHM(other.m_symbolHM), m_name(other.m_name) {} + : Group(other), m_symbolHM(other.m_symbolHM), m_name(other.m_name), + m_crystalSystem(other.m_crystalSystem) {} PointGroup &PointGroup::operator=(const PointGroup &other) { Group::operator=(other); m_symbolHM = other.m_symbolHM; m_name = other.m_name; + m_crystalSystem = other.m_crystalSystem; return *this; } @@ -115,7 +120,7 @@ std::vector<V3D> PointGroup::getEquivalentSet(const Kernel::V3D &hkl) const { equivalents.push_back((*op).matrix() * hkl); } - std::sort(equivalents.begin(), equivalents.end()); + std::sort(equivalents.begin(), equivalents.end(), std::greater<V3D>()); equivalents.erase(std::unique(equivalents.begin(), equivalents.end()), equivalents.end()); @@ -123,6 +128,60 @@ std::vector<V3D> PointGroup::getEquivalentSet(const Kernel::V3D &hkl) const { return equivalents; } +PointGroup::CrystalSystem PointGroup::getCrystalSystemFromGroup() const { + std::map<std::string, std::set<V3D> > symbolMap; + + for (auto op = m_allOperations.begin(); op != m_allOperations.end(); ++op) { + SymmetryElementWithAxis_sptr element = + boost::dynamic_pointer_cast<SymmetryElementWithAxis>( + SymmetryElementFactory::Instance().createSymElement(*op)); + + if (element) { + std::string symbol = element->hmSymbol(); + V3D axis = element->getAxis(); + + symbolMap[symbol].insert(axis); + } + } + + if (symbolMap["3"].size() == 4) { + return Cubic; + } + + if (symbolMap["6"].size() == 1) { + return Hexagonal; + } + + if (symbolMap["3"].size() == 1) { + return Trigonal; + } + + if (symbolMap["4"].size() == 1) { + return Tetragonal; + } + + if (symbolMap["2"].size() == 3 || + (symbolMap["2"].size() == 1 && symbolMap["m"].size() == 2)) { + return Orthorhombic; + } + + if (symbolMap["2"].size() == 1 || symbolMap["m"].size() == 1) { + return Monoclinic; + } + + return Triclinic; + + std::cout << getName() << ": " << std::endl; + for (auto it = symbolMap.begin(); it != symbolMap.end(); ++it) { + std::cout << it->first << " "; + for (auto k = it->second.begin(); k != it->second.end(); ++k) { + std::cout << *k << " "; + } + std::cout << std::endl; + } + std::cout << "---------" << std::endl; +} + /** @return a vector with all possible PointGroup objects */ std::vector<PointGroup_sptr> getAllPointGroups() { std::vector<std::string> allSymbols = diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp index 01e1d076de97080ed453e2c7321937cbd8a7775f..ffd085e66befde5257d4aea0ad404bb4c0f0d6ad 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp @@ -33,8 +33,7 @@ std::vector<std::string> PointGroupFactoryImpl::getAllPointGroupSymbols() const { std::vector<std::string> pointGroups; - for (auto it = m_generatorMap.begin(); it != m_generatorMap.end(); - ++it) { + for (auto it = m_generatorMap.begin(); it != m_generatorMap.end(); ++it) { pointGroups.push_back(it->first); } @@ -44,12 +43,13 @@ PointGroupFactoryImpl::getAllPointGroupSymbols() const { /// Returns the Hermann-Mauguin symbols of all point groups that belong to a /// certain crystal system. std::vector<std::string> PointGroupFactoryImpl::getPointGroupSymbols( - const PointGroup::CrystalSystem &crystalSystem) const { + const PointGroup::CrystalSystem &crystalSystem) { std::vector<std::string> pointGroups; - for (auto it = m_crystalSystemMap.begin(); it != m_crystalSystemMap.end(); - ++it) { - if (it->second == crystalSystem) { + for (auto it = m_generatorMap.begin(); it != m_generatorMap.end(); ++it) { + PointGroup_sptr pointGroup = getPrototype(it->first); + + if (pointGroup->crystalSystem() == crystalSystem) { pointGroups.push_back(it->first); } } @@ -184,7 +184,7 @@ PointGroup_sptr PointGroupGenerator::generatePrototype() { m_description); } -DECLARE_POINTGROUP("1", "x,y,z", "Triclinic") +//DECLARE_POINTGROUP("1", "x,y,z", "Triclinic") DECLARE_POINTGROUP("-1", "-x,-y,-z", "Triclinic") DECLARE_POINTGROUP("2/m", "-x,y,-z; x,-y,z", "Monoclinic, unique axis b") DECLARE_POINTGROUP("112/m", "-x,-y,z; x,y,-z", "Monoclinic, unique axis c") diff --git a/Code/Mantid/Framework/Geometry/test/PointGroupTest.h b/Code/Mantid/Framework/Geometry/test/PointGroupTest.h index 73c36b97aac60d32d6d5ccfb0207f0a2cb8a441a..6efb8c8345a3141f8de75fdea8a7a9a13e1d0c45 100644 --- a/Code/Mantid/Framework/Geometry/test/PointGroupTest.h +++ b/Code/Mantid/Framework/Geometry/test/PointGroupTest.h @@ -110,68 +110,14 @@ public: check_point_group("-4m2", V3D(1,2,3), 8, equiv); } } } -/* - void xtestConstruction() - { - TestablePointGroup defaultPointgroup; - - TS_ASSERT_EQUALS(defaultPointgroup.m_symmetryOperations.size(), 0); - } - - void xtestAddSymmetryOperation() - { - TestablePointGroup pg; - - TS_ASSERT_EQUALS(pg.getSymmetryOperations().size(), 0); - - SymmetryOperation symOp = SymmetryOperationFactory::Instance().createSymOp("x,y,z"); - pg.addSymmetryOperation(symOp); - std::vector<SymmetryOperation> ops = pg.getSymmetryOperations(); - TS_ASSERT_EQUALS(ops.size(), 1); - TS_ASSERT_EQUALS(ops[0], symOp); - } - - void xtestGenerateTransformationMatrices() - { - TestablePointGroup pg; - - SymmetryOperation identity = SymmetryOperationFactory::Instance().createSymOp("x,y,z"); - SymmetryOperation inversion = SymmetryOperationFactory::Instance().createSymOp("x,y,z"); - SymmetryOperation mirror = SymmetryOperationFactory::Instance().createSymOp("x,y,-z"); - SymmetryOperation twoFold = SymmetryOperationFactory::Instance().createSymOp("-x,-y,z"); - - pg.addSymmetryOperation(mirror); - pg.addSymmetryOperation(twoFold); - - std::vector<SymmetryOperation> ops = pg.getSymmetryOperations(); - TS_ASSERT_EQUALS(ops.size(), 2); - - std::vector<SymmetryOperation> matrices = pg.generateSymmetryOperations(ops); - - // Mirror and 2-fold axis generate inversion, identity is implicit. - TS_ASSERT_EQUALS(matrices.size(), 4); - - auto matrixVectorBegin = matrices.begin(); - auto matrixVectorEnd = matrices.end(); - - SymmetryOperation identityOp = SymmetryOperationFactory::Instance().createSymOp("x,y,z"); - - TS_ASSERT_DIFFERS(std::find(matrixVectorBegin, matrixVectorEnd, identity * identityOp), matrixVectorEnd); - TS_ASSERT_DIFFERS(std::find(matrixVectorBegin, matrixVectorEnd, inversion * identityOp), matrixVectorEnd); - TS_ASSERT_DIFFERS(std::find(matrixVectorBegin, matrixVectorEnd, mirror * identityOp), matrixVectorEnd); - TS_ASSERT_DIFFERS(std::find(matrixVectorBegin, matrixVectorEnd, twoFold * identityOp), matrixVectorEnd); - - TS_ASSERT_DIFFERS(matrices[0], matrices[1]); - } - - void xtestCrystalSystems() + void testCrystalSystems() { std::map<std::string, PointGroup::CrystalSystem> crystalSystemsMap; crystalSystemsMap["-1 (Triclinic)"] = PointGroup::Triclinic; - crystalSystemsMap["1 2/m 1 (Monoclinic, unique axis b)"] = PointGroup::Monoclinic; - crystalSystemsMap["1 1 2/m (Monoclinic, unique axis c)"] = PointGroup::Monoclinic; + crystalSystemsMap["2/m (Monoclinic, unique axis b)"] = PointGroup::Monoclinic; + crystalSystemsMap["112/m (Monoclinic, unique axis c)"] = PointGroup::Monoclinic; crystalSystemsMap["mmm (Orthorombic)"] = PointGroup::Orthorhombic; crystalSystemsMap["4/m (Tetragonal)"] = PointGroup::Tetragonal; crystalSystemsMap["4/mmm (Tetragonal)"] = PointGroup::Tetragonal; @@ -190,7 +136,7 @@ public: } } - void xtestCrystalSystemMap() + void testCrystalSystemMap() { std::vector<PointGroup_sptr> pointgroups = getAllPointGroups(); PointGroupCrystalSystemMap pgMap = getPointGroupsByCrystalSystem(); @@ -206,17 +152,6 @@ public: TS_ASSERT_EQUALS(pgMap.count(PointGroup::Cubic), 2); } - void xtestInit() - { - PointGroupLaue13 pg; - - TS_ASSERT_EQUALS(pg.getEquivalents(V3D(1, 2, 3)).size(), 1); - - pg.init(); - - TS_ASSERT_EQUALS(pg.getEquivalents(V3D(1, 2, 3)).size(), 48); - } -*/ void testPerformance() { PointGroup_sptr pg =PointGroupFactory::Instance().createPointGroup("m-3m");