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;
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
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
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
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
00136
00137 Sxy1 = Sxy2 = Sxz1 = Sxz2 = 0.0;
00138
00139
00140 Sxy1 = overlap_int(a1, l1+1, m1, n1, inorm, a2, l2, m2+1, n2, jnorm, AB, PA, PB);
00141
00142 if(m2)
00143 Sxy2 = overlap_int(a1, l1+1, m1, n1, inorm, a2, l2, m2-1, n2, jnorm, AB, PA, PB);
00144
00145 Sxz1 = overlap_int(a1, l1+1, m1, n1, inorm, a2, l2, m2, n2+1, jnorm, AB, PA, PB);
00146
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
00153 Syx1 = overlap_int(a1, l1, m1+1, n1, inorm, a2, l2+1, m2, n2, jnorm, AB, PA, PB);
00154
00155 if(l2)
00156 Syx2 = overlap_int(a1, l1, m1+1, n1, inorm, a2, l2-1, m2, n2, jnorm, AB, PA, PB);
00157
00158 Syz1 = overlap_int(a1, l1, m1+1, n1, inorm, a2, l2, m2, n2+1, jnorm, AB, PA, PB);
00159
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
00166 Szx1 = overlap_int(a1, l1, m1, n1+1, inorm, a2, l2+1, m2, n2, jnorm, AB, PA, PB);
00167
00168 if(l2)
00169 Szx2 = overlap_int(a1, l1, m1, n1+1, inorm, a2, l2-1, m2, n2, jnorm, AB, PA, PB);
00170
00171 Szy1 = overlap_int(a1, l1, m1, n1+1, inorm, a2, l2, m2+1, n2, jnorm, AB, PA, PB);
00172
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
00179 S0x1 = overlap_int(a1, l1, m1, n1, inorm, a2, l2+1, m2, n2, jnorm, AB, PA, PB);
00180
00181 if(l2)
00182 S0x2 = overlap_int(a1, l1, m1, n1, inorm, a2, l2-1, m2, n2, jnorm, AB, PA, PB);
00183
00184 S0y1 = overlap_int(a1, l1, m1, n1, inorm, a2, l2, m2+1, n2, jnorm, AB, PA, PB);
00185
00186 if(m2)
00187 S0y2 = overlap_int(a1, l1, m1, n1, inorm, a2, l2, m2-1, n2, jnorm, AB, PA, PB);
00188
00189 S0z1 = overlap_int(a1, l1, m1, n1, inorm, a2, l2, m2, n2+1, jnorm, AB, PA, PB);
00190
00191 if(n2)
00192 S0z2 = overlap_int(a1, l1, m1, n1, inorm, a2, l2, m2, n2-1, jnorm, AB, PA, PB);
00193
00194
00195
00196 muxy1 = muxy2 = muxz1 = muxz2 = 0.0;
00197
00198
00199 muxy1 = Sxy1 + (A.x - C.x) * S0y1;
00200
00201 muxz1 = Sxz1 + (A.x - C.x) * S0z1;
00202
00203 muxy2 = Sxy2 + (A.x - C.x) * S0y2;
00204
00205 muxz2 = Sxz2 + (A.x - C.x) * S0z2;
00206
00207 muyx1 = muyx2 = muyz1 = muyz2 = 0.0;
00208
00209
00210 muyx1 = Syx1 + (A.y - C.y) * S0x1;
00211
00212 muyz1 = Syz1 + (A.y - C.y) * S0z1;
00213
00214 muyx2 = Syx2 + (A.y - C.y) * S0x2;
00215
00216 muyz2 = Syz2 + (A.y - C.y) * S0z2;
00217
00218 muzx1 = muzx2 = muzy1 = muzy2 = 0.0;
00219
00220
00221 muzx1 = Szx1 + (A.z - C.z) * S0x1;
00222
00223 muzy1 = Szy1 + (A.z - C.z) * S0y1;
00224
00225 muzx2 = Szx2 + (A.z - C.z) * S0x2;
00226
00227 muzy2 = Szy2 + (A.z - C.z) * S0y2;
00228
00229
00230
00231
00232
00233
00234 Lx[I][J] += 2.0*a2*muyz1 - n2*muyz2 - 2.0*a2*muzy1 + m2*muzy2;
00235
00236
00237
00238
00239
00240
00241 Ly[I][J] += 2.0*a2*muzx1 - l2*muzx2 - 2.0*a2*muxz1 + n2*muxz2;
00242
00243
00244
00245
00246
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 }
00256
00257 }
00258 }
00259
00260
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 }
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
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
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 };};