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;
	}
}
示例#2
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


}
示例#3
0
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;
}
示例#4
0
文件: esp.c 项目: certik/openmx
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);

}
示例#5
0
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); };
示例#7
0
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);
    }
  }

}
示例#8
0
/* 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");
  }

}