/* was not a primitive cell. */ static Symmetry * get_operations(SPGCONST Cell *primitive, const double symprec, const double angle_symprec) { PointSymmetry lattice_sym; Symmetry *symmetry; debug_print("get_operations:\n"); symmetry = NULL; lattice_sym = get_lattice_symmetry(primitive->lattice, symprec, angle_symprec); if (lattice_sym.size == 0) { return NULL; } if ((symmetry = get_space_group_operations(&lattice_sym, primitive, symprec)) == NULL) { return NULL; } return symmetry; }
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; }
/* was not a primitive cell. */ static Symmetry * get_operations(SPGCONST Cell *cell, const double symprec) { int i, j, attempt; double tolerance; PointSymmetry lattice_sym; Symmetry *symmetry, *symmetry_orig, *symmetry_reduced; Primitive primitive; debug_print("get_operations:\n"); symmetry_orig = NULL; lattice_sym = get_lattice_symmetry(cell, symprec); if (lattice_sym.size == 0) { debug_print("get_lattice_symmetry failed.\n"); goto end; } primitive = prm_get_primitive_and_pure_translations(cell, symprec); if (primitive.cell->size == 0) { goto deallocate_and_end; } lattice_sym = transform_pointsymmetry(&lattice_sym, primitive.cell->lattice, cell->lattice); if (lattice_sym.size == 0) { goto deallocate_and_end; } symmetry = get_space_group_operations(&lattice_sym, primitive.cell, symprec); if (symmetry->size > 48) { tolerance = symprec; for (attempt = 0; attempt < 100; attempt++) { tolerance *= REDUCE_RATE; warning_print("spglib: number of symmetry operations for primitive cell > 48 was found. (line %d, %s).\n", __LINE__, __FILE__); warning_print("tolerance is reduced to %f\n", tolerance); symmetry_reduced = reduce_operation(primitive.cell, symmetry, tolerance); sym_free_symmetry(symmetry); symmetry = symmetry_reduced; if (symmetry_reduced->size > 48) { ; } else { break; } } } symmetry_orig = recover_operations_original(symmetry, primitive.pure_trans, cell, primitive.cell); sym_free_symmetry(symmetry); for (i = 0; i < symmetry_orig->size; i++) { for (j = 0; j < 3; j++) { symmetry_orig->trans[i][j] -= mat_Nint(symmetry_orig->trans[i][j]); } } deallocate_and_end: cel_free_cell(primitive.cell); mat_free_VecDBL(primitive.pure_trans); end: if (! symmetry_orig) { symmetry_orig = sym_alloc_symmetry(0); } return symmetry_orig; }
/* 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; }
/* was not a primitive cell. */ static int get_operation( int rot[][3][3], double trans[][3], SPGCONST Cell *cell, const double symprec ) { int num_sym; int multi; int *mapping_table; PointSymmetry lattice_sym; Cell *primitive; VecDBL *pure_trans; pure_trans = sym_get_pure_translation(cell, symprec); multi = pure_trans->size; /* Lattice symmetry for input cell*/ lattice_sym = get_lattice_symmetry( cell, symprec ); if ( lattice_sym.size == 0 ) { goto err; } /* Obtain primitive cell */ if( multi > 1 ) { mapping_table = (int*) malloc( sizeof(int) * cell->size ); primitive = prm_get_primitive( mapping_table, cell, pure_trans, symprec ); free( mapping_table ); mapping_table = NULL; if ( primitive->size < 1 ) { goto err; } lattice_sym = transform_pointsymmetry( &lattice_sym, primitive->lattice, cell->lattice ); if ( lattice_sym.size == 0 ) { goto err; } } else { primitive = cell; } /* Symmetry operation search for primitive cell */ num_sym = get_space_group_operation( rot, trans, &lattice_sym, primitive, symprec ); /* Recover symmetry operation for the input structure (overwritten) */ if( multi > 1 ) { num_sym = get_operation_supercell( rot, trans, num_sym, pure_trans, cell, primitive ); cel_free_cell( primitive ); if ( num_sym == 0 ) { goto err; } } mat_free_VecDBL( pure_trans ); return num_sym; err: mat_free_VecDBL( pure_trans ); return 0; }