示例#1
0
lapack_complex_double
phonoc_complex_prod(const lapack_complex_double a,
		    const lapack_complex_double b)
{
  lapack_complex_double c;
  c = lapack_make_complex_double
    (lapack_complex_double_real(a) * lapack_complex_double_real(b) -
     lapack_complex_double_imag(a) * lapack_complex_double_imag(b),
     lapack_complex_double_imag(a) * lapack_complex_double_real(b) +
     lapack_complex_double_real(a) * lapack_complex_double_imag(b));
  return c;
}
示例#2
0
static PyObject * py_phonopy_zheev(PyObject *self, PyObject *args)
{
  PyArrayObject* dynamical_matrix;
  PyArrayObject* eigenvalues;

  if (!PyArg_ParseTuple(args, "OO",
			&dynamical_matrix,
			&eigenvalues)) {
    return NULL;
  }

  const int dimension = (int)dynamical_matrix->dimensions[0];
  npy_cdouble *dynmat = (npy_cdouble*)dynamical_matrix->data;
  double *eigvals = (double*)eigenvalues->data;

  lapack_complex_double *a;
  int i, info;

  a = (lapack_complex_double*) malloc(sizeof(lapack_complex_double) *
				      dimension * dimension);
  for (i = 0; i < dimension * dimension; i++) {
    a[i] = lapack_make_complex_double(dynmat[i].real, dynmat[i].imag);
  }

  info = phonopy_zheev(eigvals, a, dimension, 'L');

  for (i = 0; i < dimension * dimension; i++) {
    dynmat[i].real = lapack_complex_double_real(a[i]);
    dynmat[i].imag = lapack_complex_double_imag(a[i]);
  }

  free(a);
  
  return PyLong_FromLong((long) info);
}
示例#3
0
static double get_fc3_sum
(const int i,
 const int j,
 const int k,
 const int bi,
 const double *freqs0,
 const double *freqs1,
 const double *freqs2,
 const lapack_complex_double *eigvecs0,
 const lapack_complex_double *eigvecs1,
 const lapack_complex_double *eigvecs2,
 const lapack_complex_double *fc3_reciprocal,
 const double *masses,
 const int num_atom,
 const int num_band,
 const double cutoff_frequency)
{
  double fff, sum_real, sum_imag;
  lapack_complex_double fc3_sum;

  if (freqs1[j] > cutoff_frequency && freqs2[k] > cutoff_frequency) {
    fff = freqs0[bi] * freqs1[j] * freqs2[k];
    fc3_sum = fc3_sum_in_reciprocal_to_normal
      (bi, j, k,
       eigvecs0, eigvecs1, eigvecs2,
       fc3_reciprocal,
       masses,
       num_atom);
    sum_real = lapack_complex_double_real(fc3_sum);
    sum_imag = lapack_complex_double_imag(fc3_sum);
    return (sum_real * sum_real + sum_imag * sum_imag) / fff;
  } else {
    return 0;
  }
}
示例#4
0
/* Auxiliary routine: printing a matrix */
void print_matrix( char* desc, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda ) {
        lapack_int i, j;
        printf( "\n %s\n", desc );
        for( i = 0; i < m; i++ ) {
                for( j = 0; j < n; j++ )  
                        printf( " (%6.2f,%6.2f)", lapack_complex_double_real(a[i*lda+j]), lapack_complex_double_imag(a[i*lda+j]) );
                printf( "\n" );
        }
}
示例#5
0
static lapack_complex_double fc3_sum_in_reciprocal_to_normal
(const int bi0,
 const int bi1,
 const int bi2,
 const lapack_complex_double *eigvecs0,
 const lapack_complex_double *eigvecs1,
 const lapack_complex_double *eigvecs2,
 const lapack_complex_double *fc3_reciprocal,
 const double *masses,
 const int num_atom)
{
  int i, j, k, l, m, n, index_l, index_lm, baseIndex;
  double sum_real, sum_imag, mmm, mass_l, mass_lm;
  lapack_complex_double eig_prod, eig_prod1;

  sum_real = 0;
  sum_imag = 0;

  for (l = 0; l < num_atom; l++) {
    mass_l = masses[l];
    index_l = l * num_atom * num_atom * 27;

    for (m = 0; m < num_atom; m++) {
      mass_lm = mass_l * masses[m];
      index_lm = index_l + m * num_atom * 27;

      for (i = 0; i < 3; i++) {
	for (j = 0; j < 3; j++) {
	  eig_prod1 = phonoc_complex_prod
	    (eigvecs0[(l * 3 + i) * num_atom * 3 + bi0],
	     eigvecs1[(m * 3 + j) * num_atom * 3 + bi1]);

	  for (n = 0; n < num_atom; n++) {
	    mmm = 1.0 / sqrt(mass_lm * masses[n]);
	    baseIndex = index_lm + n * 27 + i * 9 + j * 3;

	    for (k = 0; k < 3; k++) {
	      eig_prod = phonoc_complex_prod
		(eig_prod1, eigvecs2[(n * 3 + k) * num_atom * 3 + bi2]);
	      eig_prod = phonoc_complex_prod
		(eig_prod, fc3_reciprocal[baseIndex + k]);
	      sum_real += lapack_complex_double_real(eig_prod) * mmm;
	      sum_imag += lapack_complex_double_imag(eig_prod) * mmm;
	    }
	  }
	}
      }
    }
  }
  return lapack_make_complex_double(sum_real, sum_imag);
}
示例#6
0
static void real_to_reciprocal_elements(lapack_complex_double *fc4_rec_elem,
					const double q[12],
					const double *fc4,
					const Darray *shortest_vectors,
					const Iarray *multiplicity,
					const int *p2s,
					const int *s2p,
					const int pi0,
					const int pi1,
					const int pi2,
					const int pi3)
{
  int i, j, k, l, m, num_satom;
  lapack_complex_double phase_factor, phase_factors[3];
  double fc4_rec_real[81], fc4_rec_imag[81];
  int fc4_elem_address;

  for (i = 0; i < 81; i++) {
    fc4_rec_real[i] = 0;
    fc4_rec_imag[i] = 0;
  }
  
  num_satom = multiplicity->dims[0];

  i = p2s[pi0];

  for (j = 0; j < num_satom; j++) {
    if (s2p[j] != p2s[pi1]) {
      continue;
    }
    phase_factors[0] =
      get_phase_factor(q, shortest_vectors, multiplicity, pi0, j, 1);

    for (k = 0; k < num_satom; k++) {
      if (s2p[k] != p2s[pi2]) {
	continue;
      }
      phase_factors[1] =
	get_phase_factor(q, shortest_vectors, multiplicity, pi0, k, 2);

      for (l = 0; l < num_satom; l++) {
	if (s2p[l] != p2s[pi3]) {
	  continue;
	}
	phase_factors[2] =
	  get_phase_factor(q, shortest_vectors, multiplicity, pi0, l, 3);
	
	fc4_elem_address = (i * 81 * num_satom * num_satom * num_satom +
			    j * 81 * num_satom * num_satom +
			    k * 81 * num_satom +
			    l * 81);

	phase_factor = phonoc_complex_prod(phase_factors[0], phase_factors[1]);
	phase_factor = phonoc_complex_prod(phase_factor, phase_factors[2]);
	for (m = 0; m < 81; m++) {
	  fc4_rec_real[m] +=
	    lapack_complex_double_real(phase_factor) * fc4[fc4_elem_address + m];
	  fc4_rec_imag[m] +=
	    lapack_complex_double_imag(phase_factor) * fc4[fc4_elem_address + m];
	}
      }
    }
  }

  for (i = 0; i < 81; i++) {
    fc4_rec_elem[i] =
      lapack_make_complex_double(fc4_rec_real[i], fc4_rec_imag[i]);
  }
}
示例#7
0
void
get_thm_isotope_scattering_strength(double *collision,
				    const int grid_point,
				    const int *ir_grid_points,
				    const double *mass_variances,
				    const double *frequencies,
				    const lapack_complex_double *eigenvectors,
				    const int num_grid_points,
				    const int *band_indices,
				    const double *occupations, //occupation
				    const int num_band,
				    const int num_band0,
				    const double *integration_weights,
				    const double cutoff_frequency)
{
  int i, j, k, l, m, gp, bb=num_band0*num_band;
  double *e0_r, *e0_i, *f0, *n0;
  double e1_r, e1_i, a, b, f, dist, sum_g_k, n;

  e0_r = (double*)malloc(sizeof(double) * num_band * num_band0);
  e0_i = (double*)malloc(sizeof(double) * num_band * num_band0);
  f0 = (double*)malloc(sizeof(double) * num_band0);
  n0 = (double*)malloc(sizeof(double) *num_band0);

  for (i = 0; i < num_band0; i++) {
    f0[i] = frequencies[grid_point * num_band + band_indices[i]];
    n0[i] =occupations[grid_point *num_band0+band_indices[i]]; 
    for (j = 0; j < num_band; j++) {
      e0_r[i * num_band + j] = lapack_complex_double_real
	(eigenvectors[grid_point * num_band * num_band +
		      j * num_band + band_indices[i]]);
      e0_i[i * num_band + j] = lapack_complex_double_imag
	(eigenvectors[grid_point * num_band * num_band +
		      j * num_band + band_indices[i]]);
    }
  }
  
#pragma omp parallel for
  for (i = 0; i < num_grid_points * num_band0 * num_band; i++) {
    collision[i] = 0;
  }

#pragma omp parallel for private(j, k, l, m, f, gp, e1_r, e1_i, a, b, dist, sum_g_k, n)
  for (i = 0; i < num_grid_points; i++) {
    gp = ir_grid_points[i];
    for (j = 0; j < num_band0; j++) { /* band index0 */
      if (f0[j] < cutoff_frequency) {
	continue;
      }
      for (k = 0; k < num_band; k++) { /* band index */
	sum_g_k = 0;
	n = occupations[gp  *num_band + k];
	f = frequencies[gp * num_band + k];
	if (f < cutoff_frequency) {
	  continue;
	}
	dist = integration_weights[i * bb + j * num_band + k];
	for (l = 0; l < num_band / 3; l++) { /* elements */
	  a = 0;
	  b = 0;
	  for (m = 0; m < 3; m++) {
	    e1_r = lapack_complex_double_real
	      (eigenvectors
	       [gp * num_band * num_band + (l * 3 + m) * num_band + k]);
	    e1_i = lapack_complex_double_imag
	      (eigenvectors
	       [gp * num_band * num_band + (l * 3 + m) * num_band + k]);
	    a += (e0_r[j * num_band + l * 3 + m] * e1_r +
		  e0_i[j * num_band + l * 3 + m] * e1_i);
	    b += (e0_i[j * num_band + l * 3 + m] * e1_r -
		  e0_r[j * num_band + l * 3 + m] * e1_i);
	  }
	  sum_g_k += (a * a + b * b) * mass_variances[l] * dist;
	}
	collision[i * bb + j * num_band + k] += sum_g_k *f0[j] * f * (n0[j] * n + (n0[j] + n) / 2);
      }
      
    }
  }

  free(n0);
  free(f0);
  free(e0_r);
  free(e0_i);
}
示例#8
0
void get_isotope_scattering_strength(double *collision, //collision[temp, band0]
				     const int grid_point,
				     const int *ir_grid_points,
				     const double *mass_variances,
				     const double *frequencies,
				     const lapack_complex_double *eigenvectors,
				     const int *band_indices,
				     const double *occupations, //occupation
				     const int num_grid_points,
				     const int num_band,
				     const int num_band0,
				     const double sigma,
				     const double cutoff_frequency)
{
  int i, j, k, l, grid2, bb=num_band0*num_band;
  double *e0_r, *e0_i, e1_r, e1_i, a, b, f,n, *f0, *n0, sum_g_local, dist;

  e0_r = (double*)malloc(sizeof(double) * num_band * num_band0);
  e0_i = (double*)malloc(sizeof(double) * num_band * num_band0);
  f0 = (double*)malloc(sizeof(double) * num_band0);
  n0 = (double*)malloc(sizeof(double) *num_band0);

  for (i = 0; i < num_band0; i++) {
    f0[i] = frequencies[grid_point * num_band + band_indices[i]];
    n0[i] =occupations[grid_point*num_band+band_indices[i]];
    for (j = 0; j < num_band; j++) {
      e0_r[i * num_band + j] = lapack_complex_double_real
	(eigenvectors[grid_point * num_band * num_band +
		      j * num_band + band_indices[i]]);
      e0_i[i * num_band + j] = lapack_complex_double_imag
	(eigenvectors[grid_point * num_band * num_band +
		      j * num_band + band_indices[i]]);
    }
  }
  
  for (i = 0; i < num_grid_points * num_band0 * num_band; i++) {
    collision[i] = 0;
  }


 #pragma omp parallel for private(i, k, l, f,n, e1_r, e1_i, a, b, sum_g_local, dist, grid2)
    for (j = 0; j < num_grid_points; j++) {
      for (i = 0; i < num_band0; i++) { /* band index0 */
        if (f0[i] < cutoff_frequency) continue;
      grid2 = ir_grid_points[j];
      for (k = 0; k < num_band; k++) { /* band index */
        sum_g_local = 0;
        f = frequencies[grid2 * num_band + k];
        if (f < cutoff_frequency) continue;
        dist = gaussian(f - f0[i], sigma);
        for (l = 0; l < num_band; l++) { /* elements */
          e1_r = lapack_complex_double_real
            (eigenvectors[grid2 * num_band * num_band + l * num_band + k]);
          e1_i = lapack_complex_double_imag
            (eigenvectors[grid2 * num_band * num_band + l * num_band + k]);
          a = e0_r[i * num_band + l] * e1_r + e0_i[i * num_band + l] * e1_i;
          b = e0_i[i * num_band + l] * e1_r - e0_r[i * num_band + l] * e1_i;
          sum_g_local += (a * a + b * b) * mass_variances[l / 3];

        }
        n=occupations[grid2*num_band+k];
        collision[j * bb + i * num_band + k] += sum_g_local * dist * f0[i] * f * (n0[i] * n + (n0[i] + n) / 2);
      }
    }
  }

  free(n0);
  free(f0);
  free(e0_r);
  free(e0_i);
}