# pointgrp.h

    00001 //
    00002 // pointgrp.h
    00003 //
    00004 // Modifications are
    00005 // Copyright (C) 1996 Limit Point Systems, Inc.
    00006 //
    00007 // Author: Edward Seidl <seidl@janed.com>
    00008 // Maintainer: LPS
    00009 //
    00010 // This file is part of the SC Toolkit.
    00011 //
    00012 // The SC Toolkit is free software; you can redistribute it and/or modify
    00013 // it under the terms of the GNU Library General Public License as published by
    00014 // the Free Software Foundation; either version 2, or (at your option)
    00015 // any later version.
    00016 //
    00017 // The SC Toolkit is distributed in the hope that it will be useful,
    00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00020 // GNU Library General Public License for more details.
    00021 //
    00022 // You should have received a copy of the GNU Library General Public License
    00023 // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
    00024 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
    00025 //
    00026 // The U.S. Government is granted a limited license as per AL 91-7.
    00027 //
    00028
    00029 /* pointgrp.h -- definition of the point group classes
    00030  *
    00031  *      THIS SOFTWARE FITS THE DESCRIPTION IN THE U.S. COPYRIGHT ACT OF A
    00032  *      "UNITED STATES GOVERNMENT WORK".  IT WAS WRITTEN AS A PART OF THE
    00033  *      AUTHOR'S OFFICIAL DUTIES AS A GOVERNMENT EMPLOYEE.  THIS MEANS IT
    00034  *      CANNOT BE COPYRIGHTED.  THIS SOFTWARE IS FREELY AVAILABLE TO THE
    00035  *      PUBLIC FOR USE WITHOUT A COPYRIGHT NOTICE, AND THERE ARE NO
    00036  *      RESTRICTIONS ON ITS USE, NOW OR SUBSEQUENTLY.
    00037  *
    00038  *  Author:
    00039  *      E. T. Seidl
    00040  *      Bldg. 12A, Rm. 2033
    00041  *      Computer Systems Laboratory
    00042  *      Division of Computer Research and Technology
    00043  *      National Institutes of Health
    00044  *      Bethesda, Maryland 20892
    00045  *      Internet: seidl@alw.nih.gov
    00046  *      June, 1993
    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 namespace sc {
    00064
    00065 // //////////////////////////////////////////////////////////////////
    00066
    00070 class SymmetryOperation {
    00071   private:
    00072     double d[3][3];
    00073
    00074   public:
    00075     SymmetryOperation();
    00076     SymmetryOperation(const SymmetryOperation &);
    00077     ~SymmetryOperation();
    00078
    00080     double trace() const { return d[0][0]+d[1][1]+d[2][2]; }
    00081
    00083     double* operator[](int i) { return d[i]; }
    00084
    00086     const double* operator[](int i) const { return d[i]; }
    00087
    00090     double& operator()(int i, int j) { return d[i][j]; }
    00091
    00093     double operator()(int i, int j) const { return d[i][j]; }
    00094
    00096     void zero() { memset(d,0,sizeof(double)*9); }
    00097
    00099     SymmetryOperation operate(const SymmetryOperation& r) const;
    00100
    00102     SymmetryOperation transform(const SymmetryOperation& r) const;
    00103
    00105     void unit() { zero(); d[0][0] = d[1][1] = d[2][2] = 1.0; }
    00106
    00108     void E() { unit(); }
    00109
    00111     void i() { zero(); d[0][0] = d[1][1] = d[2][2] = -1.0; }
    00112
    00114     void sigma_h() { unit(); d[2][2] = -1.0; }
    00115
    00117     void sigma_xz() { unit(); d[1][1] = -1.0; }
    00118
    00120     void sigma_yz() { unit(); d[0][0] = -1.0; }
    00121
    00123     void rotation(int n);
    00124     void rotation(double theta);
    00125
    00127     void c2_x() { i(); d[0][0] = 1.0; }
    00128
    00130     void c2_y() { i(); d[1][1] = 1.0; }
    00131
    00132     void transpose();
    00133
    00135     void print(std::ostream& =ExEnv::out0()) const;
    00136 };
    00137
    00138 // //////////////////////////////////////////////////////////////////
    00139
    00145 class SymRep {
    00146   private:
    00147     int n;
    00148     double d[5][5];
    00149
    00150   public:
    00151     SymRep(int =0);
    00152     SymRep(const SymmetryOperation&);
    00153     ~SymRep();
    00154
    00156     operator SymmetryOperation() const;
    00157
    00159     inline double trace() const;
    00160
    00162     void set_dim(int i) { n=i; }
    00163
    00165     double* operator[](int i) { return d[i]; }
    00167     const double* operator[](int i) const { return d[i]; }
    00168
    00171     double& operator()(int i, int j) { return d[i][j]; }
    00173     double operator()(int i, int j) const { return d[i][j]; }
    00174
    00176     void zero() { memset(d,0,sizeof(double)*25); }
    00177
    00179     SymRep operate(const SymRep& r) const;
    00180
    00182     SymRep transform(const SymRep& r) const;
    00183
    00185     void unit() {
    00186       zero(); d[0][0] = d[1][1] = d[2][2] = d[3][3] = d[4][4] = 1.0;
    00187     }
    00188
    00190     void E() { unit(); }
    00191
    00193     void i() { zero(); d[0][0] = d[1][1] = d[2][2] = d[3][3] = d[4][4] = -1.0;}
    00194
    00196     void sigma_h();
    00197
    00199     void sigma_xz();
    00200
    00202     void sigma_yz();
    00203
    00205     void rotation(int n);
    00206     void rotation(double theta);
    00207
    00209     void c2_x();
    00210
    00212     void c2_y();
    00213
    00215     void print(std::ostream& =ExEnv::out0()) const;
    00216 };
    00217
    00218 inline double
    00219 SymRep::trace() const
    00220 {
    00221   double r=0;
    00222   for (int i=0; i < n; i++)
    00223     r += d[i][i];
    00224   return r;
    00225 }
    00226
    00227 // //////////////////////////////////////////////////////////////////
    00228
    00229
    00230 class CharacterTable;
    00231
    00239 class IrreducibleRepresentation {
    00240   friend class CharacterTable;
    00241
    00242   private:
    00243     int g;         // the order of the group
    00244     int degen;     // the degeneracy of the irrep
    00245     int nrot_;     // the number of rotations in this irrep
    00246     int ntrans_;   // the number of translations in this irrep
    00247     int complex_;  // true if this irrep has a complex representation
    00248     char *symb;    // mulliken symbol for this irrep
    00249     char *csymb;    // mulliken symbol for this irrep w/o special characters
    00250
    00251     SymRep *rep;   // representation matrices for the symops
    00252
    00253   public:
    00254     IrreducibleRepresentation();
    00255     IrreducibleRepresentation(const IrreducibleRepresentation&);
    00259     IrreducibleRepresentation(int,int,const char*,const char* =0);
    00260
    00261     ~IrreducibleRepresentation();
    00262
    00263     IrreducibleRepresentation& operator=(const IrreducibleRepresentation&);
    00264
    00266     void init(int =0, int =0, const char* =0, const char* =0);
    00267
    00269     int order() const { return g; }
    00270
    00272     int degeneracy() const { return degen; }
    00273
    00275     int complex() const { return complex_; }
    00276
    00278     int nproj() const { return degen*degen; }
    00279
    00281     int nrot() const { return nrot_; }
    00282
    00284     int ntrans() const { return ntrans_; }
    00285
    00287     const char * symbol() const { return symb; }
    00288
    00292     const char * symbol_ns() const { return (csymb?csymb:symb); }
    00293
    00296     double character(int i) const {
    00297       return complex_ ? 0.5*rep[i].trace() : rep[i].trace();
    00298     }
    00299
    00301     double p(int x1, int x2, int i) const { return rep[i](x1,x2); }
    00302
    00305     double p(int d, int i) const {
    00306       int dc=d/degen; int dr=d%degen;
    00307       return rep[i](dr,dc);
    00308     }
    00309
    00313     void print(std::ostream& =ExEnv::out0()) const;
    00314 };
    00315
    00316 // ///////////////////////////////////////////////////////////
    00325 class CharacterTable {
    00326   public:
    00327     enum pgroups {C1, CS, CI, CN, CNV, CNH, DN, DND, DNH, SN, T, TH, TD, O,
    00328                   OH, I, IH};
    00329
    00330   private:
    00331     int g;                               // the order of the point group
    00332     int nt;                              // order of the princ rot axis
    00333     pgroups pg;                          // the class of the point group
    00334     int nirrep_;                         // the number of irreps in this pg
    00335     IrreducibleRepresentation *gamma_;   // an array of irreps
    00336     SymmetryOperation *symop;            // the matrices describing sym ops
    00337     int *_inv;                           // index of the inverse symop
    00338     char *symb;                          // the Schoenflies symbol for the pg
    00339
    00341     int parse_symbol();
    00343     int make_table();
    00344
    00345     // these create the character tables for the cubic groups
    00346     void t();
    00347     void th();
    00348     void td();
    00349     void o();
    00350     void oh();
    00351     void i();
    00352     void ih();
    00353
    00354   public:
    00355     CharacterTable();
    00358     CharacterTable(const char*);
    00362     CharacterTable(const char*,const SymmetryOperation&);
    00363
    00364     CharacterTable(const CharacterTable&);
    00365     ~CharacterTable();
    00366
    00367     CharacterTable& operator=(const CharacterTable&);
    00368
    00370     int nirrep() const { return nirrep_; }
    00372     int order() const { return g; }
    00374     const char * symbol() const { return symb; }
    00376     IrreducibleRepresentation& gamma(int i) { return gamma_[i]; }
    00378     SymmetryOperation& symm_operation(int i) { return symop[i]; }
    00379
    00383     int complex() const {
    00384       if (pg==CN || pg==SN || pg==CNH || pg==T || pg==TH)
    00385         return 1;
    00386       return 0;
    00387     }
    00388
    00390     int inverse(int i) const { return _inv[i]; }
    00391
    00392     int ncomp() const {
    00393       int ret=0;
    00394       for (int i=0; i < nirrep_; i++) {
    00395         int nc = (gamma_[i].complex()) ? 1 : gamma_[i].degen;
    00396         ret += nc;
    00397       }
    00398       return ret;
    00399     }
    00400
    00402     int which_irrep(int i) {
    00403       for (int ir=0, cn=0; ir < nirrep_; ir++) {
    00404         int nc = (gamma_[ir].complex()) ? 1 : gamma_[ir].degen;
    00405         for (int c=0; c < nc; c++,cn++)
    00406           if (cn==i)
    00407             return ir;
    00408       }
    00409       return -1;
    00410     }
    00411
    00413     int which_comp(int i) {
    00414       for (int ir=0, cn=0; ir < nirrep_; ir++) {
    00415         int nc = (gamma_[ir].complex()) ? 1 : gamma_[ir].degen;
    00416         for (int c=0; c < nc; c++,cn++)
    00417           if (cn==i)
    00418             return c;
    00419       }
    00420       return -1;
    00421     }
    00422
    00424     void print(std::ostream& =ExEnv::out0()) const;
    00425 };
    00426
    00427 // ///////////////////////////////////////////////////////////
    00428
    00436 class PointGroup: public SavableState {
    00437   private:
    00438     char *symb;
    00439     SymmetryOperation frame;
    00440     SCVector3 origin_;
    00441
    00442   public:
    00443     PointGroup();
    00446     PointGroup(const char*);
    00449     PointGroup(const char*,SymmetryOperation&);
    00452     PointGroup(const char*,SymmetryOperation&,const SCVector3&);
    00487     PointGroup(const Ref<KeyVal>&);
    00488
    00489     PointGroup(StateIn&);
    00490     PointGroup(const PointGroup&);
    00491     PointGroup(const Ref<PointGroup>&);
    00492     ~PointGroup();
    00493
    00494     PointGroup& operator=(const PointGroup&);
    00495
    00497     int equiv(const Ref<PointGroup> &, double tol = 1.0e-6) const;
    00498
    00500     CharacterTable char_table() const;
    00502     const char * symbol() const { return symb; }
    00504     SymmetryOperation& symm_frame() { return frame; }
    00506     const SymmetryOperation& symm_frame() const { return frame; }
    00508     SCVector3& origin() { return origin_; }
    00509     const SCVector3& origin() const { return origin_; }
    00510
    00512     void set_symbol(const char*);
    00513
    00514     void save_data_state(StateOut& so);
    00515
    00516     void print(std::ostream&o=ExEnv::out0()) const;
    00517 };
    00518
    00519 }
    00520
    00521 #endif
    00522
    00523 // Local Variables:
    00524 // mode: c++
    00525 // c-file-style: "ETS"
    00526 // End: