angmom_ints.cc

Go to the documentation of this file.
00001 
00005 #include<cmath>
00006 #include<cstdio>
00007 #include<stdlib.h>
00008 #include<string>
00009 #include<libipv1/ip_lib.h>
00010 #include<libiwl/iwl.h>
00011 #include<libciomr/libciomr.h>
00012 #include<libint/libint.h>
00013 #include<psifiles.h>
00014 
00015 #include"defines.h"
00016 #define EXTERN
00017 #include"global.h"
00018 #include <stdexcept>
00019 
00020 namespace psi { namespace CINTS {
00021 
00022 static double overlap_int(double a1, int l1, int m1, int n1, double norm1,
00023                           double a2, int l2, int m2, int n2, double norm2,
00024                           struct coordinates AB,
00025                           struct coordinates PA,
00026                           struct coordinates PB);
00027 static double f_n(int k, int l1, int l2, double A, double B);
00028 static double int_pow(double a, int p);
00029 
00030 void angmom_ints(void)
00031 {
00032   struct coordinates PA, PB, AB, A, B;
00033   struct shell_pair *sp;
00034   register int i, j, k, l, ii, jj, kk, ll;
00035   int si, sj;
00036   int ni, nj;
00037   int l1, m1, n1, l2, m2, n2;
00038   int am_i, am_j;
00039   int ai, aj, I, J;
00040   int ioffset, joffset;
00041   int atom1, atom2;
00042   int ax, ay, az, bx, by, bz; /* nuclear coordinate indices */
00043   int coord, ntri, ij;
00044   double a1, a2;
00045   double ab2, oog, gam;
00046   double inorm, jnorm, over_pf;
00047   double **Lx, **Ly, **Lz;
00048   struct coordinates C;
00049   double Sxy1, Sxy2, Sxz1, Sxz2;
00050   double Syx1, Syx2, Syz1, Syz2;
00051   double Szx1, Szx2, Szy1, Szy2;
00052   double S0x1, S0x2, S0y1, S0y2, S0z1, S0z2;
00053   double muxy1, muxy2, muxz1, muxz2;
00054   double muyx1, muyx2, muyz1, muyz2;
00055   double muzx1, muzx2, muzy1, muzy2;
00056   double norm1, norm12, *ptr1, *ptr2;
00057   double *scratch_x, *scratch_y, *scratch_z;
00058 
00059   Lx = block_matrix(BasisSet.num_ao, BasisSet.num_ao);
00060   Ly = block_matrix(BasisSet.num_ao, BasisSet.num_ao);
00061   Lz = block_matrix(BasisSet.num_ao, BasisSet.num_ao);
00062   scratch_x = init_array(ioff[BasisSet.num_ao]);
00063   scratch_y = init_array(ioff[BasisSet.num_ao]);
00064   scratch_z = init_array(ioff[BasisSet.num_ao]);
00065 
00066   C = UserOptions.origin;
00067   if(UserOptions.print_lvl >= PRINT_OEI)
00068     fprintf(outfile, "    Reference point for ang. mom. ints. = (%5.3f, %5.3f, %5.3f)\n", C.x, C.y, C.z);
00069 
00070   for (si=0; si<BasisSet.num_shells; si++){
00071     am_i = BasisSet.shells[si].am-1;
00072     ni = ioff[BasisSet.shells[si].am];
00073     A = Molecule.centers[BasisSet.shells[si].center-1];
00074     ioffset = BasisSet.shells[si].fao - 1;
00075     atom1 = BasisSet.shells[si].center-1;
00076 
00077     ax = atom1 * 3;
00078     ay = ax + 1;
00079     az = ax + 2;
00080 
00081     for (sj=0; sj<BasisSet.num_shells; sj++){
00082       nj = ioff[BasisSet.shells[sj].am];
00083       am_j = BasisSet.shells[sj].am-1;
00084       B = Molecule.centers[BasisSet.shells[sj].center-1];
00085       joffset = BasisSet.shells[sj].fao - 1;
00086       atom2 = BasisSet.shells[sj].center-1;
00087 
00088       bx = atom2 * 3;
00089       by = bx + 1;
00090       bz = bx + 2;
00091 
00092       sp = &(BasisSet.shell_pairs[si][sj]);
00093       AB.x = sp->AB[0];
00094       AB.y = sp->AB[1];
00095       AB.z = sp->AB[2];
00096       ab2 = AB.x * AB.x;
00097       ab2 += AB.y * AB.y;
00098       ab2 += AB.z * AB.z;
00099 
00100       /*--- contract by primitives here ---*/
00101       for (i = 0; i < BasisSet.shells[si].n_prims; i++) {
00102         a1 = sp->a1[i];
00103         inorm = sp->inorm[i];
00104         for (j = 0; j < BasisSet.shells[sj].n_prims; j++) {
00105           a2 = sp->a2[j];
00106           gam = sp->gamma[i][j];
00107           jnorm = sp->jnorm[j];
00108           PA.x = sp->PA[i][j][0];
00109           PA.y = sp->PA[i][j][1];
00110           PA.z = sp->PA[i][j][2];
00111           PB.x = sp->PB[i][j][0];
00112           PB.y = sp->PB[i][j][1];
00113           PB.z = sp->PB[i][j][2];
00114           oog = 1.0/gam;
00115           over_pf = exp(-a1*a2*ab2*oog)*sqrt(M_PI*oog)*M_PI*oog*inorm*jnorm;
00116 
00117           /*--- create all am components of si ---*/
00118           ai = 0;
00119           for(ii = 0; ii <= am_i; ii++){
00120             l1 = am_i - ii;
00121             for(jj = 0; jj <= ii; jj++){
00122               m1 = ii - jj;
00123               n1 = jj;
00124               I = ioffset + ai;
00125 
00126               /*--- create all am components of sj ---*/
00127               aj = 0;
00128               for(kk = 0; kk <= am_j; kk++){
00129                 l2 = am_j - kk;
00130                 for(ll = 0; ll <= kk; ll++){
00131                   m2 = kk - ll;
00132                   n2 = ll;
00133                   J = joffset + aj;
00134 
00135                   /*** overlap integrals ***/
00136 
00137                   Sxy1 = Sxy2 = Sxz1 = Sxz2 = 0.0;
00138 
00139                   /* (a+1x|b+1y) */
00140                   Sxy1 = overlap_int(a1, l1+1, m1, n1, inorm, a2, l2, m2+1, n2, jnorm, AB, PA, PB);
00141                   /* (a+1x|b-1y) */
00142                   if(m2)
00143                     Sxy2 = overlap_int(a1, l1+1, m1, n1, inorm, a2, l2, m2-1, n2, jnorm, AB, PA, PB);
00144                   /* (a+1x|b+1z) */
00145                   Sxz1 = overlap_int(a1, l1+1, m1, n1, inorm, a2, l2, m2, n2+1, jnorm, AB, PA, PB);
00146                   /* (a+1x|b-1z) */
00147                   if(n2)
00148                     Sxz2 = overlap_int(a1, l1+1, m1, n1, inorm, a2, l2, m2, n2-1, jnorm, AB, PA, PB);
00149 
00150                   Syx1 = Syx2 = Syz1 = Syz2 = 0.0;
00151 
00152                   /* (a+1y|b+1x) */
00153                   Syx1 = overlap_int(a1, l1, m1+1, n1, inorm, a2, l2+1, m2, n2, jnorm, AB, PA, PB);
00154                   /* (a+1y|b-1x) */
00155                   if(l2)
00156                     Syx2 = overlap_int(a1, l1, m1+1, n1, inorm, a2, l2-1, m2, n2, jnorm, AB, PA, PB);
00157                   /* (a+1y|b+1z) */
00158                   Syz1 = overlap_int(a1, l1, m1+1, n1, inorm, a2, l2, m2, n2+1, jnorm, AB, PA, PB);
00159                   /* (a+1y|b-1z) */
00160                   if(n2)
00161                     Syz2 = overlap_int(a1, l1, m1+1, n1, inorm, a2, l2, m2, n2-1, jnorm, AB, PA, PB);
00162 
00163                   Szx1 = Szx2 = Szy1 = Szy2 = 0.0;
00164 
00165                   /* (a+1z|b+1x) */
00166                   Szx1 = overlap_int(a1, l1, m1, n1+1, inorm, a2, l2+1, m2, n2, jnorm, AB, PA, PB);
00167                   /* (a+1z|b-1x) */
00168                   if(l2)
00169                     Szx2 = overlap_int(a1, l1, m1, n1+1, inorm, a2, l2-1, m2, n2, jnorm, AB, PA, PB);
00170                   /* (a+1z|b+1y) */
00171                   Szy1 = overlap_int(a1, l1, m1, n1+1, inorm, a2, l2, m2+1, n2, jnorm, AB, PA, PB);
00172                   /* (a+1z|b-1y) */
00173                   if(m2)
00174                     Szy2 = overlap_int(a1, l1, m1, n1+1, inorm, a2, l2, m2-1, n2, jnorm, AB, PA, PB);
00175 
00176                   S0x1 = S0x2 = S0y1 = S0y2 = S0z1 = S0z2 = 0.0;
00177 
00178                   /* (a|b+1x) */
00179                   S0x1 = overlap_int(a1, l1, m1, n1, inorm, a2, l2+1, m2, n2, jnorm, AB, PA, PB);
00180                   /* (a|b-1x) */
00181                   if(l2)
00182                     S0x2 = overlap_int(a1, l1, m1, n1, inorm, a2, l2-1, m2, n2, jnorm, AB, PA, PB);
00183                   /* (a|b+1y) */
00184                   S0y1 = overlap_int(a1, l1, m1, n1, inorm, a2, l2, m2+1, n2, jnorm, AB, PA, PB);
00185                   /* (a|b-1y) */
00186                   if(m2)
00187                     S0y2 = overlap_int(a1, l1, m1, n1, inorm, a2, l2, m2-1, n2, jnorm, AB, PA, PB);
00188                   /* (a|b+1z) */
00189                   S0z1 = overlap_int(a1, l1, m1, n1, inorm, a2, l2, m2, n2+1, jnorm, AB, PA, PB);
00190                   /* (a|b-1z) */
00191                   if(n2)
00192                     S0z2 = overlap_int(a1, l1, m1, n1, inorm, a2, l2, m2, n2-1, jnorm, AB, PA, PB);
00193 
00194                   /*** moment integrals ***/
00195 
00196                   muxy1 = muxy2 = muxz1 = muxz2 = 0.0;
00197 
00198                   /* (a|(x-Cx)|b+1y) */
00199                   muxy1 = Sxy1 + (A.x - C.x) * S0y1;
00200                   /* (a|(x-Cx)|b+1z) */
00201                   muxz1 = Sxz1 + (A.x - C.x) * S0z1;
00202                   /* (a|(x-Cx)|b-1y) */
00203                   muxy2 = Sxy2 + (A.x - C.x) * S0y2;
00204                   /* (a|(x-Cx)|b-1z) */
00205                   muxz2 = Sxz2 + (A.x - C.x) * S0z2;
00206 
00207                   muyx1 = muyx2 = muyz1 = muyz2 = 0.0;
00208 
00209                   /* (a|(y-Cy)|b+1x) */
00210                   muyx1 = Syx1 + (A.y - C.y) * S0x1;
00211                   /* (a|(y-Cy)|b+1z) */
00212                   muyz1 = Syz1 + (A.y - C.y) * S0z1;
00213                   /* (a|(y-Cy)|b-1x) */
00214                   muyx2 = Syx2 + (A.y - C.y) * S0x2;
00215                   /* (a|(y-Cy)|b-1z) */
00216                   muyz2 = Syz2 + (A.y - C.y) * S0z2;
00217 
00218                   muzx1 = muzx2 = muzy1 = muzy2 = 0.0;
00219 
00220                   /* (a|(z-Cz)|b+1x) */
00221                   muzx1 = Szx1 + (A.z - C.z) * S0x1;
00222                   /* (a|(z-Cz)|b+1y) */
00223                   muzy1 = Szy1 + (A.z - C.z) * S0y1;
00224                   /* (a|(z-Cz)|b+1x) */
00225                   muzx2 = Szx2 + (A.z - C.z) * S0x2;
00226                   /* (a|(z-Cz)|b+1y) */
00227                   muzy2 = Szy2 + (A.z - C.z) * S0y2;
00228 
00229                   /********** Lx integrals ***********/
00230 
00231                   /* (a|Lx|b) = 2 a2 * (a|(y-Cy)|b+1z) - B.z * (a|(y-Cy)|b-1z)
00232                      - 2 a2 * (a|(z-Cz)|b+1y) + B.y * (a|(z-Cz)|b-1y) */
00233 
00234                   Lx[I][J] += 2.0*a2*muyz1 - n2*muyz2 - 2.0*a2*muzy1 + m2*muzy2;
00235                   
00236                   /********** Ly integrals ***********/
00237 
00238                   /* (a|Ly|b) = 2 a2 * (a|(z-Cz)|b+1x) - B.x * (a|(z-Cz)|b-1x)
00239                      - 2 a2 * (a|(x-Cx)|b+1z) + B.z * (a|(x-Cx)|b-1z) */
00240 
00241                   Ly[I][J] += 2.0*a2*muzx1 - l2*muzx2 - 2.0*a2*muxz1 + n2*muxz2;
00242                   
00243                   /********** Lz integrals ***********/
00244 
00245                   /* (a|Lz|b) = 2 a2 * (a|(x-Cx)|b+1y) - B.y * (a|(x-Cx)|b-1y)
00246                      - 2 a2 * (a|(y-Cy)|b+1x) + B.x * (a|(y-Cy)|b-1x) */
00247 
00248                   Lz[I][J] += 2.0*a2*muxy1 - m2*muxy2 - 2.0*a2*muyx1 + l2*muyx2;
00249 
00250                   aj++;
00251                 }
00252               }
00253               ai++;
00254             }
00255           } /* done with primitives */
00256 
00257         }
00258       } /* done with contractions */
00259 
00260       /* normalize the contracted integrals */
00261       ptr1 = GTOs.bf_norm[am_i];
00262       ptr2 = GTOs.bf_norm[am_j];
00263       for(i=0; i<ni; i++) {
00264         norm1 = ptr1[i];
00265         I = ioffset + i;
00266         for(j=0; j<nj; j++) {
00267           norm12 = norm1*ptr2[j];
00268           J = joffset + j;
00269 
00270           Lx[I][J] *= norm12;
00271           Ly[I][J] *= norm12;
00272           Lz[I][J] *= norm12;
00273         }
00274       }
00275     }
00276   } /* done with this shell pair */
00277 
00278   for(i=0,ij=0; i < BasisSet.num_ao; i++)
00279     for(j=0; j <= i; j++,ij++) {
00280       scratch_x[ij] = Lx[i][j];
00281       scratch_y[ij] = Ly[i][j];
00282       scratch_z[ij] = Lz[i][j];
00283     }
00284 
00285   if (UserOptions.print_lvl >= PRINT_OEI) {
00286     fprintf(outfile, "  -AO-Basis LX AngMom Integrals:\n");
00287     print_mat(Lx, BasisSet.num_ao, BasisSet.num_ao, outfile);
00288     fprintf(outfile, "  -AO-Basis LY AngMom Integrals:\n");
00289     print_mat(Ly, BasisSet.num_ao, BasisSet.num_ao, outfile);
00290     fprintf(outfile, "  -AO-Basis LZ AngMom Integrals:\n");
00291     print_mat(Lz, BasisSet.num_ao, BasisSet.num_ao, outfile);
00292     fprintf(outfile,"\n");
00293   }
00294 
00295   /* dump the integrals to disk here */
00296   iwl_wrtone(IOUnits.itapOEInt_Misc, PSIF_AO_LX, ioff[BasisSet.num_ao], scratch_x);
00297   iwl_wrtone(IOUnits.itapOEInt_Misc, PSIF_AO_LY, ioff[BasisSet.num_ao], scratch_y);
00298   iwl_wrtone(IOUnits.itapOEInt_Misc, PSIF_AO_LZ, ioff[BasisSet.num_ao], scratch_z);
00299 
00300   free(scratch_x);
00301   free(scratch_y);
00302   free(scratch_z);
00303   free_block(Lx);
00304   free_block(Ly);
00305   free_block(Lz);
00306 }
00307 
00308 /*-----------------------------------------------
00309   This computes overlap of 2 primitive gaussians
00310  -----------------------------------------------*/
00311 double overlap_int(double a1, int l1, int m1, int n1, double norm1,
00312                    double a2, int l2, int m2, int n2, double norm2,
00313                    struct coordinates AB,
00314                    struct coordinates PA,
00315                    struct coordinates PB)
00316 {
00317   int i, j, k, l;
00318   int imax, jmax, kmax;
00319   int print = 0;
00320   double Ix, Iy, Iz;
00321   double I;
00322   double gam;
00323   double AB2;
00324   double tval, tval1, tval2 ;
00325   double norm_fact ;
00326 
00327   
00328   AB2 = AB.x*AB.x+AB.y*AB.y+AB.z*AB.z;
00329   gam = a1+a2;
00330   norm_fact = norm1*norm2; 
00331 
00332   tval1 = 2*gam;
00333   imax = (l1+l2)/2;
00334   Ix = 0.0;
00335   for (i = 0; i<= imax; i++){
00336     tval = f_n(i*2, l1, l2, PA.x, PB.x);
00337     tval2 = int_pow(tval1, i);
00338     Ix += tval*(num_ser[i])/(tval2);
00339     }
00340   jmax = (m1+m2)/2;
00341   Iy = 0.0;
00342   for (j = 0; j<= jmax; j++){
00343     tval = f_n(j*2, m1, m2, PA.y, PB.y);
00344     tval2 = int_pow(tval1, j);
00345     Iy += tval*num_ser[j]/(tval2);
00346     }
00347   kmax = (n1+n2)/2;
00348   Iz = 0.0;
00349   for (k = 0; k<= kmax; k++){
00350     tval = f_n(k*2, n1, n2, PA.z, PB.z);
00351     tval2 = int_pow(tval1, k);
00352     Iz += tval*num_ser[k]/(tval2);
00353     }
00354  
00355   I=exp(-1*a1*a2*AB2/gam)*Ix*Iy*Iz*sqrt(M_PI/gam)*(M_PI/gam);
00356 
00357   return I*norm_fact;
00358 }
00359 
00360 double f_n(int k, int l1, int l2, double A, double B)
00361 {
00362   int i, j;
00363   double sum = 0.0;
00364   double tval;
00365   double tmp1, tmp2, tmp3, tmp4 ;
00366 
00367   for(i=0; i<=l1; i++){
00368     for(j=0; j<=l2; j++){
00369       tmp1 = tmp2 = tmp3 = tmp4 = 0.0 ;
00370       if((i+j) == k){
00371         tmp1 = int_pow(A, (l1-i));
00372         tmp2 = int_pow(B, (l2-j));
00373         tmp3 = bc[l1][i];
00374         tmp4 = bc[l2][j];
00375         tval = tmp1 * tmp2 * tmp3 * tmp4 ;
00376         sum += tval ;
00377         }
00378       }
00379     }
00380   return sum;
00381 }
00382 
00383 double int_pow(double a, int p)
00384 {
00385   register int i;
00386   double b = 1.0;
00387   
00388   for(i=0; i<p; i++) b = b*a;
00389   return b;
00390 }
00391 };};

Generated on Wed Feb 13 16:35:39 2008 for PSI by  doxygen 1.5.4