static int get_schoenflies(char symbol[10], SPGCONST double lattice[3][3], SPGCONST double position[][3], const int types[], const int num_atom, const double symprec) { Cell *cell; Primitive *primitive; Spacegroup spacegroup; cell = NULL; primitive = NULL; spacegroup.number = 0; cell = cel_alloc_cell(num_atom); cel_set_cell(cell, lattice, position, types); if ((primitive = spa_get_spacegroup(&spacegroup, cell, symprec)) != NULL) { prm_free_primitive(primitive); if (spacegroup.number > 0) { strcpy(symbol, spacegroup.schoenflies); } } cel_free_cell(cell); return spacegroup.number; }
/* Return NULL if failed */ static Primitive * get_primitive(SPGCONST Cell * cell, const double symprec) { int i, attempt; double tolerance; Primitive *primitive; VecDBL * pure_trans; debug_print("get_primitive (tolerance = %f):\n", symprec); primitive = NULL; pure_trans = NULL; if ((primitive = prm_alloc_primitive(cell->size)) == NULL) { return NULL; } tolerance = symprec; for (attempt = 0; attempt < 100; attempt++) { if ((pure_trans = sym_get_pure_translation(cell, tolerance)) == NULL) { goto cont; } if (pure_trans->size == 1) { if ((primitive->cell = get_cell_with_smallest_lattice(cell, tolerance)) != NULL) { for (i = 0; i < cell->size; i++) { primitive->mapping_table[i] = i; } goto found; } } else { if ((primitive->cell = get_primitive_cell(primitive->mapping_table, cell, pure_trans, tolerance)) != NULL) { goto found; } } mat_free_VecDBL(pure_trans); cont: tolerance *= REDUCE_RATE; warning_print("spglib: Reduce tolerance to %f ", tolerance); warning_print("(line %d, %s).\n", __LINE__, __FILE__); } prm_free_primitive(primitive); return NULL; found: primitive->tolerance = tolerance; mat_free_VecDBL(pure_trans); return primitive; }
/* 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; }
/* 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; }
/* Return NULL if failed */ static SpglibDataset * get_dataset(SPGCONST double lattice[3][3], SPGCONST double position[][3], const int types[], const int num_atom, const int hall_number, const double symprec) { Spacegroup spacegroup; SpacegroupType spacegroup_type; SpglibDataset *dataset; Cell *cell; Primitive *primitive; spacegroup.number = 0; dataset = NULL; cell = NULL; primitive = NULL; if ((dataset = (SpglibDataset*) malloc(sizeof(SpglibDataset))) == NULL) { warning_print("spglib: Memory could not be allocated."); return NULL; } 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; dataset->n_brv_atoms = 0; dataset->brv_positions = NULL; dataset->brv_types = NULL; if ((cell = cel_alloc_cell(num_atom)) == NULL) { free(dataset); dataset = NULL; return NULL; } cel_set_cell(cell, lattice, position, types); primitive = spa_get_spacegroup(&spacegroup, cell, symprec); if ((spacegroup.number > 0) && (primitive != NULL)) { /* With hall_number > 0, specific choice is searched. */ if (hall_number > 0) { spacegroup_type = spgdb_get_spacegroup_type(hall_number); if (spacegroup.number == spacegroup_type.number) { spacegroup = spa_get_spacegroup_with_hall_number(primitive, hall_number); } else { goto err; } if (spacegroup.number == 0) { goto err; } } if (spacegroup.number > 0) { if ((set_dataset(dataset, cell, primitive->cell, &spacegroup, primitive->mapping_table, primitive->tolerance)) == 0) { goto err; } } } cel_free_cell(cell); prm_free_primitive(primitive); return dataset; err: cel_free_cell(cell); prm_free_primitive(primitive); free(dataset); dataset = NULL; return NULL; }