Пример #1
0
static MatINT *get_point_group_reciprocal_with_q(const MatINT * rot_reciprocal,
						 const double symprec,
						 const int num_q,
						 SPGCONST double qpoints[][3])
{
  int i, j, k, l, is_all_ok, num_rot;
  int *ir_rot;
  double q_rot[3], diff[3];
  MatINT * rot_reciprocal_q;

  is_all_ok = 0;
  num_rot = 0;
  ir_rot = (int*)malloc(sizeof(int) * rot_reciprocal->size);
  for (i = 0; i < rot_reciprocal->size; i++) {
    ir_rot[i] = -1;
  }
  for (i = 0; i < rot_reciprocal->size; i++) {
    for (j = 0; j < num_q; j++) {
      is_all_ok = 0;
      mat_multiply_matrix_vector_id3(q_rot,
				     rot_reciprocal->mat[i],
				     qpoints[j]);

      for (k = 0; k < num_q; k++) {
	for (l = 0; l < 3; l++) {
	  diff[l] = q_rot[l] - qpoints[k][l];
	  diff[l] -= mat_Nint(diff[l]);
	}
	
	if (mat_Dabs(diff[0]) < symprec && 
	    mat_Dabs(diff[1]) < symprec &&
	    mat_Dabs(diff[2]) < symprec) {
	  is_all_ok = 1;
	  break;
	}
      }
      
      if (! is_all_ok) {
	break;
      }
    }

    if (is_all_ok) {
      ir_rot[num_rot] = i;
      num_rot++;
    }
  }

  rot_reciprocal_q = mat_alloc_MatINT(num_rot);
  for (i = 0; i < num_rot; i++) {
    mat_copy_matrix_i3(rot_reciprocal_q->mat[i],
		       rot_reciprocal->mat[ir_rot[i]]);  
  }

  free(ir_rot);

  return rot_reciprocal_q;
}
Пример #2
0
static int is_identity_metric(SPGCONST double metric_rotated[3][3],
			      SPGCONST double metric_orig[3][3],
			      const double symprec,
			      const double angle_symprec)
{
  int i, j, k;
  int elem_sets[3][2] = {{0, 1},
			 {0, 2},
			 {1, 2}};
  double cos1, cos2, x, length_ave2, sin_dtheta2;
  double length_orig[3], length_rot[3];

  for (i = 0; i < 3; i++) {
    length_orig[i] = sqrt(metric_orig[i][i]);
    length_rot[i] = sqrt(metric_rotated[i][i]);
    if (mat_Dabs(length_orig[i] - length_rot[i]) > symprec) {
      goto fail;
    }
  }

  for (i = 0; i < 3; i++) {
    j = elem_sets[i][0];
    k = elem_sets[i][1];
    if (angle_symprec > 0) {
      if (mat_Dabs(get_angle(metric_orig, j, k) -
		   get_angle(metric_rotated, j, k)) > angle_symprec) {
	goto fail;
      }
    } else {
      /* dtheta = arccos(cos(theta1) - arccos(cos(theta2))) */
      /*        = arccos(c1) - arccos(c2) */
      /*        = arccos(c1c2 + sqrt((1-c1^2)(1-c2^2))) */
      /* sin(dtheta) = sin(arccos(x)) = sqrt(1 - x^2) */
      cos1 = metric_orig[j][k] / length_orig[j] / length_orig[k];
      cos2 = metric_rotated[j][k] / length_rot[j] / length_rot[k];
      x = cos1 * cos2 + sqrt(1 - cos1 * cos1) * sqrt(1 - cos2 * cos2);
      sin_dtheta2 = 1 - x * x;
      length_ave2 = ((length_orig[j] + length_rot[j]) *
		     (length_orig[k] + length_rot[k])) / 4;
      if (sin_dtheta2 > 1e-12) {
	if (sin_dtheta2 * length_ave2 > symprec * symprec) {
	  goto fail;
	}
      }
    }
  }

  return 1;

 fail:
  return 0;
}
Пример #3
0
/* }} */
int mat_inverse_matrix_d3(double m[3][3],
			  SPGCONST double a[3][3],
			  const double precision)
{
  double det;
  double c[3][3];
  det = mat_get_determinant_d3(a);
  if (mat_Dabs(det) < precision) {
    warning_print("spglib: No inverse matrix (det=%f)\n", det);
    debug_print("No inverse matrix\n");
    return 0;
  }

  c[0][0] = (a[1][1] * a[2][2] - a[1][2] * a[2][1]) / det;
  c[1][0] = (a[1][2] * a[2][0] - a[1][0] * a[2][2]) / det;
  c[2][0] = (a[1][0] * a[2][1] - a[1][1] * a[2][0]) / det;
  c[0][1] = (a[2][1] * a[0][2] - a[2][2] * a[0][1]) / det;
  c[1][1] = (a[2][2] * a[0][0] - a[2][0] * a[0][2]) / det;
  c[2][1] = (a[2][0] * a[0][1] - a[2][1] * a[0][0]) / det;
  c[0][2] = (a[0][1] * a[1][2] - a[0][2] * a[1][1]) / det;
  c[1][2] = (a[0][2] * a[1][0] - a[0][0] * a[1][2]) / det;
  c[2][2] = (a[0][0] * a[1][1] - a[0][1] * a[1][0]) / det;
  mat_copy_matrix_d3(m, c);
  return 1;
}
Пример #4
0
static PointSymmetry
get_point_group_reciprocal_with_q(SPGCONST PointSymmetry * pointgroup,
				  const double symprec,
				  const int num_q,
				  SPGCONST double qpoints[][3])
{
  int i, j, k, l, is_all_ok=0, num_ptq = 0;
  double q_rot[3], diff[3];
  PointSymmetry pointgroup_q;

  for (i = 0; i < pointgroup->size; i++) {
    for (j = 0; j < num_q; j++) {
      is_all_ok = 0;
      mat_multiply_matrix_vector_id3(q_rot,
				     pointgroup->rot[i],
				     qpoints[j]);

      for (k = 0; k < num_q; k++) {
	for (l = 0; l < 3; l++) {
	  diff[l] = q_rot[l] - qpoints[k][l];
	  diff[l] -= mat_Nint(diff[l]);
	}
	
	if (mat_Dabs(diff[0]) < symprec && 
	    mat_Dabs(diff[1]) < symprec &&
	    mat_Dabs(diff[2]) < symprec) {
	  is_all_ok = 1;
	  break;
	}
      }
      
      if (! is_all_ok) {
	break;
      }
    }

    if (is_all_ok) {
      mat_copy_matrix_i3(pointgroup_q.rot[num_ptq], pointgroup->rot[i]);
      num_ptq++;
    }
  }
  pointgroup_q.size = num_ptq;

  return pointgroup_q;
}
Пример #5
0
/* Reference can be found in International table A. */
static int get_Delaunay_reduction( double red_lattice[3][3], 
				   SPGCONST double lattice[3][3],
				   const double symprec )
{
  int i, j;
  double volume;
  double basis[4][3];

  get_exteneded_basis(basis, lattice);

  while (1) {
    if (get_Delaunay_reduction_basis(basis, symprec)) {
      break;
    }
  }

  get_Delaunay_shortest_vectors( basis, symprec );

  for ( i = 0; i < 3; i++ ) {
    for ( j = 0; j < 3; j++ ) {
      red_lattice[i][j] = basis[j][i];
    }
  }

  volume = mat_get_determinant_d3( red_lattice );
  if ( mat_Dabs( volume ) < symprec ) {
    warning_print("spglib: Minimum lattice has no volume (line %d, %s).\n", __LINE__, __FILE__);
    goto err;
  }

  if ( volume  < 0 ) {
    /* Flip axes */
    for (i = 0; i < 3; i++) {
      for ( j = 0; j < 3; j++ ) {
	red_lattice[i][j] = -red_lattice[i][j];
      }
    }
  }


#ifdef DEBUG
  debug_print("Delaunay reduction:\n");
  debug_print_matrix_d3(red_lattice);
  double metric[3][3];
  mat_get_metric( metric, red_lattice );
  debug_print("It's metric tensor.\n");
  debug_print_matrix_d3( metric );
#endif

  return 1;

 err:
  return 0;
}
Пример #6
0
int mat_is_int_matrix(SPGCONST double mat[3][3], const double symprec)
{
  int i,j ;
  for ( i = 0; i < 3; i++ ) {
    for ( j = 0; j < 3; j++ ) {
      if ( mat_Dabs( mat_Nint( mat[i][j] ) - mat[i][j] ) > symprec ) {
	return 0;
      }
    }
  }
  return 1;
}
Пример #7
0
/* Return 0 if failed */
static int get_Delaunay_reduction(double red_lattice[3][3], 
				  SPGCONST double lattice[3][3],
				  const double symprec)
{
  int i, j;
  double volume, sum;
  double basis[4][3];

  get_exteneded_basis(basis, lattice);
  
  sum = 0;
  for (i = 0; i < 4; i++) {
    for (j = 0; j < 3; j++) {
      sum += basis[i][j] * basis[i][j];
    }
  }

  while (1) {
    if (get_Delaunay_reduction_basis(basis, symprec)) {
      break;
    }
  }

  get_Delaunay_shortest_vectors(basis, symprec);

  for (i = 0; i < 3; i++) {
    for (j = 0; j < 3; j++) {
      red_lattice[i][j] = basis[j][i];
    }
  }

  volume = mat_get_determinant_d3(red_lattice);
  if (mat_Dabs(volume) < symprec) {
    warning_print("spglib: Minimum lattice has no volume (line %d, %s).\n", __LINE__, __FILE__);
    goto err;
  }

  if (volume  < 0) {
    /* Flip axes */
    for (i = 0; i < 3; i++) {
      for (j = 0; j < 3; j++) {
	red_lattice[i][j] = -red_lattice[i][j];
      }
    }
  }

  return 1;

 err:
  return 0;
}
Пример #8
0
int mat_check_identity_matrix_d3(SPGCONST double a[3][3],
				 SPGCONST double b[3][3],
				 const double symprec)
{
  if ( mat_Dabs( a[0][0] - b[0][0] ) > symprec ||
       mat_Dabs( a[0][1] - b[0][1] ) > symprec ||
       mat_Dabs( a[0][2] - b[0][2] ) > symprec ||
       mat_Dabs( a[1][0] - b[1][0] ) > symprec ||
       mat_Dabs( a[1][1] - b[1][1] ) > symprec ||
       mat_Dabs( a[1][2] - b[1][2] ) > symprec ||
       mat_Dabs( a[2][0] - b[2][0] ) > symprec ||
       mat_Dabs( a[2][1] - b[2][1] ) > symprec ||
       mat_Dabs( a[2][2] - b[2][2] ) > symprec ) {
    return 0;
  }
  else {
    return 1;
  }
}
Пример #9
0
static void get_Delaunay_shortest_vectors( double basis[4][3],
					   const double symprec )
{
  int i, j;
  double tmpmat[3][3], b[7][3], tmpvec[3];
  
  /* Search in the set {b1, b2, b3, b4, b1+b2, b2+b3, b3+b1} */
  for ( i = 0; i < 4; i++ ) {
    for ( j = 0; j < 3; j++ ) {
      b[i][j] = basis[i][j];
    }
  }
  
  for ( i = 0; i < 3; i++ ) {
    b[4][i] = basis[0][i] + basis[1][i];
  }
  for ( i = 0; i < 3; i++ ) {
    b[5][i] = basis[1][i] + basis[2][i];
  }
  for ( i = 0; i < 3; i++ ) {
    b[6][i] = basis[2][i] + basis[0][i];
  }
  
  /* Bubble sort */
  for ( i = 0; i < 6; i++ ) {
    for ( j = 0; j < 6; j++ ) {
      if ( mat_norm_squared_d3( b[j] ) > mat_norm_squared_d3( b[j+1] ) ) {
	mat_copy_vector_d3( tmpvec, b[j] );
	mat_copy_vector_d3( b[j], b[j+1] );
	mat_copy_vector_d3( b[j+1], tmpvec );
      }
    }
  }

  for ( i = 2; i < 7; i++ ) {
    for ( j = 0; j < 3; j++ ) {
      tmpmat[j][0] = b[0][j];
      tmpmat[j][1] = b[1][j];
      tmpmat[j][2] = b[i][j];
    }
    if ( mat_Dabs( mat_get_determinant_d3( tmpmat ) ) > symprec ) {
      for ( j = 0; j < 3; j++ ) {
	basis[0][j] = b[0][j];
	basis[1][j] = b[1][j];
	basis[2][j] = b[i][j];
      }
      break;
    }
  }
}
Пример #10
0
static PointSymmetry
transform_pointsymmetry(SPGCONST PointSymmetry * lat_sym_orig,
			SPGCONST double new_lattice[3][3],
			SPGCONST double original_lattice[3][3])
{
  int i, size;
  double trans_mat[3][3], inv_mat[3][3], drot[3][3];
  PointSymmetry lat_sym_new;

  lat_sym_new.size = 0;

  mat_inverse_matrix_d3(inv_mat, original_lattice, 0);
  mat_multiply_matrix_d3(trans_mat, inv_mat, new_lattice);

  size = 0;
  for (i = 0; i < lat_sym_orig->size; i++) {
    mat_cast_matrix_3i_to_3d(drot, lat_sym_orig->rot[i]);
    mat_get_similar_matrix_d3(drot, drot, trans_mat, 0);

    /* new_lattice may have lower point symmetry than original_lattice.*/
    /* The operations that have non-integer elements are not counted. */
    if (mat_is_int_matrix(drot, mat_Dabs(mat_get_determinant_d3(trans_mat)) / 10)) {
      mat_cast_matrix_3d_to_3i(lat_sym_new.rot[size], drot);
      if (abs(mat_get_determinant_i3(lat_sym_new.rot[size])) != 1) {
	warning_print("spglib: A point symmetry operation is not unimodular.");
	warning_print("(line %d, %s).\n", __LINE__, __FILE__);
	goto err;
      }
      size++;
    }
  }

#ifdef SPGWARNING
  if (! (lat_sym_orig->size == size)) {
    warning_print("spglib: Some of point symmetry operations were dropped.");
    warning_print("(line %d, %s).\n", __LINE__, __FILE__);
  }
#endif

  lat_sym_new.size = size;
  return lat_sym_new;

 err:
  return lat_sym_new;
}
Пример #11
0
static void set_positions(Cell * trimmed_cell,
                          const VecDBL * position,
                          const int * mapping_table,
                          const int * overlap_table)
{
  int i, j, k, l, multi;

  for (i = 0; i < trimmed_cell->size; i++) {
    for (j = 0; j < 3; j++) {
      trimmed_cell->position[i][j] = 0;
    }
  }

  /* Positions of overlapped atoms are averaged. */
  for (i = 0; i < position->size; i++) {
    j = mapping_table[i];
    k = overlap_table[i];
    for (l = 0; l < 3; l++) {
      /* boundary treatment */
      /* One is at right and one is at left or vice versa. */
      if (mat_Dabs(position->vec[k][l] - position->vec[i][l]) > 0.5) {
        if (position->vec[i][l] < position->vec[k][l]) {
          trimmed_cell->position[j][l] += position->vec[i][l] + 1;
        } else {
          trimmed_cell->position[j][l] += position->vec[i][l] - 1;
        }
      } else {
        trimmed_cell->position[j][l] += position->vec[i][l];
      }
    }

  }

  multi = position->size / trimmed_cell->size;
  for (i = 0; i < trimmed_cell->size; i++) {
    for (j = 0; j < 3; j++) {
      trimmed_cell->position[i][j] /= multi;
      trimmed_cell->position[i][j] = mat_Dmod1(trimmed_cell->position[i][j]);
    }
  }
}
Пример #12
0
/* }} */
int mat_inverse_matrix_d3(double m[3][3], const double a[3][3], const double precision)
{
    double det;
    double c[3][3];
    det = mat_get_determinant_d3(a);
    if (mat_Dabs(det) < precision) {
        fprintf(stderr, "spglib: No inverse matrix\n");
        return 0;
    }

    c[0][0] = (a[1][1] * a[2][2] - a[1][2] * a[2][1]) / det;
    c[1][0] = (a[1][2] * a[2][0] - a[1][0] * a[2][2]) / det;
    c[2][0] = (a[1][0] * a[2][1] - a[1][1] * a[2][0]) / det;
    c[0][1] = (a[2][1] * a[0][2] - a[2][2] * a[0][1]) / det;
    c[1][1] = (a[2][2] * a[0][0] - a[2][0] * a[0][2]) / det;
    c[2][1] = (a[2][0] * a[0][1] - a[2][1] * a[0][0]) / det;
    c[0][2] = (a[0][1] * a[1][2] - a[0][2] * a[1][1]) / det;
    c[1][2] = (a[0][2] * a[1][0] - a[0][0] * a[1][2]) / det;
    c[2][2] = (a[0][0] * a[1][1] - a[0][1] * a[1][0]) / det;
    mat_copy_matrix_d3(m, c);
    return 1;
}
Пример #13
0
static Symmetry * get_collinear_operations(SPGCONST Symmetry *sym_nonspin,
					   SPGCONST Cell *cell,
					   const double spins[],
					   const double symprec)
{
  Symmetry *symmetry;
  int i, j, k, sign, is_found, num_sym;
  double pos[3];
  MatINT * rot;
  VecDBL * trans;

  rot = mat_alloc_MatINT(sym_nonspin->size);
  trans = mat_alloc_VecDBL(sym_nonspin->size);
  num_sym = 0;
  
  for (i = 0; i < sym_nonspin->size; i++) {
    sign = 0; /* Set sign as undetermined */
    is_found = 1;
    for (j = 0; j < cell->size; j++) {
      mat_multiply_matrix_vector_id3(pos, sym_nonspin->rot[i], cell->position[j]);
      for (k = 0; k < 3; k++) {
	pos[k] += sym_nonspin->trans[i][k];
      }
      for (k = 0; k < cell->size; k++) {
	if (cel_is_overlap(cell->position[k],
			   pos,
			   cell->lattice,
			   symprec)) {
	  if (sign == 0) {
	    if (mat_Dabs(spins[j] - spins[k]) < symprec) {
	      sign = 1;
	      break;
	    }
	    if (mat_Dabs(spins[j] + spins[k]) < symprec) {
	      sign = -1;
	      break;
	    }
	    is_found = 0;
	    break;
	  } else {
	    if (mat_Dabs(spins[j] - spins[k] * sign) < symprec) {
	      break;
	    } else {
	      is_found = 0;
	      break;
	    }
	  }
	}
      }
      if (! is_found) {
	break;
      }
    }
    if (is_found) {
      mat_copy_matrix_i3(rot->mat[num_sym], sym_nonspin->rot[i]);
      mat_copy_vector_d3(trans->vec[num_sym], sym_nonspin->trans[i]);
      num_sym++;
    }
  }

  symmetry = sym_alloc_symmetry(num_sym);
  for (i = 0; i < num_sym; i++) {
    mat_copy_matrix_i3(symmetry->rot[i], rot->mat[ i ]);
    mat_copy_vector_d3(symmetry->trans[i], trans->vec[ i ]);
  }

  mat_free_MatINT(rot);
  mat_free_VecDBL(trans);

  return symmetry;
}
Пример #14
0
/* Return 0 if failed */
static int get_primitive_lattice_vectors(double prim_lattice[3][3],
					 const VecDBL * vectors,
					 SPGCONST Cell * cell,
					 const double symprec)
{
  int i, j, k, size;
  double initial_volume, volume;
  double relative_lattice[3][3], min_vectors[3][3], tmp_lattice[3][3];
  double inv_mat_dbl[3][3];
  int inv_mat_int[3][3];

  debug_print("get_primitive_lattice_vectors:\n");

  size = vectors->size;
  initial_volume = mat_Dabs(mat_get_determinant_d3(cell->lattice));

  /* check volumes of all possible lattices, find smallest volume */
  for (i = 0; i < size; i++) {
    for (j = i + 1; j < size; j++) {
      for (k = j + 1; k < size; k++) {
	mat_multiply_matrix_vector_d3(tmp_lattice[0],
				      cell->lattice,
				      vectors->vec[i]);
	mat_multiply_matrix_vector_d3(tmp_lattice[1],
				      cell->lattice,
				      vectors->vec[j]);
	mat_multiply_matrix_vector_d3(tmp_lattice[2],
				      cell->lattice,
				      vectors->vec[k]);
	volume = mat_Dabs(mat_get_determinant_d3(tmp_lattice));
	if (volume > symprec) {
	  if (mat_Nint(initial_volume / volume) == size-2) {
	    mat_copy_vector_d3(min_vectors[0], vectors->vec[i]);
	    mat_copy_vector_d3(min_vectors[1], vectors->vec[j]);
	    mat_copy_vector_d3(min_vectors[2], vectors->vec[k]);
	    goto ret;
	  }
	}
      }
    }
  }

  /* Not found */
  warning_print("spglib: Primitive lattice vectors cound not be found ");
  warning_print("(line %d, %s).\n", __LINE__, __FILE__);
  return 0;

  /* Found */
 ret:
  for (i = 0; i < 3; i++) {
    for (j = 0; j < 3; j++) {
      relative_lattice[j][i] = min_vectors[i][j];
    }
  }

  mat_inverse_matrix_d3(inv_mat_dbl, relative_lattice, 0);
  mat_cast_matrix_3d_to_3i(inv_mat_int, inv_mat_dbl);
  if (abs(mat_get_determinant_i3(inv_mat_int)) == size-2) {
    mat_cast_matrix_3i_to_3d(inv_mat_dbl, inv_mat_int);
    mat_inverse_matrix_d3(relative_lattice, inv_mat_dbl, 0);
  } else {
    warning_print("spglib: Primitive lattice cleaning is incomplete ");
    warning_print("(line %d, %s).\n", __LINE__, __FILE__);
  }
  mat_multiply_matrix_d3(prim_lattice, cell->lattice, relative_lattice);

  return 1;  
}
Пример #15
0
static int get_ir_kpoints(int map[],
			  SPGCONST double kpoints[][3],
			  const int num_kpoint,
			  SPGCONST PointSymmetry * point_symmetry,
			  const double symprec)
{
  int i, j, k, l, num_ir_kpoint = 0, is_found;
  int *ir_map;
  double kpt_rot[3], diff[3];

  ir_map = (int*)malloc(num_kpoint*sizeof(int));

  for (i = 0; i < num_kpoint; i++) {

    map[i] = i;

    is_found = 1;

    for (j = 0; j < point_symmetry->size; j++) {
      mat_multiply_matrix_vector_id3(kpt_rot, point_symmetry->rot[j], kpoints[i]);

      for (k = 0; k < 3; k++) {
	diff[k] = kpt_rot[k] - kpoints[i][k];
	diff[k] = diff[k] - mat_Nint(diff[k]);
      }

      if (mat_Dabs(diff[0]) < symprec && 
	  mat_Dabs(diff[1]) < symprec && 
	  mat_Dabs(diff[2]) < symprec) {
	continue;
      }
      
      for (k = 0; k < num_ir_kpoint; k++) {
	mat_multiply_matrix_vector_id3(kpt_rot, point_symmetry->rot[j], kpoints[i]);

	for (l = 0; l < 3; l++) {
	  diff[l] = kpt_rot[l] - kpoints[ir_map[k]][l];
	  diff[l] = diff[l] - mat_Nint(diff[l]);
	}

	if (mat_Dabs(diff[0]) < symprec && 
	    mat_Dabs(diff[1]) < symprec && 
	    mat_Dabs(diff[2]) < symprec) {
	  is_found = 0;
	  map[i] = ir_map[k];
	  break;
	}
      }

      if (! is_found)
	break;
    }

    if (is_found) {
      ir_map[num_ir_kpoint] = i;
      num_ir_kpoint++;
    }
  }

  free(ir_map);
  ir_map = NULL;

  return num_ir_kpoint;
}
Пример #16
0
/* Return 0 if failed */
static int set_primitive_positions(Cell * primitive_cell,
                                   const VecDBL * position,
                                   const Cell * cell,
                                   int * const * table)
{
    int i, j, k, ratio, index_prim_atom;
    int *is_equivalent;

    is_equivalent = NULL;

    if ((is_equivalent = (int*) malloc(cell->size * sizeof(int))) == NULL) {
        warning_print("spglib: Memory could not be allocated ");
        goto err;
    }

    for (i = 0; i < cell->size; i++) {
        is_equivalent[i] = 0;
    }
    ratio = cell->size / primitive_cell->size;

    /* Copy positions. Positions of overlapped atoms are averaged. */
    index_prim_atom = 0;
    for (i = 0; i < cell->size; i++) {

        if (! is_equivalent[i]) {
            primitive_cell->types[index_prim_atom] = cell->types[i];

            for (j = 0; j < 3; j++) {
                primitive_cell->position[index_prim_atom][j] = 0;
            }

            for (j = 0; j < ratio; j++) { /* Loop for averaging positions */
                is_equivalent[table[i][j]] = 1;

                for (k = 0; k < 3; k++) {
                    /* boundary treatment */
                    /* One is at right and one is at left or vice versa. */
                    if (mat_Dabs(position->vec[table[i][0]][k] -
                                 position->vec[table[i][j]][k]) > 0.5) {
                        if (position->vec[table[i][j]][k] < 0) {
                            primitive_cell->position[index_prim_atom][k] =
                                primitive_cell->position[index_prim_atom][k] +
                                position->vec[table[i][j]][k] + 1;
                        } else {
                            primitive_cell->position[index_prim_atom][k] =
                                primitive_cell->position[index_prim_atom][k] +
                                position->vec[table[i][j]][k] - 1;
                        }

                    } else {
                        primitive_cell->position[index_prim_atom][k] =
                            primitive_cell->position[index_prim_atom][k] +
                            position->vec[table[i][j]][k];
                    }
                }

            }

            for (j = 0; j < 3; j++) {	/* take average and reduce */
                primitive_cell->position[index_prim_atom][j] =
                    primitive_cell->position[index_prim_atom][j] / ratio;
                primitive_cell->position[index_prim_atom][j] =
                    primitive_cell->position[index_prim_atom][j] -
                    mat_Nint(primitive_cell->position[index_prim_atom][j]);
            }
            index_prim_atom++;
        }
    }

    free(is_equivalent);
    is_equivalent = NULL;

    if (! (index_prim_atom == primitive_cell->size)) {
        warning_print("spglib: Atomic positions of primitive cell could not be determined ");
        warning_print("(line %d, %s).\n", __LINE__, __FILE__);
        goto err;
    }

    return 1;

err:
    return 0;
}
Пример #17
0
static int get_Delaunay_reduction_2D(double red_lattice[3][3], 
				     SPGCONST double lattice[3][3],
				     const int unique_axis,
				     const double symprec)
{
  int i, j, k;
  double volume;
  double basis[3][3], lattice_2D[3][2], unique_vec[3];

  k = 0;
  for (i = 0; i < 3; i++) {
    unique_vec[i] = lattice[i][unique_axis];
  }

  for (i = 0; i < 3; i++) {
    if (i != unique_axis) {
      for (j = 0; j < 3; j++) {
	lattice_2D[j][k] = lattice[j][i];
      }
      k++;
    }
  }

  get_exteneded_basis_2D(basis, lattice_2D);
  
  while (1) {
    if (get_Delaunay_reduction_basis_2D(basis, symprec)) {
      break;
    }
  }

  get_Delaunay_shortest_vectors_2D(basis, unique_vec, symprec);

  k = 0;
  for (i = 0; i < 3; i++) {
    if (i == unique_axis) {
      for (j = 0; j < 3; j++) {
	red_lattice[j][i] = lattice[j][i];
      }
    } else {
      for (j = 0; j < 3; j++) {
	red_lattice[j][i] = basis[k][j];
      }
      k++;
    }
  }

  volume = mat_get_determinant_d3(red_lattice);
  if (mat_Dabs(volume) < symprec) {
    warning_print("spglib: Minimum lattice has no volume (line %d, %s).\n", __LINE__, __FILE__);
    goto err;
  }

  if (volume  < 0) {
    for (i = 0; i < 3; i++) {
      red_lattice[i][unique_axis] = -red_lattice[i][unique_axis];
    }
  }

  return 1;

 err:
  return 0;
}
Пример #18
0
static int set_primitive_positions( Cell * primitive,
				    const VecDBL * position,
				    const Cell * cell,
				    int * const * table )
{
  int i, j, k, ratio, count;
  int *is_equivalent = (int*)malloc(cell->size * sizeof(int));

  ratio = cell->size / primitive->size;
  for (i = 0; i < cell->size; i++) {
    is_equivalent[i] = 0;
  }

  /* Copy positions. Positions of overlapped atoms are averaged. */
  count = 0;
  for ( i = 0; i < cell->size; i++ )

    if ( ! is_equivalent[i] ) {

      debug_print("Trimming... i=%d count=%d\n", i, count);
      primitive->types[count] = cell->types[i];

      for ( j = 0; j < 3; j++ ) {
	primitive->position[count][j] = 0;
      }

      for ( j = 0; j < ratio; j++ ) {	/* overlap atoms */
        if ( table[i][j] < 0 ) { /* check if table is correctly bulit. */
          break;
	}

	is_equivalent[table[i][j]] = 1;

	for (k = 0; k < 3; k++) {

	  /* boundary treatment */
	  if (mat_Dabs(position->vec[table[i][0]][k] -
		       position->vec[table[i][j]][k]) > 0.5) {

	    if (position->vec[table[i][j]][k] < 0) {
	      primitive->position[count][k]
		= primitive->position[count][k] +
		position->vec[table[i][j]][k] + 1;
	    } else {
	      primitive->position[count][k]
		= primitive->position[count][k] +
		position->vec[table[i][j]][k] - 1;
	    }

	  } else {
	    primitive->position[count][k]
	      = primitive->position[count][k] +
	      position->vec[table[i][j]][k];
	  }
	}
	
      }

      for (j = 0; j < 3; j++) {	/* take average and reduce */

	primitive->position[count][j] =
	  primitive->position[count][j] / ratio;

	primitive->position[count][j] =
	  primitive->position[count][j] -
	  mat_Nint( primitive->position[count][j] );
      }
      count++;
    }

  free(is_equivalent);
  is_equivalent = NULL;

  debug_print("Count: %d Size of cell: %d Size of primitive: %d\n", count, cell->size, primitive->size);
  if ( ! ( count == primitive->size ) ) {
    warning_print("spglib: Atomic positions of primitive cell could not be determined ");
    warning_print("(line %d, %s).\n", __LINE__, __FILE__);
    goto err;
  }

  return 1;

 err:
  return 0;
}