/* 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; }
/* primitive cell with smallest lattice is returned. */ static Primitive get_primitive_and_pure_translation(SPGCONST Cell * cell, const double symprec) { int attempt, is_found = 0; double tolerance; int *mapping_table; Primitive primitive; tolerance = symprec; for (attempt = 0; attempt < 100; attempt++) { primitive.pure_trans = sym_get_pure_translation(cell, tolerance); if (primitive.pure_trans->size == 0) { mat_free_VecDBL(primitive.pure_trans); continue; } if (primitive.pure_trans->size == 1) { primitive.cell = get_cell_with_smallest_lattice(cell, tolerance); } else { mapping_table = (int*) malloc(sizeof(int) * cell->size); primitive.cell = get_primitive(mapping_table, cell, primitive.pure_trans, tolerance); free(mapping_table); } if (primitive.cell->size > 0) { is_found = 1; break; } cel_free_cell(primitive.cell); mat_free_VecDBL(primitive.pure_trans); tolerance *= REDUCE_RATE; warning_print("spglib: Reduce tolerance to %f ", tolerance); warning_print("(line %d, %s).\n", __LINE__, __FILE__); } if (! is_found) { primitive.cell = cel_alloc_cell(0); primitive.pure_trans = mat_alloc_VecDBL(0); } return primitive; }
/* primitive cell with smallest lattice is returned. */ static Cell * get_primitive_and_mapping_table(int * mapping_table, SPGCONST Cell * cell, const double symprec) { int i, attempt; double tolerance; Cell *primitive_cell; VecDBL *pure_trans; tolerance = symprec; for (attempt = 0; attempt < 100; attempt++) { pure_trans = sym_get_pure_translation(cell, tolerance); if (pure_trans->size == 1) { primitive_cell = get_cell_with_smallest_lattice(cell, symprec); for (i = 0; i < cell->size; i++) { mapping_table[i] = i; } goto ret; } if (pure_trans->size > 1) { primitive_cell = get_primitive(mapping_table, cell, pure_trans, tolerance); if (primitive_cell->size > 0) { goto ret; } cel_free_cell(primitive_cell); } tolerance *= REDUCE_RATE; warning_print("spglib: Tolerance is reduced to %f at attempt %d\n", tolerance, attempt); warning_print("(line %d, %s).\n", __LINE__, __FILE__); mat_free_VecDBL(pure_trans); } /* not found: I hope this will not happen. */ warning_print("spglib: Primitive cell could not be found "); warning_print("(line %d, %s).\n", __LINE__, __FILE__); return cel_alloc_cell(0); ret: mat_free_VecDBL(pure_trans); set_current_tolerance(tolerance); return primitive_cell; }
Cell * prm_get_primitive( int * mapping_table, SPGCONST Cell * cell, const VecDBL *pure_trans, const double symprec ) { int i; Cell *primitive; /* If primitive could not be found, primitive->size = -1 is returned. */ /* If cell is already primitive cell, */ /* primitive cell with smallest lattice is returned. */ if ( pure_trans->size > 1 ) { primitive = get_primitive( mapping_table, cell, pure_trans, symprec ); } else { primitive = get_cell_with_smallest_lattice( cell, symprec ); for ( i = 0; i < cell->size; i++ ) { mapping_table[i] = i; } } return primitive; }