Mantid
Loading...
Searching...
No Matches
SpaceGroupFactory.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2014 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 +
7#pragma once
8
10#include "MantidGeometry/DllConfig.h"
13
14#include <map>
15
16namespace Mantid {
17namespace Geometry {
18
19bool MANTID_GEOMETRY_DLL isValidGeneratorString(const std::string &generatorString);
20
21std::vector<std::string> MANTID_GEOMETRY_DLL operator*(const SymmetryOperation &symOp,
22 const std::vector<std::string> &strings);
23
39class MANTID_GEOMETRY_DLL AbstractSpaceGroupGenerator {
40public:
41 AbstractSpaceGroupGenerator(size_t number, std::string hmSymbol, std::string generatorInformation);
42 virtual ~AbstractSpaceGroupGenerator() = default;
43
44 inline size_t getNumber() const { return m_number; }
45 inline std::string getHMSymbol() const { return m_hmSymbol; }
46 inline std::string getGeneratorString() const { return m_generatorString; }
47
48 SpaceGroup_const_sptr getPrototype();
49
50protected:
51 virtual Group_const_sptr generateGroup() const = 0;
52
53private:
54 inline bool hasValidPrototype() const { return static_cast<bool>(m_prototype); }
55 SpaceGroup_const_sptr generatePrototype();
56
57 size_t m_number;
58 std::string m_hmSymbol;
59 std::string m_generatorString;
60
62};
63
64using AbstractSpaceGroupGenerator_sptr = std::shared_ptr<AbstractSpaceGroupGenerator>;
65
69public:
70 AlgorithmicSpaceGroupGenerator(size_t number, const std::string &hmSymbol, const std::string &generatorInformation);
71
72protected:
73 Group_const_sptr generateGroup() const override;
74 std::string getCenteringSymbol() const;
75};
76
80public:
81 TransformationSpaceGroupGenerator(size_t number, const std::string &hmSymbol,
82 const std::string &generatorInformation);
83
84protected:
85 Group_const_sptr generateGroup() const override;
86 virtual SpaceGroup_const_sptr getBaseSpaceGroup() const;
87
88 void setBaseAndTransformation(const std::string &generatorInformation);
89
91 std::string m_transformation;
92};
93
97public:
98 TabulatedSpaceGroupGenerator(size_t number, const std::string &hmSymbol, const std::string &generatorInformation);
99
100protected:
101 Group_const_sptr generateGroup() const override;
102};
103
130class MANTID_GEOMETRY_DLL SpaceGroupFactoryImpl {
131public:
132 virtual ~SpaceGroupFactoryImpl() = default;
133
134 SpaceGroup_const_sptr createSpaceGroup(const std::string &hmSymbol);
135
136 bool isSubscribed(const std::string &hmSymbol) const;
137 bool isSubscribed(size_t number) const;
138
139 std::vector<std::string> subscribedSpaceGroupSymbols() const;
140 std::vector<std::string> subscribedSpaceGroupSymbols(size_t number) const;
141 std::vector<size_t> subscribedSpaceGroupNumbers() const;
142
143 std::vector<std::string> subscribedSpaceGroupSymbols(const PointGroup_sptr &pointGroup);
144
145 void unsubscribeSpaceGroup(const std::string &hmSymbol);
146
147 void subscribeGeneratedSpaceGroup(size_t number, const std::string &hmSymbol, const std::string &generators);
148 void subscribeTabulatedSpaceGroup(size_t number, const std::string &hmSymbol, const std::string &symmetryOperations);
149
152 template <typename T>
153 void subscribeUsingGenerator(size_t number, const std::string &hmSymbol, const std::string &generatorString) {
154 if (isSubscribed(hmSymbol)) {
155 throw std::invalid_argument("Space group with symbol '" + hmSymbol + "' is already registered.");
156 }
157
158 AbstractSpaceGroupGenerator_sptr generator = std::make_shared<T>(number, hmSymbol, generatorString);
159
160 subscribe(generator);
161 }
162
177 template <typename T>
178 void subscribeOrthorhombicSpaceGroup(size_t number, const std::string &hmSymbol, const std::string &generatorString) {
179 // Subscribe the base type, this must always be done.
180 subscribeUsingGenerator<T>(number, hmSymbol, generatorString);
181
182 /* For each orthorhombic space group there are in principle 6 permutations.
183 * The other 5 can be constructed by TransformationSpaceGroupGenerator,
184 * using the following transformations.
185 */
186 std::vector<std::string> transformations{"y,x,-z", "y,z,x", "z,y,-x", "z,x,y", "x,z,-y"};
187 /* For some space groups, some (or all) transformations lead to the same
188 * space
189 * group, it's necessary to keep track of this.
190 */
191 std::vector<std::string> transformedSpaceGroupSymbols;
192
193 for (const auto &transformation : transformations) {
194 std::string transformedSymbol = getTransformedSymbolOrthorhombic(hmSymbol, transformation);
195
196 bool symbolExists = std::find(transformedSpaceGroupSymbols.cbegin(), transformedSpaceGroupSymbols.cend(),
197 transformedSymbol) != transformedSpaceGroupSymbols.cend();
198
199 if (transformedSymbol != hmSymbol && !symbolExists) {
200 subscribeUsingGenerator<TransformationSpaceGroupGenerator>(
201 number, transformedSymbol, std::string(hmSymbol).append("|").append(transformation));
202 transformedSpaceGroupSymbols.emplace_back(transformedSymbol);
203 }
204 }
205 }
206
207protected:
208 std::string getTransformedSymbolOrthorhombic(const std::string &hmSymbol, const std::string &transformation) const;
209
210 SpaceGroup_const_sptr getPrototype(const std::string &hmSymbol);
211 void subscribe(const AbstractSpaceGroupGenerator_sptr &generator);
212 SpaceGroup_const_sptr constructFromPrototype(const SpaceGroup_const_sptr &prototype) const;
213
214 void fillPointGroupMap();
215
216 std::multimap<size_t, std::string> m_numberMap;
217 std::map<std::string, AbstractSpaceGroupGenerator_sptr> m_generatorMap;
218 std::multimap<std::string, std::string> m_pointGroupMap;
219
221
222private:
224};
225
227
228} // namespace Geometry
229} // namespace Mantid
230
231namespace Mantid {
232namespace Kernel {
233EXTERN_MANTID_GEOMETRY template class MANTID_GEOMETRY_DLL
235}
236} // namespace Mantid
237
238/* Macros for compile time space group registration
239 *
240 * The macros are a bit different than in other factories,
241 * because there is no identifier that can be used to generate
242 * a unique name for each RegistrationHelper instance.
243 *
244 * Instead, the __COUNTER__ macro is used, which is available
245 * in many compilers and is incremented every time it's called.
246 *
247 * Solution was found here: http://stackoverflow.com/a/1295338
248 */
249#define SPGF_CONCAT_IMPL(x, y) x##y
250#define SPGF_CONCAT(x, y) SPGF_CONCAT_IMPL(x, y)
251
252#define DECLARE_GENERATED_SPACE_GROUP(number, hmSymbol, generators) \
253 namespace { \
254 Mantid::Kernel::RegistrationHelper SPGF_CONCAT(register_spacegroup_, __COUNTER__)( \
255 ((Mantid::Geometry::SpaceGroupFactory::Instance().subscribeGeneratedSpaceGroup(number, hmSymbol, generators)), \
256 0)); \
257 }
258
259#define DECLARE_TRANSFORMED_SPACE_GROUP(number, hmSymbol, generators) \
260 namespace { \
261 Mantid::Kernel::RegistrationHelper SPGF_CONCAT(register_spacegroup_, __COUNTER__)( \
262 ((Mantid::Geometry::SpaceGroupFactory::Instance().subscribeUsingGenerator<TransformationSpaceGroupGenerator>( \
263 number, hmSymbol, generators)), \
264 0)); \
265 }
266
267#define DECLARE_TABULATED_SPACE_GROUP(number, hmSymbol, symmetryOperations) \
268 namespace { \
269 Mantid::Kernel::RegistrationHelper SPGF_CONCAT(register_spacegroup_, __COUNTER__)( \
270 ((Mantid::Geometry::SpaceGroupFactory::Instance().subscribeTabulatedSpaceGroup(number, hmSymbol, \
271 symmetryOperations)), \
272 0)); \
273 }
274
275#define DECLARE_ORTHORHOMBIC_SPACE_GROUP(number, hmSymbol, generators) \
276 namespace { \
277 Mantid::Kernel::RegistrationHelper SPGF_CONCAT(register_spacegroup_, __COUNTER__)( \
278 ((Mantid::Geometry::SpaceGroupFactory::Instance() \
279 .subscribeOrthorhombicSpaceGroup<AlgorithmicSpaceGroupGenerator>(number, hmSymbol, generators)), \
280 0)); \
281 }
282
283#define DECLARE_TRANSFORMED_ORTHORHOMBIC_SPACE_GROUP(number, hmSymbol, generators) \
284 namespace { \
285 Mantid::Kernel::RegistrationHelper SPGF_CONCAT(register_spacegroup_, __COUNTER__)( \
286 ((Mantid::Geometry::SpaceGroupFactory::Instance() \
287 .subscribeOrthorhombicSpaceGroup<TransformationSpaceGroupGenerator>(number, hmSymbol, generators)), \
288 0)); \
289 }
AbstractSpaceGroupGenerator is used by SpaceGroupFactory to delay (possibly costly) construction of s...
virtual Group_const_sptr generateGroup() const =0
Concrete space group generator that uses space group generators as given in ITA.
void subscribeUsingGenerator(size_t number, const std::string &hmSymbol, const std::string &generatorString)
Templated method to subscribe other generators than the ones provided here.
std::multimap< std::string, std::string > m_pointGroupMap
void subscribeOrthorhombicSpaceGroup(size_t number, const std::string &hmSymbol, const std::string &generatorString)
Specialized method to subscribe an orthorhombic space group.
std::multimap< size_t, std::string > m_numberMap
std::map< std::string, AbstractSpaceGroupGenerator_sptr > m_generatorMap
Concrete space group generator that constructs space groups from a list of symmetry operations with n...
Concrete generator that generates a space group from another space group using a transformation.
Manage the lifetime of a class intended to be a singleton.
MANTID_GEOMETRY_DLL Group_const_sptr operator*(const Group_const_sptr &lhs, const Group_const_sptr &rhs)
Convenience operator* for directly multiplying groups using shared pointers.
Definition: Group.cpp:248
std::shared_ptr< PointGroup > PointGroup_sptr
Shared pointer to a PointGroup.
Definition: PointGroup.h:67
bool MANTID_GEOMETRY_DLL isValidGeneratorString(const std::string &generatorString)
Free function that tries to parse the given list of symmetry operations and returns true if successfu...
std::shared_ptr< const SpaceGroup > SpaceGroup_const_sptr
Definition: SpaceGroup.h:82
std::shared_ptr< AbstractSpaceGroupGenerator > AbstractSpaceGroupGenerator_sptr
std::shared_ptr< const Group > Group_const_sptr
Definition: Group.h:179
Helper class which provides the Collimation Length for SANS instruments.
Policy class controlling creation of the singleton Implementation classes should mark their default c...