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