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; }
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; }
/*---------*/ static SpglibDataset * get_dataset(SPGCONST double lattice[3][3], SPGCONST double position[][3], const int types[], const int num_atom, const double symprec) { int attempt; int *mapping_table; double tolerance, tolerance_from_prim; Spacegroup spacegroup; SpglibDataset *dataset; Cell *cell, *primitive; dataset = (SpglibDataset*) malloc(sizeof(SpglibDataset)); dataset->spacegroup_number = 0; strcpy(dataset->international_symbol, ""); strcpy(dataset->hall_symbol, ""); strcpy(dataset->setting, ""); dataset->origin_shift[0] = 0; dataset->origin_shift[1] = 0; dataset->origin_shift[2] = 0; dataset->n_atoms = 0; dataset->wyckoffs = NULL; dataset->equivalent_atoms = NULL; dataset->n_operations = 0; dataset->rotations = NULL; dataset->translations = NULL; mapping_table = (int*) malloc(sizeof(int) * num_atom); cell = cel_alloc_cell(num_atom); cel_set_cell(cell, lattice, position, types); tolerance = symprec; for (attempt = 0; attempt < 100; attempt++) { primitive = prm_get_primitive_and_mapping_table(mapping_table, cell, tolerance); if (primitive->size > 0) { tolerance_from_prim = prm_get_current_tolerance(); spacegroup = spa_get_spacegroup_with_primitive(primitive, tolerance_from_prim); if (spacegroup.number > 0) { set_dataset(dataset, cell, primitive, &spacegroup, mapping_table, tolerance_from_prim); cel_free_cell(primitive); break; } } tolerance *= REDUCE_RATE; cel_free_cell(primitive); warning_print(" Attempt %d tolerance = %f failed.", attempt, tolerance); warning_print(" (line %d, %s).\n", __LINE__, __FILE__); } free(mapping_table); mapping_table = NULL; cel_free_cell(cell); return dataset; }
static SpglibDataset * 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; double tolerance; Spacegroup spacegroup; SpglibDataset *dataset; Cell *cell, *primitive; double inv_mat[3][3]; Symmetry *symmetry; dataset = (SpglibDataset*) malloc(sizeof(SpglibDataset)); cell = cel_alloc_cell(num_atom); cel_set_cell(cell, lattice, position, types); mapping_table = (int*) malloc(sizeof(int) * cell->size); primitive = prm_get_primitive_with_mapping_table(mapping_table, cell, symprec); tolerance = prm_get_current_tolerance(); spacegroup = spa_get_spacegroup_with_primitive(primitive, tolerance); if (spacegroup.number > 0) { /* Spacegroup type, transformation matrix, origin shift */ dataset->spacegroup_number = spacegroup.number; dataset->hall_number = spacegroup.hall_number; strcpy(dataset->international_symbol, spacegroup.international_short); strcpy(dataset->hall_symbol, spacegroup.hall_symbol); mat_inverse_matrix_d3(inv_mat, lattice, tolerance); 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, tolerance); 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; /* Equivalent atoms */ 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; /* Symmetry operations */ symmetry = ref_get_refined_symmetry_operations(cell, primitive, &spacegroup, tolerance); 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); } else { dataset->spacegroup_number = 0; } free(mapping_table); mapping_table = NULL; cel_free_cell(primitive); if (dataset->spacegroup_number == 0) { strcpy(dataset->international_symbol, ""); strcpy(dataset->hall_symbol, ""); dataset->origin_shift[0] = 0; dataset->origin_shift[1] = 0; dataset->origin_shift[2] = 0; dataset->n_atoms = 0; dataset->wyckoffs = NULL; dataset->equivalent_atoms = NULL; dataset->n_operations = 0; dataset->rotations = NULL; dataset->translations = NULL; } cel_free_cell(cell); return dataset; }