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