Esempio n. 1
0
static Cell * expand_positions(SPGCONST Cell * conv_prim,
                               SPGCONST Symmetry * conv_sym)
{
    int i, j, k, num_pure_trans;
    int num_atom;
    Cell * bravais;

    num_pure_trans = get_number_of_pure_translation(conv_sym);
    bravais = cel_alloc_cell(conv_prim->size * num_pure_trans);

    num_atom = 0;
    for (i = 0; i < conv_sym->size; i++) {
        /* Referred atoms in Bravais lattice */
        if (mat_check_identity_matrix_i3(identity, conv_sym->rot[i])) {
            for (j = 0; j < conv_prim->size; j++) {
                bravais->types[num_atom] = conv_prim->types[j];
                mat_copy_vector_d3(bravais->position[ num_atom ],
                                   conv_prim->position[j]);
                for (k = 0; k < 3; k++) {
                    bravais->position[num_atom][k] += conv_sym->trans[i][k];
                    bravais->position[num_atom][k] =
                        mat_Dmod1(bravais->position[num_atom][k]);
                }
                num_atom++;
            }
        }
    }

    mat_copy_matrix_d3(bravais->lattice, conv_prim->lattice);

    return bravais;
}
Esempio n. 2
0
static int get_rotation_axis(SPGCONST int proper_rot[3][3])
{
  int i, axis = -1;
  int vec[3];

  /* No specific axis for I and -I */
  if (mat_check_identity_matrix_i3(proper_rot, identity)) {
    goto end;
  }

  /* Look for eigenvector = rotation axis */
  for (i = 0; i < NUM_ROT_AXES; i++) {
    mat_multiply_matrix_vector_i3(vec, proper_rot, rot_axes[i]);
    if (vec[0] == rot_axes[i][0] &&
	vec[1] == rot_axes[i][1] &&
	vec[2] == rot_axes[i][2]) {
      axis = i;
      break;
    }
  }
  
 end:
#ifdef SPGDEBUG
  if (axis == -1) {
    printf("rotation axis cound not found.\n");
  }
#endif
  
  return axis;
}
Esempio n. 3
0
static MatINT *get_point_group_reciprocal(const MatINT * rotations,
					  const int is_time_reversal)
{
  int i, j, num_rot;
  MatINT *rot_reciprocal, *rot_return;
  int *unique_rot;
  SPGCONST int inversion[3][3] = {
    {-1, 0, 0 },
    { 0,-1, 0 },
    { 0, 0,-1 }
  };
  
  if (is_time_reversal) {
    rot_reciprocal = mat_alloc_MatINT(rotations->size * 2);
  } else {
    rot_reciprocal = mat_alloc_MatINT(rotations->size);
  }
  unique_rot = (int*)malloc(sizeof(int) * rot_reciprocal->size);
  for (i = 0; i < rot_reciprocal->size; i++) {
    unique_rot[i] = -1;
  }

  for (i = 0; i < rotations->size; i++) {
    mat_transpose_matrix_i3(rot_reciprocal->mat[i], rotations->mat[i]);
    
    if (is_time_reversal) {
      mat_multiply_matrix_i3(rot_reciprocal->mat[rotations->size+i],
			     inversion,
			     rot_reciprocal->mat[i]);
    }
  }

  num_rot = 0;
  for (i = 0; i < rot_reciprocal->size; i++) {
    for (j = 0; j < num_rot; j++) {
      if (mat_check_identity_matrix_i3(rot_reciprocal->mat[unique_rot[j]],
				       rot_reciprocal->mat[i])) {
	goto escape;
      }
    }
    unique_rot[num_rot] = i;
    num_rot++;
  escape:
    ;
  }

  rot_return = mat_alloc_MatINT(num_rot);
  for (i = 0; i < num_rot; i++) {
    mat_copy_matrix_i3(rot_return->mat[i], rot_reciprocal->mat[unique_rot[i]]);    }
  free(unique_rot);
  mat_free_MatINT(rot_reciprocal);

  return rot_return;
}
Esempio n. 4
0
static int get_number_of_pure_translation(SPGCONST Symmetry * conv_sym)
{
    int i, num_pure_trans = 0;

    for (i = 0; i < conv_sym->size; i++) {
        if (mat_check_identity_matrix_i3(identity, conv_sym->rot[i])) {
            num_pure_trans++;
        }
    }

    return num_pure_trans;
}
Esempio n. 5
0
static Symmetry * get_primitive_db_symmetry(SPGCONST double t_mat[3][3],
        const Symmetry *conv_sym,
        const double symprec)
{
    int i, j, num_op;
    double inv_mat[3][3], tmp_mat[3][3];
    MatINT *r_prim;
    VecDBL *t_prim;
    Symmetry *prim_sym;

    r_prim = mat_alloc_MatINT(conv_sym->size);
    t_prim = mat_alloc_VecDBL(conv_sym->size);

    mat_inverse_matrix_d3(inv_mat, t_mat, symprec);

    num_op = 0;
    for (i = 0; i < conv_sym->size; i++) {
        for (j = 0; j < i; j++) {
            if (mat_check_identity_matrix_i3(conv_sym->rot[i],
                                             conv_sym->rot[j])) {
                goto pass;
            }
        }

        /* R' = T*R*T^-1 */
        mat_multiply_matrix_di3(tmp_mat, t_mat, conv_sym->rot[i]);
        mat_multiply_matrix_d3(tmp_mat, tmp_mat, inv_mat);
        mat_cast_matrix_3d_to_3i(r_prim->mat[ num_op ], tmp_mat);
        /* t' = T*t */
        mat_multiply_matrix_vector_d3(t_prim->vec[ num_op ],
                                      t_mat,
                                      conv_sym->trans[ i ]);
        num_op++;

pass:
        ;
    }

    prim_sym = sym_alloc_symmetry(num_op);
    for (i = 0; i < num_op; i++) {
        mat_copy_matrix_i3(prim_sym->rot[i], r_prim->mat[i]);
        for (j = 0; j < 3; j++) {
            prim_sym->trans[i][j] = t_prim->vec[i][j] - mat_Nint(t_prim->vec[i][j]);
        }
    }

    mat_free_MatINT(r_prim);
    mat_free_VecDBL(t_prim);

    return prim_sym;
}
Esempio n. 6
0
/* num_q is the number of the qpoints. */
static PointSymmetry get_point_group_reciprocal(const MatINT * rotations,
						const int is_time_reversal)
{
  int i, j, num_pt = 0;
  MatINT *rot_reciprocal;
  PointSymmetry point_symmetry;
  SPGCONST int inversion[3][3] = {
    {-1, 0, 0 },
    { 0,-1, 0 },
    { 0, 0,-1 }
  };
  
  if (is_time_reversal) {
    rot_reciprocal = mat_alloc_MatINT(rotations->size * 2);
  } else {
    rot_reciprocal = mat_alloc_MatINT(rotations->size);
  }

  for (i = 0; i < rotations->size; i++) {
    mat_transpose_matrix_i3(rot_reciprocal->mat[i], rotations->mat[i]);
    
    if (is_time_reversal) {
      mat_multiply_matrix_i3(rot_reciprocal->mat[rotations->size+i],
			     inversion,
			     rot_reciprocal->mat[i]);
    }
  }


  for (i = 0; i < rot_reciprocal->size; i++) {
    for (j = 0; j < num_pt; j++) {
      if (mat_check_identity_matrix_i3(point_symmetry.rot[j],
				       rot_reciprocal->mat[i])) {
	goto escape;
      }
    }
    
    mat_copy_matrix_i3(point_symmetry.rot[num_pt],
		       rot_reciprocal->mat[i]);
    num_pt++;
  escape:
    ;
  }

  point_symmetry.size = num_pt;

  mat_free_MatINT(rot_reciprocal);

  return point_symmetry;
}
Esempio n. 7
0
static Symmetry * reduce_operation(SPGCONST Cell * cell,
				   SPGCONST Symmetry * symmetry,
				   const double symprec)
{
  int i, j, num_sym;
  Symmetry * sym_reduced;
  PointSymmetry point_symmetry;
  MatINT *rot;
  VecDBL *trans;

  debug_print("reduce_operation:\n");

  point_symmetry = get_lattice_symmetry(cell, symprec);
  rot = mat_alloc_MatINT(symmetry->size);
  trans = mat_alloc_VecDBL(symmetry->size);

  num_sym = 0;
  for (i = 0; i < point_symmetry.size; i++) {
    for (j = 0; j < symmetry->size; j++) {
      if (mat_check_identity_matrix_i3(point_symmetry.rot[i],
				       symmetry->rot[j])) {
	if (is_overlap_all_atoms(symmetry->trans[j],
				 symmetry->rot[j],
				 cell,
				 symprec,
				 0)) {
	  mat_copy_matrix_i3(rot->mat[num_sym], symmetry->rot[j]);
	  mat_copy_vector_d3(trans->vec[num_sym], symmetry->trans[j]);
	  num_sym++;
	}
      }
    }
  }

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

  mat_free_MatINT(rot);
  mat_free_VecDBL(trans);

  debug_print("  num_sym %d -> %d\n", symmetry->size, num_sym);

  return sym_reduced;
}
Esempio n. 8
0
/* Return NULL if failed */
static int * get_mapping_table(SPGCONST Symmetry *symmetry,
			       SPGCONST Cell * cell,
			       const double symprec)
{
  int i, j, k, is_found;
  double pos[3];
  int *mapping_table;
  SPGCONST int I[3][3] = {{ 1, 0, 0},
			  { 0, 1, 0},
			  { 0, 0, 1}};

  mapping_table = NULL;

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

  for (i = 0; i < cell->size; i++) {
    is_found = 0;
    for (j = 0; j < symmetry->size; j++) {
      if (mat_check_identity_matrix_i3(symmetry->rot[j], I)) {
	for (k = 0; k < 3; k++) {
	  pos[k] = cell->position[i][k] + symmetry->trans[j][k];
	}
	for (k = 0; k < cell->size; k++) {
	  if (cel_is_overlap(pos, cell->position[k], cell->lattice, symprec)) {
	    if (k < i) {
	      mapping_table[i] = mapping_table[k];
	      is_found = 1;
	      break;
	    }
	  }
	}
      }
      if (is_found) {
	break;
      }
    }
    if (!is_found) {
      mapping_table[i] = i;
    }
  }

  return mapping_table;
}
Esempio n. 9
0
static PointSymmetry get_pointsymmetry(SPGCONST int rotations[][3][3],
				       const int num_rotations)
{
  int i, j;
  PointSymmetry pointsym;

  pointsym.size = 0;
  for (i = 0; i < num_rotations; i++) {
    for (j = 0; j < pointsym.size; j++) {
      if (mat_check_identity_matrix_i3(rotations[i], pointsym.rot[j])) {
	goto escape;
      }
    }
    mat_copy_matrix_i3(pointsym.rot[pointsym.size], rotations[i]);
    pointsym.size++;
  escape:
    ;
  }

  return pointsym;
}
Esempio n. 10
0
/* Return NULL if failed */
static MatINT *get_point_group_reciprocal(const MatINT * rotations,
					  const int is_time_reversal)
{
  int i, j, num_rot;
  MatINT *rot_reciprocal, *rot_return;
  int *unique_rot;
  SPGCONST int inversion[3][3] = {
    {-1, 0, 0 },
    { 0,-1, 0 },
    { 0, 0,-1 }
  };

  rot_reciprocal = NULL;
  rot_return = NULL;
  unique_rot = NULL;
  
  if (is_time_reversal) {
    if ((rot_reciprocal = mat_alloc_MatINT(rotations->size * 2)) == NULL) {
      return NULL;
    }
  } else {
    if ((rot_reciprocal = mat_alloc_MatINT(rotations->size)) == NULL) {
      return NULL;
    }
  }

  if ((unique_rot = (int*)malloc(sizeof(int) * rot_reciprocal->size)) == NULL) {
    warning_print("spglib: Memory of unique_rot could not be allocated.");
    mat_free_MatINT(rot_reciprocal);
    return NULL;
  }

  for (i = 0; i < rot_reciprocal->size; i++) {
    unique_rot[i] = -1;
  }

  for (i = 0; i < rotations->size; i++) {
    mat_transpose_matrix_i3(rot_reciprocal->mat[i], rotations->mat[i]);
    
    if (is_time_reversal) {
      mat_multiply_matrix_i3(rot_reciprocal->mat[rotations->size+i],
			     inversion,
			     rot_reciprocal->mat[i]);
    }
  }

  num_rot = 0;
  for (i = 0; i < rot_reciprocal->size; i++) {
    for (j = 0; j < num_rot; j++) {
      if (mat_check_identity_matrix_i3(rot_reciprocal->mat[unique_rot[j]],
				       rot_reciprocal->mat[i])) {
	goto escape;
      }
    }
    unique_rot[num_rot] = i;
    num_rot++;
  escape:
    ;
  }

  if ((rot_return = mat_alloc_MatINT(num_rot)) != NULL) {
    for (i = 0; i < num_rot; i++) {
      mat_copy_matrix_i3(rot_return->mat[i], rot_reciprocal->mat[unique_rot[i]]);
    }
  }

  free(unique_rot);
  unique_rot = NULL;
  mat_free_MatINT(rot_reciprocal);
  rot_reciprocal = NULL;

  return rot_return;
}
Esempio n. 11
0
/* Return NULL if failed */
static Symmetry * reduce_operation(SPGCONST Cell * primitive,
				   SPGCONST Symmetry * symmetry,
				   const double symprec,
				   const double angle_symprec)
{
  int i, j, num_sym;
  Symmetry * sym_reduced;
  PointSymmetry point_symmetry;
  MatINT *rot;
  VecDBL *trans;

  debug_print("reduce_operation:\n");

  sym_reduced = NULL;
  rot = NULL;
  trans = NULL;

  point_symmetry = get_lattice_symmetry(primitive->lattice,
					symprec,
					angle_symprec);
  if (point_symmetry.size == 0) {
    return NULL;
  }

  if ((rot = mat_alloc_MatINT(symmetry->size)) == NULL) {
    return NULL;
  }

  if ((trans = mat_alloc_VecDBL(symmetry->size)) == NULL) {
    mat_free_MatINT(rot);
    rot = NULL;
    return NULL;
  }

  num_sym = 0;
  for (i = 0; i < point_symmetry.size; i++) {
    for (j = 0; j < symmetry->size; j++) {
      if (mat_check_identity_matrix_i3(point_symmetry.rot[i],
				       symmetry->rot[j])) {
	if (is_overlap_all_atoms(symmetry->trans[j],
				 symmetry->rot[j],
				 primitive,
				 symprec,
				 0)) {
	  mat_copy_matrix_i3(rot->mat[num_sym], symmetry->rot[j]);
	  mat_copy_vector_d3(trans->vec[num_sym], symmetry->trans[j]);
	  num_sym++;
	}
      }
    }
  }

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

  mat_free_MatINT(rot);
  rot = NULL;
  mat_free_VecDBL(trans);
  trans = NULL;

  return sym_reduced;
}
Esempio n. 12
0
/* Acta Cryst. (2002). A58, 60-65 */
static int set_exact_location(double position[3],
                              const Symmetry * conv_sym,
                              SPGCONST double bravais_lattice[3][3],
                              const double symprec)
{
  int i, j, k, num_sum, multi, num_pure_trans;
  double sum_rot[3][3];
  double pos[3], sum_trans[3];

  debug_print("get_exact_location\n");

  num_sum = 0;
  for (i = 0; i < 3; i++) {
    sum_trans[i] = 0.0;
    for (j = 0; j < 3; j++) {
      sum_rot[i][j] = 0;
    }
  }

  num_pure_trans = 0;
  for (i = 0; i < conv_sym->size; i++) {
    if (mat_check_identity_matrix_i3(identity, conv_sym->rot[i])) {
      num_pure_trans++;
      for (j = 0; j < 3; j++) {
        pos[j] = position[j];
      }
    } else {
      mat_multiply_matrix_vector_id3(pos,
                                     conv_sym->rot[i],
                                     position);
    }
    for (j = 0; j < 3; j++) {
      pos[j] += conv_sym->trans[i][j];
    }

    if (cel_is_overlap(pos,
                       position,
                       bravais_lattice,
                       symprec)) {
      for (j = 0; j < 3; j++) {
        for (k = 0; k < 3; k++) {
          sum_rot[j][k] += conv_sym->rot[i][j][k];
        }
        sum_trans[j] +=
          conv_sym->trans[i][j] - mat_Nint(pos[j] - position[j]);
      }
      num_sum++;
    }
  }

  for (i = 0; i < 3; i++) {
    sum_trans[i] /= num_sum;
    for (j = 0; j < 3; j++) {
      sum_rot[i][j] /= num_sum;
    }
  }

  /* (sum_rot|sum_trans) is the special-position operator. */
  /* Elements of sum_rot can be fractional values. */
  mat_multiply_matrix_vector_d3(position,
                                sum_rot,
                                position);

  for (i = 0; i < 3; i++) {
    position[i] += sum_trans[i];
  }

  multi = conv_sym->size / num_pure_trans / num_sum;
  if (multi * num_sum * num_pure_trans == conv_sym->size) {
    return multi;
  } else {
    return 0;
  }
}