/
xtalcomp.h
163 lines (137 loc) · 5.61 KB
/
xtalcomp.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/**********************************************************************
XtalComp - Determine if two crystal description represent the same
structure
Copyright (C) 2011 by David C. Lonie
This source code is released under the New BSD License, (the "License").
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
***********************************************************************/
#ifndef XTALCOMP_H
#define XTALCOMP_H
#include "xcmatrix.h"
#include "xctransform.h"
#include "xcvector.h"
#include <map>
#include <utility>
#include <vector>
class XtalComp
{
public:
/**
* Compare two crystal descriptions, return true if the underlying
* structures are same, false otherwise.
*
* cellMatrix[1|2] are 3x3 matrices that contain the cell vectors as
* the matrix rows, e.g.
* cellMatrix[0][0] = v1[0];
* cellMatrix[0][1] = v1[1];
* cellMatrix[0][2] = v1[2];
* cellMatrix[1][0] = v2[0];
* ...
*
* types[1|2] are vectors of atomic numbers that correspond to entries
* in postions[1|2].
*
* positions[1|2] are vectors of XcVectors (see XcVector.h) that
* correspond to types[1|2]. The XcVectors are the fractional
* coordinates of the atoms.
*
* @param cellMatrix1 Cell vectors of first description
* @param types1 Atomic numbers of first description
* @param positions1 Fractional coordinates of first description
* @param cellMatrix2 Cell vectors of second description
* @param types2 Atomic numbers of second description
* @param positions2 Fractional coordinates of second description
* @param transform Array to be overwritten with a row-major matrix
* representing the transformation used if the structures are determined
* to match.
* @param cartTol Tolerance for atomic position comparisons in cartesian units
* @params angleTol Used for matching candidate sublattices -- default of
* 0.25 degrees should be sufficient.
* @param reduceXtalToPrimitive Whether or not to reduce the crystals to
* their primitive cells before comparing them. This uses the space group
* library (spglib) -- default is true.
*
* @return True if structures match, false otherwise
*/
static bool compare(const XcMatrix &cellMatrix1,
const std::vector<unsigned int> &types1,
const std::vector<XcVector> &positions1,
const XcMatrix &cellMatrix2,
const std::vector<unsigned int> &types2,
const std::vector<XcVector> &positions2,
float transform[16] = 0,
const double cartTol = 0.05,
const double angleTol = 0.25,
const bool reduceXtalToPrimitive = true);
virtual ~XtalComp();
// Internal type: See m_duplicatedAtoms for description.
typedef std::map<size_t, std::pair<size_t, size_t> > DuplicateMap;
protected:
class ReducedXtal;
// Initialization
XtalComp(ReducedXtal *rx1, ReducedXtal *rx2,
const double cartTol, const double angleTol);
void setLeastFrequentAtomInfo();
void setReferenceBasis();
void prepareRx1();
void getCurrentTransform(float[16]);
// Are there more comparisons to make?
bool hasMoreTransforms() const;
bool hasMoreTranslations() const;
// Update working coordinates
void applyNextTransform();
void applyNextTranslation();
// Make next comparison
bool compareCurrent();
// Reduce the xtal to its primitive form
// Returns the space group
static unsigned int reduceToPrimitive(std::vector<XcVector>& fcoords,
std::vector<unsigned int>& atomicNums,
XcMatrix& cellMatrix,
const double cartTol);
// Tolerance
double m_lengthtol;
double m_angletol;
// Reduced xtals
ReducedXtal *m_rx1;
ReducedXtal *m_rx2;
// Least frequent atom info
unsigned int m_lfAtomType;
unsigned int m_lfAtomCount;
// Duplicated Atoms: made to prevent duplicate atoms produced by the
// expandedFractionalCoordinates() function from being matched.
// The vector is appended when duplicates are made, and it is used
// in compareCurrent() when a match is made.
// The key is the index of the original atom in rx1, and the value is the
// start and end indicies of the duplicated atoms.
// Thus, if the original atom (rx1[key]) is matched to an rx2 atom, all rx1
// atoms in the range specified in the pair need to indicate that they have
// already been matched as well.
DuplicateMap m_duplicatedAtoms;
// Supercell of lfAtoms in xtal2
void buildSuperLfCCoordList2();
std::vector<XcVector> m_superLfCCoordList2;
void findCandidateTransforms();
// Add atoms around cell boundaries for stability during comparisons
static void expandFractionalCoordinates(
std::vector<unsigned int> *types, std::vector<XcVector> *fcoords,
DuplicateMap *duplicateAtoms, const XcMatrix &cmat, const double tol);
// Reference vectors:
XcVector m_refVec1;
XcVector m_refVec2;
XcVector m_refVec3;
std::vector<XcTransform> m_transforms;
XcTransform m_transform;
unsigned int m_transformsIndex;
void buildTransformedXtal2();
XcMatrix m_transformedCMat;
XcMatrix m_transformedFMat;
std::vector<unsigned int> m_transformedTypes;
std::vector<XcVector> m_transformedFCoords;
std::vector<XcVector> m_transformedCCoords;
};
#endif