Mantid
Loading...
Searching...
No Matches
PointGroup.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 +
11#include "MantidKernel/Logger.h"
12
13#include <algorithm>
14#include <boost/algorithm/string.hpp>
15#include <memory>
16#include <set>
17
18namespace Mantid::Geometry {
20using Kernel::V3D;
21namespace {
23Kernel::Logger g_log("PointGroup");
24} // namespace
25
42std::vector<V3D> PointGroup::getEquivalents(const V3D &hkl) const {
43 auto equivalents = getAllEquivalents(hkl);
44
45 std::sort(equivalents.begin(), equivalents.end(), std::greater<V3D>());
46
47 equivalents.erase(std::unique(equivalents.begin(), equivalents.end()), equivalents.end());
48
49 return equivalents;
50}
51
66 auto equivalents = getAllEquivalents(hkl);
67
68 return *std::max_element(equivalents.begin(), equivalents.end());
69}
70
72PointGroup::PointGroup(const std::string &symbolHM, const Group &group, const std::string &description)
73 : Group(group), m_symbolHM(symbolHM), m_name(symbolHM + " (" + description + ")") {
76}
77
79const std::string &PointGroup::getSymbol() const { return m_symbolHM; }
80
81bool PointGroup::isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const {
82 auto hklEquivalents = getAllEquivalents(hkl);
83
84 return (std::find(hklEquivalents.cbegin(), hklEquivalents.cend(), hkl2) != hklEquivalents.end());
85}
86
88 switch (m_crystalSystem) {
90 return "-1";
92 if (m_symbolHM.substr(0, 2) == "11") {
93 return "112/m"; // unique axis c
94 } else {
95 return "2/m"; // unique axis b
96 }
98 return "mmm";
100 if (m_symbolHM == "4" || m_symbolHM == "-4" || m_symbolHM == "4/m") {
101 return "4/m";
102 } else {
103 return "4/mmm";
104 }
106 if (m_symbolHM == "6" || m_symbolHM == "-6" || m_symbolHM == "6/m") {
107 return "6/m";
108 } else {
109 return "6/mmm";
110 }
112 if (m_symbolHM.substr(m_symbolHM.size() - 1) == "r") {
113 // Rhombohedral
114 if (m_symbolHM == "3" || m_symbolHM == "-3") {
115 return "-3 r";
116 } else {
117 return "-3m r";
118 }
119 } else {
120 // Hexagonal
121 if (m_symbolHM == "3" || m_symbolHM == "-3") {
122 return "-3";
123 } else if (m_symbolHM.substr(1) == "1") {
124 return "-31m";
125 } else {
126 return "-3m1";
127 }
128 }
130 if (m_symbolHM == "23" || m_symbolHM == "m-3") {
131 return "m-3";
132 } else {
133 return "m-3m";
134 }
135 default:
136 g_log.warning() << "Invalid crystal system - returning group with lowest symmetry (inversion only).\n";
137 return "-1"; // never used but required for gcc warning
138 }
139}
140
155std::vector<V3D> PointGroup::getAllEquivalents(const Kernel::V3D &hkl) const {
156 std::vector<V3D> equivalents;
157 equivalents.reserve(m_allOperations.size());
158 std::transform(m_allOperations.cbegin(), m_allOperations.cend(), std::back_inserter(equivalents),
159 [&hkl](const auto &operation) { return operation.transformHKL(hkl); });
160 return equivalents;
161}
162
175 std::map<std::string, std::set<V3D>> symbolMap;
176
177 for (const auto &operation : m_allOperations) {
178 SymmetryElementWithAxis_sptr element = std::dynamic_pointer_cast<SymmetryElementWithAxis>(
179 SymmetryElementFactory::Instance().createSymElement(operation));
180
181 if (element) {
182 std::string symbol = element->hmSymbol();
183 V3D axis = element->getAxis();
184
185 symbolMap[symbol].insert(axis);
186 }
187 }
188
189 if (symbolMap["3"].size() == 4) {
191 }
192
193 if (symbolMap["6"].size() == 1 || symbolMap["-6"].size() == 1) {
195 }
196
197 if (symbolMap["3"].size() == 1) {
199 }
200
201 if (symbolMap["4"].size() == 1 || symbolMap["-4"].size() == 1) {
203 }
204
205 if (symbolMap["2"].size() == 3 || (symbolMap["2"].size() == 1 && symbolMap["m"].size() == 2)) {
207 }
208
209 if (symbolMap["2"].size() == 1 || symbolMap["m"].size() == 1) {
211 }
212
214}
215
251
253std::vector<PointGroup_sptr> getAllPointGroups() {
254 auto &pointGroupFactory = PointGroupFactory::Instance();
255 std::vector<std::string> allSymbols = pointGroupFactory.getAllPointGroupSymbols();
256 std::vector<PointGroup_sptr> out;
257 out.reserve(allSymbols.size());
258 std::transform(allSymbols.cbegin(), allSymbols.cend(), std::back_inserter(out),
259 [&pointGroupFactory](const auto &symbol) { return pointGroupFactory.createPointGroup(symbol); });
260 return out;
261}
262
266
267 std::vector<PointGroup_sptr> pointGroups = getAllPointGroups();
268
269 for (auto &pointGroup : pointGroups) {
270 map.emplace(pointGroup->crystalSystem(), pointGroup);
271 }
272
273 return map;
274}
275
277std::string getCrystalSystemAsString(const PointGroup::CrystalSystem &crystalSystem) {
278 switch (crystalSystem) {
280 return "Cubic";
282 return "Tetragonal";
284 return "Hexagonal";
286 return "Trigonal";
288 return "Orthorhombic";
290 return "Monoclinic";
291 default:
292 return "Triclinic";
293 }
294}
295
298PointGroup::CrystalSystem getCrystalSystemFromString(const std::string &crystalSystem) {
299 std::string crystalSystemLC = boost::algorithm::to_lower_copy(crystalSystem);
300
301 if (crystalSystemLC == "cubic") {
303 } else if (crystalSystemLC == "tetragonal") {
305 } else if (crystalSystemLC == "hexagonal") {
307 } else if (crystalSystemLC == "trigonal") {
309 } else if (crystalSystemLC == "orthorhombic") {
311 } else if (crystalSystemLC == "monoclinic") {
313 } else if (crystalSystemLC == "triclinic") {
315 } else {
316 throw std::invalid_argument("Not a valid crystal system: '" + crystalSystem + "'.");
317 }
318}
319
321std::string getLatticeSystemAsString(const PointGroup::LatticeSystem &latticeSystem) {
322 switch (latticeSystem) {
324 return "Cubic";
326 return "Tetragonal";
328 return "Hexagonal";
330 return "Rhombohedral";
332 return "Orthorhombic";
334 return "Monoclinic";
335 default:
336 return "Triclinic";
337 }
338}
339
342PointGroup::LatticeSystem getLatticeSystemFromString(const std::string &latticeSystem) {
343 std::string latticeSystemLC = boost::algorithm::to_lower_copy(latticeSystem);
344
345 if (latticeSystemLC == "cubic") {
347 } else if (latticeSystemLC == "tetragonal") {
349 } else if (latticeSystemLC == "hexagonal") {
351 } else if (latticeSystemLC == "rhombohedral") {
353 } else if (latticeSystemLC == "orthorhombic") {
355 } else if (latticeSystemLC == "monoclinic") {
357 } else if (latticeSystemLC == "triclinic") {
359 } else {
360 throw std::invalid_argument("Not a valid lattice system: '" + latticeSystem + "'.");
361 }
362}
363
365 const PointGroup::CrystalSystem &rhs) const {
366 return static_cast<int>(lhs) < static_cast<int>(rhs);
367}
368
370std::ostream &operator<<(std::ostream &stream, const PointGroup &self) {
371 stream << "Point group with:\n"
372 << "Lattice system: " << getLatticeSystemAsString(self.latticeSystem()) << "\n"
373 << "Crystal system: " << getCrystalSystemAsString(self.crystalSystem()) << "\n"
374 << "Symbol: " << self.getSymbol();
375 return stream;
376}
377
378} // namespace Mantid::Geometry
const std::vector< double > & rhs
The class Group represents a set of symmetry operations (or symmetry group).
Definition Group.h:135
CoordinateSystem getCoordinateSystem() const
Returns the axis system of the group (either orthogonal or hexagonal).
Definition Group.cpp:37
std::vector< SymmetryOperation > m_allOperations
Definition Group.h:173
A class containing the Point Groups for a crystal.
Definition PointGroup.h:31
PointGroup(const std::string &symbolHM, const Group &group, const std::string &description="")
Protected constructor - can not be used directly.
bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const
Return true if the hkls are in same group.
LatticeSystem getLatticeSystemFromCrystalSystemAndGroup(const CrystalSystem &crystalSystem) const
Returns the LatticeSystem of the point group, using the crystal system.
const std::string & getSymbol() const
Hermann-Mauguin symbol.
LatticeSystem latticeSystem() const
Definition PointGroup.h:44
std::vector< Kernel::V3D > getEquivalents(const Kernel::V3D &hkl) const
Returns a vector with all equivalent hkls.
CrystalSystem getCrystalSystemFromGroup() const
Returns the CrystalSystem determined from symmetry elements.
CrystalSystem m_crystalSystem
Definition PointGroup.h:64
std::vector< Kernel::V3D > getAllEquivalents(const Kernel::V3D &hkl) const
Generates a set of hkls.
LatticeSystem m_latticeSystem
Definition PointGroup.h:65
std::string getLauePointGroupSymbol() const
CrystalSystem crystalSystem() const
Definition PointGroup.h:43
Kernel::V3D getReflectionFamily(const Kernel::V3D &hkl) const
Returns the same hkl for all equivalent hkls.
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
Class for 3D vectors.
Definition V3D.h:34
MANTID_GEOMETRY_DLL PointGroup::LatticeSystem getLatticeSystemFromString(const std::string &latticeSystem)
Returns the lattice system enum that corresponds to the supplied string or throws an invalid_argument...
Mantid::Kernel::Logger g_log("Goniometer")
std::multimap< PointGroup::CrystalSystem, PointGroup_sptr, CrystalSystemComparator > PointGroupCrystalSystemMap
Definition PointGroup.h:93
std::shared_ptr< SymmetryElementWithAxis > SymmetryElementWithAxis_sptr
MANTID_GEOMETRY_DLL std::string getLatticeSystemAsString(const PointGroup::LatticeSystem &latticeSystem)
Returns the supplied LatticeSystem as a string.
MANTID_GEOMETRY_DLL std::ostream & operator<<(std::ostream &stream, const PointGroup &self)
Returns a streamed representation of the PointGroup object.
MANTID_GEOMETRY_DLL PointGroup::CrystalSystem getCrystalSystemFromString(const std::string &crystalSystem)
Returns the crystal system enum that corresponds to the supplied string or throws an invalid_argument...
MANTID_GEOMETRY_DLL std::string getCrystalSystemAsString(const PointGroup::CrystalSystem &crystalSystem)
Return a human-readable string for the given crystal system.
MANTID_GEOMETRY_DLL std::vector< PointGroup_sptr > getAllPointGroups()
MANTID_GEOMETRY_DLL PointGroupCrystalSystemMap getPointGroupsByCrystalSystem()
Returns a multimap with crystal system as key and point groups as values.
Mantid::Kernel::Matrix< int > IntMatrix
Definition Matrix.h:207
bool operator()(const PointGroup::CrystalSystem &lhs, const PointGroup::CrystalSystem &rhs) const