/* Return NULL if failed */ Cell * spa_transform_to_primitive(SPGCONST Cell * cell, SPGCONST double trans_mat[3][3], const Centering centering, const double symprec) { int * mapping_table; double tmat[3][3], tmat_inv[3][3], prim_lat[3][3]; Cell * primitive; mapping_table = NULL; primitive = NULL; mat_inverse_matrix_d3(tmat_inv, trans_mat, 0); switch (centering) { case PRIMITIVE: mat_copy_matrix_d3(tmat, tmat_inv); break; case A_FACE: mat_multiply_matrix_d3(tmat, tmat_inv, A_mat); break; case C_FACE: mat_multiply_matrix_d3(tmat, tmat_inv, C_mat); break; case FACE: mat_multiply_matrix_d3(tmat, tmat_inv, F_mat); break; case BODY: mat_multiply_matrix_d3(tmat, tmat_inv, I_mat); break; case R_CENTER: mat_multiply_matrix_d3(tmat, tmat_inv, R_mat); break; default: goto err; } if ((mapping_table = (int*) malloc(sizeof(int) * cell->size)) == NULL) { warning_print("spglib: Memory could not be allocated "); goto err; } mat_multiply_matrix_d3(prim_lat, cell->lattice, tmat); primitive = cel_trim_cell(mapping_table, prim_lat, cell, symprec); free(mapping_table); mapping_table = NULL; return primitive; err: return NULL; }
/* Return NULL if failed */ static Cell * get_primitive_cell(int * mapping_table, SPGCONST Cell * cell, const VecDBL * pure_trans, const double symprec) { int multi; double prim_lat[3][3], smallest_lat[3][3]; Cell * primitive_cell; debug_print("get_primitive:\n"); primitive_cell = NULL; /* Primitive lattice vectors are searched. */ /* To be consistent, sometimes tolerance is decreased iteratively. */ /* The descreased tolerance is stored in 'static double tolerance'. */ multi = get_primitive_lattice_vectors_iterative(prim_lat, cell, pure_trans, symprec); if (! multi) { goto not_found; } if (! lat_smallest_lattice_vector(smallest_lat, prim_lat, symprec)) { goto not_found; } /* Fit atoms into new primitive cell */ if ((primitive_cell = cel_trim_cell(mapping_table, smallest_lat, cell, symprec)) == NULL) { goto not_found; } /* found */ return primitive_cell; not_found: warning_print("spglib: Primitive cell could not be found "); warning_print("(line %d, %s).\n", __LINE__, __FILE__); return NULL; }