Exemple #1
0
Symmetry * sym_get_operation( SPGCONST Cell *cell,
			      const double symprec ) {
  int i, j, num_sym;
  MatINT *rot;
  VecDBL *trans;
  Symmetry *symmetry;
  
  rot = mat_alloc_MatINT( cell->size * 48 );
  trans = mat_alloc_VecDBL( cell->size * 48 );

  num_sym = get_operation( rot->mat, trans->vec, cell, symprec );

#ifdef DEBUG
  debug_print("*** get_symmetry (found symmetry operations) *** \n");
  debug_print("Lattice \n");
  debug_print_matrix_d3(cell->lattice);
  for ( i = 0; i < num_sym; i++ ) {
    debug_print("--- %d ---\n", i + 1);
    debug_print_matrix_i3(rot->mat[i]);
    debug_print("%f %f %f\n",
  		trans->vec[i][0], trans->vec[i][1], trans->vec[i][2]);
  }
#endif
  
  symmetry = sym_alloc_symmetry( num_sym );
  for ( i = 0; i < num_sym; i++ ) {
    mat_copy_matrix_i3(symmetry->rot[i], rot->mat[i]);
    for (j = 0; j < 3; j++)
      symmetry->trans[i][j] = trans->vec[i][j];
  }

  mat_free_MatINT( rot );
  mat_free_VecDBL( trans );

  return symmetry;
}
Exemple #2
0
static int laue3m(int axes[3],
		  SPGCONST PointSymmetry * pointsym)
{
  int i, is_found, tmpval, axis;
  int prop_rot[3][3], prop_rot2[3][3], t_mat[3][3];
  int axis_vec[3];

  for (i = 0; i < pointsym->size; i++) {
    get_proper_rotation(prop_rot, pointsym->rot[i]);

    /* Search three-fold rotation */
    if (mat_get_trace_i3(prop_rot) == 0) {
      /* The first axis */
      axes[2] = get_rotation_axis(prop_rot);
      debug_print("laue3m prop_rot\n");
      debug_print_matrix_i3(prop_rot);
      break;
    }
  }

  is_found = 0;
  for (i = 0; i < pointsym->size; i++) {
    get_proper_rotation(prop_rot2, pointsym->rot[i]);

    /* Search two-fold rotation */
    if (! (mat_get_trace_i3(prop_rot2) == -1)) {
      continue;
    }

    /* The second axis */
    axis = get_rotation_axis(prop_rot2);
    if (! (axis == axes[2])) {
      axes[0] = axis;
      is_found = 1;
      break;
    }
  }
  if (! is_found) { goto err; }

  /* The third axis */
  mat_multiply_matrix_vector_i3(axis_vec, prop_rot, rot_axes[axes[0]]);
  is_found = 0;
  for (i = 0; i < NUM_ROT_AXES; i++) {
    is_found = is_exist_axis(axis_vec, i);
    if (is_found == 1) {
      axes[1] = i;
      break;
    }
    if (is_found == -1) {
      axes[1] = i + NUM_ROT_AXES;
      break;
    }
  }
  if (! is_found) { goto err; }

  set_transformation_matrix(t_mat, axes);
  if (mat_get_determinant_i3(t_mat) < 0) {
    tmpval = axes[0];
    axes[0] = axes[1];
    axes[1] = tmpval;
  }

  return 1;

 err:
  return 0;
}
Exemple #3
0
static Symmetry * get_conventional_symmetry( SPGCONST double transform_mat[3][3],
					     const Centering centering,
					     const Symmetry *primitive_sym )
{
  int i, j, k, multi, size;
  double tmp_trans;
  double tmp_matrix_d3[3][3], shift[4][3];
  double symmetry_rot_d3[3][3], primitive_sym_rot_d3[3][3];
  Symmetry *symmetry;

  size = primitive_sym->size;

  if (centering == FACE) {
    symmetry = sym_alloc_symmetry(size * 4);
  }
  else {
    if (centering) {
      symmetry = sym_alloc_symmetry(size * 2);
    } else {
      symmetry = sym_alloc_symmetry(size);
    }
  }

  for (i = 0; i < size; i++) {
    mat_cast_matrix_3i_to_3d(primitive_sym_rot_d3, primitive_sym->rot[i]);

    /* C*S*C^-1: recover conventional cell symmetry operation */
    mat_get_similar_matrix_d3( symmetry_rot_d3,
			       primitive_sym_rot_d3,
			       transform_mat,
			       0 );
    mat_cast_matrix_3d_to_3i( symmetry->rot[i], symmetry_rot_d3 );

    /* translation in conventional cell: C = B^-1*P */
    mat_inverse_matrix_d3( tmp_matrix_d3,
			   transform_mat,
			   0 );
    mat_multiply_matrix_vector_d3( symmetry->trans[i], tmp_matrix_d3,
				   primitive_sym->trans[i] );
  }

  multi = 1;

  if (centering) {
    if (centering != FACE) {
      for (i = 0; i < 3; i++) {	shift[0][i] = 0.5; }
      if (centering == A_FACE) { shift[0][0] = 0; }
      if (centering == B_FACE) { shift[0][1] = 0; }
      if (centering == C_FACE) { shift[0][2] = 0; }

      multi = 2;
    }

    if (centering == FACE) {
      shift[0][0] = 0;
      shift[0][1] = 0.5;
      shift[0][2] = 0.5;
      shift[1][0] = 0.5;
      shift[1][1] = 0;
      shift[1][2] = 0.5;
      shift[2][0] = 0.5;
      shift[2][1] = 0.5;
      shift[2][2] = 0;

      multi = 4;
    }

    for (i = 0; i < multi - 1; i++) {
      for (j = 0; j < size; j++) {
	mat_copy_matrix_i3( symmetry->rot[(i+1) * size + j],
			    symmetry->rot[j] );
	for (k = 0; k < 3; k++) {
	  tmp_trans = symmetry->trans[j][k] + shift[i][k];
	  symmetry->trans[(i+1) * size + j][k] = tmp_trans;
	}
      }
    }
  }


  /* Reduce translations into -0 < trans < 1.0 */
  for (i = 0; i < multi; i++) {
    for (j = 0; j < size; j++) {
      for (k = 0; k < 3; k++) {
  	tmp_trans = symmetry->trans[i * size + j][k];
  	tmp_trans -= mat_Nint(tmp_trans);
  	if ( tmp_trans < 0 ) {
  	  tmp_trans += 1.0;
  	}
  	symmetry->trans[i * size + j][k] = tmp_trans;
      }
    }
  }

#ifdef DEBUG
  debug_print("Multi: %d\n", multi);
  debug_print("Centering: %d\n", centering);
  debug_print("sym size: %d\n", symmetry->size);
  
  for (i = 0; i < symmetry->size; i++) {
    debug_print("--- %d ---\n", i + 1);
    debug_print_matrix_i3(symmetry->rot[i]);
    debug_print("%f %f %f\n", symmetry->trans[i][0],
		symmetry->trans[i][1], symmetry->trans[i][2]);
  }
#endif

  return symmetry;
}