示例#1
0
static int get_third_q_of_triplets_at_q(int bz_address[3][3],
					const int q_index,
					const int bz_map[],
					const int mesh[3],
					const int bzmesh[3])
{
  int i, j, smallest_g, smallest_index, sum_g, delta_g[3];
  int bzgp[KPT_NUM_BZ_SEARCH_SPACE], bz_address_double[3];

  modulo_i3(bz_address[q_index], mesh);
  for (i = 0; i < 3; i++) {
    delta_g[i] = 0;
    for (j = 0; j < 3; j++) {
      delta_g[i] += bz_address[j][i];
    }
    delta_g[i] /= mesh[i];
  }
  
  for (i = 0; i < KPT_NUM_BZ_SEARCH_SPACE; i++) {
    for (j = 0; j < 3; j++) {
      bz_address_double[j] = (bz_address[q_index][j] +
			      kpt_bz_search_space[i][j] * mesh[j]) * 2;
    }
    bzgp[i] = bz_map[kgd_get_grid_point_double_mesh(bz_address_double, bzmesh)];
  }

  for (i = 0; i < KPT_NUM_BZ_SEARCH_SPACE; i++) {
    if (bzgp[i] != -1) {
      goto escape;
    }
  }

 escape:

  smallest_g = 4;
  smallest_index = 0;

  for (i = 0; i < KPT_NUM_BZ_SEARCH_SPACE; i++) {
    if (bzgp[i] > -1) { /* q'' is in BZ */
      sum_g = (abs(delta_g[0] + kpt_bz_search_space[i][0]) +
	       abs(delta_g[1] + kpt_bz_search_space[i][1]) +
	       abs(delta_g[2] + kpt_bz_search_space[i][2]));
      if (sum_g < smallest_g) {
	smallest_index = i;
	smallest_g = sum_g;
      }
    }
  }

  for (i = 0; i < 3; i++) {
    bz_address[q_index][i] += kpt_bz_search_space[smallest_index][i] * mesh[i];
  }

  return smallest_g;
}
示例#2
0
文件: kpoint.c 项目: gcgs1/phonopy
static int get_ir_reciprocal_mesh_distortion(int grid_address[][3],
                                             int ir_mapping_table[],
                                             const int mesh[3],
                                             const int is_shift[3],
                                             const MatINT *rot_reciprocal)
{
  int i, j, k, grid_point_rot, indivisible;
  int address_double[3], address_double_rot[3], divisor[3];

  kgd_get_all_grid_addresses(grid_address, mesh);

  for (i = 0; i < 3; i++) {
    divisor[i] = mesh[(i + 1) % 3] * mesh[(i + 2) % 3];
  }

#pragma omp parallel for private(j, k, grid_point_rot, address_double, address_double_rot)
  for (i = 0; i < mesh[0] * mesh[1] * mesh[2]; i++) {
    kgd_get_grid_address_double_mesh(address_double,
				     grid_address[i],
				     mesh,
				     is_shift);
    for (j = 0; j < 3; j++) {
      address_double[j] *= divisor[j];
    }
    ir_mapping_table[i] = i;
    for (j = 0; j < rot_reciprocal->size; j++) {
      mat_multiply_matrix_vector_i3(address_double_rot,
				    rot_reciprocal->mat[j],
				    address_double);
      for (k = 0; k < 3; k++) {
        indivisible = address_double_rot[k] % divisor[k];
        if (indivisible) {break;}
        address_double_rot[k] /= divisor[k];
        if ((address_double_rot[k] % 2 != 0 && is_shift[k] == 0) ||
            (address_double_rot[k] % 2 == 0 && is_shift[k] == 1)) {
          indivisible = 1;
          break;
        }
      }
      if (indivisible) {continue;}
      grid_point_rot = kgd_get_grid_point_double_mesh(address_double_rot, mesh);
      if (grid_point_rot < ir_mapping_table[i]) {
#ifdef _OPENMP
	ir_mapping_table[i] = grid_point_rot;
#else
	ir_mapping_table[i] = ir_mapping_table[grid_point_rot];
	break;
#endif
      }
    }
  }

  return get_num_ir(ir_mapping_table, mesh);
}
示例#3
0
static int get_BZ_triplets_at_q(int triplets[][3],
				const int grid_point,
				PHPYCONST int bz_grid_address[][3],
				const int bz_map[],
				const int map_triplets[],
				const int num_map_triplets,
				const int mesh[3])
{
  int i, j, k, num_ir;
  int bz_address[3][3], bz_address_double[3], bzmesh[3];
  int *ir_grid_points;

  for (i = 0; i < 3; i++) {
    bzmesh[i] = mesh[i] * 2;
  }

  num_ir = 0;
  ir_grid_points = (int*) malloc(sizeof(int) * num_map_triplets);
  for (i = 0; i < num_map_triplets; i++) {
    if (map_triplets[i] == i) {
      ir_grid_points[num_ir] = i;
      num_ir++;
    }
  }
 
#pragma omp parallel for private(j, k, bz_address, bz_address_double)
  for (i = 0; i < num_ir; i++) {
    for (j = 0; j < 3; j++) {
      bz_address[0][j] = bz_grid_address[grid_point][j];
      bz_address[1][j] = bz_grid_address[ir_grid_points[i]][j];
      bz_address[2][j] = - bz_address[0][j] - bz_address[1][j];
    }
    for (j = 2; j > -1; j--) {
      if (get_third_q_of_triplets_at_q(bz_address,
    				       j,
    				       bz_map,
    				       mesh,
    				       bzmesh) == 0) {
    	break;
      }
    }
    for (j = 0; j < 3; j++) {
      for (k = 0; k < 3; k++) {
	bz_address_double[k] = bz_address[j][k] * 2;
      }
      triplets[i][j] =
	bz_map[kgd_get_grid_point_double_mesh(bz_address_double, bzmesh)];
    }
  }

  free(ir_grid_points);
  
  return num_ir;
}
示例#4
0
文件: spglib.c 项目: nfh/phonopy
/*---------*/
int spg_get_grid_point_from_address(const int grid_address[3],
				    const int mesh[3])
{
  int address_double[3];
  int is_shift[3];

  is_shift[0] = 0;
  is_shift[1] = 0;
  is_shift[2] = 0;
  kgd_get_grid_address_double_mesh(address_double,
				   grid_address,
				   mesh,
				   is_shift);
  return kgd_get_grid_point_double_mesh(address_double, mesh);
}
示例#5
0
文件: kpoint.c 项目: gcgs1/phonopy
static int get_ir_reciprocal_mesh_normal(int grid_address[][3],
                                         int ir_mapping_table[],
                                         const int mesh[3],
                                         const int is_shift[3],
                                         const MatINT *rot_reciprocal)
{
  /* In the following loop, mesh is doubled. */
  /* Even and odd mesh numbers correspond to */
  /* is_shift[i] are 0 or 1, respectively. */
  /* is_shift = [0,0,0] gives Gamma center mesh. */
  /* grid: reducible grid points */
  /* ir_mapping_table: the mapping from each point to ir-point. */

  int i, j, grid_point_rot;
  int address_double[3], address_double_rot[3];

  kgd_get_all_grid_addresses(grid_address, mesh);

#pragma omp parallel for private(j, grid_point_rot, address_double, address_double_rot)
  for (i = 0; i < mesh[0] * mesh[1] * mesh[2]; i++) {
    kgd_get_grid_address_double_mesh(address_double,
				     grid_address[i],
				     mesh,
				     is_shift);
    ir_mapping_table[i] = i;
    for (j = 0; j < rot_reciprocal->size; j++) {
      mat_multiply_matrix_vector_i3(address_double_rot,
				    rot_reciprocal->mat[j],
				    address_double);
      grid_point_rot = kgd_get_grid_point_double_mesh(address_double_rot, mesh);
      if (grid_point_rot < ir_mapping_table[i]) {
#ifdef _OPENMP
	ir_mapping_table[i] = grid_point_rot;
#else
	ir_mapping_table[i] = ir_mapping_table[grid_point_rot];
	break;
#endif
      }
    }
  }

  return get_num_ir(ir_mapping_table, mesh);
}
示例#6
0
文件: kpoint.c 项目: gcgs1/phonopy
void kpt_get_grid_points_by_rotations(int rot_grid_points[],
				      const int address_orig[3],
				      const MatINT * rot_reciprocal,
				      const int mesh[3],
				      const int is_shift[3])
{
  int i;
  int address_double_orig[3], address_double[3];

  for (i = 0; i < 3; i++) {
    address_double_orig[i] = address_orig[i] * 2 + is_shift[i];
  }
  for (i = 0; i < rot_reciprocal->size; i++) {
    mat_multiply_matrix_vector_i3(address_double,
				  rot_reciprocal->mat[i],
				  address_double_orig);
    rot_grid_points[i] = kgd_get_grid_point_double_mesh(address_double, mesh);
  }
}
示例#7
0
文件: kpoint.c 项目: gcgs1/phonopy
/* bz_map[prod(mesh * 2)] */
static int relocate_BZ_grid_address(int bz_grid_address[][3],
				    int bz_map[],
				    SPGCONST int grid_address[][3],
				    const int mesh[3],
				    SPGCONST double rec_lattice[3][3],
				    const int is_shift[3])
{
  double tolerance, min_distance;
  double q_vector[3], distance[KPT_NUM_BZ_SEARCH_SPACE];
  int bzmesh[3], bz_address_double[3];
  int i, j, k, min_index, boundary_num_gp, total_num_gp, bzgp, gp;

  tolerance = get_tolerance_for_BZ_reduction(rec_lattice, mesh);
  for (i = 0; i < 3; i++) {
    bzmesh[i] = mesh[i] * 2;
  }
  for (i = 0; i < bzmesh[0] * bzmesh[1] * bzmesh[2]; i++) {
    bz_map[i] = -1;
  }
  
  boundary_num_gp = 0;
  total_num_gp = mesh[0] * mesh[1] * mesh[2];

  /* Multithreading doesn't work for this loop since gp calculated */
  /* with boundary_num_gp is unstable to store bz_grid_address. */
  for (i = 0; i < total_num_gp; i++) {
    for (j = 0; j < KPT_NUM_BZ_SEARCH_SPACE; j++) {
      for (k = 0; k < 3; k++) {
	q_vector[k] = 
	  ((grid_address[i][k] + bz_search_space[j][k] * mesh[k]) * 2 +
	   is_shift[k]) / ((double)mesh[k]) / 2;
      }
      mat_multiply_matrix_vector_d3(q_vector, rec_lattice, q_vector);
      distance[j] = mat_norm_squared_d3(q_vector);
    }
    min_distance = distance[0];
    min_index = 0;
    for (j = 1; j < KPT_NUM_BZ_SEARCH_SPACE; j++) {
      if (distance[j] < min_distance) {
	min_distance = distance[j];
	min_index = j;
      }
    }

    for (j = 0; j < KPT_NUM_BZ_SEARCH_SPACE; j++) {
      if (distance[j] < min_distance + tolerance) {
	if (j == min_index) {
	  gp = i;
	} else {
	  gp = boundary_num_gp + total_num_gp;
	}
	
	for (k = 0; k < 3; k++) {
	  bz_grid_address[gp][k] = 
	    grid_address[i][k] + bz_search_space[j][k] * mesh[k];
	  bz_address_double[k] = bz_grid_address[gp][k] * 2 + is_shift[k];
	}
	bzgp = kgd_get_grid_point_double_mesh(bz_address_double, bzmesh);
	bz_map[bzgp] = gp;
	if (j != min_index) {
	  boundary_num_gp++;
	}
      }
    }
  }

  return boundary_num_gp + total_num_gp;
}
示例#8
0
static int get_ir_triplets_at_q(int map_triplets[],
				int map_q[],
				int grid_address[][3],
				const int grid_point,
				const int mesh[3],
				const MatINT * rot_reciprocal)
{
  int i, j, num_grid, q_2, num_ir_q, num_ir_triplets, ir_grid_point;
  int mesh_double[3], is_shift[3];
  int address_double0[3], address_double1[3], address_double2[3];
  int *ir_grid_points, *third_q;
  double tolerance;
  double stabilizer_q[1][3];
  MatINT *rot_reciprocal_q;

  tolerance = 0.01 / (mesh[0] + mesh[1] + mesh[2]);
  num_grid = mesh[0] * mesh[1] * mesh[2];

  for (i = 0; i < 3; i++) {
    /* Only consider the gamma-point */
    is_shift[i] = 0;
    mesh_double[i] = mesh[i] * 2;
  }

  /* Search irreducible q-points (map_q) with a stabilizer */
  /* q */  
  grid_point_to_address_double(address_double0, grid_point, mesh, is_shift);
  for (i = 0; i < 3; i++) {
    stabilizer_q[0][i] =
      (double)address_double0[i] / mesh_double[i] - (address_double0[i] > mesh[i]);
  }

  rot_reciprocal_q = kpt_get_point_group_reciprocal_with_q(rot_reciprocal,
							   tolerance,
							   1,
							   stabilizer_q);
  num_ir_q = kpt_get_irreducible_reciprocal_mesh(grid_address,
						 map_q,
						 mesh,
						 is_shift,
						 rot_reciprocal_q);
  mat_free_MatINT(rot_reciprocal_q);

  third_q = (int*) malloc(sizeof(int) * num_ir_q);
  ir_grid_points = (int*) malloc(sizeof(int) * num_ir_q);
  num_ir_q = 0;
  for (i = 0; i < num_grid; i++) {
    if (map_q[i] == i) {
      ir_grid_points[num_ir_q] = i;
      num_ir_q++;
    }
    map_triplets[i] = -1;
  }

#pragma omp parallel for private(j, address_double1, address_double2)
  for (i = 0; i < num_ir_q; i++) {
    grid_point_to_address_double(address_double1,
				 ir_grid_points[i],
				 mesh,
				 is_shift); /* q' */
    for (j = 0; j < 3; j++) { /* q'' */
      address_double2[j] = - address_double0[j] - address_double1[j];
    }
    third_q[i] = kgd_get_grid_point_double_mesh(address_double2, mesh);
  }

  num_ir_triplets = 0;
  for (i = 0; i < num_ir_q; i++) {
    ir_grid_point = ir_grid_points[i];
    q_2 = third_q[i];
    if (map_triplets[map_q[q_2]] > -1) {
      map_triplets[ir_grid_point] = map_q[q_2];
    } else {
      map_triplets[ir_grid_point] = ir_grid_point;
      num_ir_triplets++;
    }
  }

#pragma omp parallel for
  for (i = 0; i < num_grid; i++) {
    map_triplets[i] = map_triplets[map_q[i]];
  }
  
  free(third_q);
  third_q = NULL;
  free(ir_grid_points);
  ir_grid_points = NULL;

  return num_ir_triplets;
}