Exemple #1
0
static PyObject * get_ir_reciprocal_mesh(PyObject *self, PyObject *args)
{
  double symprec;
  PyArrayObject* grid_address_py;
  PyArrayObject* map;
  PyArrayObject* mesh;
  PyArrayObject* is_shift;
  int is_time_reversal;
  PyArrayObject* lattice;
  PyArrayObject* position;
  PyArrayObject* atom_type;
  if (!PyArg_ParseTuple(args, "OOOOiOOOd",
			&grid_address_py,
			&map,
			&mesh,
			&is_shift,
			&is_time_reversal,
			&lattice,
			&position,
			&atom_type,
			&symprec)) {
    return NULL;
  }

  SPGCONST double (*lat)[3] = (double(*)[3])PyArray_DATA(lattice);
  SPGCONST double (*pos)[3] = (double(*)[3])PyArray_DATA(position);
  const int* types = (int*)PyArray_DATA(atom_type);
  const int* mesh_int = (int*)PyArray_DATA(mesh);
  const int* is_shift_int = (int*)PyArray_DATA(is_shift);
  const int num_atom = PyArray_DIMS(position)[0];
  int (*grid_address)[3] = (int(*)[3])PyArray_DATA(grid_address_py);
  int *map_int = (int*)PyArray_DATA(map);

  /* num_sym has to be larger than num_sym_from_array_size. */
  const int num_ir = spg_get_ir_reciprocal_mesh(grid_address,
						map_int,
						mesh_int,
						is_shift_int,
						is_time_reversal,
						lat,
						pos,
						types,
						num_atom,
						symprec);

  return PyLong_FromLong((long) num_ir);
}
Exemple #2
0
static PyObject * get_ir_reciprocal_mesh(PyObject *self, PyObject *args)
{
  double symprec;
  PyArrayObject* grid_address_py;
  PyArrayObject* map;
  PyArrayObject* mesh;
  PyArrayObject* is_shift;
  int is_time_reversal;
  PyArrayObject* lattice;
  PyArrayObject* position;
  PyArrayObject* atom_type;
  if (!PyArg_ParseTuple(args, "OOOOiOOOd",
			&grid_address_py,
			&map,
			&mesh,
			&is_shift,
			&is_time_reversal,
			&lattice,
			&position,
			&atom_type,
			&symprec))
    return NULL;

  SPGCONST double (*lat)[3] = (double(*)[3])lattice->data;
  SPGCONST double (*pos)[3] = (double(*)[3])position->data;
  const int* types = (int*)atom_type->data;
  const int* mesh_int = (int*)mesh->data;
  const int* is_shift_int = (int*)is_shift->data;
  const int num_atom = position->dimensions[0];
  int (*grid_address)[3] = (int(*)[3])grid_address_py->data;
  int *map_int = (int*)map->data;

  /* num_sym has to be larger than num_sym_from_array_size. */
  const int num_ir = spg_get_ir_reciprocal_mesh(grid_address,
						map_int,
						mesh_int,
						is_shift_int,
						is_time_reversal,
						lat,
						pos,
						types,
						num_atom,
						symprec);
  
  return PyInt_FromLong((long) num_ir);
}
Exemple #3
0
static int test_spg_get_ir_reciprocal_mesh(void)
{
  double lattice[3][3] = {{4, 0, 0}, {0, 4, 0}, {0, 0, 3}};
  double position[][3] =
    {
      {0, 0, 0},
      {0.5, 0.5, 0.5},
      {0.3, 0.3, 0},
      {0.7, 0.7, 0},
      {0.2, 0.8, 0.5},
      {0.8, 0.2, 0.5},
    };
  int types[] = {1, 1, 2, 2, 2, 2};
  int num_atom = 6;
  int m = 40;
  int mesh[] = {m, m, m};
  int is_shift[] = {1, 1, 1};
  int grid_address[m * m * m][3];
  int grid_mapping_table[m * m * m];

  printf("*** spg_get_ir_reciprocal_mesh of Rutile structure ***:\n");

  int num_ir = spg_get_ir_reciprocal_mesh(grid_address,
					  grid_mapping_table,
					  mesh,
					  is_shift,
					  1,
					  lattice,
					  position,
					  types,
					  num_atom,
					  1e-5);

  if (num_ir) {
    printf("Number of irreducible k-points of Rutile with\n");
    printf("40x40x40 Monkhorst-Pack mesh is %d (4200).\n", num_ir);
    return 0;
  } else {
    return 1;
  }
}
Exemple #4
0
static PyObject * get_ir_reciprocal_mesh(PyObject *self, PyObject *args)
{
  int i, j;
  double symprec;
  PyArrayObject* grid_point;
  PyArrayObject* map;
  PyArrayObject* mesh;
  PyArrayObject* is_shift;
  int is_time_reversal;
  PyArrayObject* lattice;
  PyArrayObject* position;
  PyArrayObject* atom_type;
  if (!PyArg_ParseTuple(args, "OOOOiOOOd",
			&grid_point,
			&map,
			&mesh,
			&is_shift,
			&is_time_reversal,
			&lattice,
			&position,
			&atom_type,
			&symprec))
    return NULL;

  SPGCONST double (*lat)[3] = (double(*)[3])lattice->data;
  SPGCONST double (*pos)[3] = (double(*)[3])position->data;
  const int num_grid = grid_point->dimensions[0];
  const long* types_long = (long*)atom_type->data;
  const long* mesh_long = (long*)mesh->data;
  const long* is_shift_long = (long*)is_shift->data;
  const int num_atom = position->dimensions[0];
  long *grid_long = (long*)grid_point->data;
  int grid_int[num_grid][3];
  long *map_long = (long*)map->data;
  int map_int[num_grid];
  
  int types[num_atom];
  for (i = 0; i < num_atom; i++) {
    types[i] = (int)types_long[i];
  }

  int mesh_int[3];
  int is_shift_int[3];
  for (i = 0; i < 3; i++) {
    mesh_int[i] = (int) mesh_long[i];
    is_shift_int[i] = (int) is_shift_long[i];
  }  

  /* Check memory space */
  if (mesh_int[0]*mesh_int[1]*mesh_int[2] > num_grid) {
    return NULL;
  }

  /* num_sym has to be larger than num_sym_from_array_size. */
  const int num_ir = spg_get_ir_reciprocal_mesh(grid_int,
						map_int,
						mesh_int,
						is_shift_int,
						is_time_reversal,
						lat,
						pos,
						types,
						num_atom,
						symprec);
  
  for (i = 0; i < mesh_int[0] * mesh_int[1] * mesh_int[2]; i++) {
    for (j = 0; j < 3; j++)
      grid_long[ i*3 + j ] = (long) grid_int[i][j];
    map_long[i] = (long) map_int[i];
  }
  
  return PyInt_FromLong((long) num_ir);
}
Exemple #5
0
/* (http://phonopy.sf.net/) */
static void test_tetrahedron_method(void)
{
  printf("*** Example of tetrahedron method of NaCl to calculate DOS ***:\n");
  printf("Read data from frequency.dat and write DOS to dos.dat.\n");

  int i, j, k, l, q, r;

  /* NaCl 20x20x20 mesh */
  double lattice[3][3] = {
    {0.000000000000000, 2.845150738087836, 2.845150738087836},
    {2.845150738087836, 0.000000000000000, 2.845150738087836},
    {2.845150738087836, 2.845150738087836, 0.000000000000000}
  };
  double position[][3] =
    {{0, 0, 0},
     {0.5, 0.5, 0.5}};
  int types[] = {1, 2};
  int num_atom = 2;
  int m = 20;
  int mesh[] = {m, m, m};
  int num_gp = mesh[0] * mesh[1] * mesh[2];
  int is_shift[] = {0, 0, 0};
  int grid_address[num_gp][3];
  int grid_mapping_table[num_gp];
  int weights[num_gp];
  int num_ir = spg_get_ir_reciprocal_mesh(grid_address,
					  grid_mapping_table,
					  mesh,
					  is_shift,
					  1,
					  lattice,
					  position,
					  types,
					  num_atom,
					  1e-5);
  int ir_gp[num_ir];
  int ir_weights[num_ir];
  int gp_ir_index[num_gp];
  int relative_grid_address[24][4][3];
  double rec_lat[3][3];
  FILE *fp;
  char * line = NULL;
  size_t len = 0;
  ssize_t read;
  double frequency[num_ir * num_atom * 3];
  double max_f, min_f;
  double t_omegas[24][4];
  int g_addr[3];
  int gp;
  int num_freqs = 201;
  double dos[num_freqs];
  double integral_dos[num_freqs];
  double omegas[num_freqs];
  double iw;
  
  for (i = 0; i < num_gp; i++) {
    weights[i] = 0;
  }

  for (i = 0; i < num_gp; i++) {
    weights[grid_mapping_table[i]]++;
  }

  j = 0;
  for (i = 0; i < num_gp; i++) {
    if (weights[i] != 0) {
      ir_gp[j] = i;
      ir_weights[j] = weights[i];
      gp_ir_index[i] = j;
      j++;
    } else {
      gp_ir_index[i] = gp_ir_index[grid_mapping_table[i]];
    }
  }

  printf("Number of irreducible k-points: %d\n", num_ir);
  
  mat_inverse_matrix_d3(rec_lat, lattice, 1e-5);
  thm_get_relative_grid_address(relative_grid_address, rec_lat);

  /* for (i = 0; i < 24; i++) { */
  /*   for (j = 0; j < 4; j++) { */
  /*     printf("[%2d %2d %2d] ", */
  /* 	     relative_grid_address[i][j][0], */
  /* 	     relative_grid_address[i][j][1], */
  /* 	     relative_grid_address[i][j][2]); */
  /*   } */
  /*   printf("\n"); */
  /* } */

  fp = fopen("frequency.dat", "r");

  for (i = 0; i < num_ir * num_atom * 3; i++) {
    read = getline(&line, &len, fp);
    if (read == -1) {
      break;
    }
    frequency[i] = strtod(line, NULL);
  }

  fclose(fp);

  max_f = frequency[0];
  min_f = frequency[0];
  for (i = 0; i < num_ir * num_atom * 3; i++) {
    if (max_f < frequency[i]) {
      max_f = frequency[i];
    }
    if (min_f > frequency[i]) {
      min_f = frequency[i];
    }
  }
  
  printf("Number of frequencies: %d\n", i);
  

#pragma omp parallel for private(j, k, l, q, r, g_addr, gp, t_omegas, iw)
  for (i = 0; i < num_freqs; i++) {
    dos[i] = 0;
    integral_dos[i] = 0;
    omegas[i] = min_f + (max_f - min_f) / (num_freqs - 1) * i;
    for (j = 0; j < num_ir;  j++) {
      for (k = 0; k < num_atom * 3; k++) {
	for (l = 0; l < 24; l++) {
	  for (q = 0; q < 4; q++) {
	    for (r = 0; r < 3; r++) {
	      g_addr[r] = grid_address[ir_gp[j]][r] +
		relative_grid_address[l][q][r];
	    }
	    gp = spg_get_grid_point_from_address(g_addr, mesh);
	    t_omegas[l][q] = frequency[gp_ir_index[gp] * num_atom * 3 + k];
	  }
	}
	iw = thm_get_integration_weight(omegas[i], t_omegas, 'J');
	dos[i] += iw * ir_weights[j];
	iw = thm_get_integration_weight(omegas[i], t_omegas, 'I');
	integral_dos[i] += iw * ir_weights[j];
      }
    }
  }

  fp = fopen("dos.dat", "w");

  for (i = 0; i < num_freqs; i++) {
    fprintf(fp, "%f %f\n", omegas[i], dos[i] / num_gp);
  }

  fprintf(fp, "\n\n");
  
  for (i = 0; i < num_freqs; i++) {
    fprintf(fp, "%f %f\n", omegas[i], integral_dos[i] / num_gp);
  }
    
  fclose(fp);
}