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 #ifndef _chemistry_qc_basis_gpetite_h
00028 #define _chemistry_qc_basis_gpetite_h
00029
00030 #ifdef __GNUC__
00031 #pragma interface
00032 #endif
00033
00034 #include <stdexcept>
00035
00036 #include <scconfig.h>
00037 #include <util/misc/scint.h>
00038 #include <chemistry/qc/basis/basis.h>
00039 #include <chemistry/qc/basis/petite.h>
00040
00041 namespace sc {
00042
00046 class canonical_aaaa {
00047 public:
00048 canonical_aaaa();
00049 canonical_aaaa(const Ref<GaussianBasisSet>& bi,
00050 const Ref<GaussianBasisSet>& bj,
00051 const Ref<GaussianBasisSet>& bk,
00052 const Ref<GaussianBasisSet>& bl
00053 );
00054 sc_int_least64_t offset(int i, int j, int k, int l) {
00055 long ij = (i>j?(((i*long(i+1))>>1)+j):(((j*long(j+1))>>1)+i));
00056 long kl = (k>l?(((k*long(k+1))>>1)+l):(((l*long(l+1))>>1)+k));
00057 sc_int_least64_t
00058 off = (ij>kl?(((ij*sc_int_least64_t(ij+1))>>1)+kl)
00059 :(((kl*sc_int_least64_t(kl+1))>>1)+ij));
00060 return off;
00061 }
00062 };
00063
00068 class canonical_aabc {
00069 long nk_, nl_;
00070 public:
00071 canonical_aabc(const Ref<GaussianBasisSet>& bi,
00072 const Ref<GaussianBasisSet>& bj,
00073 const Ref<GaussianBasisSet>& bk,
00074 const Ref<GaussianBasisSet>& bl
00075 );
00076 sc_int_least64_t offset(int i, int j, int k, int l) {
00077 long ij = (i>j?(((i*long(i+1))>>1)+j):(((j*long(j+1))>>1)+i));
00078 return k + nk_*sc_int_least64_t(l + nl_*ij);
00079 }
00080 };
00081
00086 class canonical_abcc {
00087 long nj_, nkl_;
00088 public:
00089 canonical_abcc(const Ref<GaussianBasisSet>& bi,
00090 const Ref<GaussianBasisSet>& bj,
00091 const Ref<GaussianBasisSet>& bk,
00092 const Ref<GaussianBasisSet>& bl
00093 );
00094 sc_int_least64_t offset(int i, int j, int k, int l) {
00095 long kl = (k>l?(((k*long(k+1))>>1)+l):(((l*long(l+1))>>1)+k));
00096 return kl + nkl_*sc_int_least64_t(j + nj_*i);
00097 }
00098 };
00099
00104 class canonical_aabb {
00105 long nij_;
00106 public:
00107 canonical_aabb(const Ref<GaussianBasisSet>& bi,
00108 const Ref<GaussianBasisSet>& bj,
00109 const Ref<GaussianBasisSet>& bk,
00110 const Ref<GaussianBasisSet>& bl
00111 );
00112 sc_int_least64_t offset(int i, int j, int k, int l) {
00113 long ij = (i>j?(((i*long(i+1))>>1)+j):(((j*long(j+1))>>1)+i));
00114 long kl = (k>l?(((k*long(k+1))>>1)+l):(((l*long(l+1))>>1)+k));
00115 return ij + nij_*sc_int_least64_t(kl);
00116 }
00117 };
00118
00122 class canonical_abab {
00123 long nj_;
00124 public:
00125 canonical_abab(const Ref<GaussianBasisSet>& bi,
00126 const Ref<GaussianBasisSet>& bj,
00127 const Ref<GaussianBasisSet>& bk,
00128 const Ref<GaussianBasisSet>& bl
00129 );
00130 sc_int_least64_t offset(int i, int j, int k, int l) {
00131 long ij = i*nj_ + j;
00132 long kl = k*nj_ + l;
00133 sc_int_least64_t
00134 off = (ij>kl?(((ij*sc_int_least64_t(ij+1))>>1)+kl)
00135 :(((kl*sc_int_least64_t(kl+1))>>1)+ij));
00136 return off;
00137 }
00138 };
00139
00143 class canonical_abcd {
00144 int ni_, nj_, nk_;
00145 public:
00146 canonical_abcd(const Ref<GaussianBasisSet>& bi,
00147 const Ref<GaussianBasisSet>& bj,
00148 const Ref<GaussianBasisSet>& bk,
00149 const Ref<GaussianBasisSet>& bl
00150 );
00151 sc_int_least64_t offset(int i, int j, int k, int l) {
00152 return (i + ni_*sc_int_least64_t(j + nj_*long(k + nk_*l)));
00153 }
00154 };
00155
00158 class GPetiteList4: public RefCount {
00159 bool c1_;
00160 int ng_;
00161 protected:
00162 int **shell_map_i_;
00163 int **shell_map_j_;
00164 int **shell_map_k_;
00165 int **shell_map_l_;
00166 Ref<GaussianBasisSet> b1_, b2_, b3_, b4_;
00167 bool c1() const { return c1_; }
00168 int order() const { return ng_; }
00169 public:
00170 GPetiteList4(const Ref<GaussianBasisSet> &b1,
00171 const Ref<GaussianBasisSet> &b2,
00172 const Ref<GaussianBasisSet> &b3,
00173 const Ref<GaussianBasisSet> &b4);
00174 ~GPetiteList4();
00175 const Ref<GaussianBasisSet>& basis1() const { return b1_; }
00176 const Ref<GaussianBasisSet>& basis2() const { return b2_; }
00177 const Ref<GaussianBasisSet>& basis3() const { return b3_; }
00178 const Ref<GaussianBasisSet>& basis4() const { return b4_; }
00179 const Ref<PointGroup>& point_group() const { return b1_->molecule()->point_group(); }
00180 virtual int in(int i, int j, int k, int l) = 0;
00181 };
00182
00189 template <class C4>
00190 class GenericPetiteList4 : public GPetiteList4 {
00191 C4 c_;
00192 public:
00193 GenericPetiteList4(const Ref<GaussianBasisSet> &b1,
00194 const Ref<GaussianBasisSet> &b2,
00195 const Ref<GaussianBasisSet> &b3,
00196 const Ref<GaussianBasisSet> &b4);
00197 ~GenericPetiteList4();
00198 int in(int i, int j, int k, int l);
00199 };
00200
00201 template <class C4>
00202 inline int
00203 GenericPetiteList4<C4>::in(int i, int j, int k, int l)
00204 {
00205 if (c1()) return 1;
00206
00207 sc_int_least64_t ijkl = c_.offset(i,j,k,l);
00208 int nijkl = 1;
00209
00210 const int ng = order();
00211 for (int g=1; g < ng; g++) {
00212 int gi = shell_map_i_[i][g];
00213 int gj = shell_map_j_[j][g];
00214 int gk = shell_map_k_[k][g];
00215 int gl = shell_map_l_[l][g];
00216 sc_int_least64_t gijkl = c_.offset(gi,gj,gk,gl);
00217
00218 if (gijkl > ijkl) return 0;
00219 else if (gijkl == ijkl) nijkl++;
00220 }
00221
00222 return ng/nijkl;
00223 }
00224
00226 class canonical_aa {
00227 public:
00228 canonical_aa(const Ref<GaussianBasisSet>& bi,
00229 const Ref<GaussianBasisSet>& bj
00230 );
00231 sc_int_least64_t offset(int i, int j) {
00232 const long ij = (i>j?(((i*long(i+1))>>1)+j):(((j*long(j+1))>>1)+i));
00233 return ij;
00234 }
00235 };
00236
00239 class canonical_ab {
00240 int ni_;
00241 public:
00242 canonical_ab(const Ref<GaussianBasisSet>& bi,
00243 const Ref<GaussianBasisSet>& bj
00244 );
00245 sc_int_least64_t offset(int i, int j) {
00246 return (i + ni_*sc_int_least64_t(j));
00247 }
00248 };
00249
00252 class GPetiteList2: public RefCount {
00253 bool c1_;
00254 int ng_;
00255 protected:
00256 int **shell_map_i_;
00257 int **shell_map_j_;
00258 Ref<GaussianBasisSet> b1_, b2_;
00259 bool c1() const { return c1_; }
00260 int order() const { return ng_; }
00261 public:
00262 GPetiteList2(const Ref<GaussianBasisSet> &b1,
00263 const Ref<GaussianBasisSet> &b2);
00264 ~GPetiteList2();
00265 const Ref<GaussianBasisSet>& basis1() const { return b1_; }
00266 const Ref<GaussianBasisSet>& basis2() const { return b2_; }
00267 const Ref<PointGroup>& point_group() const { return b1_->molecule()->point_group(); }
00268 virtual int in(int i, int j) = 0;
00269 };
00270
00276 template <class C2>
00277 class GenericPetiteList2 : public GPetiteList2 {
00278 C2 c_;
00279 public:
00280 GenericPetiteList2(const Ref<GaussianBasisSet> &b1,
00281 const Ref<GaussianBasisSet> &b2);
00282 ~GenericPetiteList2();
00283 int in(int i, int j);
00284 void symmetrize(const RefSymmSCMatrix& skel, const RefSymmSCMatrix& sym) const;
00285 void symmetrize(const RefSCMatrix& skel, const RefSCMatrix& sym) const;
00286 };
00287
00288 template <class C2>
00289 inline int
00290 GenericPetiteList2<C2>::in(int i, int j)
00291 {
00292 if (c1()) return 1;
00293
00294 sc_int_least64_t ij = c_.offset(i,j);
00295 int nij = 1;
00296
00297 const int ng = order();
00298 for (int g=1; g < ng; g++) {
00299 int gi = shell_map_i_[i][g];
00300 int gj = shell_map_j_[j][g];
00301 const sc_int_least64_t gij = c_.offset(gi,gj);
00302
00303 if (gij > ij) return 0;
00304 else if (gij == ij) nij++;
00305 }
00306
00307 return ng/nij;
00308 }
00309
00312 struct GPetiteListFactory {
00313 static Ref<GPetiteList2> plist2(const Ref<GaussianBasisSet> &b1,
00314 const Ref<GaussianBasisSet> &b2);
00315 static Ref<GPetiteList4> plist4(const Ref<GaussianBasisSet> &b1,
00316 const Ref<GaussianBasisSet> &b2,
00317 const Ref<GaussianBasisSet> &b3,
00318 const Ref<GaussianBasisSet> &b4);
00319 };
00320
00322 void symmetrize(const Ref<GPetiteList2>& plist2, const Ref<Integral>& integral, const RefSymmSCMatrix& skel, const RefSymmSCMatrix& sym);
00324 void symmetrize(const Ref<GPetiteList2>& plist2, const Ref<Integral>& integral, const RefSCMatrix& skel, const RefSCMatrix& sym);
00325 }
00326
00327 #endif
00328
00329
00330
00331
00332