00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #ifdef __GNUC__
00050 #pragma interface
00051 #endif
00052
00053 #ifndef _math_symmetry_pointgrp_h
00054 #define _math_symmetry_pointgrp_h
00055
00056 #include <iostream>
00057
00058 #include <util/class/class.h>
00059 #include <util/state/state.h>
00060 #include <util/keyval/keyval.h>
00061 #include <math/scmat/vector3.h>
00062
00063
00064
00068 class SymmetryOperation {
00069 private:
00070 double d[3][3];
00071
00072 public:
00073 SymmetryOperation();
00074 SymmetryOperation(const SymmetryOperation &);
00075 ~SymmetryOperation();
00076
00078 double trace() const { return d[0][0]+d[1][1]+d[2][2]; }
00079
00081 double* operator[](int i) { return d[i]; }
00082
00084 const double* operator[](int i) const { return d[i]; }
00085
00088 double& operator()(int i, int j) { return d[i][j]; }
00089
00091 double operator()(int i, int j) const { return d[i][j]; }
00092
00094 void zero() { memset(d,0,sizeof(double)*9); }
00095
00097 SymmetryOperation operate(const SymmetryOperation& r) const;
00098
00100 SymmetryOperation transform(const SymmetryOperation& r) const;
00101
00103 void unit() { zero(); d[0][0] = d[1][1] = d[2][2] = 1.0; }
00104
00106 void E() { unit(); }
00107
00109 void i() { zero(); d[0][0] = d[1][1] = d[2][2] = -1.0; }
00110
00112 void sigma_h() { unit(); d[2][2] = -1.0; }
00113
00115 void sigma_xz() { unit(); d[1][1] = -1.0; }
00116
00118 void sigma_yz() { unit(); d[0][0] = -1.0; }
00119
00121 void rotation(int n);
00122 void rotation(double theta);
00123
00125 void c2_x() { i(); d[0][0] = 1.0; }
00126
00128 void c2_y() { i(); d[1][1] = 1.0; }
00129
00130 void transpose();
00131
00133 void print(std::ostream& =ExEnv::out()) const;
00134 };
00135
00136
00137
00143 class SymRep {
00144 private:
00145 int n;
00146 double d[5][5];
00147
00148 public:
00149 SymRep(int =0);
00150 SymRep(const SymmetryOperation&);
00151 ~SymRep();
00152
00154 operator SymmetryOperation() const;
00155
00157 inline double trace() const;
00158
00160 void set_dim(int i) { n=i; }
00161
00163 double* operator[](int i) { return d[i]; }
00165 const double* operator[](int i) const { return d[i]; }
00166
00169 double& operator()(int i, int j) { return d[i][j]; }
00171 double operator()(int i, int j) const { return d[i][j]; }
00172
00174 void zero() { memset(d,0,sizeof(double)*25); }
00175
00177 SymRep operate(const SymRep& r) const;
00178
00180 SymRep transform(const SymRep& r) const;
00181
00183 void unit() {
00184 zero(); d[0][0] = d[1][1] = d[2][2] = d[3][3] = d[4][4] = 1.0;
00185 }
00186
00188 void E() { unit(); }
00189
00191 void i() { zero(); d[0][0] = d[1][1] = d[2][2] = d[3][3] = d[4][4] = -1.0;}
00192
00194 void sigma_h();
00195
00197 void sigma_xz();
00198
00200 void sigma_yz();
00201
00203 void rotation(int n);
00204 void rotation(double theta);
00205
00207 void c2_x();
00208
00210 void c2_y();
00211
00213 void print(std::ostream& =ExEnv::out()) const;
00214 };
00215
00216 inline double
00217 SymRep::trace() const
00218 {
00219 double r=0;
00220 for (int i=0; i < n; i++)
00221 r += d[i][i];
00222 return r;
00223 }
00224
00225
00226
00227
00228 class CharacterTable;
00229
00237 class IrreducibleRepresentation {
00238 friend class CharacterTable;
00239
00240 private:
00241 int g;
00242 int degen;
00243 int nrot_;
00244 int ntrans_;
00245 int complex_;
00246 char *symb;
00247
00248 SymRep *rep;
00249
00250 public:
00251 IrreducibleRepresentation();
00252 IrreducibleRepresentation(const IrreducibleRepresentation&);
00256 IrreducibleRepresentation(int,int,const char*);
00257
00258 ~IrreducibleRepresentation();
00259
00260 IrreducibleRepresentation& operator=(const IrreducibleRepresentation&);
00261
00263 void init(int =0, int =0, const char* =0);
00264
00266 int order() const { return g; }
00267
00269 int degeneracy() const { return degen; }
00270
00272 int complex() const { return complex_; }
00273
00275 int nproj() const { return degen*degen; }
00276
00278 int nrot() const { return nrot_; }
00279
00281 int ntrans() const { return ntrans_; }
00282
00284 const char * symbol() const { return symb; }
00285
00288 double character(int i) const {
00289 return complex_ ? 0.5*rep[i].trace() : rep[i].trace();
00290 }
00291
00293 double p(int x1, int x2, int i) const { return rep[i](x1,x2); }
00294
00297 double p(int d, int i) const {
00298 int dc=d/degen; int dr=d%degen;
00299 return rep[i](dr,dc);
00300 }
00301
00305 void print(std::ostream& =ExEnv::out()) const;
00306 };
00307
00308
00317 class CharacterTable {
00318 public:
00319 enum pgroups {C1, CS, CI, CN, CNV, CNH, DN, DND, DNH, SN, T, TH, TD, O,
00320 OH, I, IH};
00321
00322 private:
00323 int g;
00324 int nt;
00325 pgroups pg;
00326 int nirrep_;
00327 IrreducibleRepresentation *gamma_;
00328 SymmetryOperation *symop;
00329 int *_inv;
00330 char *symb;
00331
00333 int parse_symbol();
00335 int make_table();
00336
00337
00338 void t();
00339 void th();
00340 void td();
00341 void o();
00342 void oh();
00343 void i();
00344 void ih();
00345
00346 public:
00347 CharacterTable();
00350 CharacterTable(const char*);
00354 CharacterTable(const char*,const SymmetryOperation&);
00355
00356 CharacterTable(const CharacterTable&);
00357 ~CharacterTable();
00358
00359 CharacterTable& operator=(const CharacterTable&);
00360
00362 int nirrep() const { return nirrep_; }
00364 int order() const { return g; }
00366 const char * symbol() const { return symb; }
00368 IrreducibleRepresentation& gamma(int i) { return gamma_[i]; }
00370 SymmetryOperation& symm_operation(int i) { return symop[i]; }
00371
00375 int complex() const {
00376 if (pg==CN || pg==SN || pg==CNH || pg==T || pg==TH)
00377 return 1;
00378 return 0;
00379 }
00380
00382 int inverse(int i) const { return _inv[i]; }
00383
00384 int ncomp() const {
00385 int ret=0;
00386 for (int i=0; i < nirrep_; i++) {
00387 int nc = (gamma_[i].complex()) ? 1 : gamma_[i].degen;
00388 ret += nc;
00389 }
00390 return ret;
00391 }
00392
00394 int which_irrep(int i) {
00395 for (int ir=0, cn=0; ir < nirrep_; ir++) {
00396 int nc = (gamma_[ir].complex()) ? 1 : gamma_[ir].degen;
00397 for (int c=0; c < nc; c++,cn++)
00398 if (cn==i)
00399 return ir;
00400 }
00401 return -1;
00402 }
00403
00405 int which_comp(int i) {
00406 for (int ir=0, cn=0; ir < nirrep_; ir++) {
00407 int nc = (gamma_[ir].complex()) ? 1 : gamma_[ir].degen;
00408 for (int c=0; c < nc; c++,cn++)
00409 if (cn==i)
00410 return c;
00411 }
00412 return -1;
00413 }
00414
00416 void print(std::ostream& =ExEnv::out()) const;
00417 };
00418
00419
00420
00428 class PointGroup: public SavableState {
00429 private:
00430 char *symb;
00431 SymmetryOperation frame;
00432 SCVector3 origin_;
00433
00434 public:
00435 PointGroup();
00438 PointGroup(const char*);
00441 PointGroup(const char*,SymmetryOperation&);
00444 PointGroup(const char*,SymmetryOperation&,const SCVector3&);
00479 PointGroup(const Ref<KeyVal>&);
00480
00481 PointGroup(StateIn&);
00482 PointGroup(const PointGroup&);
00483 PointGroup(const Ref<PointGroup>&);
00484 ~PointGroup();
00485
00486 PointGroup& operator=(const PointGroup&);
00487
00489 int equiv(const Ref<PointGroup> &, double tol = 1.0e-6) const;
00490
00492 CharacterTable char_table() const;
00494 const char * symbol() const { return symb; }
00496 SymmetryOperation& symm_frame() { return frame; }
00498 const SymmetryOperation& symm_frame() const { return frame; }
00500 SCVector3& origin() { return origin_; }
00501 const SCVector3& origin() const { return origin_; }
00502
00504 void set_symbol(const char*);
00505
00506 void save_data_state(StateOut& so);
00507
00508 void print(std::ostream&o=ExEnv::out()) const;
00509 };
00510
00511
00512 #endif
00513
00514
00515
00516
00517