// // tformv3.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. // #if defined(__GNUC__) #pragma implementation #endif #include #include #include #include #include #include #include #include using namespace sc; //////////////////////////////////////////////////////////////////////////// #define PRINT 0 void Int2eV3::transform_init() { source = 0; nsourcemax = 0; } void Int2eV3::transform_done() { delete[] source; } void Int1eV3::transform_init() { source = 0; nsourcemax = 0; } void Int1eV3::transform_done() { delete[] source; } static void do_copy1(double *source, double *target, int chunk, int n1, int s1, int offset1, int n2, int s2, int offset2) { int i1, i2; for (i1=0; i1has_pure(); int pure2 = sh2->has_pure(); int ncart1 = sh1->ncartesian(); int ncart2 = sh2->ncartesian(); int nfunc1 = sh1->nfunction(); int nfunc2 = sh2->nfunction(); int nfunci, nfuncj; if (!pure1 && !pure2) return; /* Loop through the generalized general contractions, * transforming the first index. */ if (pure1) { copy_to_source(integrals, ncart1*ncart2*chunk); memset(integrals, 0, sizeof(double)*sh1->nfunction()*ncart2*chunk); ogc1 = 0; ogc1pure = 0; for (i=0; incontraction(); i++) { am1 = sh1->am(i); nfunci = sh1->nfunction(i); ogc2 = 0; for (j=0; jncontraction(); j++) { am2 = sh2->am(j); nfuncj = sh2->nfunction(j); if (sh1->is_pure(i)) { SphericalTransformIter trans(integ->spherical_transform(sh1->am(i))); do_sparse_transform11(source, integrals, chunk, trans, ogc1, ogc1pure, INT_NCART(am2), ncart2, ogc2); } else { do_copy1(source, integrals, chunk, nfunci, nfunc1, ogc1pure, INT_NCART(am2), ncart2, ogc2); } ogc2 += INT_NCART(am2); } ogc1 += INT_NCART(am1); ogc1pure += INT_NPURE(am1); } } if (pure2) { copy_to_source(integrals, nfunc1*ncart2*chunk); memset(integrals, 0, sizeof(double)*sh1->nfunction()*sh2->nfunction()*chunk); ogc1 = 0; for (i=0; incontraction(); i++) { am1 = sh1->am(i); nfunci = sh1->nfunction(i); ogc2 = 0; ogc2pure = 0; for (j=0; jncontraction(); j++) { am2 = sh2->am(j); nfuncj = sh2->nfunction(j); if (sh2->is_pure(j)) { SphericalTransformIter trans(integ->spherical_transform(sh2->am(j))); do_sparse_transform12(source, integrals, chunk, trans, INT_NPURE(am1), ogc1, ncart2, ogc2, sh2->nfunction(), ogc2pure); } else { do_copy1(source, integrals, chunk, nfunci, nfunc1, ogc1, nfuncj, nfunc2, ogc2pure); } ogc2 += INT_NCART(am2); ogc2pure += INT_NPURE(am2); } ogc1 += INT_NPURE(am1); } } } /* it is ok for integrals and target to overlap */ void Int1eV3::transform_1e(Integral *integ, double *integrals, double *target, GaussianShell *sh1, GaussianShell *sh2, int chunk) { int ntarget; do_transform_1e(integ, integrals, sh1, sh2, chunk); /* copy the integrals to the target, if necessary */ ntarget = sh1->nfunction() * sh2->nfunction(); if (integrals != target) { memmove(target, integrals, ntarget*sizeof(double)*chunk); } } /* it is not ok for integrals and target to overlap */ void Int1eV3::accum_transform_1e(Integral *integ, double *integrals, double *target, GaussianShell *sh1, GaussianShell *sh2, int chunk) { int i, ntarget; do_transform_1e(integ, integrals, sh1, sh2, chunk); /* accum the integrals to the target */ ntarget = sh1->nfunction() * sh2->nfunction() * chunk; for (i=0; incartesian(); ncart[1] = sh2->ncartesian(); ncart[2] = sh3->ncartesian(); ncart[3] = sh4->ncartesian(); nfunc[0] = sh1->nfunction(); nfunc[1] = sh2->nfunction(); nfunc[2] = sh3->nfunction(); nfunc[3] = sh4->nfunction(); ntarget1 = ncart[0]; ntarget2 = ncart[1]; ntarget3 = ncart[2]; ntarget4 = ncart[3]; nsource1 = ncart[0]; nsource2 = ncart[1]; nsource3 = ncart[2]; nsource4 = ncart[3]; if (index >= 0) { ntarget1 = nfunc[0]; if (index >= 1) { ntarget2 = nfunc[1]; nsource1 = nfunc[0]; ni = &nfunci; ogc1 = &ogcfunc[0]; if (index >= 2) { ntarget3 = nfunc[2]; nsource2 = nfunc[1]; nj = &nfuncj; ogc2 = &ogcfunc[1]; if (index >= 3) { ntarget4 = nfunc[3]; nsource3 = nfunc[2]; nk = &nfunck; ogc3 = &ogcfunc[2]; } } } } switch (index) { case 0: shell = sh1; tgencon = &i; break; case 1: shell = sh2; tgencon = &j; break; case 2: shell = sh3; tgencon = &k; break; case 3: shell = sh4; tgencon = &l; break; default: shell = 0; tgencon = 0; break; } #if PRINT { double *tmp = integrals; ExEnv::outn() << scprintf("Before transform of index %d (%dx%dx%dx%d)\n", index, nsource1, nsource2, nsource3, nsource4); for (i=0; i1.e-15) { ExEnv::outn() << scprintf("(%d %d|%d %d) = %15.11lf\n",i,j,k,l,*tmp); } tmp++; } } } } } #endif copy_to_source(integrals, nsource1*nsource2*nsource3*nsource4); memset(target, 0, sizeof(double)*ntarget1*ntarget2*ntarget3*ntarget4); ogccart[0] = 0; ogcfunc[0] = 0; for (i=0; incontraction(); i++) { am1 = sh1->am(i); nfunci = sh1->nfunction(i); ncarti = INT_NCART(am1); ogccart[1] = 0; ogcfunc[1] = 0; for (j=0; jncontraction(); j++) { am2 = sh2->am(j); nfuncj = sh2->nfunction(j); ncartj = INT_NCART(am2); ogccart[2] = 0; ogcfunc[2] = 0; for (k=0; kncontraction(); k++) { am3 = sh3->am(k); nfunck = sh3->nfunction(k); ncartk = INT_NCART(am3); ogccart[3] = 0; ogcfunc[3] = 0; for (l=0; lncontraction(); l++) { am4 = sh4->am(l); nfuncl = sh4->nfunction(l); ncartl = INT_NCART(am4); if (shell->is_pure(*tgencon)) { SphericalTransformIter trans(integ->spherical_transform(shell->am(*tgencon))); do_sparse_transform2(source, target, index, trans, ncart[index], nfunc[index], ogccart[index], ogcfunc[index], *ni, nsource1, *ogc1, *nj, nsource2, *ogc2, *nk, nsource3, *ogc3, *nl, nsource4, *ogc4); } else { do_copy2(source, integrals, *ni, nsource1, *ogc1, *nj, nsource2, *ogc2, *nk, nsource3, *ogc3, *nl, nsource4, *ogc4); } ogccart[3] += ncartl; ogcfunc[3] += nfuncl; } ogccart[2] += ncartk; ogcfunc[2] += nfunck; } ogccart[1] += ncartj; ogcfunc[1] += nfuncj; } ogccart[0] += ncarti; ogcfunc[0] += nfunci; } #if PRINT { double *tmp = integrals; ExEnv::outn() << scprintf("After transform of index %d (%dx%dx%dx%d)\n", index, ntarget1, ntarget2, ntarget3, ntarget4); for (i=0; i1.e-15) { ExEnv::outn() << scprintf("(%d %d|%d %d) = %15.11lf\n", i,j,k,l,*tmp); } tmp++; } } } } } #endif } void Int2eV3::transform_2e_slow(Integral *integ, double *integrals, double *target, GaussianShell *sh1, GaussianShell *sh2, GaussianShell *sh3, GaussianShell *sh4) { int pure1 = sh1->has_pure(); int pure2 = sh2->has_pure(); int pure3 = sh3->has_pure(); int pure4 = sh4->has_pure(); if (pure1) { do_gencon_sparse_transform_2e(integ, integrals, target, 0, sh1, sh2, sh3, sh4); integrals = target; } if (pure2) { do_gencon_sparse_transform_2e(integ, integrals, target, 1, sh1, sh2, sh3, sh4); integrals = target; } if (pure3) { do_gencon_sparse_transform_2e(integ, integrals, target, 2, sh1, sh2, sh3, sh4); integrals = target; } if (pure4) { do_gencon_sparse_transform_2e(integ, integrals, target, 3, sh1, sh2, sh3, sh4); integrals = target; } if (integrals != target) { int nint = sh1->nfunction() * sh2->nfunction() * sh3->nfunction() * sh4->nfunction(); memmove(target, integrals, sizeof(double)*nint); } } ///////////////////////////////////////////////////////////////////////////// static void do_sparse_transform2_1new(double *source, double *target, SphericalTransformIter& trans, int stcart, int stpure, int n2, int n3, int n4) { int i234, n234=n2*n3*n4; for (trans.begin(); trans.ready(); trans.next()) { double coef = trans.coef(); int pure = trans.pureindex(); int cart = trans.cartindex(); int offtarget4 = pure*n234; int offsource4 = cart*n234; for (i234=0; i234has_pure(); int pure2 = sh2->has_pure(); int pure3 = sh3->has_pure(); int pure4 = sh4->has_pure(); int nfunc1=sh1->nfunction(); int nfunc2=sh2->nfunction(); int nfunc3=sh3->nfunction(); int nfunc4=sh4->nfunction(); int nfunc34 = nfunc3 * nfunc4; int nfunc234 = nfunc2 * nfunc34; int nfunc1234 = nfunc1 * nfunc234; if (!pure1 && !pure2 && !pure3 && !pure4) { if (pureint!=cartint) memmove(pureint, cartint, sizeof(double)*nfunc1234); return; } int ncart1=sh1->ncartesian(); int ncart2=sh2->ncartesian(); int ncart3=sh3->ncartesian(); int ncart4=sh4->ncartesian(); int ncart34 = ncart3 * ncart4; int ncart234 = ncart2 * ncart34; // allocate the scratch arrays, if needed source_space(ncart1*ncart234); int ncon1 = sh1->ncontraction(); int ncon2 = sh2->ncontraction(); int ncon3 = sh3->ncontraction(); int ncon4 = sh4->ncontraction(); if (ncon1==1 && ncon2==1 && ncon3==1 && ncon4==1) { double *sourcebuf = cartint; double *targetbuf = target; // transform indices if (pure1) { SphericalTransformIter transi(integ->spherical_transform(sh1->am(0))); memset(targetbuf,0,sizeof(double)*nfunc1*ncart2*ncart3*ncart4); do_sparse_transform2_1new(sourcebuf, targetbuf, transi, ncart1, nfunc1, ncart2, ncart3, ncart4); double*tmp=sourcebuf; sourcebuf=targetbuf; targetbuf=tmp; } if (pure2) { SphericalTransformIter transj(integ->spherical_transform(sh2->am(0))); memset(targetbuf,0,sizeof(double)*nfunc1*nfunc2*ncart3*ncart4); do_sparse_transform2_2new(sourcebuf, targetbuf, transj, ncart2, nfunc2, nfunc1, ncart3, ncart4); double*tmp=sourcebuf; sourcebuf=targetbuf; targetbuf=tmp; } if (pure3) { SphericalTransformIter transk(integ->spherical_transform(sh3->am(0))); memset(targetbuf,0,sizeof(double)*nfunc1*nfunc2*nfunc3*ncart4); do_sparse_transform2_3new(sourcebuf, targetbuf, transk, ncart3, nfunc3, nfunc1, nfunc2, ncart4); double*tmp=sourcebuf; sourcebuf=targetbuf; targetbuf=tmp; } if (pure4) { SphericalTransformIter transl(integ->spherical_transform(sh4->am(0))); memset(targetbuf,0,sizeof(double)*nfunc1234); do_sparse_transform2_4new(sourcebuf, targetbuf, transl, ncart4, nfunc4, nfunc1, nfunc2, nfunc3); double*tmp=sourcebuf; sourcebuf=targetbuf; targetbuf=tmp; } if (sourcebuf!=pureint) memmove(pureint, sourcebuf, sizeof(double)*nfunc1234); } else { // begin gc loop int ogccart1 = 0; int ogcfunc1 = 0; for (int i=0; iam(i); int nfunci = sh1->nfunction(i); int ispurei = sh1->is_pure(i); int ncarti = INT_NCART_NN(am1); int ogccart2 = 0; int ogcfunc2 = 0; SphericalTransformIter transi(integ->spherical_transform(am1)); for (int j=0; jam(j); int nfuncj = sh2->nfunction(j); int ispurej = sh2->is_pure(j); int ncartj = INT_NCART_NN(am2); int ogccart3 = 0; int ogcfunc3 = 0; SphericalTransformIter transj(integ->spherical_transform(am2)); for (int k=0; kam(k); int nfunck = sh3->nfunction(k); int ispurek = sh3->is_pure(k); int ncartk = INT_NCART_NN(am3); int ogccart4 = 0; int ogcfunc4 = 0; SphericalTransformIter transk(integ->spherical_transform(am3)); for (int l=0; lam(l); int nfuncl = sh4->nfunction(l); int ispurel = sh4->is_pure(l); int ncartl = INT_NCART_NN(am4); ; // copy to source buffer int cartindex1 = ogccart1*ncart234 + ogccart2*ncart34 + ogccart3*ncart4 + ogccart4; double *tmp_source = source; int is; for (is=0; isspherical_transform(am4)); do_sparse_transform2_4new(sourcebuf, targetbuf, transl, ncartl, nfuncl, nfunci, nfuncj, nfunck); double*tmp=sourcebuf; sourcebuf=targetbuf; targetbuf=tmp; } // copy to scratch buffer int funcindex1 = ogcfunc1*nfunc234 + ogcfunc2*nfunc34 + ogcfunc3*nfunc4 + ogcfunc4; tmp_source = sourcebuf; for (is=0; is