// // build2e.cc // // Copyright (C) 1996 Limit Point Systems, Inc. // // Author: Curtis Janssen // Maintainer: LPS // // This file is part of the SC Toolkit. // // The SC Toolkit is free software; you can redistribute it and/or modify // it under the terms of the GNU Library General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // The SC Toolkit is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with the SC Toolkit; see the file COPYING.LIB. If not, write to // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // // The U.S. Government is granted a limited license as per AL 91-7. // #include #include #include #include #include #include #include #include #include using namespace std; using namespace sc; #define CHECK_STACK_ALIGNMENT 0 #if CHECK_STACK_ALIGNMENT static void stack_alignment_error(void *ptr, const char *where) { ExEnv::outn() << "UNALIGNED STACK: " << where << ": " << ptr << endl; } static inline void stack_alignment_check(void *ptr, const char *where) { if ((unsigned)ptr & 7) stack_alignment_error(ptr,where); } #else # define stack_alignment_check(ptr,where) #endif /* MG is the maximum angular momentum for which we will use * the generated build routines. It is defined in oint3/build.h */ #define MINA(x) (((x)am1) { iswtch(&am1,&am2); iswtch(&nc1,&nc2); } if (am4>am3) { iswtch(&am3,&am4); iswtch(&nc3,&nc4); } if ((am3 > am1)||((am3 == am1)&&(am4 > am2))) { iswtch(&am1,&am3); iswtch(&nc1,&nc3); iswtch(&am2,&am4); iswtch(&nc2,&nc4); } /* If the center permutation 1<->3 and 2<->4 is performed, then * we may need the am for center 2 to be as big as for center 4. */ if (am4 > am2) am2 = am4; /* As far as this routine knows the biggest nc can end up anywhere. */ if (nc2>nc1) nc1 = nc2; if (nc3>nc1) nc1 = nc3; if (nc4>nc1) nc1 = nc4; nc2 = nc3 = nc4 = nc1; jmax_for_con = (int *) malloc(sizeof(int)*nc1); // storage for jmax_for_con is not counted since it is freed below for (i=0; imax_am_for_contraction(i); if ( (bs2_ != bs1_) &&((tmp=(int_unit2?0:bs2_->max_am_for_contraction(i)))>jmax_for_con[i])) jmax_for_con[i] = tmp; if ( (bs3_ != bs1_) && (bs3_ != bs2_) &&((tmp=bs3_->max_am_for_contraction(i))>jmax_for_con[i])) jmax_for_con[i] = tmp; if ( (bs4_ != bs1_) && (bs4_ != bs2_) && (bs4_ != bs3_) &&((tmp=(int_unit4?0:bs4_->max_am_for_contraction(i)))>jmax_for_con[i])) jmax_for_con[i] = tmp; } /* If derivatives are needed, then am1 can be bigger. */ if (order==1) am1++; /* To compute derivative integral bounds, am3 can be bigger also. */ if (order==1 && int_derivative_bounds) am3++; am12 = am1 + am2; am34 = am3 + am4; am = am12 + am34; /* Allocate the intlist. */ contract_length.set_dim(am12+1,am34+1,am34+1); build.int_v_list.set_dim(am12+1,am34+1,am+1); used_storage_build_ += contract_length.nbyte(); used_storage_build_ += build.int_v_list.nbyte(); #if CHECK_INTEGRAL_ALGORITHM ExEnv::outn() << "contract_length: " << contract_length.nbyte() << endl; ExEnv::outn() << "int_v_list: " << build.int_v_list.nbyte() << endl; #endif /* Set all slots to 0 */ for (i=0; i<=am12; i++) { for (j=0; j<=am34; j++) { for (k=0; k<=am12+am34; k++) { build.int_v_list(i,j,k) = 0; } } } for (i=0; i<=am12; i++) { for (j=0; j<=am34; j++) { for (k=0; k<=am34; k++) { contract_length(i,j,k) = 0; for (l=j; l<=k; l++) { contract_length(i,j,k) += INT_NCART(i)*INT_NCART(l); } } } } /* Compute the size of the buffer for the primitive integrals. */ int_v_bufsize = 0; int_v0_bufsize = 0; for (i=0; i<=am12; i++) { for (j=0; j<=am34; j++) { int_v0_bufsize += INT_NCART(i)*INT_NCART(j); for (k=0; k<=am12+am34-i-j; k++) { int_v_bufsize += INT_NCART(i)*INT_NCART(j); } } } int_v0_buf = (double*) malloc(sizeof(double)*int_v_bufsize); used_storage_build_ += sizeof(double)*int_v_bufsize; if (!int_v0_buf) { ExEnv::errn() << scprintf("couldn't allocate all integral intermediates\n"); fail(); } add_store(int_v0_buf); int_v_buf = &int_v0_buf[int_v0_bufsize]; /* Allocate storage for the needed slots. */ for (i=0; i<=am12; i++) { for (j=0; j<=am34; j++) { build.int_v_list(i,j,0) = int_v0_buf; int_v0_buf += INT_NCART(i)*INT_NCART(j); for (k=1; k<=am12+am34-i-j; k++) { build.int_v_list(i,j,k) = int_v_buf; int_v_buf += INT_NCART(i)*INT_NCART(j); } } } /* Allocate storage for the contracted integrals (these are the output * of the build routines). */ /* The ci, etc, indices refer to which set of contraction * coefficients we are using. */ e0f0_con_int_bufsize = 0; e0f0_con_ints_array = new IntV3Arraydoublep2***[nc1]; used_storage_build_ += sizeof(IntV3Arraydoublep2***)*nc1; for (ci=0; cip = 0; n_store_last = 0; } if (n_store_last >= STORAGE_CHUNK) { store_list_t* tmp = (store_list_t*) malloc(sizeof(store_list_t)); assert(tmp); tmp->p = store; store = tmp; n_store_last = 0; } store->data[n_store_last++] = p; } /* free_store frees the memory that add_store keeps track of */ void Int2eV3::free_store() { _free_store(store,n_store_last); store = 0; } void Int2eV3::_free_store(store_list_t* s, int n) { int i; if (!s) return; for (i=0; idata[i]); } _free_store(s->p,STORAGE_CHUNK); free(s); } void Int2eV3::int_buildgcam(int minam1, int minam2, int minam3, int minam4, int maxam1, int maxam2, int maxam3, int maxam4, int dam1, int dam2, int dam3, int dam4, int sh1, int sh2, int sh3, int sh4, int eAB) { int k,m,n; int ci,cj,ck,cl; int maxam12,maxam34; int nc1,nc2,nc3,nc4; if (maxam1<0 || maxam2<0 || maxam3<0 || maxam4<0) return; if (minam1<0) minam1=0; if (minam2<0) minam2=0; if (minam3<0) minam3=0; if (minam4<0) minam4=0; maxam12 = maxam1 + maxam2; maxam34 = maxam3 + maxam4; nc1 = pbs1_->shell(sh1).ncontraction(); if (pbs2_.null()) nc2 = 1; else nc2 = pbs2_->shell(sh2).ncontraction(); nc3 = pbs3_->shell(sh3).ncontraction(); if (pbs4_.null()) nc4 = 1; else nc4 = pbs4_->shell(sh4).ncontraction(); /* Zero the target contracted integrals that the build routine * will accumulate into. */ for (m=minam1; m<=maxam12; m++) { for (n=minam3; n<=maxam34; n++) { int nm_cart = INT_NCART(m)*INT_NCART(n); for (ci=0; ciam(ci)+dam1) continue; for (cj=0; cjam(ci)+dam1+int_shell2->am(cj)+dam2 < m) continue; for (ck=0; ckam(ck)+dam3) continue; for (cl=0; clam(ck)+dam3 +int_shell4->am(cl)+dam4 < n) continue; double *tmp = e0f0_con_ints_array[ci][cj][ck][cl](m,n); for (int ii=0; ii 4) build_using_gcs(nc1,nc2,nc3,nc4, minam1,minam3,maxam12,maxam34,dam1,dam2,dam3,dam4,eAB); else build_not_using_gcs(nc1,nc2,nc3,nc4, minam1,minam3,maxam12,maxam34,dam1,dam2,dam3,dam4,eAB); } void Int2eV3::build_not_using_gcs(int nc1, int nc2, int nc3, int nc4, int minam1, int minam3, int maxam12, int maxam34, int dam1, int dam2, int dam3, int dam4, int eAB) { int i,j,k,l,m; int ci,cj,ck,cl; double *bufferprim; #if 0 ExEnv::outn() << scprintf("not_gcs: %d%d%d%d\n", int_expweight1, int_expweight2, int_expweight3, int_expweight4 ); #endif /* Sum thru all possible contractions. */ for (ci=0; ciam(ci) + dam1; if (mlower < 0) continue; IntV3Arraydoublep2 ***e0f0_i = e0f0_con_ints_array[ci]; for (cj=0; cjam(cj) + dam2; if (mupper < mlower) continue; if (mlower < minam1) mlower = minam1; if (mupper > maxam12) mupper = maxam12; IntV3Arraydoublep2 **e0f0_ij = e0f0_i[cj]; for (ck=0; ckam(ck) + dam3; if (nlower < 0) continue; IntV3Arraydoublep2 *e0f0_ijk = e0f0_ij[ck]; for (cl=0; clam(cl) + dam4; if (nupper < nlower) continue; if (nlower < minam3) nlower = minam3; if (nupper > maxam34) nupper = maxam34; /* Loop over the primitives. */ for (i=0; inprimitive(); i++) { double coef0; coef0 = int_shell1->coefficient_unnorm(ci,i); if (int_expweight1) coef0 = coef0 * int_shell1->exponent(i); /* This factor of two comes from the derivative integral formula. */ if (int_expweight1) coef0 *= 2.0; if (int_expweight2) coef0 *= 2.0; if (int_expweight3) coef0 *= 2.0; if (int_expweight4) coef0 *= 2.0; if (int_store1) opr1 = int_shell_to_prim[osh1] + i; for (j=0; jnprimitive(); j++) { double coef1; coef1 = int_shell2->coefficient_unnorm(cj,j); if (int_expweight2) coef1 *= coef0 * int_shell2->exponent(j); else coef1 *= coef0; if (int_store1) opr2 = int_shell_to_prim[osh2] + j; for (k=0; knprimitive(); k++) { double coef2; coef2 = int_shell3->coefficient_unnorm(ck,k); if (int_expweight3) coef2 *= coef1 * int_shell3->exponent(k); else coef2 *= coef1; if (int_store1) opr3 = int_shell_to_prim[osh3] + k; for (l=0; lnprimitive(); l++) { double coef3; coef3 = int_shell4->coefficient_unnorm(cl,l); if (int_expweight4) coef3 *= coef2 * int_shell4->exponent(l); else coef3 *= coef2; if (int_store1) opr4 = int_shell_to_prim[osh4] + l; /* Produce the remaining intermediates. */ gen_prim_intermediates_with_norm(i,j,k,l, maxam12+maxam34,coef3); /* Generate the target integrals. */ if ((maxam12 == 0) && (maxam34 == 0)) { /* Do nothing: gen_prim_intermediates has set everything up. */ } else if ((minam1<=MG)&&(minam3<=MG)&&(maxam12<=MG)&&(maxam34<=MG)) { if (build_routine[minam1] [maxam12] [minam3] [maxam34][eAB]==&BuildIntV3::impossible_integral){ ExEnv::errn() << scprintf("trying to build with int2v%d%d%d%d (exact)\n", minam1,maxam12,minam3,maxam34); } if (!(build.*build_routine[minam1] [maxam12] [minam3] [maxam34][eAB])()) { ExEnv::outn() << "build2e.cc: did not succeed in building all integrals" << endl; abort(); } } else { blockbuildprim(minam1,maxam12,minam3,maxam34); } /* Contract the primitive target integrals. */ /* Throw out all unneeded contractions. */ if (i||j||k||l) { for (m=mlower; m<=mupper; m++) { int o; int sizec = contract_length(m,nlower,nupper); double *restrictxx con_ints = e0f0_ijk[cl](m,nlower); bufferprim = build.int_v_list(m,nlower,0); for (o=sizec; o!=0; o--) { *con_ints++ += *bufferprim++; } } } else { // for the first primitive write to con_ints rather // than accumulate into it for (m=mlower; m<=mupper; m++) { int o; int sizec = contract_length(m,nlower,nupper); double *restrictxx con_ints = e0f0_ijk[cl](m,nlower); bufferprim = build.int_v_list(m,nlower,0); for (o=sizec; o!=0; o--) { *con_ints++ = *bufferprim++; } } } } } } } } } } } } void Int2eV3::build_using_gcs(int nc1, int nc2, int nc3, int nc4, int minam1, int minam3, int maxam12, int maxam34, int dam1, int dam2, int dam3, int dam4, int eAB) { int i,j,k,l,m; int ci,cj,ck,cl; int maxam1234=maxam12+maxam34; double coef0,coef1,coef2,coef3; double ishl1expi=1.0, ishl2expj=1.0, ishl3expk=1.0; double *bufferprim; double c0scale; /* Loop over the primitives. */ for (i=0; inprimitive(); i++) { if (int_store1) opr1 = int_shell_to_prim[osh1] + i; if (int_expweight1) ishl1expi=2.0*int_shell1->exponent(i); for (j=0; jnprimitive(); j++) { if (int_store1) opr2 = int_shell_to_prim[osh2] + j; ishl2expj = (int_expweight2) ? 2.0*int_shell2->exponent(j)*ishl1expi : ishl1expi; for (k=0; knprimitive(); k++) { if (int_store1) opr3 = int_shell_to_prim[osh3] + k; ishl3expk = (int_expweight3) ? 2.0*int_shell3->exponent(k)*ishl2expj : ishl2expj; for (l=0; lnprimitive(); l++) { if (int_store1) opr4 = int_shell_to_prim[osh4] + l; c0scale = (int_expweight4) ? 2.0*int_shell4->exponent(l)*ishl3expk : ishl3expk; /* Produce the remaining intermediates. */ gen_prim_intermediates(i,j,k,l, maxam1234); /* Generate the target integrals. */ if (!maxam1234) { /* Do nothing: gen_prim_intermediates has set everything up. */ } else if ((minam1<=MG)&&(minam3<=MG)&&(maxam12<=MG)&&(maxam34<=MG)) { intfunc brptr=build_routine[minam1][maxam12][minam3][maxam34][eAB]; if (brptr == &BuildIntV3::impossible_integral) { ExEnv::errn() << scprintf("trying to build with int2v%d%d%d%d (exact)\n", minam1,maxam12,minam3,maxam34); } if (!(build.*brptr)()) { ExEnv::outn() << "build2e.cc: did not succeed in building all integrals" << endl; abort(); } } else { blockbuildprim(minam1,maxam12,minam3,maxam34); } /* Sum thru all possible contractions. * Throw out all unneeded contractions. */ for (ci=0; ciam(ci) + dam1; if (mlower < 0) continue; coef0 = int_shell1->coefficient_unnorm(ci,i)*c0scale; IntV3Arraydoublep2 ***e0f0_i = e0f0_con_ints_array[ci]; for (cj=0; cjam(cj) + dam2; if (mupper < mlower) continue; if (mlower < minam1) mlower = minam1; if (mupper > maxam12) mupper = maxam12; coef1 = int_shell2->coefficient_unnorm(cj,j)*coef0; IntV3Arraydoublep2 **e0f0_ij = e0f0_i[cj]; for (ck=0; ckam(ck) + dam3; if (nlower < 0) continue; coef2 = int_shell3->coefficient_unnorm(ck,k)*coef1; IntV3Arraydoublep2 *e0f0_ijk = e0f0_ij[ck]; for (cl=0; clam(cl) + dam4; if (nupper < nlower) continue; if (nlower < minam3) nlower = minam3; if (nupper > maxam34) nupper = maxam34; coef3 = int_shell4->coefficient_unnorm(cl,l)*coef2; /* Contract the primitive target integrals. */ if (i||j||k||l) { for (m=mlower; m<=mupper; m++) { int o; int sizec = contract_length(m,nlower,nupper); double *restrictxx con_ints = e0f0_ijk[cl](m,nlower); bufferprim = build.int_v_list(m,nlower,0); /* Sum the integrals into the contracted integrals. */ #ifdef SUNMOS for (o=0; o < sizec; o++) { con_ints[o] += coef3 * bufferprim[o]; } #else for (o=sizec; o; o--) { *con_ints++ += coef3 * *bufferprim++; } #endif } } else { for (m=mlower; m<=mupper; m++) { int o; int sizec = contract_length(m,nlower,nupper); double *restrictxx con_ints = e0f0_ijk[cl](m,nlower); bufferprim = build.int_v_list(m,nlower,0); /* Write the integrals to the contracted integrals. */ #ifdef SUNMOS for (o=0; o < sizec; o++) { con_ints[o] = coef3 * bufferprim[o]; } #else for (o=sizec; o; o--) { *con_ints++ = coef3 * *bufferprim++; } #endif } } } } } } } } } } } /* This routine constructs intermediates needed for each quartet of * primitives. It is given the total angular momentum as the argument * and requires that the global primitive offsets and other global * constants be initialized. */ void Int2eV3::gen_prim_intermediates(int pr1, int pr2, int pr3, int pr4, int am) { int i; double T; double pmq,pmq2; double AmB,AmB2; /* This is 2^(1/2) * pi^(5/4) */ const double sqrt2pi54 = 5.9149671727956129; double conv_to_s; if (int_store2) { double *tmp; build.int_v_zeta12 = int_prim_zeta(opr1,opr2); build.int_v_zeta34 = int_prim_zeta(opr3,opr4); build.int_v_oo2zeta12 = int_prim_oo2zeta(opr1,opr2); build.int_v_oo2zeta34 = int_prim_oo2zeta(opr3,opr4); tmp = int_prim_p(opr1,opr2); build.int_v_p120 = *tmp++; build.int_v_p121 = *tmp++; build.int_v_p122 = *tmp; tmp = int_prim_p(opr3,opr4); build.int_v_p340 = *tmp++; build.int_v_p341 = *tmp++; build.int_v_p342 = *tmp; build.int_v_k12 = int_prim_k(opr1,opr2); build.int_v_k34 = int_prim_k(opr3,opr4); } else { build.int_v_zeta12 = int_shell1->exponent(pr1) + int_shell2->exponent(pr2); build.int_v_zeta34 = int_shell3->exponent(pr3) + int_shell4->exponent(pr4); build.int_v_oo2zeta12 = 1.0/build.int_v_zeta12; build.int_v_oo2zeta34 = 1.0/build.int_v_zeta34; build.int_v_p120 = build.int_v_oo2zeta12 * ( int_shell1->exponent(pr1) * build.int_v_r10 + int_shell2->exponent(pr2) * build.int_v_r20 ); build.int_v_p121 = build.int_v_oo2zeta12 * ( int_shell1->exponent(pr1) * build.int_v_r11 + int_shell2->exponent(pr2) * build.int_v_r21 ); build.int_v_p122 = build.int_v_oo2zeta12 * ( int_shell1->exponent(pr1) * build.int_v_r12 + int_shell2->exponent(pr2) * build.int_v_r22 ); build.int_v_p340 = build.int_v_oo2zeta34 * ( int_shell3->exponent(pr3) * build.int_v_r30 + int_shell4->exponent(pr4) * build.int_v_r40 ); build.int_v_p341 = build.int_v_oo2zeta34 * ( int_shell3->exponent(pr3) * build.int_v_r31 + int_shell4->exponent(pr4) * build.int_v_r41 ); build.int_v_p342 = build.int_v_oo2zeta34 * ( int_shell3->exponent(pr3) * build.int_v_r32 + int_shell4->exponent(pr4) * build.int_v_r42 ); /* Compute AmB^2 for shell 1 and 2. */ AmB = build.int_v_r20 - build.int_v_r10; AmB2 = AmB*AmB; AmB = build.int_v_r21 - build.int_v_r11; AmB2 += AmB*AmB; AmB = build.int_v_r22 - build.int_v_r12; AmB2 += AmB*AmB; build.int_v_k12 = sqrt2pi54 * build.int_v_oo2zeta12 * exp( - int_shell1->exponent(pr1)*int_shell2->exponent(pr2) * build.int_v_oo2zeta12 * AmB2 ); /* Compute AmB^2 for shells 3 and 4. */ AmB = build.int_v_r40 - build.int_v_r30; AmB2 = AmB*AmB; AmB = build.int_v_r41 - build.int_v_r31; AmB2 += AmB*AmB; AmB = build.int_v_r42 - build.int_v_r32; AmB2 += AmB*AmB; build.int_v_k34 = sqrt2pi54 * build.int_v_oo2zeta34 * exp( - int_shell3->exponent(pr3)*int_shell4->exponent(pr4) * build.int_v_oo2zeta34 * AmB2 ); build.int_v_oo2zeta12 *= 0.5; build.int_v_oo2zeta34 *= 0.5; } build.int_v_ooze = 1.0/(build.int_v_zeta12 + build.int_v_zeta34); build.int_v_W0 = build.int_v_ooze*( build.int_v_zeta12 * build.int_v_p120 + build.int_v_zeta34 * build.int_v_p340 ); build.int_v_W1 = build.int_v_ooze*( build.int_v_zeta12 * build.int_v_p121 + build.int_v_zeta34 * build.int_v_p341 ); build.int_v_W2 = build.int_v_ooze*( build.int_v_zeta12 * build.int_v_p122 + build.int_v_zeta34 * build.int_v_p342 ); pmq = build.int_v_p120 - build.int_v_p340; pmq2 = pmq*pmq; pmq = build.int_v_p121 - build.int_v_p341; pmq2 += pmq*pmq; pmq = build.int_v_p122 - build.int_v_p342; pmq2 += pmq*pmq; T = build.int_v_zeta12 * build.int_v_zeta34 * build.int_v_ooze * pmq2; double *fjttable = fjt_->values(am,T); /* Convert the fjttable produced by int_fjt into the S integrals */ conv_to_s = sqrt(build.int_v_ooze) * build.int_v_k12 * build.int_v_k34; for (i=0; i<=am; i++) { build.int_v_list(0,0,i)[0] = fjttable[i] * conv_to_s; } } /* This is like gen_prim_intermediates, except the normalization is * put into the ssss integrals. */ void Int2eV3::gen_prim_intermediates_with_norm(int pr1, int pr2, int pr3, int pr4, int am, double norm) { int i; double T; double pmq,pmq2; double AmB,AmB2; /* This is 2^(1/2) * pi^(5/4) */ const double sqrt2pi54 = 5.9149671727956129; double conv_to_s; if (int_store2) { build.int_v_zeta12 = int_prim_zeta(opr1,opr2); build.int_v_zeta34 = int_prim_zeta(opr3,opr4); build.int_v_oo2zeta12 = int_prim_oo2zeta(opr1,opr2); build.int_v_oo2zeta34 = int_prim_oo2zeta(opr3,opr4); build.int_v_p120 = int_prim_p(opr1,opr2,0); build.int_v_p121 = int_prim_p(opr1,opr2,1); build.int_v_p122 = int_prim_p(opr1,opr2,2); build.int_v_p340 = int_prim_p(opr3,opr4,0); build.int_v_p341 = int_prim_p(opr3,opr4,1); build.int_v_p342 = int_prim_p(opr3,opr4,2); build.int_v_k12 = int_prim_k(opr1,opr2); build.int_v_k34 = int_prim_k(opr3,opr4); } else { build.int_v_zeta12 = int_shell1->exponent(pr1) + int_shell2->exponent(pr2); build.int_v_zeta34 = int_shell3->exponent(pr3) + int_shell4->exponent(pr4); build.int_v_oo2zeta12 = 1.0/build.int_v_zeta12; build.int_v_oo2zeta34 = 1.0/build.int_v_zeta34; build.int_v_p120 = build.int_v_oo2zeta12 * ( int_shell1->exponent(pr1) * build.int_v_r10 + int_shell2->exponent(pr2) * build.int_v_r20 ); build.int_v_p121 = build.int_v_oo2zeta12 * ( int_shell1->exponent(pr1) * build.int_v_r11 + int_shell2->exponent(pr2) * build.int_v_r21 ); build.int_v_p122 = build.int_v_oo2zeta12 * ( int_shell1->exponent(pr1) * build.int_v_r12 + int_shell2->exponent(pr2) * build.int_v_r22 ); build.int_v_p340 = build.int_v_oo2zeta34 * ( int_shell3->exponent(pr3) * build.int_v_r30 + int_shell4->exponent(pr4) * build.int_v_r40 ); build.int_v_p341 = build.int_v_oo2zeta34 * ( int_shell3->exponent(pr3) * build.int_v_r31 + int_shell4->exponent(pr4) * build.int_v_r41 ); build.int_v_p342 = build.int_v_oo2zeta34 * ( int_shell3->exponent(pr3) * build.int_v_r32 + int_shell4->exponent(pr4) * build.int_v_r42 ); /* Compute AmB^2 for shell 1 and 2. */ AmB = build.int_v_r20 - build.int_v_r10; AmB2 = AmB*AmB; AmB = build.int_v_r21 - build.int_v_r11; AmB2 += AmB*AmB; AmB = build.int_v_r22 - build.int_v_r12; AmB2 += AmB*AmB; build.int_v_k12 = sqrt2pi54 * build.int_v_oo2zeta12 * exp( - int_shell1->exponent(pr1)*int_shell2->exponent(pr2) * build.int_v_oo2zeta12 * AmB2 ); /* Compute AmB^2 for shells 3 and 4. */ AmB = build.int_v_r40 - build.int_v_r30; AmB2 = AmB*AmB; AmB = build.int_v_r41 - build.int_v_r31; AmB2 += AmB*AmB; AmB = build.int_v_r42 - build.int_v_r32; AmB2 += AmB*AmB; build.int_v_k34 = sqrt2pi54 * build.int_v_oo2zeta34 * exp( - int_shell3->exponent(pr3)*int_shell4->exponent(pr4) * build.int_v_oo2zeta34 * AmB2 ); build.int_v_oo2zeta12 *= 0.5; build.int_v_oo2zeta34 *= 0.5; } build.int_v_ooze = 1.0/(build.int_v_zeta12 + build.int_v_zeta34); build.int_v_W0 = build.int_v_ooze*( build.int_v_zeta12 * build.int_v_p120 + build.int_v_zeta34 * build.int_v_p340 ); build.int_v_W1 = build.int_v_ooze*( build.int_v_zeta12 * build.int_v_p121 + build.int_v_zeta34 * build.int_v_p341 ); build.int_v_W2 = build.int_v_ooze*( build.int_v_zeta12 * build.int_v_p122 + build.int_v_zeta34 * build.int_v_p342 ); pmq = build.int_v_p120 - build.int_v_p340; pmq2 = pmq*pmq; pmq = build.int_v_p121 - build.int_v_p341; pmq2 += pmq*pmq; pmq = build.int_v_p122 - build.int_v_p342; pmq2 += pmq*pmq; T = build.int_v_zeta12 * build.int_v_zeta34 * build.int_v_ooze * pmq2; double *fjttable = fjt_->values(am,T); /* Convert the fjttable produced by int_fjt into the S integrals */ conv_to_s = sqrt(build.int_v_ooze) * build.int_v_k12 * build.int_v_k34 * norm; for (i=0; i<=am; i++) { build.int_v_list(0,0,i)[0] = fjttable[i] * conv_to_s; } } /* This routine computes the shell intermediates. */ void Int2eV3::gen_shell_intermediates(int sh1, int sh2, int sh3, int sh4) { if (int_store1) { build.int_v_r10 = int_shell_r(osh1,0); build.int_v_r11 = int_shell_r(osh1,1); build.int_v_r12 = int_shell_r(osh1,2); build.int_v_r20 = int_shell_r(osh2,0); build.int_v_r21 = int_shell_r(osh2,1); build.int_v_r22 = int_shell_r(osh2,2); build.int_v_r30 = int_shell_r(osh3,0); build.int_v_r31 = int_shell_r(osh3,1); build.int_v_r32 = int_shell_r(osh3,2); build.int_v_r40 = int_shell_r(osh4,0); build.int_v_r41 = int_shell_r(osh4,1); build.int_v_r42 = int_shell_r(osh4,2); } else { build.int_v_r10 = pbs1_->r(pbs1_->shell_to_center(sh1),0); build.int_v_r11 = pbs1_->r(pbs1_->shell_to_center(sh1),1); build.int_v_r12 = pbs1_->r(pbs1_->shell_to_center(sh1),2); if (pbs2_.null()) { build.int_v_r20 = 0.0; build.int_v_r21 = 0.0; build.int_v_r22 = 0.0; } else { build.int_v_r20 = pbs2_->r(pbs2_->shell_to_center(sh2),0); build.int_v_r21 = pbs2_->r(pbs2_->shell_to_center(sh2),1); build.int_v_r22 = pbs2_->r(pbs2_->shell_to_center(sh2),2); } build.int_v_r30 = pbs3_->r(pbs3_->shell_to_center(sh3),0); build.int_v_r31 = pbs3_->r(pbs3_->shell_to_center(sh3),1); build.int_v_r32 = pbs3_->r(pbs3_->shell_to_center(sh3),2); if (pbs4_.null()) { build.int_v_r40 = 0.0; build.int_v_r41 = 0.0; build.int_v_r42 = 0.0; } else { build.int_v_r40 = pbs4_->r(pbs4_->shell_to_center(sh4),0); build.int_v_r41 = pbs4_->r(pbs4_->shell_to_center(sh4),1); build.int_v_r42 = pbs4_->r(pbs4_->shell_to_center(sh4),2); } } } void Int2eV3::blockbuildprim(int minam1,int maxam12,int minam3,int maxam34) { int m, b; int l=maxam12+maxam34; // the (0,0,m) integrals have already been initialized // compute (0,b,m) integrals for (m=l-1; m>=0; m--) { int bmax = l-m; if (bmax>maxam34) bmax=maxam34; blockbuildprim_3(1,bmax,m); } // compute (a,b,m) integrals for (m=maxam12-1; m>=0; m--) { for (b=0; b<=maxam34; b++) { // This is how the code was for a long while, // but at some point it started giving the wrong // answers and seems wrong from inspection. Valgrind // flags that uninitialized I10i integrals are being // used, which results from amin > 1. I have switched // to the correctly behaving amin = 1. // int amin = minam1-m; // if (amin<1) amin=1; // int amax = maxam12-m; // blockbuildprim_1(amin,amax,b,m); int amax = maxam12-m; blockbuildprim_1(1,amax,b,m); } } } void Int2eV3::blockbuildprim_1(int amin,int amax,int am34,int m) { double *I00; double *I10; /* = [a0|c0](m) */ double *I11; /* = [a0|c0](m+1) */ double *I20; /* = [a-1 0|c0](m) */ double *I21; /* = [a-1 0|c0](m+1) */ double *I31; /* = [a0|c-1 0](m+1) */ int cartindex12; int cartindex34; int cartindex1234; int size34=0,size34m1; int i12, j12, k12; int i34, j34, k34; double ***vlist1; double **vlist10; double **vlist11; double ***vlist2; double **vlist20; vlist1 = build.int_v_list(amin-1); vlist10 = vlist1[am34]; if (am34) { vlist11 = vlist1[am34-1]; } if (amin>1) { vlist2 = build.int_v_list(amin-2); vlist20 = vlist2[am34]; } /* The size of the am34 group of primitives. */ size34 = INT_NCART_NN(am34); /* The size of the group of primitives with ang. mom. = am34 - 1 */ size34m1 = INT_NCART_DEC(am34,size34); // Some local intermediates double half_ooze = 0.5 * build.int_v_ooze; double zeta34_ooze = build.int_v_zeta34 * build.int_v_ooze; double W0_m_p120 = build.int_v_W0 - build.int_v_p120; double p120_m_r10 = build.int_v_p120 - build.int_v_r10; double oo2zeta12 = build.int_v_oo2zeta12; double p121_m_r11 = build.int_v_p121 - build.int_v_r11; double W1_m_p121 = build.int_v_W1 - build.int_v_p121; double p122_m_r12 = build.int_v_p122 - build.int_v_r12; double W2_m_p122 = build.int_v_W2 - build.int_v_p122; stack_alignment_check(&half_ooze, "buildprim_1: half_ooze"); for (int am12=amin; am12<=amax; am12++) { /* Construct the needed intermediate integrals. */ double ***vlist0 = build.int_v_list(am12); double **vlist00 = vlist0[am34]; I00 = vlist00[m]; I10 = vlist10[m]; I11 = vlist10[m+1]; //I00 = build.int_v_list(am12,am34,m); //I10 = build.int_v_list(am12-1,am34,m); //I11 = build.int_v_list(am12-1,am34,m+1); if (am34) { I31 = vlist11[m+1]; //I31 = build.int_v_list(am12 - 1, am34 - 1, m + 1); vlist11 = vlist0[am34-1]; } if (am12>1) { I20 = vlist20[m]; I21 = vlist20[m+1]; //I20 = build.int_v_list(am12 - 2, am34, m); //I21 = build.int_v_list(am12 - 2, am34, m + 1); } vlist20 = vlist10; vlist10 = vlist00; /* Construct the new integrals. */ cartindex12 = 0; cartindex1234 = 0; // the i12==0, k12==0, j12=am12 case (build on y) i12 = 0; j12 = am12; k12 = 0; int i12y1 = 0; //= INT_CARTINDEX(am12-1,i12,j12-1); int i12y1s34 = i12y1*size34; int i12y1s34m1 = i12y1*size34m1; double *I10i = &I10[i12y1s34]; double *I11i = &I11[i12y1s34]; double *restrictxx I00i = &I00[cartindex1234]; if (j12==1) { for (cartindex34=0; cartindex34 1 int i12y2s34 = 0; // = INT_CARTINDEX(am12-2,i12,j12-2)*size34; double *I20i = &I20[i12y2s34]; double *I21i = &I21[i12y2s34]; for (cartindex34=0; cartindex34 0 int i34y1 = cartindex34-i34;//=INT_CARTINDEX(am34-1,i34,j34-1) j34 = am34 - i34; double j34_half_ooze = j34 * half_ooze; for (k34=0; k341 case (build on z) double k12m1_oo2zeta12 = oo2zeta12; for (k12=2; k12<=am12-i12; k12++) { j12 = am12 - k12; i12z1 = cartindex12-i12-1;//=INT_CARTINDEX(am12-1,i12,j12); i12z1s34 = i12z1*size34; i12z1s34m1 = i12z1*size34m1; int i12z2s34 = (cartindex12-i12-i12-2)*size34; //=INT_CARTINDEX(am12-2,i12,j12)*size34; I10i = &I10[i12z1s34]; I11i = &I11[i12z1s34]; double *I20i = &I20[i12z2s34]; double *I21i = &I21[i12z2s34]; I00i = &I00[cartindex1234]; for (cartindex34=0; cartindex341 case (build on x) if (am12<2) continue; double i12m1_oo2zeta12 = oo2zeta12; i12x1 = cartindex12-am12-1; i12x1s34 = i12x1*size34; i12x1s34m1 = i12x1*size34m1; int i12x2s34 = (cartindex12-am12-am12-1)*size34; I10i = &I10[i12x1s34]; I11i = &I11[i12x1s34]; double *I20i = &I20[i12x2s34]; double *I21i = &I21[i12x2s34]; I00i = &I00[cartindex1234]; for (i12=2; i12<=am12; i12++) { int sizek12_size34 = (am12-i12+1)*size34; int k12_c34; for (k12_c34=0; k12_c341) { vlist02 = vlist0[bmin-2]; } for (int am34=bmin; am34<=bmax; am34++) { /* Construct the needed intermediate integrals. */ double **vlist00 = vlist0[am34]; I00 = vlist00[m]; I10 = vlist01[m]; I11 = vlist01[m+1]; //I00 = build.int_v_list(0, am34, m); //I10 = build.int_v_list(0, am34 - 1, m); //I11 = build.int_v_list(0, am34 - 1, m + 1); if (am34>1) { I20 = vlist02[m]; I21 = vlist02[m+1]; //I20 = build.int_v_list(0, am34 - 2, m); //I21 = build.int_v_list(0, am34 - 2, m + 1); } vlist02 = vlist01; vlist01 = vlist00; /* The size of the group of primitives with ang. mom. = am34 - 1 */ size34 = INT_NCART_NN(am34); size34m1 = INT_NCART_DEC(am34,size34); size34m2 = INT_NCART(am34-2); // Useful constants double p340_m_r30 = build.int_v_p340 - build.int_v_r30; double W0_m_p340 = build.int_v_W0 - build.int_v_p340; double p341_m_r31 = build.int_v_p341 - build.int_v_r31; double W1_m_p341 = build.int_v_W1 - build.int_v_p341; double p342_m_r32 = build.int_v_p342 - build.int_v_r32; double W2_m_p342 = build.int_v_W2 - build.int_v_p342; double oo2zeta34 = build.int_v_oo2zeta34; double zeta12_ooze = build.int_v_zeta12 * build.int_v_ooze; stack_alignment_check(&p340_m_r30, "buildprim_3: p340_m_r30"); /* Construct the new integrals. */ double *restrictxx I00o = I00; // points the current target integral I10o = I10; I11o = I11; //int cartindex34 = 0; // i34 == 0, k34 == 0, j34 = am34 /* ------------------ Build from the y position. */ /* I10 I11 and I21 */ *I00o = *I10o * p341_m_r31 + *I11o * W1_m_p341; if (am34>1) { I20o = I20; I21o = I21; *I00o += (am34 - 1) * oo2zeta34 * (*I20o - *I21o * zeta12_ooze); } //cartindex34++; // i34 == 0, k34 >= 1 // loop over a portion of the l=am34-1 integrals I00o = &I00o[1]; for (ci34m1=0; ci34m1 1 I00o = &I00o[1]; // loop over a portion of the l=am34-2 integrals double k34m1_oo2zeta34 = oo2zeta34; for (ci34m2=0; ci34m2= 1 I00o = &I00o[am34-1]; //note: ci34m1 = INT_CARTINDEX(am34-1,i34-1,j34) for (ci34m1=0; ci34m1 1 I00o = &I00o[am34]; //note: ci34m2=INT_CARTINDEX(am34-2,i34-2,j34) ci34m2=0; double i34m1_oo2zeta34 = oo2zeta34; for (i34=2; i34<=am34; i34++) { for (k34=0; k34<=am34-i34; k34++) { /* I20 and I21 contrib */ /* ------------------ Build from the x position. */ I00o[ci34m2] += i34m1_oo2zeta34 * (I20o[ci34m2] - I21o[ci34m2] * zeta12_ooze); ci34m2++; } i34m1_oo2zeta34 += oo2zeta34; } //cartindex34 += size34m2; I00o = &I00o[size34m2]; } } ///////////////////////////////////////////////////////////////////////////// // Local Variables: // mode: c++ // c-file-style: "CLJ-CONDENSED" // End: