static PyObject * get_dataset(PyObject *self, PyObject *args) { int i, j, k, num_atom; double symprec; SpglibDataset *dataset; PyArrayObject* lattice_vectors; PyArrayObject* atomic_positions; PyArrayObject* atom_types; PyObject* array, *vec, *mat, *rot, *trans, *wyckoffs, *equiv_atoms; double *p_lattice; double *p_positions; double lattice[3][3]; double (*positions)[3]; int *types_int; int *types; if (!PyArg_ParseTuple(args, "OOOd", &lattice_vectors, &atomic_positions, &atom_types, &symprec)) { return NULL; } p_lattice = (double(*))lattice_vectors->data; p_positions = (double(*))atomic_positions->data; num_atom = atom_types->dimensions[0]; positions = (double(*)[3]) malloc(sizeof(double[3]) * num_atom); types_int = (int*)atom_types->data; types = (int*) malloc(sizeof(int) * num_atom); set_spglib_cell(lattice, positions, types, num_atom, p_lattice, p_positions, types_int); dataset = spg_get_dataset(lattice, positions, types, num_atom, symprec); free(types); free(positions); array = PyList_New(10); /* Space group number, international symbol, hall symbol */ PyList_SetItem(array, 0, PyInt_FromLong((long) dataset->spacegroup_number)); PyList_SetItem(array, 1, PyString_FromString(dataset->international_symbol)); PyList_SetItem(array, 2, PyInt_FromLong((long) dataset->hall_number)); PyList_SetItem(array, 3, PyString_FromString(dataset->hall_symbol)); /* Transformation matrix */ mat = PyList_New(3); for (i = 0; i < 3; i++) { vec = PyList_New(3); for (j = 0; j < 3; j++) { PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->transformation_matrix[i][j])); } PyList_SetItem(mat, i, vec); } PyList_SetItem(array, 4, mat); /* Origin shift */ vec = PyList_New(3); for (i = 0; i < 3; i++) { PyList_SetItem(vec, i, PyFloat_FromDouble(dataset->origin_shift[i])); } PyList_SetItem(array, 5, vec); /* Rotation matrices */ rot = PyList_New(dataset->n_operations); for (i = 0; i < dataset->n_operations; i++) { mat = PyList_New(3); for (j = 0; j < 3; j++) { vec = PyList_New(3); for (k = 0; k < 3; k++) { PyList_SetItem(vec, k, PyInt_FromLong((long) dataset->rotations[i][j][k])); } PyList_SetItem(mat, j, vec); } PyList_SetItem(rot, i, mat); } PyList_SetItem(array, 6, rot); /* Translation vectors */ trans = PyList_New(dataset->n_operations); for (i = 0; i < dataset->n_operations; i++) { vec = PyList_New(3); for (j = 0; j < 3; j++) { PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->translations[i][j])); } PyList_SetItem(trans, i, vec); } PyList_SetItem(array, 7, trans); /* Wyckoff letters, Equivalent atoms */ wyckoffs = PyList_New(dataset->n_atoms); equiv_atoms = PyList_New(dataset->n_atoms); for (i = 0; i < dataset->n_atoms; i++) { PyList_SetItem(wyckoffs, i, PyInt_FromLong((long) dataset->wyckoffs[i])); PyList_SetItem(equiv_atoms, i, PyInt_FromLong((long) dataset->equivalent_atoms[i])); } PyList_SetItem(array, 8, wyckoffs); PyList_SetItem(array, 9, equiv_atoms); spg_free_dataset(dataset); return array; }
static int refine_cell(double lattice[3][3], double position[][3], int types[], const int num_atom, const double symprec) { int i, n_brv_atoms; SpglibDataset *dataset; n_brv_atoms = 0; dataset = NULL; if ((dataset = get_dataset(lattice, position, types, num_atom, 0, symprec)) == NULL) { return 0; } n_brv_atoms = dataset->n_brv_atoms; mat_copy_matrix_d3(lattice, dataset->brv_lattice); for (i = 0; i < dataset->n_brv_atoms; i++) { types[i] = dataset->brv_types[i]; mat_copy_vector_d3(position[i], dataset->brv_positions[i]); } spg_free_dataset(dataset); return n_brv_atoms; }
/* Return 0 if failed */ static int get_multiplicity(SPGCONST double lattice[3][3], SPGCONST double position[][3], const int types[], const int num_atom, const double symprec) { int size; SpglibDataset *dataset; size = 0; dataset = NULL; if ((dataset = get_dataset(lattice, position, types, num_atom, 0, symprec)) == NULL) { return 0; } size = dataset->n_operations; spg_free_dataset(dataset); return size; }
/*---------*/ static int get_ir_reciprocal_mesh(int grid_address[][3], int map[], const int mesh[3], const int is_shift[3], const int is_time_reversal, SPGCONST double lattice[3][3], SPGCONST double position[][3], const int types[], const int num_atom, const double symprec) { SpglibDataset *dataset; int num_ir, i; MatINT *rotations; dataset = get_dataset(lattice, position, types, num_atom, symprec); rotations = mat_alloc_MatINT(dataset->n_operations); for (i = 0; i < dataset->n_operations; i++) { mat_copy_matrix_i3(rotations->mat[i], dataset->rotations[i]); } num_ir = kpt_get_irreducible_reciprocal_mesh(grid_address, map, mesh, is_shift, is_time_reversal, rotations); mat_free_MatINT(rotations); spg_free_dataset(dataset); return num_ir; }
static int test_spg_get_stabilized_reciprocal_mesh(void) { SpglibDataset *dataset; double lattice[3][3] = {{4, 0, 0}, {0, 4, 0}, {0, 0, 3}}; double position[][3] = { {0, 0, 0}, {0.5, 0.5, 0.5}, {0.3, 0.3, 0}, {0.7, 0.7, 0}, {0.2, 0.8, 0.5}, {0.8, 0.2, 0.5}, }; int types[] = {1, 1, 2, 2, 2, 2}; int num_atom = 6; dataset = spg_get_dataset(lattice, position, types, num_atom, 1e-5); if (dataset == NULL) { return 1; } int m = 40; int mesh[] = {m, m, m}; int is_shift[] = {1, 1, 1}; int grid_address[m * m * m][3]; int grid_mapping_table[m * m * m]; double q[] = {0, 0.5, 0.5}; printf("*** spg_get_stabilized_reciprocal_mesh of Rutile structure ***:\n"); int num_ir = spg_get_stabilized_reciprocal_mesh(grid_address, grid_mapping_table, mesh, is_shift, 1, dataset->n_operations, dataset->rotations, 1, (double(*)[3])q); spg_free_dataset(dataset); if (num_ir) { printf("Number of irreducible k-points stabilized by q=(0, 1/2, 1/2) of Rutile with\n"); printf("40x40x40 Monkhorst-Pack mesh is %d (8000).\n", num_ir); return 0; } else { return 1; } }
/* Return 0 if failed */ static int get_symmetry_from_dataset(int rotation[][3][3], double translation[][3], const int max_size, SPGCONST double lattice[3][3], SPGCONST double position[][3], const int types[], const int num_atom, const double symprec) { int i, num_sym; SpglibDataset *dataset; num_sym = 0; dataset = NULL; if ((dataset = get_dataset(lattice, position, types, num_atom, 0, symprec)) == NULL) { return 0; } if (dataset->n_operations > max_size) { fprintf(stderr, "spglib: Indicated max size(=%d) is less than number ", max_size); fprintf(stderr, "spglib: of symmetry operations(=%d).\n", dataset->n_operations); goto ret; } num_sym = dataset->n_operations; for (i = 0; i < num_sym; i++) { mat_copy_matrix_i3(rotation[i], dataset->rotations[i]); mat_copy_vector_d3(translation[i], dataset->translations[i]); } ret: spg_free_dataset(dataset); return num_sym; }
static PyObject * get_dataset(PyObject *self, PyObject *args) { int i, j, k, n; double symprec, angle_tolerance; SpglibDataset *dataset; PyArrayObject* lattice; PyArrayObject* position; PyArrayObject* atom_type; PyObject *array, *vec, *mat, *rot, *trans, *wyckoffs, *equiv_atoms; PyObject *std_lattice, *std_types, *std_positions; if (!PyArg_ParseTuple(args, "OOOdd", &lattice, &position, &atom_type, &symprec, &angle_tolerance)) { return NULL; } SPGCONST double (*lat)[3] = (double(*)[3])PyArray_DATA(lattice); SPGCONST double (*pos)[3] = (double(*)[3])PyArray_DATA(position); const int num_atom = PyArray_DIMS(position)[0]; const int* typat = (int*)PyArray_DATA(atom_type); dataset = spgat_get_dataset(lat, pos, typat, num_atom, symprec, angle_tolerance); array = PyList_New(15); n = 0; /* Space group number, international symbol, hall symbol */ PyList_SetItem(array, n, PyLong_FromLong((long) dataset->spacegroup_number)); n++; PyList_SetItem(array, n, PyLong_FromLong((long) dataset->hall_number)); n++; PyList_SetItem(array, n, PYUNICODE_FROMSTRING(dataset->international_symbol)); n++; PyList_SetItem(array, n, PYUNICODE_FROMSTRING(dataset->hall_symbol)); n++; /* Transformation matrix */ mat = PyList_New(3); for (i = 0; i < 3; i++) { vec = PyList_New(3); for (j = 0; j < 3; j++) { PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->transformation_matrix[i][j])); } PyList_SetItem(mat, i, vec); } PyList_SetItem(array, n, mat); n++; /* Origin shift */ vec = PyList_New(3); for (i = 0; i < 3; i++) { PyList_SetItem(vec, i, PyFloat_FromDouble(dataset->origin_shift[i])); } PyList_SetItem(array, n, vec); n++; /* Rotation matrices */ rot = PyList_New(dataset->n_operations); for (i = 0; i < dataset->n_operations; i++) { mat = PyList_New(3); for (j = 0; j < 3; j++) { vec = PyList_New(3); for (k = 0; k < 3; k++) { PyList_SetItem(vec, k, PyLong_FromLong((long) dataset->rotations[i][j][k])); } PyList_SetItem(mat, j, vec); } PyList_SetItem(rot, i, mat); } PyList_SetItem(array, n, rot); n++; /* Translation vectors */ trans = PyList_New(dataset->n_operations); for (i = 0; i < dataset->n_operations; i++) { vec = PyList_New(3); for (j = 0; j < 3; j++) { PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->translations[i][j])); } PyList_SetItem(trans, i, vec); } PyList_SetItem(array, n, trans); n++; /* Wyckoff letters, Equivalent atoms */ wyckoffs = PyList_New(dataset->n_atoms); equiv_atoms = PyList_New(dataset->n_atoms); for (i = 0; i < dataset->n_atoms; i++) { PyList_SetItem(wyckoffs, i, PyLong_FromLong((long) dataset->wyckoffs[i])); PyList_SetItem(equiv_atoms, i, PyLong_FromLong((long) dataset->equivalent_atoms[i])); } PyList_SetItem(array, n, wyckoffs); n++; PyList_SetItem(array, n, equiv_atoms); n++; std_lattice = PyList_New(3); for (i = 0; i < 3; i++) { vec = PyList_New(3); for (j = 0; j < 3; j++) { PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->std_lattice[i][j])); } PyList_SetItem(std_lattice, i, vec); } PyList_SetItem(array, n, std_lattice); n++; /* Standardized unit cell */ std_types = PyList_New(dataset->n_std_atoms); std_positions = PyList_New(dataset->n_std_atoms); for (i = 0; i < dataset->n_std_atoms; i++) { vec = PyList_New(3); for (j = 0; j < 3; j++) { PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->std_positions[i][j])); } PyList_SetItem(std_types, i, PyLong_FromLong((long) dataset->std_types[i])); PyList_SetItem(std_positions, i, vec); } PyList_SetItem(array, n, std_types); n++; PyList_SetItem(array, n, std_positions); n++; /* Point group */ PyList_SetItem(array, n, PyLong_FromLong((long) dataset->pointgroup_number)); n++; PyList_SetItem(array, n, PYUNICODE_FROMSTRING(dataset->pointgroup_symbol)); n++; spg_free_dataset(dataset); return array; }
static PyObject * get_dataset(PyObject *self, PyObject *args) { int i, j, k; double symprec, angle_tolerance; SpglibDataset *dataset; PyArrayObject* lattice; PyArrayObject* position; PyArrayObject* atom_type; PyObject* array, *vec, *mat, *rot, *trans, *wyckoffs, *equiv_atoms; if (!PyArg_ParseTuple(args, "OOOdd", &lattice, &position, &atom_type, &symprec, &angle_tolerance)) { return NULL; } SPGCONST double (*lat)[3] = (double(*)[3])lattice->data; SPGCONST double (*pos)[3] = (double(*)[3])position->data; const int num_atom = position->dimensions[0]; const int* typat = (int*)atom_type->data; dataset = spgat_get_dataset(lat, pos, typat, num_atom, symprec, angle_tolerance); array = PyList_New(9); /* Space group number, international symbol, hall symbol */ PyList_SetItem(array, 0, PyInt_FromLong((long) dataset->spacegroup_number)); PyList_SetItem(array, 1, PyString_FromString(dataset->international_symbol)); PyList_SetItem(array, 2, PyString_FromString(dataset->hall_symbol)); /* Transformation matrix */ mat = PyList_New(3); for (i = 0; i < 3; i++) { vec = PyList_New(3); for (j = 0; j < 3; j++) { PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->transformation_matrix[i][j])); } PyList_SetItem(mat, i, vec); } PyList_SetItem(array, 3, mat); /* Origin shift */ vec = PyList_New(3); for (i = 0; i < 3; i++) { PyList_SetItem(vec, i, PyFloat_FromDouble(dataset->origin_shift[i])); } PyList_SetItem(array, 4, vec); /* Rotation matrices */ rot = PyList_New(dataset->n_operations); for (i = 0; i < dataset->n_operations; i++) { mat = PyList_New(3); for (j = 0; j < 3; j++) { vec = PyList_New(3); for (k = 0; k < 3; k++) { PyList_SetItem(vec, k, PyInt_FromLong((long) dataset->rotations[i][j][k])); } PyList_SetItem(mat, j, vec); } PyList_SetItem(rot, i, mat); } PyList_SetItem(array, 5, rot); /* Translation vectors */ trans = PyList_New(dataset->n_operations); for (i = 0; i < dataset->n_operations; i++) { vec = PyList_New(3); for (j = 0; j < 3; j++) { PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->translations[i][j])); } PyList_SetItem(trans, i, vec); } PyList_SetItem(array, 6, trans); /* Wyckoff letters, Equivalent atoms */ wyckoffs = PyList_New(dataset->n_atoms); equiv_atoms = PyList_New(dataset->n_atoms); for (i = 0; i < dataset->n_atoms; i++) { PyList_SetItem(wyckoffs, i, PyInt_FromLong((long) dataset->wyckoffs[i])); PyList_SetItem(equiv_atoms, i, PyInt_FromLong((long) dataset->equivalent_atoms[i])); } PyList_SetItem(array, 7, wyckoffs); PyList_SetItem(array, 8, equiv_atoms); spg_free_dataset(dataset); return array; }
static int show_spg_dataset(double lattice[3][3], const double origin_shift[3], double position[][3], const int num_atom, const int types[]) { SpglibDataset *dataset; char ptsymbol[6]; int pt_trans_mat[3][3]; int i, j; const char *wl = "abcdefghijklmnopqrstuvwxyz"; for ( i = 0; i < num_atom; i++ ) { for ( j = 0; j < 3; j++ ) { position[i][j] += origin_shift[j]; } } dataset = spg_get_dataset(lattice, position, types, num_atom, 1e-5); if (dataset == NULL) { return 1; } printf("International: %s (%d)\n", dataset->international_symbol, dataset->spacegroup_number ); printf("Hall symbol: %s\n", dataset->hall_symbol ); if (spg_get_pointgroup(ptsymbol, pt_trans_mat, dataset->rotations, dataset->n_operations)) { printf("Point group: %s\n", ptsymbol); printf("Transformation matrix:\n"); for ( i = 0; i < 3; i++ ) { printf("%f %f %f\n", dataset->transformation_matrix[i][0], dataset->transformation_matrix[i][1], dataset->transformation_matrix[i][2]); } printf("Wyckoff letters:\n"); for ( i = 0; i < dataset->n_atoms; i++ ) { printf("%c ", wl[dataset->wyckoffs[i]]); } printf("\n"); printf("Equivalent atoms:\n"); for (i = 0; i < dataset->n_atoms; i++) { printf("%d ", dataset->equivalent_atoms[i]); } printf("\n"); for (i = 0; i < dataset->n_operations; i++) { printf("--- %d ---\n", i + 1); for (j = 0; j < 3; j++) { printf("%2d %2d %2d\n", dataset->rotations[i][j][0], dataset->rotations[i][j][1], dataset->rotations[i][j][2]); } printf("%f %f %f\n", dataset->translations[i][0], dataset->translations[i][1], dataset->translations[i][2]); } spg_free_dataset(dataset); return 0; } else { spg_free_dataset(dataset); return 1; } }
/* Return 0 if failed */ static int get_symmetry_with_collinear_spin(int rotation[][3][3], double translation[][3], int equivalent_atoms[], const int max_size, SPGCONST double lattice[3][3], SPGCONST double position[][3], const int types[], const double spins[], const int num_atom, const double symprec) { int i, size; Symmetry *symmetry, *sym_nonspin; Cell *cell; SpglibDataset *dataset; size = 0; symmetry = NULL; sym_nonspin = NULL; cell = NULL; dataset = NULL; if ((cell = cel_alloc_cell(num_atom)) == NULL) { goto err; } cel_set_cell(cell, lattice, position, types); if ((dataset = get_dataset(lattice, position, types, num_atom, 0, symprec)) == NULL) { cel_free_cell(cell); goto err; } if ((sym_nonspin = sym_alloc_symmetry(dataset->n_operations)) == NULL) { spg_free_dataset(dataset); cel_free_cell(cell); goto err; } for (i = 0; i < dataset->n_operations; i++) { mat_copy_matrix_i3(sym_nonspin->rot[i], dataset->rotations[i]); mat_copy_vector_d3(sym_nonspin->trans[i], dataset->translations[i]); } spg_free_dataset(dataset); if ((symmetry = spn_get_collinear_operations(equivalent_atoms, sym_nonspin, cell, spins, symprec)) == NULL) { sym_free_symmetry(sym_nonspin); cel_free_cell(cell); goto err; } sym_free_symmetry(sym_nonspin); if (symmetry->size > max_size) { fprintf(stderr, "spglib: Indicated max size(=%d) is less than number ", max_size); fprintf(stderr, "spglib: of symmetry operations(=%d).\n", symmetry->size); sym_free_symmetry(symmetry); goto err; } for (i = 0; i < symmetry->size; i++) { mat_copy_matrix_i3(rotation[i], symmetry->rot[i]); mat_copy_vector_d3(translation[i], symmetry->trans[i]); } size = symmetry->size; cel_free_cell(cell); sym_free_symmetry(symmetry); return size; err: return 0; }
static int get_standardized_cell(double lattice[3][3], double position[][3], int types[], const int num_atom, const int to_primitive, const double symprec) { int num_std_atom; SpglibDataset *dataset; Cell *std_cell, *cell; Centering centering; num_std_atom = 0; dataset = NULL; std_cell = NULL; cell = NULL; if ((dataset = get_dataset(lattice, position, types, num_atom, 0, symprec)) == NULL) { goto err; } if (to_primitive) { if ((centering = get_centering(dataset->hall_number)) == CENTERING_ERROR) { goto err; } if (dataset->hall_number == 433 || dataset->hall_number == 436 || dataset->hall_number == 444 || dataset->hall_number == 450 || dataset->hall_number == 452 || dataset->hall_number == 458 || dataset->hall_number == 460) { centering = R_CENTER; } } else { centering = PRIMITIVE; } if ((cell = cel_alloc_cell(num_atom)) == NULL) { spg_free_dataset(dataset); goto err; } cel_set_cell(cell, lattice, position, types); std_cell = spa_transform_to_primitive(cell, dataset->transformation_matrix, centering, symprec); spg_free_dataset(dataset); cel_free_cell(cell); if (std_cell == NULL) { goto err; } set_cell(lattice, position, types, std_cell); num_std_atom = std_cell->size; cel_free_cell(std_cell); return num_std_atom; err: return 0; }
static int standardize_primitive(double lattice[3][3], double position[][3], int types[], const int num_atom, const double symprec) { int num_prim_atom; Centering centering; SpglibDataset *dataset; Cell *primitive, *bravais; double identity[3][3] = {{ 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }}; num_prim_atom = 0; dataset = NULL; primitive = NULL; bravais = NULL; if ((dataset = get_dataset(lattice, position, types, num_atom, 0, symprec)) == NULL) { return 0; } if ((centering = get_centering(dataset->hall_number)) == CENTERING_ERROR) { goto err; } if (dataset->hall_number == 433 || dataset->hall_number == 436 || dataset->hall_number == 444 || dataset->hall_number == 450 || dataset->hall_number == 452 || dataset->hall_number == 458 || dataset->hall_number == 460) { centering = R_CENTER; } if ((bravais = cel_alloc_cell(dataset->n_std_atoms)) == NULL) { spg_free_dataset(dataset); return 0; } cel_set_cell(bravais, dataset->std_lattice, dataset->std_positions, dataset->std_types); spg_free_dataset(dataset); primitive = spa_transform_to_primitive(bravais, identity, centering, symprec); cel_free_cell(bravais); if (primitive == NULL) { goto err; } set_cell(lattice, position, types, primitive); num_prim_atom = primitive->size; cel_free_cell(primitive); return num_prim_atom; err: return 0; }