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 #ifndef _chemistry_qc_basis_petite_h
00029 #define _chemistry_qc_basis_petite_h
00030
00031 #ifdef __GNUC__
00032 #pragma interface
00033 #endif
00034
00035 #include <iostream>
00036
00037 #include <util/misc/scint.h>
00038 #include <util/ref/ref.h>
00039 #include <util/container/array.h>
00040 #include <math/scmat/blocked.h>
00041 #include <math/scmat/offset.h>
00042 #include <chemistry/molecule/molecule.h>
00043 #include <chemistry/qc/basis/gaussbas.h>
00044 #include <chemistry/qc/basis/integral.h>
00045
00046
00047
00048 inline sc_int_least64_t
00049 ij_offset64(sc_int_least64_t i, sc_int_least64_t j)
00050 {
00051 return (i>j) ? (((i*(i+1)) >> 1) + j) : (((j*(j+1)) >> 1) + i);
00052 }
00053
00054 inline sc_int_least64_t
00055 i_offset64(sc_int_least64_t i)
00056 {
00057 return ((i*(i+1)) >> 1);
00058 }
00059
00060
00061
00062 struct contribution {
00063 int bfn;
00064 double coef;
00065
00066 contribution();
00067 contribution(int b, double c);
00068 ~contribution();
00069 };
00070
00071 struct SO {
00072 int len;
00073 int length;
00074 contribution *cont;
00075
00076 SO();
00077 SO(int);
00078 ~SO();
00079
00080 SO& operator=(const SO&);
00081
00082 void set_length(int);
00083 void reset_length(int);
00084
00085
00086 int equiv(const SO& so);
00087 };
00088
00089 struct SO_block {
00090 int len;
00091 SO *so;
00092
00093 SO_block();
00094 SO_block(int);
00095 ~SO_block();
00096
00097 void set_length(int);
00098 void reset_length(int);
00099
00100 int add(SO& s, int i);
00101 void print(const char *title);
00102 };
00103
00104
00105
00106
00107 class PetiteList : public RefCount {
00108 private:
00109 int natom_;
00110 int nshell_;
00111 int ng_;
00112 int nirrep_;
00113 int nblocks_;
00114 int c1_;
00115
00116 Ref<GaussianBasisSet> gbs_;
00117 Ref<Integral> ints_;
00118
00119 char *p1_;
00120 int **atom_map_;
00121
00122 int **shell_map_;
00123
00124 char *lamij_;
00125
00126 int *nbf_in_ir_;
00127
00128 void init();
00129
00130 public:
00131 PetiteList(const Ref<GaussianBasisSet>&, const Ref<Integral>&);
00132 ~PetiteList();
00133
00134 int nirrep() const { return nirrep_; }
00135 int order() const { return ng_; }
00136 int atom_map(int n, int g) const { return (c1_) ? n : atom_map_[n][g]; }
00137 int shell_map(int n, int g) const { return (c1_) ? n : shell_map_[n][g]; }
00138 int lambda(int ij) const { return (c1_) ? 1 : (int) lamij_[ij]; }
00139 int lambda(int i, int j) const
00140 { return (c1_) ? 1 : (int) lamij_[ij_offset(i,j)]; }
00141
00142 int in_p1(int n) const { return (c1_) ? 1 : (int) p1_[n]; }
00143 int in_p2(int ij) const { return (c1_) ? 1 : (int) lamij_[ij]; }
00144 int in_p4(int ij, int kl, int i, int j, int k, int l) const;
00145
00146 int nfunction(int i) const
00147 { return (c1_) ? gbs_->nbasis() : nbf_in_ir_[i]; }
00148
00149 int nblocks() const { return nblocks_; }
00150
00151 void print(std::ostream& =ExEnv::out(), int verbose=1);
00152
00153
00154 RefSCDimension AO_basisdim();
00155 RefSCDimension SO_basisdim();
00156
00157
00158 RefSCMatrix r(int g);
00159
00160
00161 SO_block * aotoso_info();
00162 RefSCMatrix aotoso();
00163 RefSCMatrix sotoao();
00164
00165
00166 void symmetrize(const RefSymmSCMatrix& skel, const RefSymmSCMatrix& sym);
00167
00168
00169
00170 RefSymmSCMatrix to_SO_basis(const RefSymmSCMatrix&);
00171
00172
00173 RefSymmSCMatrix to_AO_basis(const RefSymmSCMatrix&);
00174
00175
00176
00177 RefSCMatrix evecs_to_AO_basis(const RefSCMatrix&);
00178
00179 RefSCMatrix evecs_to_SO_basis(const RefSCMatrix&);
00180 };
00181
00182 inline int
00183 PetiteList::in_p4(int ij, int kl, int i, int j, int k, int l) const
00184 {
00185 if (c1_)
00186 return 1;
00187
00188 sc_int_least64_t ijkl = i_offset64(ij)+kl;
00189 int nijkl=0;
00190
00191 for (int g=0; g < ng_; g++) {
00192 int gij = ij_offset(shell_map_[i][g],shell_map_[j][g]);
00193 int gkl = ij_offset(shell_map_[k][g],shell_map_[l][g]);
00194 sc_int_least64_t gijkl = ij_offset64(gij,gkl);
00195
00196 if (gijkl > ijkl)
00197 return 0;
00198 else if (gijkl == ijkl)
00199 nijkl++;
00200 }
00201
00202 return ng_/nijkl;
00203 }
00204
00205
00206
00207 #endif
00208
00209
00210
00211
00212