Spacegroup spa_get_spacegroup( SPGCONST Cell * cell, const double symprec ) { Cell *primitive; int *mapping_table; Spacegroup spacegroup; VecDBL *pure_trans; pure_trans = sym_get_pure_translation( cell, symprec ); 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 > 0 ) { spacegroup = get_spacegroup( primitive, symprec ); } else { spacegroup.number = 0; warning_print("spglib: Space group could not be found "); warning_print("(line %d, %s).\n", __LINE__, __FILE__); } cel_free_cell( primitive ); return spacegroup; }
Spacegroup spa_get_spacegroup( SPGCONST Cell * cell, const double symprec ) { Cell *primitive; int *mapping_table; Spacegroup spacegroup; VecDBL *pure_trans; double tolerance; pure_trans = sym_get_pure_translation( cell, symprec ); mapping_table = (int*) malloc( sizeof(int) * cell->size ); primitive = prm_get_primitive( mapping_table, cell, pure_trans, symprec ); free( mapping_table ); mapping_table = NULL; /* In some case, tolerance (symprec) to find primitive lattice is reduced. */ /* The reduced tolerance should be used to find symmetry operations. */ tolerance = prm_get_tolerance(); if ( primitive->size > -1 ) { spacegroup = get_spacegroup( primitive, tolerance ); } else { spacegroup.number = 0; warning_print("spglib: Space group could not be found "); warning_print("(line %d, %s).\n", __LINE__, __FILE__); } cel_free_cell( primitive ); return spacegroup; }
static int find_primitive(double lattice[3][3], double position[][3], int types[], const int num_atom, const double symprec) { int i, num_prim_atom=0; Cell *cell, *primitive; cell = cel_alloc_cell(num_atom); cel_set_cell(cell, lattice, position, types); /* find primitive cell */ primitive = prm_get_primitive(cell, symprec); if (primitive->size == cell->size) { /* Already primitive */ num_prim_atom = 0; } else { /* Primitive cell was found. */ num_prim_atom = primitive->size; if (num_prim_atom < num_atom && num_prim_atom > 0 ) { mat_copy_matrix_d3(lattice, primitive->lattice); for (i = 0; i < primitive->size; i++) { types[i] = primitive->types[i]; mat_copy_vector_d3(position[i], primitive->position[i]); } } } cel_free_cell(primitive); cel_free_cell(cell); return num_prim_atom; }
static Cell * refine_cell(SPGCONST Cell * cell, const double symprec) { int *wyckoffs, *equiv_atoms; double tolerance; Cell *primitive, *bravais, *conv_prim; Symmetry *conv_sym; Spacegroup spacegroup; debug_print("refine_cell:\n"); primitive = prm_get_primitive(cell, symprec); if (primitive->size == 0) { cel_free_cell(primitive); bravais = cel_alloc_cell(0); goto end; } tolerance = prm_get_current_tolerance(); spacegroup = spa_get_spacegroup_with_primitive(primitive, tolerance); wyckoffs = (int*)malloc(sizeof(int) * primitive->size); equiv_atoms = (int*)malloc(sizeof(int) * primitive->size); conv_prim = get_bravais_exact_positions_and_lattice(wyckoffs, equiv_atoms, &spacegroup, primitive, tolerance); free(equiv_atoms); equiv_atoms = NULL; free(wyckoffs); wyckoffs = NULL; conv_sym = get_db_symmetry(spacegroup.hall_number); bravais = expand_positions(conv_prim, conv_sym); debug_print("primitive cell in refine_cell:\n"); debug_print_matrix_d3(primitive->lattice); debug_print("conventional lattice in refine_cell:\n"); debug_print_matrix_d3(conv_prim->lattice); debug_print("bravais lattice in refine_cell:\n"); debug_print_matrix_d3(bravais->lattice); cel_free_cell(conv_prim); sym_free_symmetry(conv_sym); cel_free_cell(primitive); end: /* Return bravais->size = 0, if the bravais could not be found. */ return bravais; }
static Cell * refine_cell( SPGCONST Cell * cell, const double symprec ) { int *mapping_table, *wyckoffs, *equiv_atoms; Cell *primitive, *bravais, *conv_prim; Symmetry *conv_sym; VecDBL *pure_trans; Spacegroup spacegroup; pure_trans = sym_get_pure_translation( cell, symprec ); 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 ) { cel_free_cell( primitive ); bravais = cel_alloc_cell( -1 ); goto ret; } spacegroup = spa_get_spacegroup_with_primitive( primitive, symprec ); wyckoffs = (int*)malloc( sizeof( int ) * primitive->size ); equiv_atoms = (int*)malloc( sizeof( int ) * primitive->size ); conv_prim = get_bravais_exact_positions_and_lattice( wyckoffs, equiv_atoms, &spacegroup, primitive, symprec ); free( equiv_atoms ); equiv_atoms = NULL; free( wyckoffs ); wyckoffs = NULL; conv_sym = get_db_symmetry( spacegroup.hall_number ); bravais = expand_positions( conv_prim, conv_sym ); cel_free_cell( conv_prim ); sym_free_symmetry( conv_sym ); cel_free_cell( primitive ); ret: /* Return bravais->size = -1, if the bravais could not be found. */ return bravais; }
/* NULL is returned if failed */ Primitive * spa_get_spacegroup(Spacegroup * spacegroup, SPGCONST Cell * cell, const double symprec) { int attempt; double tolerance; Primitive *primitive; debug_print("spa_get_spacegroup (tolerance = %f):\n", symprec); primitive = NULL; tolerance = symprec; for (attempt = 0; attempt < 100; attempt++) { if ((primitive = prm_get_primitive(cell, tolerance)) == NULL) { goto cont; } *spacegroup = search_spacegroup(primitive->cell, spacegroup_to_hall_number, 230, primitive->tolerance); if (spacegroup->number > 0) { break; } else { prm_free_primitive(primitive); primitive = NULL; } cont: warning_print("spglib: Attempt %d tolerance = %f failed.", attempt, tolerance); warning_print(" (line %d, %s).\n", __LINE__, __FILE__); tolerance *= REDUCE_RATE; } if (primitive == NULL) { warning_print("spglib: Space group could not be found "); warning_print("(line %d, %s).\n", __LINE__, __FILE__); } return primitive; }
int spg_find_primitive( double lattice[3][3], double position[][3], int types[], const int num_atom, const double symprec ) { int i, j, num_prim_atom=0; int *mapping_table; Cell *cell, *primitive; VecDBL *pure_trans; cell = cel_alloc_cell( num_atom ); cel_set_cell( cell, lattice, position, types ); pure_trans = sym_get_pure_translation( cell, symprec ); /* find primitive cell */ if ( pure_trans->size > 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; num_prim_atom = primitive->size; if ( num_prim_atom < num_atom && num_prim_atom > 0 ) { mat_copy_matrix_d3( lattice, primitive->lattice ); for ( i = 0; i < primitive->size; i++ ) { types[i] = primitive->types[i]; for (j=0; j<3; j++) { position[i][j] = primitive->position[i][j]; } } } cel_free_cell( primitive ); } else { num_prim_atom = 0; } mat_free_VecDBL( pure_trans ); cel_free_cell( cell ); return num_prim_atom; }
Spacegroup spa_get_spacegroup(SPGCONST Cell * cell, const double symprec) { double tolerance; Cell *primitive; Spacegroup spacegroup; primitive = prm_get_primitive(cell, symprec); tolerance = prm_get_current_tolerance(); if (primitive->size > 0) { spacegroup = get_spacegroup(primitive, tolerance); } else { spacegroup.number = 0; warning_print("spglib: Space group could not be found "); warning_print("(line %d, %s).\n", __LINE__, __FILE__); } cel_free_cell(primitive); return spacegroup; }
/* Return 0 if failed */ static int find_primitive(double lattice[3][3], double position[][3], int types[], const int num_atom, const double symprec) { int i, num_prim_atom; Cell *cell; Primitive *primitive; cell = NULL; primitive = NULL; num_prim_atom = 0; if ((cell = cel_alloc_cell(num_atom)) == NULL) { return 0; } cel_set_cell(cell, lattice, position, types); /* find primitive cell */ if ((primitive = prm_get_primitive(cell, symprec)) == NULL) { cel_free_cell(cell); return 0; } num_prim_atom = primitive->cell->size; if (num_prim_atom < num_atom && num_prim_atom > 0 ) { mat_copy_matrix_d3(lattice, primitive->cell->lattice); for (i = 0; i < primitive->cell->size; i++) { types[i] = primitive->cell->types[i]; mat_copy_vector_d3(position[i], primitive->cell->position[i]); } } prm_free_primitive(primitive); cel_free_cell(cell); return num_prim_atom; }
/* 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; }
SpglibDataset * spg_get_dataset( SPGCONST double lattice[3][3], SPGCONST double position[][3], const int types[], const int num_atom, const double symprec ) { int i, j; int *mapping_table, *wyckoffs, *equiv_atoms, *equiv_atoms_prim; Spacegroup spacegroup; SpglibDataset *dataset; Cell *cell, *primitive; double inv_mat[3][3]; Symmetry *symmetry; VecDBL *pure_trans; dataset = (SpglibDataset*) malloc( sizeof( SpglibDataset ) ); cell = cel_alloc_cell( num_atom ); cel_set_cell( cell, lattice, position, types ); pure_trans = sym_get_pure_translation( cell, symprec ); mapping_table = (int*) malloc( sizeof(int) * cell->size ); primitive = prm_get_primitive( mapping_table, cell, pure_trans, symprec ); mat_free_VecDBL( pure_trans ); spacegroup = spa_get_spacegroup_with_primitive( primitive, symprec ); /* Spacegroup type, transformation matrix, origin shift */ if ( spacegroup.number > 0 ) { dataset->spacegroup_number = spacegroup.number; strcpy( dataset->international_symbol, spacegroup.international_short); strcpy( dataset->hall_symbol, spacegroup.hall_symbol); mat_inverse_matrix_d3( inv_mat, lattice, symprec ); mat_multiply_matrix_d3( dataset->transformation_matrix, inv_mat, spacegroup.bravais_lattice ); mat_copy_vector_d3( dataset->origin_shift, spacegroup.origin_shift ); } /* Wyckoff positions */ wyckoffs = (int*) malloc( sizeof(int) * primitive->size ); equiv_atoms_prim = (int*) malloc( sizeof(int) * primitive->size ); for ( i = 0; i < primitive->size; i++ ) { wyckoffs[i] = -1; equiv_atoms_prim[i] = -1; } ref_get_Wyckoff_positions( wyckoffs, equiv_atoms_prim, primitive, &spacegroup, symprec ); dataset->n_atoms = cell->size; dataset->wyckoffs = (int*) malloc( sizeof(int) * cell->size ); for ( i = 0; i < cell->size; i++ ) { dataset->wyckoffs[i] = wyckoffs[ mapping_table[i] ]; } free( wyckoffs ); wyckoffs = NULL; dataset->equivalent_atoms = (int*) malloc( sizeof(int) * cell->size ); equiv_atoms = (int*) malloc( sizeof(int) * primitive->size ); for ( i = 0; i < primitive->size; i++ ) { for ( j = 0; j < cell->size; j++ ) { if ( mapping_table[j] == equiv_atoms_prim[i] ) { equiv_atoms[i] = j; break; } } } for ( i = 0; i < cell->size; i++ ) { dataset->equivalent_atoms[i] = equiv_atoms[ mapping_table[i] ]; } free( equiv_atoms ); equiv_atoms = NULL; free( equiv_atoms_prim ); equiv_atoms_prim = NULL; free( mapping_table ); mapping_table = NULL; /* Symmetry operations */ symmetry = ref_get_refined_symmetry_operations( cell, primitive->lattice, &spacegroup, symprec ); cel_free_cell( cell ); cel_free_cell( primitive ); dataset->rotations = (int (*)[3][3]) malloc(sizeof(int[3][3]) * symmetry->size ); dataset->translations = (double (*)[3]) malloc(sizeof(double[3]) * symmetry->size ); dataset->n_operations = symmetry->size; for ( i = 0; i < symmetry->size; i++ ) { mat_copy_matrix_i3( dataset->rotations[i], symmetry->rot[i] ); mat_copy_vector_d3( dataset->translations[i], symmetry->trans[i] ); } sym_free_symmetry( symmetry ); return dataset; }