int Is_Three_Atoms_Colinear(int ia, int ib, int ic) { double v1_x, v1_y, v1_z; double v2_x, v2_y, v2_z; double dot_v1_v2; double *x_Mol, *y_Mol, *z_Mol; x_Mol = Mol.x; y_Mol = Mol.y; z_Mol = Mol.z; v1_x = x_Mol[ib] - x_Mol[ia]; v1_y = y_Mol[ib] - y_Mol[ia]; v1_z = z_Mol[ib] - z_Mol[ia]; v2_x = x_Mol[ic] - x_Mol[ib]; v2_y = y_Mol[ic] - y_Mol[ib]; v2_z = z_Mol[ic] - z_Mol[ib]; Normalize(v1_x, v1_y, v1_z); Normalize(v2_x, v2_y, v2_z); dot_v1_v2 = fabs(Dot_Product(v1_x, v1_y, v1_z, v2_x, v2_y, v2_z)); if(dot_v1_v2 > cos(15.0*radianInv)) { // smaller than 10 degree return 1; } else { return 0; } }
void TRAN_Calc_VHartree_G0(dcomplex vl, dcomplex vr, /* value of the electrode */ double vl_c_r, double vl_c_i, /* value of left edge (x_0) of the C region , calculated by FFT */ double vr_c_r, double vr_c_i, /* value of right edge the (x_(l+1)) C region ,calculated by FFT */ int ix0, int ixlp1 , double gtv1[4], double *pot_r, double *pot_i /* input,output --- overwrite */ ) { double r1,r2; double len; dcomplex vb,va; int i1; /*debug * printf("vl=%le %le, vr= %le %le\n", vl.r,vl.i, vr.r, vr.i); * printf("vl_c_r=%le %le\n", vl_c_r,vl_c_i); * printf("vr_c_r=%le %le\n", vr_c_r,vr_c_i); */ len = Dot_Product(gtv1,gtv1); len = sqrt(len); r1 = len*ix0; r2 = len*ixlp1; vb.r = vl.r - vl_c_r; vb.i = vl.i - vl_c_i; va.r =( vr.r-vr_c_r-vb.r )/ (r2-r1); va.i =( vr.i-vr_c_i-vb.i )/ (r2-r1); for (i1=ix0+1;i1<ixlp1;i1++) { r2 = len*i1; pot_r[i1] += va.r*(r2-r1)+vb.r; /* add it */ pot_i[i1] += va.i*(r2-r1)+vb.i; /* add it */ } #if 0 printf("G0 Re\n"); for (i3=iz0+1;i3<izlp1;i3++) { printf("%lf ",pot_r[i3]); } printf("G0 Im\n"); for (i3=iz0+1;i3<izlp1;i3++) { printf("%lf ",pot_i[i3]); } #endif }
float Vec_Angle(float vec_a[3], float vec_b[3]) { float acos_factor; if ((!vec_a[0] && !vec_a[1] && !vec_a[2]) || (!vec_b[0] && !vec_b[1] && !vec_b[2])) { return 0; } acos_factor = Dot_Product(vec_a, vec_b) / (Vec_Length(vec_a) * Vec_Length(vec_b)); if (acos_factor > 1) { // Clamp arccos factor in case of inaccurate calculations acos_factor = 1; } else if (acos_factor < -1) { acos_factor = -1; } return (acos(acos_factor) / PI) * 180; }
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); }
Word16 Pitch_fr3_fast(/* (o) : pitch period. */ Word16 exc[], /* (i) : excitation buffer */ Word16 xn[], /* (i) : target vector */ Word16 h[], /* (i) Q12 : impulse response of filters. */ Word16 L_subfr, /* (i) : Length of subframe */ Word16 t0_min, /* (i) : minimum value in the searched range. */ Word16 t0_max, /* (i) : maximum value in the searched range. */ Word16 i_subfr, /* (i) : indicator for first subframe. */ Word16 *pit_frac /* (o) : chosen fraction. */ ) { Word16 t, t0; Word16 Dn[L_SUBFR]; Word16 exc_tmp[L_SUBFR]; Word32 max, corr, L_temp; /*-----------------------------------------------------------------* * Compute correlation of target vector with impulse response. * *-----------------------------------------------------------------*/ Cor_h_X(h, xn, Dn); /*-----------------------------------------------------------------* * Find maximum integer delay. * *-----------------------------------------------------------------*/ max = MIN_32; t0 = t0_min; /* Only to remove warning from some compilers */ for(t=t0_min; t<=t0_max; t++) { corr = Dot_Product(Dn, &exc[-t], L_subfr); L_temp = L_sub(corr, max); if(L_temp > 0) {max = corr; t0 = t; } } /*-----------------------------------------------------------------* * Test fractions. * *-----------------------------------------------------------------*/ /* Fraction 0 */ Pred_lt_3(exc, t0, 0, L_subfr); max = Dot_Product(Dn, exc, L_subfr); *pit_frac = 0; /* If first subframe and lag > 84 do not search fractional pitch */ if( (i_subfr == 0) && (sub(t0, 84) > 0) ) return t0; Copy(exc, exc_tmp, L_subfr); /* Fraction -1/3 */ Pred_lt_3(exc, t0, -1, L_subfr); corr = Dot_Product(Dn, exc, L_subfr); L_temp = L_sub(corr, max); if(L_temp > 0) { max = corr; *pit_frac = -1; Copy(exc, exc_tmp, L_subfr); } /* Fraction +1/3 */ Pred_lt_3(exc, t0, 1, L_subfr); corr = Dot_Product(Dn, exc, L_subfr); L_temp = L_sub(corr, max); if(L_temp > 0) { max = corr; *pit_frac = 1; } else Copy(exc_tmp, exc, L_subfr); return t0; }
// -------------------------------------------------------------------------- // 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); };
void Make_FracCoord(char *file) { int i,k,Mc_AN,Gc_AN,ct_AN; int itmp; int numprocs,myid,ID,tag=999; double Cxyz[4]; char fname1[YOUSO10]; FILE *fp; MPI_Status stat; MPI_Request request; MPI_Comm_size(mpi_comm_level1,&numprocs); MPI_Comm_rank(mpi_comm_level1,&myid); if (myid==Host_ID){ sprintf(fname1,"%s%s.frac",filepath,filename); if ((fp = fopen(fname1,"w")) != NULL){ fprintf(fp,"\n"); fprintf(fp,"***********************************************************\n"); fprintf(fp,"***********************************************************\n"); fprintf(fp," Fractional coordinates of the final structure \n"); fprintf(fp,"***********************************************************\n"); fprintf(fp,"***********************************************************\n\n"); for (Gc_AN=1; Gc_AN<=atomnum; Gc_AN++){ /* The zero is taken as the origin of the unit cell. */ Cxyz[1] = Gxyz[Gc_AN][1]; Cxyz[2] = Gxyz[Gc_AN][2]; Cxyz[3] = Gxyz[Gc_AN][3]; Cell_Gxyz[Gc_AN][1] = Dot_Product(Cxyz,rtv[1])*0.5/PI; Cell_Gxyz[Gc_AN][2] = Dot_Product(Cxyz,rtv[2])*0.5/PI; Cell_Gxyz[Gc_AN][3] = Dot_Product(Cxyz,rtv[3])*0.5/PI; /* The fractional coordinates are kept within 0 to 1. */ for (i=1; i<=3; i++){ itmp = (int)Cell_Gxyz[Gc_AN][i]; if (1.0<Cell_Gxyz[Gc_AN][i]){ Cell_Gxyz[Gc_AN][i] = fabs(Cell_Gxyz[Gc_AN][i] - (double)itmp); } else if (Cell_Gxyz[Gc_AN][i]<-1.0e-13){ Cell_Gxyz[Gc_AN][i] = fabs(Cell_Gxyz[Gc_AN][i] + (double)(abs(itmp)+1)); } } k = WhatSpecies[Gc_AN]; fprintf(fp,"%6d %4s %18.14f %18.14f %18.14f\n", Gc_AN,SpeName[k], Cell_Gxyz[Gc_AN][1], Cell_Gxyz[Gc_AN][2], Cell_Gxyz[Gc_AN][3]); } fclose(fp); } } }
/* implicit input from trans_variables.h * double **Density_Grid_e * double **dVHart_Grid_e */ void TRAN_Set_Electrode_Grid( MPI_Comm comm1, double *Grid_Origin, /* origin of the grid */ double tv[4][4], /* unit vector of the cell*/ double Left_tv[4][4], /* unit vector left */ double Right_tv[4][4], /* unit vector right */ double gtv[4][4], /* unit vector of the grid point, which is gtv*integer */ int Ngrid1, int Ngrid2, int Ngrid3, /* # of c grid points */ double *Density_Grid /* work */ ) { double offset[4]; double R[4]; int l1[2]; int i,j,k; int side; int spin; int n1,n2,n3; int id; double dx[4],dx_e[4]; int idim=1; double chargeeps=1.0e-12; int myid; MPI_Comm_rank(comm1, &myid); if (myid==Host_ID){ printf("<TRAN_Set_Electrode_Grid>\n"); } if (print_stdout) printf("interpolation start\n"); /* allocation */ if (print_stdout){ printf("%d %d %d %d %d\n",Ngrid1,Ngrid2,Ngrid3,TRAN_grid_bound[0], TRAN_grid_bound[1]); } for (side=0;side<2;side++) { ElectrodeDensity_Grid[side] = (double**)malloc(sizeof(double*)*(SpinP_switch_e[side]+1)); } side=0; l1[0]= 0; l1[1]= TRAN_grid_bound[0]; for (spin=0;spin<=SpinP_switch_e[side];spin++) { ElectrodeDensity_Grid[side][spin]= (double*)malloc(sizeof(double)*Ngrid3*Ngrid2*(l1[1]-l1[0]+1)); } ElectrodedVHart_Grid[side]=(double*)malloc(sizeof(double)*Ngrid3*Ngrid2*(l1[1]-l1[0]+1)); side=1; l1[0]= TRAN_grid_bound[1]; l1[1]= Ngrid1-1; for (spin=0;spin<=SpinP_switch_e[side];spin++) { ElectrodeDensity_Grid[side][spin]= (double*)malloc(sizeof(double)*Ngrid3*Ngrid2*(l1[1]-l1[0]+1)); } ElectrodedVHart_Grid[side]=(double*)malloc(sizeof(double)*Ngrid3*Ngrid2*(l1[1]-l1[0]+1)); /********************************************** left side **********************************************/ side=0; /* find the fist atom of L */ for (i=1;i<=atomnum;i++) { if ( TRAN_region[i]%10==2 && TRAN_Original_Id[i]==1){ id = i; break; } } if (print_stdout){ printf("the first atom of L = %d\n",id); } #if 1 for (i=1;i<=3;i++) { dx_e[i] = Gxyz_e[side][1][i] - Grid_Origin_e[side][i]; } for (i=1;i<=3;i++) { dx[i] = Gxyz[id][i] - Grid_Origin[i]; } if (print_stdout){ printf("shift of the cell(L)=%lf %lf %lf\n", dx[1]-dx_e[1],dx[2]-dx_e[2],dx[3]-dx_e[3]); } for (i=1;i<=3;i++) { offset[i]= -dx[i] + dx_e[i]; } if (print_stdout){ printf("shift of the cell(L)=%lf %lf %lf\n", offset[1], offset[2], offset[3]); } #else for (i=1;i<=3;i++) { offset[i]= 0.0; } if (print_stdout){ printf("shift of the cell(L)=%lf %lf %lf\n", offset[1], offset[2], offset[3]); } #endif l1[0]= 0; l1[1]= TRAN_grid_bound[0]; if (print_stdout){ printf("left boundary %d %d\n",l1[0],l1[1]); printf("interpolation %d %d %d -> %d:%d %d %d\n", Ngrid1_e[side], Ngrid2_e[side], Ngrid3_e[side], l1[0], l1[1],Ngrid2,Ngrid3); } for (spin=0;spin<=SpinP_switch_e[side]; spin++) { TRAN_Interp_ElectrodeDensity_Grid( comm1, offset, Density_Grid_e[side][spin], Ngrid1_e[side], Ngrid2_e[side], Ngrid3_e[side], tv_e[side], gtv_e[side], Density_Grid,Ngrid1,Ngrid2,Ngrid3, l1, tv,gtv); #define grid_idx(i,j,k) ( ((i)-l1[0])*Ngrid2*Ngrid3+(j)*Ngrid3 + (k) ) for (i=l1[0];i<=l1[1];i++){ for (j=0;j<Ngrid2;j++) { for (k=0; k<Ngrid3;k++) { ElectrodeDensity_Grid[side][spin][ grid_idx(i,j,k) ] = Density_Grid[ grid_idx(i,j,k) ]; } } } for (i=0;i<Ngrid3*Ngrid2*(l1[1]-l1[0]+1); i++) { if ( ElectrodeDensity_Grid[side][spin][i] < chargeeps ) { ElectrodeDensity_Grid[side][spin][i] = 0.0; } } #ifdef DEBUG #undef DEBUG #endif #ifdef DEBUG { char name[100];int i; double R[4]; for (i=1;i<=3;i++) R[i]=0.0; sprintf(name,"Density_Grid_el.%d",myid); TRAN_Print_Grid(name, Grid_Origin_e[side], gtv_e[side], Ngrid1_e[side], Ngrid2_e[side],0, Ngrid3_e[side]-1 , R, Density_Grid_e[side][0] ); /* spin=0*/ sprintf(name,"ElectrodeDensity_Gridl.%d",myid); TRAN_Print_Grid(name,Grid_Origin,gtv, l1[1]-l1[0]+1, Ngrid2, 0,Ngrid3-1, R, ElectrodeDensity_Grid[side][0]); /* spin=0 */ } #endif } TRAN_Interp_ElectrodeDensity_Grid(comm1, offset, dVHart_Grid_e[side], Ngrid1_e[side], Ngrid2_e[side], Ngrid3_e[side], tv_e[side], gtv_e[side], Density_Grid,Ngrid1,Ngrid2,Ngrid3,l1, tv,gtv); for (i=l1[0];i<=l1[1];i++){ for (j=0;j<Ngrid2;j++) { for (k=0; k<Ngrid3;k++) { ElectrodedVHart_Grid[side][ grid_idx(i,j,k) ] = Density_Grid[ grid_idx(i,j,k) ]; } } } #ifdef DEBUG { char name[100]; int i; double R[4]; for (i=1;i<=3;i++) R[i]=0.0; sprintf(name,"dVHart_Grid_el.%d", myid); TRAN_Print_Grid(name,Grid_Origin_e[side], gtv_e[side], Ngrid1_e[side],Ngrid2_e[side], 0,Ngrid3_e[side]-1, R, dVHart_Grid_e[side]); sprintf(name,"ElectrodedVHart_Gridl.%d", myid); TRAN_Print_Grid(name,Grid_Origin, gtv, l1[1]-l1[0]+1,Ngrid2,0,Ngrid3-1, R, ElectrodedVHart_Grid[side] ); } #endif /********************************************** right side **********************************************/ side=1; /* find the fist atom of R */ for (i=1;i<=atomnum;i++) { if ( TRAN_region[i]%10== 3 && TRAN_Original_Id[i]==1 ) { id = i; break; } } if (print_stdout){ printf("the first atom of R is =%d\n",id); } l1[0]= TRAN_grid_bound[1]; l1[1]= Ngrid1-1; if (print_stdout){ printf("right boundary %d %d\n",l1[0],l1[1]); } i=1; for (j=1;j<=3;j++) { R[j]=tv[i][j]-1.0*Right_tv[i][j]; } /* Right cell starts at Origin+R * Density at Origin+R = Density_e at Origin_e */ #if 1 for (i=1;i<=3;i++) { dx_e[i]= Gxyz_e[side][1][i] - Grid_Origin_e[side][i]; } for (i=1;i<=3;i++) { dx[i] = Gxyz[id][i] - (Grid_Origin[i]+R[i]); } if (print_stdout){ printf("shift of the cell(R)=%lf %lf %lf\n", dx[1]-dx_e[1],dx[2]-dx_e[2],dx[3]-dx_e[3]); } for (i=1;i<=3;i++) { offset[i]= -dx[i]+dx_e[i]-R[i]+gtv[idim][i]*l1[0]; } if (print_stdout){ printf("shift of the cell(R)=%lf %lf %lf\n", offset[1], offset[2],offset[3]); } #else for (i=1;i<=3;i++) { offset[i]= gtv[3][i]*l3[0]-R[i]; } offset[3]= sqrt( Dot_Product(offset,offset) ); offset[1]= 0.0; offset[2]= 0.0; if (print_stdout){ printf("shift of the cell(R)=%lf %lf %lf\n", offset[1], offset[2],offset[3]); } #endif l1[1] = l1[1]- l1[0]; l1[0] = 0; if (print_stdout){ printf("right boundary (shift) %d %d\n",l1[0],l1[1]); } for (spin=0;spin<= SpinP_switch_e[side]; spin++) { TRAN_Interp_ElectrodeDensity_Grid(comm1, offset, Density_Grid_e[side][spin], Ngrid1_e[side], Ngrid2_e[side], Ngrid3_e[side], tv_e[side], gtv_e[side], Density_Grid,Ngrid1,Ngrid2,Ngrid3,l1, tv,gtv); /* ElectrodeDensity_Grid[2][ Ngrid1*Ngrid2*(l3[1]-l3[0]+1)] */ for (i=l1[0];i<=l1[1];i++){ /* l1[0]=0 */ for (j=0;j<Ngrid2;j++) { for (k=0; k<Ngrid3;k++) { ElectrodeDensity_Grid[side][spin][ grid_idx(i,j,k) ] = Density_Grid[ grid_idx(i,j,k) ]; } } } for (i=0;i<Ngrid3*Ngrid2*(l1[1]-l1[0]+1); i++) { if (ElectrodeDensity_Grid[side][spin][i] < chargeeps ) { ElectrodeDensity_Grid[side][spin][i] =0.0; } } } #ifdef DEBUG { char name[100]; sprintf(name,"Density_Grid_er.%d",myid); TRAN_Print_Grid(name, Grid_Origin_e[side], gtv_e[side], Ngrid1_e[side],Ngrid2_e[side],0,Ngrid3_e[side]-1, R, Density_Grid_e[side][0]); sprintf(name,"ElectrodeDensity_Gridr.%d",myid); TRAN_Print_Grid(name, Grid_Origin,gtv, l1[1]-l1[0]+1,Ngrid2,0, Ngrid3-1, R, ElectrodeDensity_Grid[side][0]); } #endif TRAN_Interp_ElectrodeDensity_Grid(comm1, offset, dVHart_Grid_e[side], Ngrid1_e[side], Ngrid2_e[side], Ngrid3_e[side], tv_e[side], gtv_e[side], Density_Grid,Ngrid1,Ngrid2,Ngrid3, l1,tv,gtv); /* ElectrodeDensity_Grid[2][ Ngrid1*Ngrid2*(l3[1]-l3[0]+1)] */ for (i=l1[0];i<=l1[1];i++){ for (j=0;j<Ngrid2;j++) { for (k=0; k<Ngrid3;k++ ) { ElectrodedVHart_Grid[side][ grid_idx(i,j,k)]= Density_Grid[ grid_idx(i,j,k) ]; } } } #ifdef DEBUG { char name[100]; sprintf(name,"dVHart_Grid_er.%d",myid); TRAN_Print_Grid(name, Grid_Origin_e[side], gtv_e[side], Ngrid1_e[side],Ngrid2_e[side],0,Ngrid3_e[side]-1, R, dVHart_Grid_e[side] ); sprintf(name,"ElectrodedVHart_Gridr.%d",myid); TRAN_Print_Grid(name,Grid_Origin,gtv, l1[1]-l1[0]+1,Ngrid2,0, Ngrid3-1, R, ElectrodedVHart_Grid[side] ); } #endif /********************************************************* FFT: ElectrodedVHart_Grid(x,y,z) -> ElectrodedVHart_Grid(kx,ky,z) *********************************************************/ TRAN_FFT_Electrode_Grid(comm1, -1); if (print_stdout){ printf("interpolation end\n"); } }