CHAPTER 13

Space Group and Crystallographic Symmetry

 

The implementation of space group plays a central role in CCL and CPL to provide knowledge of crystallographic symmetry for other components of the libraries and applications.  Other classes such as Miller indices and structure factor rely on the symmetry knowledge to perform their operations.

 

13.1 Space Group

 

13.1.1 ccl::spaceGroup class

 

This class loads in a database file that contains symmetry information of all 230 space groups.  Various member functions return the symmetry operators and other characteristics of a space group.

 

13.1.1.1 Constructors and Assignment

spaceGroup(const size_t = 1);

spaceGroup(const char*);

spaceGroup(const std::string&);

The general constructors take a space group number, a C string or a std::string of a space group name to construct a space group.  The default constructor constructs the space group P1.  The space group name is a lowercase string similar to the space group symbol found in the International Tables.  Table 13.1.1.0.1 lists these strings.  When this class is constructed, a database file is loaded.  An environment variable CCLHOME must be set to specify the location where CCL is installed.  The space group library will be loaded from $CCLHOME/lib.

 

spaceGroup(const spaceGroup&);

const spaceGroup& operator=(const spaceGroup&);

Copy constructor and assignment operator = are available.

 

void setSpaceGroup(const size_t = 1);

void setSpaceGroup(const char*);

void setSpaceGroup(const std::string&);

After a space group is constructed, it is still possible to change it to another space group by using these set functions.

 


 

No.   Name

No.   Name

No.   Name

No.   Name

No.   Name

  1 p1

  2 p-1

  3 p2

  4 p21

  5 c2

 

  7 pc

  8 cm

  9 cc

 10 p2/m

 11 p21/m

 12 c2/m

 13 p2/c

 14 p21/c

 15 c2/c

 16 p222

 17 p2221

 18 p21212

 19 p212121

 20 c2221

 21 c222

 22 f222

 23 i222

 24 i212121

 25 pmm2

 26 pmc21

 27 pcc2

 28 pma2

 29 pca21

 30 pnc2

 31 pmn21

 32 pba2

 33 pna21

 34 pnn2

 35 cmm2

 36 cmc21

 37 ccc2

 38 amm2

 39 abm2

 40 ama2

 41 aba2

 42 fmm2

 43 fdd2

 44 imm2

 45 iba2

 46 ima2

 47 pmmm

 48 pnnn

 49 pccm

 50 pban

 51 pmma

 52 pnna

 53 pmna

 54 pcca

 55 pbam

 56 pccn

 57 pbcm

 58 pnnm

 59 pmmn

 60 pbcn

 61 pbca

 62 pnma

 63 cmcm

 64 cmca

 65 cmmm

 66 cccm

 67 cmma

 68 ccca

 69 fmmm

 70 fddd

 71 immm

 72 ibam

 73 ibca

 74 imma

 75 p4

 76 p41

 77 p42

 78 p43

 79 i4

 80 i41

 81 p-4

 82 i-4

 83 p4/m

 84 p42/m

 85 p4/n

 86 p42/n

 87 i4/m

 88 i41/a

 89 p422

 90 p4212

 91 p4122

 92 p41212

 93 p4222

 94 p42212

 95 p4322

 96 p43212

 97 i422

 98 i4122

 99 p4mm

100 p4bm

101 p42cm

102 p42nm

103 p4cc

104 p4nc

105 p42mc

106 p42bc

107 i4mm

108 i4cm

109 i41md

110 i41cd

111 p-42m

112 p-42c

113 p-421m

114 p-421c

115 p-4m2

116 p-4c2

117 p-4b2

118 p-4n2

119 i-4m2

120 i-4c2

121 i-42m

122 i-42d

123 p4/mmm

124 p4/mcc

125 p4/nbm

126 p4/nnc

127 p4/mbm

128 p4/mnc

129 p4/nmm

130 p4/ncc

131 p42/mmc

132 p42/mcm

133 p42/nbc

134 p42/nnm

135 p42/mbc

136 p42/mnm

137 p42/nmc

138 p42/ncm

139 i4/mmm

140 i4/mcm

141 i41/amd

142 i41/acd

143 p3

144 p31

145 p32

146 r3

147 p-3

148 r-3

149 p312

150 p321

151 p3112

152 p3121

153 p3212

154 p3221

155 r32

156 p3m1

157 p31m

158 p3c1

159 p31c

160 r3m

161 r3c

162 p-31m

163 p-31c

164 p3m1

165 p-3c1

166 r-3m

167 r-3c

168 p6

169 p61

170 p65

171 p62

172 p64

173 p63

174 p-6

175 p6/m

176 p63/m

177 p622

178 p6122

179 p6522

180 p6222

181 p6422

182 p6322

183 p6mm

184 p6cc

185 p63cm

186 p63mc

187 p-6m2

188 p-6c2

189 p-62m

190 p-62c

191 p6/mmm

192 p6/mcc

193 p63/mcm

194 p63/mmc

195 p23

196 f23

197 i23

198 p213

199 i213

200 pm-3

201 pn-3

202 fm-3

203 fd-3

204 im-3

205 pa-3

206 ia-3

207 p432

208 p4332

209 f432

210 f4132

211 i432

212 p4332

213 p4132

214 i4132

215 p-43m

216 f4-3m

217 i-43

218 p-43n

219 f-43c

220 i-43d

221 pm-3m

222 pn-3n

223 pm-3n

224 pn-3m

225 fm-3m

226 fm-3c

227 fd-3m

228 fd-3c

229 im-3m

230 ia-3d

 

Table 13.1.1.1.1 Accepted strings for space group names.


13.1.1.2 Space Group Characteristics

These member functions return several characteristics of a space group.  All these functions are declared const, that is, by no means they can change the already constructed space group.

 

std::string spaceGroupName(const bool cap = 1) const;

Returns the space group name as std::string.  The optional Boolean indicates whether the first character is capitalized.  See Table 13.1.1.1.1 for possible returned values.

 

std::string pointGroupName() const;

Returns the space group name without the first character for lattice type.

 

int lattice(const bool cap = 1) const;

Returns the lattice type of the space group as a single letter.  The optional Boolean indicates whether the letter is capitalized.

 

size_t spaceGroupNumber() const;

Returns the space group number.

 

std::string getCrystalSystem() const;

std::string crystalSystem() const;

Return the crystal system as std::string.  The possible returned values are triclinic, monoclinic, orthorhombic, tetragonal, trigonal, hexagonal, and cubic.

 

bool getCentralSymmetric() const;

bool centrosymmetric() const;

Test whether the space group is central symmetric.  If one of the symmetry operators (See 13.1.3 below) has

 

R = ,

 

this space group is central symmetric.

 

bool getEnantiomorphism() const;

bool enantiomorphic() const;

Test whether the space group is enantiomorphic.  If one of the symmetry operators (See 13.1.1.3 below) has |R| = -1, this space group is enantiomorphic.  All central symmetric space groups are enantiomorphic.

 

void rmInversion();

Removes the inversion operator and all derived operators from the inversion if any.  Please note that this function indeed alters the symmetry of the space group.  Use this function with caution.

 

13.1.1.3 Symmetry Operation and Symmetry Operators

The space defined by a unit cell is divided into several asymmetric units.  The content of each asymmetric unit is a copy of another.  The calculation of a position in an asymmetric unit from a position of another is a symmetry operation.  Such operation can be described by this equation:

 

u = Rv + t

 

where u and v are two vectors in two asymmetric units, respectively.  R is a 3-dimensional matrix, and t is a translation vector.  The pair of R and t is called a symmetry operator.  It can be shown that if u and v are both in the fractional coordinate system of the unit cell, R and t can be much simplified.  R will consist of elements 1, 0, or, -1; t will consist of multiples of 1/4 or 1/6.  Therefore, symmetry operation is always done in fractional coordinate system.  Please note that R is not necessarily a rotation matrix, therefore may not be orthogonal.  A space group has a fixed number of symmetry operators.  One of them must be a 3-dimensional identity matrix and a 0 vector.

 

Some of the following functions take 0-offset subscript in parentheses (), which is not consistent with the conventional style.  These functions remain due to backward compatibility.

 

If a subscript is out of range, an error message will be printed, and default matrix or vector will be returned.  This behavior in future release.

 

size_t getOperateSize() const;

size_t operateSize() const;

size_t operatorSize() const;

Return the number of operators the space group has.

 

mac::matrix3D<int> R(const size_t i) const;

Returns the i-th operator matrix R, where i is a 1-offset subscript.

 

mac::matrix3D<int> getOperate(const size_t) const;

Returns a matrix R.  This function takes a 0-offset subscript.

 

mac::vector3D<double> t(const size_t i) const;

Returns the i-th translation vector t, where i is a 1-offset subscript.

 

mac::vector3D<double> getTranslate(

   const size_t) const;

Given a 0-offset subscript, returns a vector t. 

 

vector<mac::matrix3D<int> > operators() const;

vector<mac::matrix3D<int> > getOperate() const;

Returns all R¡¯s of this space group.  The order of the returned std::vector is consistent with that from the next function getTranslate().

 

vector<mac::vector3D<double> >

   translations() const;

vector<mac::vector3D<double> >

   getTranslate() const;

Returns all t¡¯s of this space group.  The order of the returned std::vector is consistent with that from the previous function getOperate().

 

13.1.1.4 Unique Symmetry Operators

Some symmetry operators may share the same R, but not the same t, so that the set of R¡¯s are therefore not unique.  The following member functions deal with only the unique set of R¡¯s.

 

size_t uniqueOperatorSize() const;

size_t uniqueOperateSize() const;

size_t getUniqueOperateSize() const;

Return the number of unique R¡¯s for this space group.

 

mac::matrix3D<int> uniqueR(const size_t i) const;

Returns the i-th unique operator matrix R, where i is a 1-offset subscript.  The order is determined as below.

 

mac::matrix3D<int> getUniqueOperate(const size_t)

   const;

Given a 0-offset subscript, returns a unique R.  The order is determined as below.

 

set<mac::matrix3D<int> > uniqueOperators() const;

set<mac::matrix3D<int> > getUniqueOperate()

                                           const;

Returns all unique R¡¯s in the ascending order determined by lessThan comparison.

 

13.1.1.5 Patterson Space Group

The Patterson space group can be derived from the original space group by removal of all translations of screw axes and sliders, but retaining the translations of lattice centering, and addition of a inversion if needed.

 

spaceGroup Patterson() const;

Returns Patterson space group of this space group.  This function is const, that is, the original space group is not altered.

 

The Patterson space group of any space group listed in Table 13.1.1.0.1 can be found in that table, except four, Amm2, Abm2, Ama2, and Aba2.  Their Patterson space group should be Cmmm but with a different orientation from those four original ones.  A permuted space group Ammm is needed to keep the consistent orientation.  Ammm is included in the space group database coming with the distribution, and named number 1065.  Table 13.1.5.0.1 lists the results of the function Patterson().

 

No.      Name         Patterson

No.     Name        Patterson

No.      Name         Patterson

  1   P1       P-1

  2   P-1      P-1

  3   P2       P2/m

  4   P21      P2/m

  5   C2       C2/m

  6   Pm       P2/m

  7   Pc       P2/m

  8   Cm       C2/m

  9   Cc       C2/m

 10   P2/m     P2/m

 11   P21/m    P2/m

 12   C2/m     C2/m

 13   P2/c     P2/m

 14   P21/c    P2/m

 15   C2/c     C2/m

 16   P222     Pmmm

 17   P2221    Pmmm

 18   P21212   Pmmm

 19   P212121  Pmmm

 20   C2221    Cmmm

 21   C222     Cmmm

 22   F222     Fmmm

 23   I222     Immm

 24   I212121  Immm

 25   Pmm2     Pmmm

 26   Pmc21    Pmmm

 27   Pcc2     Pmmm

 28   Pma2     Pmmm

 29   Pca21    Pmmm

 30   Pnc2     Pmmm

 31   Pmn21    Pmmm

 32   Pba2     Pmmm

 33   Pna21    Pmmm

 34   Pnn2     Pmmm

 35   Cmm2     Cmmm

 36   Cmc21    Cmmm

 37   Ccc2     Cmmm

 38   Amm2     Ammm

 39   Abm2     Ammm

 40   Ama2     Ammm

 41   Aba2     Ammm

 42   Fmm2     Fmmm

 43   Fdd2     Fmmm

 44   Imm2     Immm

 45   Iba2     Immm

 46   Ima2     Immm

 47   Pmmm     Pmmm

 48   Pnnn     Pmmm

 49   Pccm     Pmmm

 50   Pban     Pmmm

 51   Pmma     Pmmm

 52   Pnna     Pmmm

 53   Pmna     Pmmm

 54   Pcca     Pmmm

 55   Pbam     Pmmm

 56   Pccn     Pmmm

 57   Pbcm     Pmmm

 58   Pnnm     Pmmm

 59   Pmmn     Pmmm

 60   Pbcn     Pmmm

 61   Pbca     Pmmm

 62   Pnma     Pmmm

 63   Cmcm     Cmmm

 64   Cmca     Cmmm

 65   Cmmm     Cmmm

 66   Cccm     Cmmm

 67   Cmma     Cmmm

 68   Ccca     Cmmm

 69   Fmmm     Fmmm

 70   Fddd     Fmmm

 71   Immm     Immm

 72   Ibam     Immm

 73   Ibca     Immm

 74   Imma     Immm

 75   P4       P4/m

 76   P41      P4/m

 77   P42      P4/m

 78  P43      P4/m

 79  I4       I4/m

 80  I41      I4/m

 81  P-4      P4/m

 82  I-4      I4/m

 83  P4/m     P4/m

 84  P42/m    P4/m

 85  P4/n     P4/m

 86  P42/n    P4/m

 87  I4/m     I4/m

 88  I41/a    I4/m

 89  P422     P4/mmm

 90  P4212    P4/mmm

 91  P4122    P4/mmm

 92  P41212   P4/mmm

 93  P4222    P4/mmm

 94  P42212   P4/mmm

 95  P4322    P4/mmm

 96  P43212   P4/mmm

 97  I422     I4/mmm

 98  I4122    I4/mmm

 99  P4mm     P4/mmm

100  P4bm     P4/mmm

101  P42cm    P4/mmm

102  P42nm    P4/mmm

103  P4cc     P4/mmm

104  P4nc     P4/mmm

105  P42mc    P4/mmm

106  P42bc    P4/mmm

107  I4mm     I4/mmm

108  I4cm     I4/mmm

109  I41md    I4/mmm

110  I41cd    I4/mmm

111  P-42m    P4/mmm

112  P-42c    P4/mmm

113  P-421m   P4/mmm

114  P-421c   P4/mmm

115  P-4m2    P4/mmm

116  P-4c2    P4/mmm

117  P-4b2    P4/mmm

118  P-4n2    P4/mmm

119  I-4m2    I4/mmm

120  I-4c2    I4/mmm

121  I-42m    I4/mmm

122  I-42d    I4/mmm

123  P4/mmm   P4/mmm

124  P4/mcc   P4/mmm

125  P4/nbm   P4/mmm

126  P4/nnc   P4/mmm

127  P4/mbm   P4/mmm

128  P4/mnc   P4/mmm

129  P4/nmm   P4/mmm

130  P4/ncc   P4/mmm

131  P42/mmc  P4/mmm

132  P42/mcm  P4/mmm

133  P42/nbc  P4/mmm

134  P42/nnm  P4/mmm

135  P42/mbc  P4/mmm

136  P42/mnm  P4/mmm

137  P42/nmc  P4/mmm

138  P42/ncm  P4/mmm

139  I4/mmm   I4/mmm

140  I4/mcm   I4/mmm

141  I41/amd  I4/mmm

142  I41/acd  I4/mmm

143  P3       P-3

144  P31      P-3

145  P32      P-3

146  R3       R-3

147  P-3      P-3

148  R-3      R-3

149  P312     P-31m

150  P321     P-3m1

151  P3112    P-31m

152  P3121    P-3m1

153  P3212    P-31m

154  P3221    P-3m1

155   R32      R-3m

156   P3m1     P-3m1

157   P31m     P-31m

158   P3c1     P-3m1

159   P31c     P-31m

160   R3m      R-3m

161   R3c      R-3m

162   P-31m    P-31m

163   P-31c    P-31m

164   P-3m1    P-3m1

165   P-3c1    P-3m1

166   R-3m     R-3m

167   R-3c     R-3m

168   P6       P6/m

169   P61      P6/m

170   P65      P6/m

171   P62      P6/m

172   P64      P6/m

173   P63      P6/m

174   P-6      P6/m

175   P6/m     P6/m

176   P63/m    P6/m

177   P622     P6/mmm

178   P6122    P6/mmm

179   P6522    P6/mmm

180   P6222    P6/mmm

181   P6422    P6/mmm

182   P6322    P6/mmm

183   P6mm     P6/mmm

184   P6cc     P6/mmm

185   P63cm    P6/mmm

186   P63mc    P6/mmm

187   P-6m2    P6/mmm

188   P-6c2    P6/mmm

189   P-62m    P6/mmm

190   P-62c    P6/mmm

191   P6/mmm   P6/mmm

192   P6/mcc   P6/mmm

193   P63/mcm  P6/mmm

194   P63/mmc  P6/mmm

195   P23      Pm-3

196   F23      Fm-3

197   I23      Im-3

198   P213     Pm-3

199   I213     Im-3

200   Pm-3     Pm-3

201   Pn--3

202   Fm-3     Fm-3

203   Fd-3     Fm-3

204   Im-3     Im-3

205   Pa--3

206   Ia-3     Im-3

207   P432     Pm-3m

208   P4332    Pm-3m

209   F432     Fm-3m

210   F4132    Fm-3m

211   I432     Im-3m

212   P4332    Pm-3m

213   P4132    Pm-3m

214   I4132    Im-3m

215   P-43m    Pm-3m

216   F4-3m    Fm-3m

217   I-43     Im-3m

218   P-43n    Pm-3m

219   F-43c    Fm-3m

220   I-43d    Im-3m

221   Pm-3m    Pm-3m

222   Pn-3n    Pm-3m

223   Pm-3n    Pm-3m

224   Pn-3m    Pm-3m

225   Fm-3m    Fm-3m

226   Fm-3c    Fm-3m

227   Fd-3m    Fm-3m

228   Fd-3c    Fm-3m

229   Im-3m    Im-3m

230   Ia-3d    Im-3m

 

Table 13.1.1.5.1 Patterson space groups returned by the function Patterson().

 

#include <ccl/spaceGroup.h>

 

main()

{

   for (int i = 1; i < 231; i++)

   {

      const short psGeneral = message::getPrintingSwitch(message::typeGeneral);

      const short psBusy    = message::getPrintingSwitch(message::typeBusy);

      message::setPrintingSwitch(message::typeGeneral, 0);

      message::setPrintingSwitch(message::typeBusy,    0);

      const ccl::spaceGroup sg(i);

      message::setPrintingSwitch(message::typeGeneral, psGeneral);

      message::setPrintingSwitch(message::typeBusy,    psBusy);

      cout << sg.spaceGroupNumber() << " "

           << sg.spaceGroupName() << "   "

           << sg.Patterson().spaceGroupName() << endl;

   }

 

   return 0;

}

 

Listing 13.1.1.5.1 Deriving Patterson space groups from any space group.

 

13.1.1.6 Point Group

The point group of any space group can be derived by removal of all translations, and ignore the lattice type.

 

spaceGroup pointGroup() const;

Returns point group of the original space group.  The point group returned has the type of ccl::spaceGroup.  The returned object has consistent orientation with the original space group.

 

std::string pointGroupName() const;

Returns point group name.  This function simply removes the first character of the space group symbol.  The point group name reflects the orientation.  For example, -4m2 and -42m are really the same point group, but their orientations are different.

 

No.      Name     Point group

No.     Name      Point group

No.      Name     Point group

1     P1       1

2     P-1      -1

3     P2       2

4     P21      2

5     C2       2

6     Pm       m

7     Pc       m

8     Cm       m

9     Cc       m

10    P2/m     2/m

11    P21/m    2/m

12    C2/m     2/m

13    P2/c     2/m

14    P21/c    2/m

15    C2/c     2/m

16    P222     222

17    P2221    222

18    P21212   222

19    P212121  222

20    C2221    222

21    C222     222

22    F222     222

23    I222     222

24    I212121  222

25    Pmm2     mm2

26    Pmc21    mm2

27    Pcc2     mm2

28    Pma2     mm2

29    Pca21    mm2

30    Pnc2     mm2

31    Pmn21    mm2

32    Pba2     mm2

33    Pna21    mm2

34    Pnn2     mm2

35    Cmm2     mm2

36    Cmc21    mm2

37    Ccc2     mm2

38    Amm2     mm2

39    Abm2     mm2

40    Ama2     mm2

41    Aba2     mm2

42    Fmm2     mm2

43    Fdd2     mm2

44    Imm2     mm2

45    Iba2     mm2

46    Ima2     mm2

47    Pmmm     mmm

48    Pnnn     mmm

49    Pccm     mmm

50    Pban     mmm

51    Pmma     mmm

52    Pnna     mmm

53    Pmna     mmm

54    Pcca     mmm

55    Pbam     mmm

56    Pccn     mmm

57    Pbcm     mmm

58    Pnnm     mmm

59    Pmmn     mmm

60    Pbcn     mmm

61    Pbca     mmm

62    Pnma     mmm

63    Cmcm     mmm

64    Cmca     mmm

65    Cmmm     mmm

66    Cccm     mmm

67    Cmma     mmm

68    Ccca     mmm

69    Fmmm     mmm

70    Fddd     mmm

71    Immm     mmm

72    Ibam     mmm

73    Ibca     mmm

74    Imma     mmm

75    P4       4

76    P41      4

77    P42      4

78   P43      4

79   I4       4

80   I41      4

81   P-4      -4

82   I-4      -4

83   P4/m     4/m

84   P42/m    4/m

85   P4/n     4/m

86   P42/n    4/m

87   I4/m     4/m

88   I41/a    4/m

89   P422     422

90   P4212    422

91   P4122    422

92   P41212   422

93   P4222    422

94   P42212   422

95   P4322    422

96   P43212   422

97   I422     422

98   I4122    422

99   P4mm     4mm

100  P4bm     4mm

101  P42cm    4mm

102  P42nm    4mm

103  P4cc     4mm

104  P4nc     4mm

105  P42mc    4mm

106  P42bc    4mm

107  I4mm     4mm

108  I4cm     4mm

109  I41md    4mm

110  I41cd    4mm

111  P-42m    -42m

112  P-42c    -42m

113  P-421m   -42m

114  P-421c   -42m

115  P-4m2    -4m2

116  P-4c2    -4m2

117  P-4b2    -4m2

118  P-4n2    -4m2

119  I-4m2    -4m2

120  I-4c2    -4m2

121  I-42m    -42m

122  I-42d    -42m

123  P4/mmm   4/mmm

124  P4/mcc   4/mmm

125  P4/nbm   4/mmm

126  P4/nnc   4/mmm

127  P4/mbm   4/mmm

128  P4/mnc   4/mmm

129  P4/nmm   4/mmm

130  P4/ncc   4/mmm

131  P42/mmc  4/mmm

132  P42/mcm  4/mmm

133  P42/nbc  4/mmm

134  P42/nnm  4/mmm

135  P42/mbc  4/mmm

136  P42/mnm  4/mmm

137  P42/nmc  4/mmm

138  P42/ncm  4/mmm

139  I4/mmm   4/mmm

140  I4/mcm   4/mmm

141  I41/amd  4/mmm

142  I41/acd  4/mmm

143  P3       3

144  P31      3

145  P32      3

146  R3       3

147  P-3      -3

148  R-3      -3

149  P312     312

150  P321     321

151  P3112    312

152  P3121    321

153  P3212    312

154  P3221    321

155   R32      321

156   P3m1     3m1

157   P31m     31m

158   P3c1     3m1

159   P31c     31m

160   R3m      3m1

161   R3c      3m1

162   P-31m    -31m

163   P-31c    -31m

164   P-3m1    -3m1

165   P-3c1    -3m1

166   R-3m     -3m1

167   R-3c     -3m1

168   P6       6

169   P61      6

170   P65      6

171   P62      6

172   P64      6

173   P63      6

174   P-6      -6

175   P6/m     6/m

176   P63/m    6/m

177   P622     622

178   P6122    622

179   P6522    622

180   P6222    622

181   P6422    622

182   P6322    622

183   P6mm     6mm

184   P6cc     6mm

185   P63cm    6mm

186   P63mc    6mm

187   P-6m2    -6m2

188   P-6c2    -6m2

189   P-62m    -62m

190   P-62c    -62m

191   P6/mmm   6/mmm

192   P6/mcc   6/mmm

193   P63/mcm  6/mmm

194   P63/mmc  6/mmm

195   P23      23

196   F23      23

197   I23      23

198   P213     23

199   I213     23

200   Pm-3     m-3

201   Pn-3     m-3

202   Fm-3     m-3

203   Fd-3     m-3

204   Im-3     m-3

205   Pa-3     m-3

206   Ia-3     m-3

207   P432     432

208   P4332    432

209   F432     432

210   F4132    432

211   I432     432

212   P4332    432

213   P4132    432

214   I4132    432

215   P-43m    -43m

216   F4-3m    -43m

217   I-43     -43m

218   P-43n    -43m

219   F-43c    -43m

220   I-43d    -43m

221   Pm-3m    m-3m

222   Pn-3n    m-3m

223   Pm-3n    m-3m

224   Pn-3m    m-3m

225   Fm-3m    m-3m

226   Fm-3c    m-3m

227   Fd-3m    m-3m

228   Fd-3c    m-3m

229   Im-3m    m-3m

230   Ia-3d    m-3m

 

Table 13.1.1.6.1 Point groups derived by the function pointGroup().

 

#include <ccl/spaceGroup.h>

 

main()

{

   for (int i = 1; i < 231; i++)

   {

      const short psGeneral = message::getPrintingSwitch(message::typeGeneral);

      const short psBusy    = message::getPrintingSwitch(message::typeBusy);

      message::setPrintingSwitch(message::typeGeneral, 0);

      message::setPrintingSwitch(message::typeBusy,    0);

      const ccl::spaceGroup sg(i);

      message::setPrintingSwitch(message::typeGeneral, psGeneral);

      message::setPrintingSwitch(message::typeBusy,    psBusy);

      cout << sg.spaceGroupNumber() << " "

           << sg.spaceGroupName() << "   "

           << sg.pointGroup().pointGroupName() << endl;

   }

 

   return 0;

}

 

Listing 13.1.1.6.1 Using pointGroup().

 

13.1.1.7 Output

The operator << is overloaded to print the space group information.

 

std::string position(const size_t) const;

Returns an std::string such as ¡®-y+2/3, x-y+1/3, z+1/3¡¯ that shows the operator of the given 0-offset subscript.

 

static std::string position(

   const mac::matrix3D<int>&,

   const mac::vector3D<double>&);

Converts a matrix R and a translation t to an operator as std::string.  If some arbitrary matrices and vectors are given to this function, the result may not be intended.  Always use the member function position() above if possible.

 

The following program tests the class ccl::spaceGroup.

 

#include <assert.h>

#include <string.h>

#include <ccl/spaceGroup.h>

 

main()

{

   ccl::spaceGroup sg;      // Construct a default space group

   cout << sg << endl;      // Output

   sg = ccl::spaceGroup(5); // Construct space group #5

   cout << sg << endl;

   sg = ccl::spaceGroup("p212121"); // Construct space group P212121

   cout << sg << endl;

   sg = ccl::spaceGroup(std::string("I4122")); // Construct space group I4122

   cout << sg << endl;

   sg.setSpaceGroup(173);   // By space group #

   cout << sg << endl;

   sg.setSpaceGroup("r3");  // By space group name

   cout << sg << endl;

   assert (sg.spaceGroupName(0) == "r3");

   assert (sg.spaceGroupName()  == "R3");

   assert (sg.lattice(0) == "r");

   assert (sg.lattice()  == "R");

   assert (sg.spaceGroupNumber() == 146);

   assert (sg.operateSize() == 9);

   assert (sg.uniqueOperateSize() == 3);

   assert (sg.crystalSystem() == "trigonal");

   assert (!sg.centrosymmetric());

   assert (!sg.enantiomorphic());

   assert (sg.getOperate(0) == mac::matrix3D<int>());

   assert (sg.getTranslate(0) == mac::vector3D<double>());

   assert (sg.getOperate()[1] == sg.getOperate(1));

   assert (sg.getTranslate()[1] == sg.getTranslate(1));

   assert (*(sg.getUniqueOperate().begin()) == sg.getUniqueOperate(0));

   for (int i = 0; i < sg.operateSize(); i++) cout << sg.position(i) << endl;

 

   return 0;

}

 

Listing 13.1.1.0.1 Testing ccl:spaceGroup.

 

13.1.2 The shadow class cpl.ccl.symm.spaceGroup

 

The shadow class cpl.ccl.symm.spaceGroup has all functions of the original class ccl::spaceGroup except those return STL containers, since these container classes are not yet wrapped into Python.  In following sections, sg is a spaceGroup object.

 

13.1.2.1 Constructors

spaceGroup(n = 1)

Constructs a spaceGroup object with the space group number n.  The default is P1.

 

spaceGroup(s)

Constructs a spaceGroup object that models space group s, where s is a string similar to the space group symbol found in the International Tables.  See Table 13.1.1.0.1 for recognized strings.

 

spaceGroup(sg)

The copy constructor returns a new spaceGroup object identical to the given space group sg.

 

sg.setSpaceGroup(n)

sg.setSpaceGroup(s)

Set the existing space group sg to space group number n, or space group symbol s, respectively.

 

13.1.2.2 Space Group Characteristics

sg.spaceGroupName(cap = 1)

Returns the space group name of sg.  cap indicates whether the first character of the returned string is capitalized.

 

sg.pointGroupName()

Returns the point group name.  See 13.1.6 for more.

 

sg.lattice(cap = 1)

Returns lattice type of the space group sg.  cap indicates whether the returned character is capitalized.

 

sg.spaceGroupNumber()

Returns the number of sg.

 

sg.getCrystalSystem()

sg.crystalSystem()

Return crystal system of sg.

 

sg.getCentralSymmetric()

sg.centrosymmetric()

Return true if sg is a central symmetric space group, and false otherwise.

 

sg.getEnantiomorphism()

sg.enantiomorphic()

Return true if sg is a enantiomorphic space group, and false otherwise.

 

13.1.2.3 Symmetry Operators

sg.operatorSize()

sg.operateSize()

sg.getOperateSize()

Return the number of symmetry operators for the space group sg.

 

sg.R(i)

Returns the i-th operator matrix of sg, where i is a 1-offset subscript.

 

sg.getOperate(i)

Returns an operator matrix.  This function takes a 0-offset subscript.  This function may be removed in future release.

 

sg.t(i)

Returns the i-th translation vector, where i is a 1-offset subscript.

 

sg.getTranslate(i)

Returns a translation vector.  This function takes a 0-offset subscript.  This function may be removed in future release.

 

sg.operators()

sg.getOperate()

Return a tuple that contains all operation matrices.

 

sg.translations()

sg.getTranslate()

Return a tuple that contains all translation vectors.

 

13.1.2.4 Unique Symmetry Operators

sg.uniqueOperatorSize()

sg.uniqueOperateSize()

sg.getUniqueOperateSize()

Return the number of unique operators.

 

sg.uniqueR(i)

Rteurns the i-th unique operator matrix, where i is a 0-offset subscript.

 

sg.getUniqueOperate(i)

Returns a unique operator matrix.  This function takes a 1-offset subscript.

 

13.1.2.5 Patterson Space Group and Point Group

sg.Patterson()

sg.pointGroup()

Return Patterson space group and point group of sg, respectively.  See 13.1.5 and 13.1.6 for detail.

 

sg.pointGroupName()

Returns point group symbol.

 

13.1.2.6 Output

sg.position(i)

Returns a string showing a general position.  This function takes a 0-offset subscript.  CAUTION: this subscript does not consistent with CPL convention used elsewhere, and may be changed in future release.

 

__str__() function is defined to print information about the space group.

 

This example tests the shadow class cpl.mac.vm.spaceGroup.  This program shall only print information about the space group P212121, if everything is fine.

 

#!/usr/bin/python

 

import cpl

 

SG = cpl.ccl.symm.spaceGroup

sg = SG()                               # Default space group

sg = SG(5)                              # Constructs space group #5

sg = cpl.ccl.symm.spaceGroup("p212121") # Constructs space group P212121

print sg                                # Output

assert sg.spaceGroupName(0) == "p212121"

assert sg.spaceGroupName()  == "P212121"

assert sg.lattice(0) == 'p'

assert sg.lattice()  == 'P'

assert sg.spaceGroupNumber() == 19

assert sg.operatorSize() == 4

assert sg.uniqueOperatorSize() == 4

assert sg.crystalSystem() == "orthorhombic"

assert not sg.centrosymmetric()

assert not sg.enantiomorphic()

assert sg.R(1) == cpl.mac.vm.matrix3DINT()

assert sg.t(1) == cpl.mac.vm.vector3DDBL()

op = []

tr = []

for i in range(sg.operatorSize()):

   op.append(sg.R(i + 1))

   tr.append(sg.t(i + 1))

for i in range(sg.uniqueOperatorSize()): assert sg.uniqueR(i + 1) in op

 

Listing 13.1.2.0.1 Testing cpl.ccl.symm.spaceGroup.

 

13.2 Miller Indices

 

Every reflection has its own unique identifier that consists of three integers h, k, l, called Miller indices.

 

13.2.1 ccl::MillerIndices class

 

A set of Miller indices can be considered as a 3-dimensional vector with three integer elements, but few operations of mac::vector3D<int> are meaningful to Miller indices.  ccl::MillerIndices is therefore not derived from mac::vector3D<int>, but contains a private member of it.  In this way, the vector operations are not available to Miller indices, unless defined.

 

13.2.1.1 Constructors and destructor

MillerIndices(const int = 0,

              const int = 0,

              const int = 0);

MillerIndices(const mac::vector3D<int>);

The default constructor returns a MillerIndices of the direct beam.  The general constructors take three integers or a vector of integer.

 

MillerIndices(const double,

              const double,

              const double);

MillerIndices(const mac::vector3D<double>);

These constructors construct from the nearest integers of the given doubles.

 

MillerIndices(const MillerIndices&);

The copy constructor duplicates the given MillerIndices.

 

~MillerIndices();

There is nothing to do in destructor.

 

13.2.1.2 Conversion

operator mac::vector3D<int>()    const;

operator mac::vector3D<double>() const;

These conversion operators return vector3D<int> and vector3D<double>, respectively.

 

MillerIndices operator-() const;

MillerIndices operator+() const;

The unary operator ¨C returns MillerIndices of -h, -k, -l.  The unary operator + returns an identical MillerIndices.

 

13.2.1.3 Element access

int h() const;

int k() const;

int l() const;

Return h, k, l, respectively.

 

13.2.1.4 Comparison

bool operator!() const;

bool operator==(const MillerIndices&) const;

bool operator!=(const MillerIndices&) const;

bool operator< (const MillerIndices&) const;

bool operator> (const MillerIndices&) const;

bool operator<=(const MillerIndices&) const;

bool operator>=(const MillerIndices&) const;

All comparison operators have the same definitions as those of mac::vector3D<int>.

 

13.2.1.5 Prime indices

bool prime() const;

Returns true, if the Miller indices are prime to each other; and false otherwise.

 

MillerIndices primeOf() const;

static MillerIndices primeOf(

   const MillerIndices);

Return the prime indices harmonic to the MillerIndices.

 

13.2.1.6 Unique reflection

bool unique(const spaceGroup&,

            const bool anomalous = 0) const;

Returns true, if the MillerIndices represents a unique reflection in the given space group; and false otherwise.  The unique volume in the reciprocal space is defined internally by CCL.  The current release does not allow user definition.  The optional Boolean indicates whether anomalous signal is present.  If it is set, MillerIndices -H is unique when H is; if unset, -H is not unique when H is.

 

Throughout this chapter and the rest of CCL, this anomalous Boolean indicator will appear many times in different cases.  Its meaning may be overloaded, but it always indicates whether anomalous signal is present or considered by the user.

 

13.2.1.7 Symmetry-related reflections

bool symmetric(const MillerIndices&,

               const spaceGroup&,

               const bool = 0) const;

static bool symmetric(const MillerIndices&,

                      const MillerIndices&,

                      const spaceGroup&,

                      const bool = 0);

The member function tests whether this MillerIndices is symmetry-related to the given one in the space group specified.  The static function tests whether the two given MillerIndices are symmetry-related.  The optional Boolean is again anomalous indicator.  If it is set, -H and H are not symmetry-related; if unset, they are.

 

MillerIndices symmetric(

   const spaceGroup&,

   const bool = 0,

   std::set<MillerIndices>* = NULL) const;

MillerIndices symmetric(

   const spaceGroup&,

   const bool = 0,

   std::vector<MillerIndices>* = NULL) const;

Return the unique reflection that is symmetry-related to this MillerIndices in the given space group.  If the optional Boolean is set, anomalous signal is considered present, so that ¨CH is unique when H is unique.  If anomalous signal is absent, -H is not unique when H is.  See the example below.  If the last pointer is valid, the std::set<MillerIndices> or std::vector<MillerIndices> it points to will be filled by all symmetry-related MillerIndices.

 

protected:

   MillerIndices symmetric(

      const spaceGroup&,

      const bool,

      std::multiset<MillerIndices>*,

      const bool boundary = 1) const;

This protected member function is the same as the above, except that all symmetry-related reflections are returned in form of std::multiset<MillerIndices>.  This function is usually used internally in order to calculate the multiplicity of a reflection.  If the last optional Boolean boundary is set, only those reflections on the boundary of unique volumes will duplicate in the multiset.  If boundary is unset, lattice type will also affect the duplicated reflections in the multiset.

 

protected:

   void symmetric(

      const spaceGroup&,

      std::map<MillerIndices,

               mac::vector3D<double> >&,

      const bool = 0) const;

This protected member function historically used the overloaded name symmetric, but it is rather different from the rest of functions symmetric.  It does not identifies unique reflection, and therefore does not require anomalous Boolean indicator.  Given a space group, it modifies the map, which contains all symmetry-related MillerIndices, and their corresponding translation vector of the symmetry operation.  This function is used internally in calculation of phase shift of symmetry-related structure factors, also known as color symmetry (See 13.3 for detail).  If the last optional Boolean is set, only the reflections in a hemisphere is returned.

 

13.2.1.8 Centric reflection

bool centric(const spaceGroup&) const;

Returns true, if this reflection is a centric in the space group specified; or false otherwise.

 

13.2.1.9 Systematic absence

bool absent(const spaceGroup&) const;

Returns true, if this reflection is systematically absent in the space group given; or false otherwise.

 

13.2.1.10 Resolution

double d    (const cell&) const;

double dStar(const cell&) const;

Return d in Å or d* in Å-1, respectively.  The cell constants are required.  The given cell can be either direct or reciprocal cell, which makes no difference to the outcome.

 

13.2.1.11 Output

friend ostream &operator<<(ostream&,

                           const MillerIndices&);

The operator << is defined to print MillerIndices to an ostream.

 

The following program tests the public functions of ccl::MillerIndices.

 

#include <assert.h>

#include <string.h>

#include <mac/utility.h>

#include <CCL/spaceGroup.h>

#include <CCL/MillerIndices.h>

 

main()

{

   ccl::spaceGroup sg(5);

   typedef ccl::MillerIndices MI;

   MI hkl(1, 3, 3);

   MI mi;

   assert (!mi);

   mi = hkl;

   assert (!!mi);

 

   assert (hkl.prime());

   assert (hkl.unique(sg));

   assert (hkl == MI(3, 9, 9).primeOf());

 

   assert (!MI(0, 2, 0).centric(sg));

   assert ( MI(2, 0, 3).centric(sg));

   assert ( MI(1, 2, 3).absent(sg));

   assert (!MI(1, 3, 2).absent(sg));

 

   std::set<MI> symm;

   mi = hkl.symmetric(sg, 0, &symm);

   assert (mi == hkl);

 

   cout <<

      "If anomalous signal does not present, symmetry-related reflections of "

        << hkl << ":" << endl;

   for (std::set<MI>::const_iterator i = symm.begin(); i != symm.end(); i++)

      cout << *i << endl;

   cout << endl;

 

   hkl.symmetric(sg, 1, &symm);

   cout << "If anomalous signal presents, symmetry-related reflections of "

        << hkl << ":" << endl;

   for (std::set<MI>::const_iterator i = symm.begin(); i != symm.end(); i++)

      cout << *i << endl;

   cout << endl;

 

   ccl::cell cl(20, 30, 40, 90, 100, 90);

   assert (mac::approx(hkl.d(cl),     hkl.d(*cl)));

   assert (mac::approx(hkl.dStar(cl), hkl.dStar(*cl)));

   assert (mac::approx(hkl.d(cl), 1 / hkl.dStar(cl)));

 

   return 0;

}

 

Listing 13.2.1.0.1 Testing ccl::MillerIndices.

 

Loading the Space-group Database ...

__________

\  ____  /

 \ \  / /

  \ \/ /

   \  /

    \/

  Yield!   ....................................................

File /home/renz/code/ccl/lib/symlib is open for read.

...............................................................

 

The space-group #5 is loaded.

File /home/renz/code/ccl/lib/symlib read.

If anomalous signal does not present, symmetry-related reflections of     1    3    3:

   -1   -3   -3

   -1    3   -3

    1   -3    3

    1    3    3

 

If anomalous signal presents, symmetry-related reflections of     1    3    3:

   -1    3   -3

    1    3    3

 

Listing 13.2.1.0.2 The effect of the optional Boolean anomalous.

 

13.2.2 The shadow class cpl.ccl.symm.MillerIndices

 

In this section, H and K are objects of MillerIndices; sg, an object of cpl.ccl.symm.spaceGroup; and cl, an object of cpl.ccl.symm.cell.

 

13.2.2.1 Constructors

MillerIndices(h = 0, k = 0, l = 0)

Constructs an object of cpl.ccl.symm.MillerIndices from no more than three integers.  The default MillerIndices is the direct beam.

 

MillerIndices(H)

The copy constructor copies H to another MillerIndices.

 

13.2.2.2 Conversion

H.vector3DINT()

H.vector3DDBL()

Convert H to an object of cpl.mac.vm.vector3DINT and cpl.mac.vm.vector3DDBL, respectively.

 

+H

-H

Return H itself, or the Friedel mate of H, respectively.

 

13.2.2.3 Element access

H.h()

H.k()

H.l()

Return h, k, l, respectively.

 

13.2.2.4 Comparison

H.is_zero()

Returns true, if all h, k, l are 0.

 

H == K

H != K

H <  K

H >  K

H <= K

H >= K

These operators are defined exactly the same as those of cpl.mac.vm.vector3DINT.  See 3.1.2.10.

 

13.2.2.5 Prime indices

H.prime()

Returns true, if H is a prime MillerIndices; and false otherwise.

 

H.primeOf()

MillerIndices.prime_of(H)

Return prime Miller indices of H.

 

13.2.2.6 Unique reflection

H.unique(sg, anomalous = 0)

Returns true, if the H represents a unique reflection in the given space group sg; and false otherwise.  The optional Boolean anomalous indicates whether anomalous signal is present.  If it is set, MillerIndices

-H is unique when H is; if unset, -H is not unique when H is.  See 13.2.1.6 for more detail.

 

13.2.2.7 Symmetry-related reflections

H.symmRelated(K, sg, anomalous = 0)

symm(H, K, sg, anomalous = 0)

Test whether H is symmetry-related to K in the space group sg.  If the optional Boolean anomalous is set, -H and H are not symmetry-related; if unset, they are.

 

H.symmetric(sg, anomalous = 0, v = NULL)

Return the unique reflection that is symmetry-related to H in the given space group sg.  If the optional Boolean anomalous is set, anomalous signal is considered present, so that ¨CH is unique when H is unique.  If anomalous signal is absent, -H is not unique when H is.  If the last argument v is a valid cpl.ccl.symm.vectorH, it will be filled by all symmetry-related MillerIndices.

 

13.2.2.8 Centric reflection

H.centric(sg)

Returns true, if H is centric in the space group sg; or false otherwise.

 

13.2.2.9 Systematic absence

H.absent(sg)

Returns true, if H is systematically absent in the space group sg; or false otherwise.

 

13.2.2.10 Resolution

H.d    (cl)

H.dStar(cl)

Return d in Å or d* in Å-1, respectively.  The cell cl is required.  The given cell can be either direct or reciprocal cell, which makes no difference to the outcome.

 

13.2.2.11 Output

H.__str__()

The special function is defined to print MillerIndices H.

 

This program tests the shadow class cpl.ccl.symm.MillerIndices.

 

#!/usr/bin/python

 

import cpl

 

sg = cpl.ccl.symm.spaceGroup(5)

MI = cpl.ccl.symm.MillerIndices

mi = MI()

assert mi.is_zero()

hkl = MI(1, 3, 3)

assert hkl.prime()

assert hkl.unique(sg)

assert hkl == MI(3, 9, 9).primeOf()

assert not MI(0, 2, 0).centric(sg)

assert MI(2, 0, 3).centric(sg)

assert MI(1, 2, 3).absent(sg)

assert not MI(1, 3, 2).absent(sg)

symm = cpl.ccl.symm.vectorH()

mi = hkl.symmetric(sg, 0, symm)

assert mi == hkl

print "If anomalous signal does not present, symmetry-related reflections of ",

print hkl, ":"

for i in symm: print i

print

hkl.symmetric(sg, 1, symm)

print "If anomalous signal presents, symmetry-related reflections of ",

print hkl, ":"

for i in symm: print i

print

cl = cpl.ccl.symm.cell(20, 30, 40, 90, 100, 90)

assert cpl.mac.utility.approx(hkl.d(cl),     hkl.d(~cl))

assert cpl.mac.utility.approx(hkl.dStar(cl), hkl.dStar(~cl))

assert cpl.mac.utility.approx(hkl.d(cl), 1 / hkl.dStar(cl))

 

Listing 13.2.2.0.1 Testing cpl.ccl.symm.MillerIndices.

 

13.2.3 Container of MillerIndices

 

std::vector<ccl::MillerIndices> is instantiated and can be accessed by using cpl.ccl.symm.vectorHKL.  See 2.2.1 cpl.std for more detail.