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; }
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; }
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; }