QMCPACK
SymmetryOperations.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
9 //
10 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 
14 #ifndef QMCPLUSPLUS_SYMMETRYOPERATIONS_H
15 #define QMCPLUSPLUS_SYMMETRYOPERATIONS_H
16 
17 #include "OhmmsData/AttributeSet.h"
18 
19 namespace qmcplusplus
20 {
22 {
23 public:
24  SymmetryGroup(std::string nm = "invalid") : name(nm), nClasses(0), nSymmetries(0) {}
25 
27 
28  void addOperator(Matrix<double> op, std::vector<double> characterlist, int cls)
29  {
30  SymOps.push_back(op);
31  nSymmetries++;
32  Characters.push_back(characterlist);
33  Classes.push_back(cls);
34  nClasses = std::max(nClasses, cls);
35  if (nClasses > characterlist.size())
36  {
37  app_log() << " Character table size or class number is wrong." << std::endl;
38  APP_ABORT("SymmetryGroup::addOperator");
39  }
40  }
41 
42  void putClassCharacterTable(std::vector<std::vector<double>> cct) { CharacterTableByClass = cct; }
43 
44  double getsymmetryCharacter(int symmetryOperation, int irrep) { return Characters[symmetryOperation][irrep]; }
45 
46  double getclassCharacter(int clss, int irrep) { return CharacterTableByClass[clss][irrep]; }
47 
48  int getClass(int symmetryOperation) { return Classes[symmetryOperation]; }
49 
50  int getSymmetriesSize() { return nSymmetries; }
51  int getClassesSize() { return nClasses; }
52 
53  void TransformSinglePosition(ParticleSet::ParticlePos& oldPos, int symNumber, int el = 0)
54  {
56  for (int i = 0; i < 3; i++)
57  for (int j = 0; j < 3; j++)
58  rv[0][i] += SymOps[symNumber][i][j] * oldPos[el][j];
59  oldPos[el] = rv[0];
60  }
61 
62  void TransformAllPositions(ParticleSet::ParticlePos& oldPos, int symNumber)
63  {
64  ParticleSet::ParticlePos rv(oldPos.size());
65  for (int k = 0; k < oldPos.size(); k++)
66  for (int i = 0; i < 3; i++)
67  for (int j = 0; j < 3; j++)
68  rv[k][i] += SymOps[symNumber][i][j] * oldPos[k][j];
69  oldPos = rv;
70  }
71 
72 private:
73  std::vector<Matrix<double>> SymOps;
74  std::vector<std::vector<double>> Characters;
75  std::vector<std::vector<double>> CharacterTableByClass;
76  std::vector<int> Classes;
77  std::string name;
78  int nClasses;
80 };
81 
82 
83 /**Builds the symmetry class
84 */
86 {
87 public:
88  /// Constructor.
89 
91 
93 
95 
96  void put(xmlNodePtr q)
97  {
98  symname = "";
99  xmlNodePtr kids = q->children;
100  while (kids != NULL)
101  {
102  std::string cname((const char*)(kids->name));
103  if (cname == "symmetryclass")
104  {
105  ParameterSet aAttrib;
106  aAttrib.add(symname, "name");
107  aAttrib.put(kids);
108  }
109  kids = kids->next;
110  }
111  if (symname == "D2H")
112  buildD2H();
113  else if (symname == "C2V")
114  buildC2V();
115  else
116  {
117  buildByHand(q);
118  // app_log()<<"Symmetry Class "<< symname <<" not yet implemented"<< std::endl;
119  // APP_ABORT("SymmetryClass::put");
120  }
121  }
122 
123 
124 private:
126  std::string symname;
127 
128  void buildI(SymmetryGroup& I, std::vector<double> ctable, int cls)
129  {
130  Matrix<double> matrix_i(3, 3);
131  for (int i = 0; i < 3; i++)
132  matrix_i[i][i] = 1.0;
133  I.addOperator(matrix_i, ctable, cls);
134  };
135  // C2V
136  void buildC2Vx(SymmetryGroup& C2, std::vector<double> ctable, int cls)
137  {
138  Matrix<double> matrix_c2x(3, 3);
139  matrix_c2x[0][0] = -1;
140  matrix_c2x[1][1] = 1;
141  matrix_c2x[2][2] = -1;
142  C2.addOperator(matrix_c2x, ctable, cls);
143  };
144  void buildC2Vy(SymmetryGroup& C2, std::vector<double> ctable, int cls)
145  {
146  Matrix<double> matrix_c2y(3, 3);
147  matrix_c2y[0][2] = 1;
148  matrix_c2y[1][1] = 1;
149  matrix_c2y[2][0] = 1;
150  C2.addOperator(matrix_c2y, ctable, cls);
151  };
152  void buildC2Vz(SymmetryGroup& C2, std::vector<double> ctable, int cls)
153  {
154  Matrix<double> matrix_c2z(3, 3);
155  matrix_c2z[0][2] = -1;
156  matrix_c2z[1][1] = 1;
157  matrix_c2z[2][0] = -1;
158  C2.addOperator(matrix_c2z, ctable, cls);
159  };
160  // D2H
161  void buildD2Hx(SymmetryGroup& C2, std::vector<double> ctable, int cls)
162  {
163  Matrix<double> matrix_c2x(3, 3);
164  matrix_c2x[0][0] = 1;
165  matrix_c2x[1][1] = -1;
166  matrix_c2x[2][2] = -1;
167  C2.addOperator(matrix_c2x, ctable, cls);
168  };
169  void buildD2Hy(SymmetryGroup& C2, std::vector<double> ctable, int cls)
170  {
171  Matrix<double> matrix_c2y(3, 3);
172  matrix_c2y[0][0] = -1;
173  matrix_c2y[1][1] = 1;
174  matrix_c2y[2][2] = -1;
175  C2.addOperator(matrix_c2y, ctable, cls);
176  };
177  void buildD2Hz(SymmetryGroup& C2, std::vector<double> ctable, int cls)
178  {
179  Matrix<double> matrix_c2z(3, 3);
180  matrix_c2z[0][0] = -1;
181  matrix_c2z[1][1] = -1;
182  matrix_c2z[2][2] = 1;
183  C2.addOperator(matrix_c2z, ctable, cls);
184  };
185 
186  // void buildD2(SymmetryGroup& C2, std::vector<double> ctable, int cls)
187  // {
188  // Matrix<double> matrix_c2x(3,3), matrix_c2y(3,3), matrix_c2z(3,3);
189  // matrix_c2z[0][0]=-1; matrix_c2z[1][1]=-1; matrix_c2z[2][2]=1;
190  // matrix_c2y[0][0]=-1; matrix_c2y[1][1]=1; matrix_c2y[2][2]=-1;
191  // matrix_c2x[0][0]=1; matrix_c2x[1][1]=-1; matrix_c2x[2][2]=-1;
192  // C2.addOperator(matrix_c2x, ctable, cls);
193  // C2.addOperator(matrix_c2y, ctable, cls);
194  // C2.addOperator(matrix_c2z, ctable, cls);
195  // return C2;
196  // };
197 
198  // void buildSigmaD(SymmetryGroup& SD, std::vector<double> ctable, int cls)
199  // {
200  // Matrix<double> matrix_sd1(3,3), matrix_sd2(3,3), matrix_sd3(3,3), matrix_sd4(3,3), matrix_sd5(3,3), matrix_sd6(3,3);
201  //
202  // matrix_sd1[0][0]=1; matrix_sd1[2][1]=1; matrix_sd1[1][2]=1;
203  // matrix_sd2[0][0]=1; matrix_sd2[2][1]=-1; matrix_sd2[1][2]=-1;
204  // matrix_sd3[0][1]=1; matrix_sd3[1][0]=1; matrix_sd3[2][2]=1;
205  // matrix_sd4[0][1]=-1; matrix_sd4[1][0]=-1; matrix_sd4[2][2]=1;
206  // matrix_sd5[0][2]=1; matrix_sd5[1][1]=1; matrix_sd5[2][0]=1;
207  // matrix_sd6[0][2]=-1; matrix_sd6[1][1]=1; matrix_sd6[2][0]=-1;
208  //
209  // SD.addOperator(matrix_sd1, ctable, cls);
210  // SD.addOperator(matrix_sd2, ctable, cls);
211  // SD.addOperator(matrix_sd3, ctable, cls);
212  // SD.addOperator(matrix_sd4, ctable, cls);
213  // SD.addOperator(matrix_sd5, ctable, cls);
214  // SD.addOperator(matrix_sd6, ctable, cls);
215  //
216  // return SD;
217  // };
218 
219  // void buildS_4(SymmetryGroup& SD, std::vector<double> ctable, int cls)
220  // {
221  // Matrix<double> matrix_sd1(3,3), matrix_sd2(3,3), matrix_sd3(3,3), matrix_sd4(3,3), matrix_sd5(3,3), matrix_sd6(3,3);
222  //
223  // matrix_sd1[0][0]=1; matrix_sd1[2][1]=-1; matrix_sd1[1][2]=1;
224  // matrix_sd2[0][0]=1; matrix_sd2[2][1]=1; matrix_sd2[1][2]=-1;
225  // matrix_sd3[0][1]=1; matrix_sd3[1][0]=-1; matrix_sd3[2][2]=1;
226  // matrix_sd4[0][1]=-1; matrix_sd4[1][0]=1; matrix_sd4[2][2]=1;
227  // matrix_sd5[0][2]=1; matrix_sd5[1][1]=1; matrix_sd5[2][0]=-1;
228  // matrix_sd6[0][2]=-1; matrix_sd6[1][1]=1; matrix_sd6[2][0]=1;
229  //
230  // SD.addOperator(matrix_sd1, ctable, cls);
231  // SD.addOperator(matrix_sd2, ctable, cls);
232  // SD.addOperator(matrix_sd3, ctable, cls);
233  // SD.addOperator(matrix_sd4, ctable, cls);
234  // SD.addOperator(matrix_sd5, ctable, cls);
235  // SD.addOperator(matrix_sd6, ctable, cls);
236  //
237  // return SD;
238  // };
239 
240  void buildD2H()
241  {
242  //Character table
243  std::vector<std::vector<double>> CT(4, std::vector<double>(4, 0));
244  CT[0][0] = 1;
245  CT[0][1] = 1;
246  CT[0][2] = 1;
247  CT[0][3] = 1;
248  CT[1][0] = 1;
249  CT[1][1] = 1;
250  CT[1][2] = -1;
251  CT[1][3] = -1;
252  CT[2][0] = 1;
253  CT[2][1] = -1;
254  CT[2][2] = 1;
255  CT[2][3] = -1;
256  CT[3][0] = 1;
257  CT[3][1] = -1;
258  CT[3][2] = -1;
259  CT[3][3] = 1;
260  buildI(symgrp, CT[0], 0);
261  buildD2Hx(symgrp, CT[1], 1);
262  buildD2Hy(symgrp, CT[2], 2);
263  buildD2Hz(symgrp, CT[3], 3);
265  };
266 
267  void buildC2V()
268  {
269  //Character table
270  std::vector<std::vector<double>> CT(4, std::vector<double>(4, 0));
271  CT[0][0] = 1;
272  CT[0][1] = 1;
273  CT[0][2] = 1;
274  CT[0][3] = 1;
275  CT[1][0] = 1;
276  CT[1][1] = 1;
277  CT[1][2] = -1;
278  CT[1][3] = -1;
279  CT[2][0] = 1;
280  CT[2][1] = -1;
281  CT[2][2] = 1;
282  CT[2][3] = -1;
283  CT[3][0] = 1;
284  CT[3][1] = -1;
285  CT[3][2] = -1;
286  CT[3][3] = 1;
287  buildI(symgrp, CT[0], 0);
288  buildC2Vx(symgrp, CT[1], 1);
289  buildC2Vy(symgrp, CT[2], 2);
290  buildC2Vz(symgrp, CT[3], 3);
292  };
293 
294  void buildByHand(xmlNodePtr q)
295  {
296  int nClasses(0);
297  int nSymmetries(0);
298  xmlNodePtr kids = q->children;
299  xmlNodePtr symclssptr(NULL);
300  while (kids != NULL)
301  {
302  std::string cname((const char*)(kids->name));
303  if (cname == "symmetryclass")
304  {
305  symclssptr = kids;
306  OhmmsAttributeSet aAttrib;
307  aAttrib.add(nClasses, "classes");
308  aAttrib.add(nSymmetries, "operators");
309  aAttrib.add(nSymmetries, "symmetries");
310  aAttrib.put(kids);
311  }
312  kids = kids->next;
313  }
314  std::vector<std::vector<double>> CT;
315  std::vector<std::vector<double>> OPS;
316  std::vector<int> clCT;
317  kids = symclssptr->children;
318  while (kids != NULL)
319  {
320  std::string cname((const char*)(kids->name));
321  if (cname == "charactertable")
322  {
323  xmlNodePtr kids2 = kids->children;
324  while (kids2 != NULL)
325  {
326  std::string cname2((const char*)(kids2->name));
327  if (cname2 == "class")
328  {
329  std::string clss;
330  OhmmsAttributeSet oAttrib;
331  oAttrib.add(clss, "name");
332  oAttrib.put(kids2);
333  std::vector<double> c;
334  putContent(c, kids2);
335  CT.push_back(c);
336  }
337  kids2 = kids2->next;
338  }
339  }
340  kids = kids->next;
341  }
342  kids = symclssptr->children;
343  while (kids != NULL)
344  {
345  std::string cname((const char*)(kids->name));
346  if (cname == "symmetries")
347  {
348  xmlNodePtr kids2 = kids->children;
349  while (kids2 != NULL)
350  {
351  std::string cname2((const char*)(kids2->name));
352  if (cname2 == "operator")
353  {
354  int clss(-1);
355  OhmmsAttributeSet oAttrib;
356  oAttrib.add(clss, "class");
357  oAttrib.put(kids2);
358  if (clss == -1)
359  {
360  app_log() << " Must label class of operators" << std::endl;
361  APP_ABORT("SymmetryClass::put");
362  }
363  clCT.push_back(clss);
364  std::vector<double> c;
365  putContent(c, kids2);
366  OPS.push_back(c);
367  }
368  kids2 = kids2->next;
369  }
370  }
371  kids = kids->next;
372  }
373  //make operator matrices, associate them with the class and add them to the symmetry group.
374  for (int i = 0; i < OPS.size(); i++)
375  {
376  Matrix<double> op(3, 3);
377  for (int j = 0; j < 3; j++)
378  for (int k = 0; k < 3; k++)
379  op(j, k) = OPS[i][j * 3 + k];
380  symgrp.addOperator(op, CT[clCT[i] - 1], clCT[i]);
381  }
383  // for(int j=0; j<CT.size();j++) for(int k=0; k<CT[0].size();k++) app_log()<<CT[j][k]<<" ";
384  }
385 };
386 
387 
388 } // namespace qmcplusplus
389 #endif
void buildD2Hz(SymmetryGroup &C2, std::vector< double > ctable, int cls)
void buildC2Vx(SymmetryGroup &C2, std::vector< double > ctable, int cls)
void buildD2Hx(SymmetryGroup &C2, std::vector< double > ctable, int cls)
std::vector< std::vector< double > > CharacterTableByClass
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
SymmetryGroup * getSymmetryGroup()
std::ostream & app_log()
Definition: OutputManager.h:65
double getclassCharacter(int clss, int irrep)
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
Attaches a unit to a Vector for IO.
bool put(std::istream &is) override
read from std::istream
Definition: ParameterSet.h:42
std::vector< Matrix< double > > SymOps
void buildC2Vz(SymmetryGroup &C2, std::vector< double > ctable, int cls)
size_type size() const
return the current size
Definition: OhmmsVector.h:162
class to handle a set of parameters
Definition: ParameterSet.h:27
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
Builds the symmetry class.
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
void TransformSinglePosition(ParticleSet::ParticlePos &oldPos, int symNumber, int el=0)
void buildI(SymmetryGroup &I, std::vector< double > ctable, int cls)
std::complex< double > I
bool putContent(T &a, xmlNodePtr cur)
replaces a&#39;s value with the first "element" in the "string" returned by XMLNodeString{cur}.
Definition: libxmldefs.h:88
void add(PDT &aparam, const std::string &aname_in, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new parameter corresponding to an xmlNode <parameter>
std::vector< std::vector< double > > Characters
void TransformAllPositions(ParticleSet::ParticlePos &oldPos, int symNumber)
void buildD2Hy(SymmetryGroup &C2, std::vector< double > ctable, int cls)
void putClassCharacterTable(std::vector< std::vector< double >> cct)
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
Definition: AttributeSet.h:42
void buildC2Vy(SymmetryGroup &C2, std::vector< double > ctable, int cls)
SymmetryGroup(std::string nm="invalid")
void addOperator(Matrix< double > op, std::vector< double > characterlist, int cls)
int getClass(int symmetryOperation)
double getsymmetryCharacter(int symmetryOperation, int irrep)