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_scf_lgbuild_h
00029 #define _chemistry_qc_scf_lgbuild_h
00030
00031 #ifdef __GNUC__
00032 #pragma interface
00033 #endif
00034
00035 #undef SCF_CHECK_BOUNDS
00036 #undef SCF_DONT_USE_BOUNDS
00037
00038 #include <chemistry/qc/scf/gbuild.h>
00039
00040 template<class T>
00041 class LocalGBuild : public GBuild<T> {
00042 public:
00043 double tnint;
00044
00045 protected:
00046 MessageGrp *grp_;
00047 TwoBodyInt *tbi_;
00048 GaussianBasisSet *gbs_;
00049 PetiteList *rpl_;
00050
00051 signed char *pmax;
00052 int threadno_;
00053 int nthread_;
00054 double accuracy_;
00055
00056 public:
00057 LocalGBuild(T& t, const Ref<TwoBodyInt>& tbi, const Ref<PetiteList>& rpl,
00058 const Ref<GaussianBasisSet>& bs, const Ref<MessageGrp>& g,
00059 signed char *pm, double acc, int nt=1, int tn=0) :
00060 GBuild<T>(t),
00061 pmax(pm), nthread_(nt), threadno_(tn), accuracy_(acc)
00062 {
00063 grp_ = g.pointer();
00064 tbi_ = tbi.pointer();
00065 rpl_ = rpl.pointer();
00066 gbs_ = bs.pointer();
00067 }
00068 ~LocalGBuild() {}
00069
00070 void run() {
00071 int tol = (int) (log(accuracy_)/log(2.0));
00072 int me=grp_->me();
00073 int nproc = grp_->n();
00074
00075
00076 GaussianBasisSet& gbs = *gbs_;
00077 PetiteList& pl = *rpl_;
00078 TwoBodyInt& tbi = *tbi_;
00079
00080 tbi.set_redundant(0);
00081 const double *intbuf = tbi.buffer();
00082
00083 tnint=0;
00084 sc_int_least64_t threadind=0;
00085 sc_int_least64_t ijklind=0;
00086
00087 for (int i=0; i < gbs.nshell(); i++) {
00088 if (!pl.in_p1(i))
00089 continue;
00090
00091 int fi=gbs.shell_to_function(i);
00092 int ni=gbs(i).nfunction();
00093
00094 for (int j=0; j <= i; j++) {
00095 int oij = i_offset(i)+j;
00096
00097 if (!pl.in_p2(oij))
00098 continue;
00099
00100 int fj=gbs.shell_to_function(j);
00101 int nj=gbs(j).nfunction();
00102 int pmaxij = pmax[oij];
00103
00104 for (int k=0; k <= i; k++, ijklind++) {
00105 if (ijklind%nproc != me)
00106 continue;
00107
00108 threadind++;
00109 if (threadind % nthread_ != threadno_)
00110 continue;
00111
00112 int fk=gbs.shell_to_function(k);
00113 int nk=gbs(k).nfunction();
00114
00115 int pmaxijk=pmaxij, ptmp;
00116 if ((ptmp=pmax[i_offset(i)+k]-1) > pmaxijk) pmaxijk=ptmp;
00117 if ((ptmp=pmax[ij_offset(j,k)]-1) > pmaxijk) pmaxijk=ptmp;
00118
00119 int okl = i_offset(k);
00120 for (int l=0; l <= (k==i?j:k); l++,okl++) {
00121 int pmaxijkl = pmaxijk;
00122 if ((ptmp=pmax[okl]) > pmaxijkl) pmaxijkl=ptmp;
00123 if ((ptmp=pmax[i_offset(i)+l]-1) > pmaxijkl) pmaxijkl=ptmp;
00124 if ((ptmp=pmax[ij_offset(j,l)]-1) > pmaxijkl) pmaxijkl=ptmp;
00125
00126 int qijkl = pl.in_p4(oij,okl,i,j,k,l);
00127 if (!qijkl)
00128 continue;
00129
00130 #ifdef SCF_CHECK_BOUNDS
00131 double intbound = pow(2.0,double(tbi.log2_shell_bound(i,j,k,l)));
00132 double pbound = pow(2.0,double(pmaxijkl));
00133 intbound *= qijkl;
00134 GBuild<T>::contribution.set_bound(intbound, pbound);
00135 #else
00136 # ifndef SCF_DONT_USE_BOUNDS
00137 if (tbi.log2_shell_bound(i,j,k,l)+pmaxijkl < tol)
00138 continue;
00139 # endif
00140 #endif
00141
00142
00143 tbi.compute_shell(i,j,k,l);
00144
00145
00146 int e12 = (i==j);
00147 int e34 = (k==l);
00148 int e13e24 = (i==k) && (j==l);
00149 int e_any = e12||e34||e13e24;
00150
00151 int fl=gbs.shell_to_function(l);
00152 int nl=gbs(l).nfunction();
00153
00154 int ii,jj,kk,ll;
00155 int I,J,K,L;
00156 int index=0;
00157
00158 for (I=0, ii=fi; I < ni; I++, ii++) {
00159 for (J=0, jj=fj; J <= (e12 ? I : nj-1); J++, jj++) {
00160 for (K=0, kk=fk; K <= (e13e24 ? I : nk-1); K++, kk++) {
00161 int lend = (e34 ? ((e13e24)&&(K==I) ? J : K)
00162 : ((e13e24)&&(K==I)) ? J : nl-1);
00163
00164 for (L=0, ll=fl; L <= lend; L++, ll++, index++) {
00165
00166 if (fabs(intbuf[index]) < 1.0e-15)
00167 continue;
00168
00169 double pki_int = intbuf[index];
00170
00171 if (isnan(pki_int))
00172 abort();
00173
00174 if (qijkl > 1)
00175 pki_int *= qijkl;
00176
00177 if (e_any) {
00178 int ij,kl;
00179 double val;
00180
00181 if (jj == kk) {
00182
00183
00184
00185
00186
00187
00188 if (ii == jj || kk == ll) {
00189 ij = i_offset(ii)+jj;
00190 kl = i_offset(kk)+ll;
00191 val = (ij==kl) ? 0.5*pki_int : pki_int;
00192
00193 GBuild<T>::contribution.cont5(ij,kl,val);
00194
00195 } else {
00196
00197
00198
00199
00200
00201
00202
00203 ij = i_offset(ii)+jj;
00204 kl = i_offset(kk)+ll;
00205 val = (ij==kl) ? 0.5*pki_int : pki_int;
00206
00207 GBuild<T>::contribution.cont4(ij,kl,val);
00208
00209
00210
00211
00212
00213
00214
00215
00216 ij = ij_offset(ii,ll);
00217 kl = ij_offset(kk,jj);
00218 val = (ij==kl) ? 0.5*pki_int : pki_int;
00219
00220 GBuild<T>::contribution.cont3(ij,kl,val);
00221 }
00222 } else if (ii == kk || jj == ll) {
00223
00224
00225
00226
00227
00228
00229
00230 ij = i_offset(ii)+jj;
00231 kl = i_offset(kk)+ll;
00232 val = (ij==kl) ? 0.5*pki_int : pki_int;
00233
00234 GBuild<T>::contribution.cont4(ij,kl,val);
00235
00236
00237
00238
00239
00240
00241
00242
00243 ij = ij_offset(ii,kk);
00244 kl = ij_offset(jj,ll);
00245 val = (ij==kl) ? 0.5*pki_int : pki_int;
00246
00247 GBuild<T>::contribution.cont3(ij,kl,val);
00248
00249 } else {
00250
00251
00252
00253
00254
00255 ij = i_offset(ii)+jj;
00256 kl = i_offset(kk)+ll;
00257 val = (ij==kl) ? 0.5*pki_int : pki_int;
00258
00259 GBuild<T>::contribution.cont1(ij,kl,val);
00260
00261
00262
00263
00264
00265
00266 ij = ij_offset(ii,kk);
00267 kl = ij_offset(jj,ll);
00268 val = (ij==kl) ? 0.5*pki_int : pki_int;
00269
00270 GBuild<T>::contribution.cont2(ij,kl,val);
00271
00272 if ((ii != jj) && (kk != ll)) {
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 ij = ij_offset(ii,ll);
00283 kl = ij_offset(kk,jj);
00284
00285 GBuild<T>::contribution.cont2(ij,kl,val);
00286 }
00287 }
00288 } else {
00289 if (jj == kk) {
00290
00291
00292
00293
00294
00295
00296
00297 GBuild<T>::contribution.cont4(i_offset(ii)+jj,i_offset(kk)+ll,pki_int);
00298
00299
00300
00301
00302
00303
00304
00305
00306 GBuild<T>::contribution.cont3(ij_offset(ii,ll),ij_offset(kk,jj),pki_int);
00307
00308 } else if (ii == kk || jj == ll) {
00309
00310
00311
00312
00313
00314
00315
00316 GBuild<T>::contribution.cont4(i_offset(ii)+jj,i_offset(kk)+ll,pki_int);
00317
00318
00319
00320
00321
00322
00323
00324
00325 GBuild<T>::contribution.cont3(ij_offset(ii,kk),ij_offset(jj,ll),pki_int);
00326
00327 } else {
00328
00329
00330
00331
00332
00333 GBuild<T>::contribution.cont1(i_offset(ii)+jj,i_offset(kk)+ll,pki_int);
00334
00335
00336
00337
00338
00339
00340 GBuild<T>::contribution.cont2(ij_offset(ii,kk),ij_offset(jj,ll),pki_int);
00341
00342
00343
00344
00345
00346
00347 GBuild<T>::contribution.cont2(ij_offset(ii,ll),ij_offset(kk,jj),pki_int);
00348 }
00349 }
00350 }
00351 }
00352 }
00353 }
00354
00355 tnint += (double) ni*nj*nk*nl;
00356 }
00357 }
00358 }
00359 }
00360 }
00361 };
00362
00363 #endif
00364
00365
00366
00367
00368