void calc_esp() { static int ct_AN,n1,n2,n3,po,spe; static int i,j,k; static int Rn1,Rn2,Rn3; static int num_grid; static double sum0,sum1,rij,rik; static double cx,cy,cz; static double bik,bij; static double x,y,z; static double dif,total_diff; static double GridVol; static double dx,dy,dz; static double dpx,dpy,dpz,tdp; static double tmp[4]; static double **A,*B; static double *A2; static INTEGER N, NRHS, LDA, *IPIV, LDB, INFO; /* find the number of grids in the shell */ num_grid = 0; for (n1=0; n1<Ngrid1; n1++){ for (n2=0; n2<Ngrid2; n2++){ for (n3=0; n3<Ngrid3; n3++){ if (grid_flag[n1][n2][n3]==1) num_grid++; } } } printf("Number of grids in a van der Waals shell = %2d\n",num_grid); Cross_Product(gtv[2],gtv[3],tmp); GridVol = fabs( Dot_Product(gtv[1],tmp) ); printf("Volume per grid = %15.10f (Bohr^3)\n",GridVol); /* make a matrix A and a vector B */ A = (double**)malloc(sizeof(double*)*(atomnum+10)); for (i=0; i<(atomnum+10); i++){ A[i] = (double*)malloc(sizeof(double)*(atomnum+10)); for (j=0; j<(atomnum+10); j++) A[i][j] = 0.0; } A2 = (double*)malloc(sizeof(double)*(atomnum+10)*(atomnum+10)); B = (double*)malloc(sizeof(double)*(atomnum+10)); for (j=1; j<=atomnum; j++){ for (k=1; k<=atomnum; k++){ sum0 = 0.0; sum1 = 0.0; for (n1=0; n1<Ngrid1; n1++){ for (n2=0; n2<Ngrid2; n2++){ for (n3=0; n3<Ngrid3; n3++){ if (grid_flag[n1][n2][n3]==1){ x = X_grid[n1][n2][n3]; y = Y_grid[n1][n2][n3]; z = Z_grid[n1][n2][n3]; bij = 0.0; bik = 0.0; for (Rn1=-MaxRn1; Rn1<=MaxRn1; Rn1++){ for (Rn2=-MaxRn2; Rn2<=MaxRn2; Rn2++){ for (Rn3=-MaxRn3; Rn3<=MaxRn3; Rn3++){ cx = (double)Rn1*tv[1][1] + (double)Rn2*tv[2][1] + (double)Rn3*tv[3][1]; cy = (double)Rn1*tv[1][2] + (double)Rn2*tv[2][2] + (double)Rn3*tv[3][2]; cz = (double)Rn1*tv[1][3] + (double)Rn2*tv[2][3] + (double)Rn3*tv[3][3]; /* rij */ dx = x - (Gxyz[j][1] + cx); dy = y - (Gxyz[j][2] + cy); dz = z - (Gxyz[j][3] + cz); rij = sqrt(dx*dx + dy*dy + dz*dz); bij += 1.0/rij; /* rik */ dx = x - (Gxyz[k][1] + cx); dy = y - (Gxyz[k][2] + cy); dz = z - (Gxyz[k][3] + cz); rik = sqrt(dx*dx + dy*dy + dz*dz); bik += 1.0/rik; } } } sum0 += bij*bik; if (j==1){ /* sum1 -= (VHart[n1][n2][n3] + VNA[n1][n2][n3])*bik; */ sum1 -= VHart[n1][n2][n3]*bik; } } } } } A[j][k] = sum0; if (j==1) B[k-1] = sum1; } } /* MK */ if (Modified_MK==0){ for (k=1; k<=atomnum; k++){ A[atomnum+1][k] = 1.0; A[k][atomnum+1] = 1.0; } A[atomnum+1][atomnum+1] = 0.0; B[atomnum] = 0.0; /* A to A2 */ i = 0; for (k=1; k<=(atomnum+1); k++){ for (j=1; j<=(atomnum+1); j++){ A2[i] = A[j][k]; i++; } } /* solve Aq = B */ N = atomnum + 1; NRHS = 1; LDA = N; LDB = N; IPIV = (INTEGER*)malloc(sizeof(INTEGER)*N); F77_NAME(dgesv,DGESV)(&N, &NRHS, A2, &LDA, IPIV, B, &LDB, &INFO); if( INFO==0 ){ printf("Success\n" ); } else{ printf("Failure: linear dependent\n" ); exit(0); } printf("\n"); for(i=0; i<atomnum; i++){ printf(" Atom=%4d Fitting Effective Charge=%15.11f\n",i+1,B[i]); } } /* Modified MK */ else if (Modified_MK==1){ for (k=1; k<=atomnum; k++){ A[atomnum+1][k] = 1.0; A[k][atomnum+1] = 1.0; A[atomnum+2][k] = Gxyz[k][1]; A[atomnum+3][k] = Gxyz[k][2]; A[atomnum+4][k] = Gxyz[k][3]; A[k][atomnum+2] = Gxyz[k][1]; A[k][atomnum+3] = Gxyz[k][2]; A[k][atomnum+4] = Gxyz[k][3]; } B[atomnum ] = 0.0; B[atomnum+1] = Ref_DipMx/AU2Debye; B[atomnum+2] = Ref_DipMy/AU2Debye; B[atomnum+3] = Ref_DipMz/AU2Debye; /* A to A2 */ i = 0; for (k=1; k<=(atomnum+4); k++){ for (j=1; j<=(atomnum+4); j++){ A2[i] = A[j][k]; i++; } } /* solve Aq = B */ N = atomnum + 4; NRHS = 1; LDA = N; LDB = N; IPIV = (INTEGER*)malloc(sizeof(INTEGER)*N); F77_NAME(dgesv,DGESV)(&N, &NRHS, A2, &LDA, IPIV, B, &LDB, &INFO); if( INFO==0 ){ printf("Success\n" ); } else{ printf("Failure: linear dependent\n" ); exit(0); } printf("\n"); for(i=0; i<atomnum; i++){ printf(" Atom=%4d Fitting Effective Charge=%15.11f\n",i+1,B[i]); } } dpx = 0.0; dpy = 0.0; dpz = 0.0; for (ct_AN=1; ct_AN<=atomnum; ct_AN++){ x = Gxyz[ct_AN][1]; y = Gxyz[ct_AN][2]; z = Gxyz[ct_AN][3]; dpx += AU2Debye*B[ct_AN-1]*x; dpy += AU2Debye*B[ct_AN-1]*y; dpz += AU2Debye*B[ct_AN-1]*z; } tdp = sqrt(dpx*dpx + dpy*dpy + dpz*dpz); printf("\n"); printf(" Magnitude of dipole moment %15.10f (Debye)\n",tdp); printf(" Component x y z %15.10f %15.10f %15.10f\n",dpx,dpy,dpz); /* calc diff */ total_diff = 0.0; for (n1=0; n1<Ngrid1; n1++){ for (n2=0; n2<Ngrid2; n2++){ for (n3=0; n3<Ngrid3; n3++){ if (grid_flag[n1][n2][n3]==1){ x = X_grid[n1][n2][n3]; y = Y_grid[n1][n2][n3]; z = Z_grid[n1][n2][n3]; for (Rn1=-MaxRn1; Rn1<=MaxRn1; Rn1++){ for (Rn2=-MaxRn2; Rn2<=MaxRn2; Rn2++){ for (Rn3=-MaxRn3; Rn3<=MaxRn3; Rn3++){ cx = (double)Rn1*tv[1][1] + (double)Rn2*tv[2][1] + (double)Rn3*tv[3][1]; cy = (double)Rn1*tv[1][2] + (double)Rn2*tv[2][2] + (double)Rn3*tv[3][2]; cz = (double)Rn1*tv[1][3] + (double)Rn2*tv[2][3] + (double)Rn3*tv[3][3]; for (j=1; j<=atomnum; j++){ dx = x - (Gxyz[j][1] + cx); dy = y - (Gxyz[j][2] + cy); dz = z - (Gxyz[j][3] + cz); rij = sqrt(dx*dx + dy*dy + dz*dz); dif = -VHart[n1][n2][n3] + B[j-1]/rij; total_diff += dif*dif; } } } } } } } } total_diff = sqrt(total_diff)/(GridVol*num_grid); printf("RMS between the given ESP and fitting charges (Hartree/Bohr^3)=%15.12f\n\n", total_diff); /* freeing of arrays */ for (i=0; i<(atomnum+10); i++){ free(A[i]); } free(A); free(B); free(A2); free(IPIV); }
// -------------------------------------------------------------------------- // int Class_VolTri::ReturnSimplexID( a3vector1D &P, int S0 ) { // ========================================================================== // // int Class_VolTri::ReturnSimplexID( // // a3vector1D &P, // // int S0) // // // // Return the ID of the simplex enclosing point P. // // ========================================================================== // // INPUT // // ========================================================================== // // - P : a3vector1D, point coordinates // // - S0 : int, seed for search procedure // // ========================================================================== // // OUTPUT // // ========================================================================== // // - S : int, ID of simplex enclosing point P // // ========================================================================== // // ========================================================================== // // VARIABLES DECLARATION // // ========================================================================== // // Local variables bool check = false; int n, m, p; double max_dp, dp; bvector1D visited(nSimplex, false); ivector2D face_vlist; a3vector1D x, y, xF, xS, dir; a3vector2D face_normals; LIFOstack<int> stack; // Counters int i, j, k, l, S, A; /*debug*/int n_visited = 0; // /*debug*/ofstream log_file; // /*debug*/log_file.open("SEARCH.log", ifstream::app); // ========================================================================== // // INITIALIZE PARAMETERS // // ========================================================================== // // x.fill(0.0); // y.fill(0.0); // /*debug*/log_file << "point coordinates: " << P << endl; // ========================================================================== // // BUILD ADJACENCY IF NOT ALREADY BUILT // // ========================================================================== // if ((Adjacency.size() == 0) || (Adjacency.size() < nSimplex)) { BuildAdjacency(); } // ========================================================================== // // LOOP UNTIL SIMPLEX IS FOUND // // ========================================================================== // stack.push(S0); while ((stack.TOPSTK > 0) && (!check)) { // /*debug*/n_visited++; // Pop item from stack -------------------------------------------------- // S = stack.pop(); visited[S] = true; // /*debug*/log_file << " traversing simplex: " << S << endl; // /*debug*/log_file << " (visited: " << n_visited << " of " << nSimplex << endl; // Simplex infos -------------------------------------------------------- // n = infos[e_type[S]].n_vert; m = infos[e_type[S]].n_faces; // Get face vertices ---------------------------------------------------- // { face_vlist.resize(m); for (j = 0; j < m; ++j) { face_vlist[j] = FaceVertices(S, j); } //next j } // Simplex baricenter --------------------------------------------------- // { xS.fill(0.0); for (j = 0; j < n; ++j) { for (l = 0; l < 3; ++l) { xS[l] += Vertex[Simplex[S][j]][l]; } //next l } //next j xS = xS/((double) n); } // Compute face normals ------------------------------------------------- // { face_normals.resize(m); for (j = 0; j < m; ++j) { if (face_vlist[j].size() == 2) { x = Vertex[face_vlist[j][1]] - Vertex[face_vlist[j][0]]; x[2] = 0.0; y[0] = 0.0; y[1] = 0.0; y[2] = 1.0; face_normals[j] = Cross_Product(x, y); } else { x = Vertex[face_vlist[j][2]] - Vertex[face_vlist[j][1]]; y = Vertex[face_vlist[j][1]] - Vertex[face_vlist[j][0]]; face_normals[j] = Cross_Product(x, y); } face_normals[j] = face_normals[j]/max(norm_2(face_normals[j]), 2.0e-16); } //next j } // Check if Simplex S encloses point P ---------------------------------- // { check = true; for (j = 0; j < m; ++j) { n = face_vlist[j].size(); // Compute face center xF.fill(0.0); for (k = 0; k < n; ++k) { for (l = 0; l < 3; l++) { xF[l] += Vertex[face_vlist[j][k]][l]; } //next l } //next k xF = xF/((double) n); // Check if simplex encloses point dir = P - xF; dir = dir/max(norm_2(dir), 2.0e-16); check = (check && (Dot_Product(dir, face_normals[j]) <= 0.0)); } //next j } // /*debug*/log_file << " encloses point: " << check << endl; // Look for best direction (Euristic search of best path) --------------- // // NOTES: // // - modificare il criterio euristico per la scelta del path migliore // // * congiungente P-xS attraversa una faccia. // // * distanza minima dalle facce. // // ---------------------------------------------------------------------- // if (!check) { // local direction of searching path dir = P - xS; dir = dir/max(norm_2(dir), 2.0e-16); // Loop over simplex faces max_dp = -2.0; i = 0; j = -1; while (i < m) { dp = Dot_Product(face_normals[i], dir); if (dp > max_dp) { j = i; max_dp = dp; } i++; } //next i // Alternative directions for (i = 0; i < m; ++i) { A = Adjacency[S][i]; if ((i != j) && (A >= 0) && (!visited[A])) { stack.push(A); } } //next i A = Adjacency[S][j]; if ((A >= 0) && (!visited[A])) { stack.push(A); } } } //next simplex // /*debug*/log_file << " (visited: " << n_visited << " of " << nSimplex << ")" << endl; // Old algorithm ============================================================ // { // while ((n_visited <= nSimplex) && (!check) && (S0 >= 0)) { // // Update simplex ID ---------------------------------------------------- // // // cout << " on simplex " << S0; // S = S0; // n_visited++; // visited[S] = true; // /*debug*/log_file << " traversing simplex: " << S << endl; // /*debug*/log_file << " (visited: " << n_visited << " of " << nSimplex << endl; // // Simplex infos -------------------------------------------------------- // // m = infos[e_type[S]].n_faces; // p = infos[e_type[S]].n_vert; // // Compute simplex baricenter ------------------------------------------- // // { // xS.fill(0.0); // for (j = 0; j < p; ++j) { // for (l = 0; l < dim; ++l) { // xS[l] += Vertex[Simplex[S][j]][l]; // } //next l // } //next j // xS = xS/((double) p); // } // // Get face vertices ---------------------------------------------------- // // { // face_vlist.resize(m); // for (j = 0; j < m; ++j) { // face_vlist[j] = FaceVertices(S, j); // } //next j // } // // Compute face normals ------------------------------------------------- // // { // face_normals.resize(m); // for (j = 0; j < m; ++j) { // if (face_vlist[j].size() == 2) { // x[0] = Vertex[face_vlist[j][1]][0] - Vertex[face_vlist[j][0]][0]; // x[1] = Vertex[face_vlist[j][1]][1] - Vertex[face_vlist[j][0]][1]; // x[2] = 0.0; // y[0] = 0.0; // y[1] = 0.0; // y[2] = 1.0; // face_normals[j] = Cross_Product(x, y); // } // else { // x[0] = Vertex[face_vlist[j][2]][0] - Vertex[face_vlist[j][1]][0]; // x[1] = Vertex[face_vlist[j][2]][1] - Vertex[face_vlist[j][1]][1]; // x[2] = Vertex[face_vlist[j][2]][2] - Vertex[face_vlist[j][1]][2]; // y[0] = Vertex[face_vlist[j][1]][0] - Vertex[face_vlist[j][0]][0]; // y[1] = Vertex[face_vlist[j][1]][1] - Vertex[face_vlist[j][0]][1]; // y[2] = Vertex[face_vlist[j][1]][2] - Vertex[face_vlist[j][0]][2]; // face_normals[j] = Cross_Product(x, y); // } // face_normals[j] = face_normals[j]/max(norm_2(face_normals[j]), 2.0e-16); // } //next j // } // // Check if P is enclosed in simplex S0 --------------------------------- // // { // check = true; // for (j = 0; j < m; ++j) { // n = face_vlist[j].size(); // // Compute face center // xF.fill(0.0); // for (k = 0; k < n; ++k) { // for (l = 0; l < dim; l++) { // xF[l] += Vertex[face_vlist[j][k]][l]; // } //next l // } //next k // xF = xF/((double) n); // // Check if simplex encloses point // for (l = 0; l < dim; l++) { // dir[l] = P[l] - xF[l]; // } //next l // dir = dir/max(norm_2(dir), 2.0e-16); // check = (check && (Dot_Product(dir, face_normals[j]) <= 0.0)); // // cout << " f " << j << ", c: " << check; // } //next j // } // // cout << ", check: " << check << endl; // /*debug*/log_file << " encloses point: " << check << endl; // // Look for best direction (Euristic search) ---------------------------- // // if (!check) { // // Find face to be crossed (Euristic search of best path) // { // // path local direction // for (l = 0; l < dim; ++l) { // dir[l] = P[l] - xS[l]; // } //next l // dir = dir/max(norm_2(dir), 2.0e-16); // // Loop over simplex faces // // WARNING: infinite loop at corner simplicies!! // max_dp = -2.0; // i = -1; // j = 0; // while (j < m) { // dp = Dot_Product(face_normals[j], dir); // A = Adjacency[S][j]; // if ((dp > max_dp) && (A >= 0)) {//&& (!visited[A])) { // i = j; // max_dp = dp; // } // j++; // } //next j // } // // Move to adjacent simplex // if (i >= 0) { S0 = Adjacency[S][i]; } // else { S0 = -1;} // } // /*debug*/log_file << " next simplex: " << S0 << endl; // } //next simplex } // /*debug*/log_file.close(); return(S); };