mirror of https://github.com/phonopy/phonopy.git
Spglib update to version 1.9.2
This commit is contained in:
parent
893ec5470d
commit
2c903fe1c5
19
c/_spglib.c
19
c/_spglib.c
|
@ -60,6 +60,7 @@ static PyObject * get_grid_points_by_rotations(PyObject *self, PyObject *args);
|
|||
static PyObject * get_BZ_grid_points_by_rotations(PyObject *self, PyObject *args);
|
||||
static PyObject * relocate_BZ_grid_address(PyObject *self, PyObject *args);
|
||||
static PyObject * get_symmetry_from_database(PyObject *self, PyObject *args);
|
||||
static PyObject * py_niggli_reduce(PyObject *self, PyObject *args);
|
||||
|
||||
struct module_state {
|
||||
PyObject *error;
|
||||
|
@ -107,6 +108,7 @@ static PyMethodDef _spglib_methods[] = {
|
|||
"Rotated grid points in BZ are returned"},
|
||||
{"BZ_grid_address", relocate_BZ_grid_address, METH_VARARGS,
|
||||
"Relocate grid addresses inside Brillouin zone"},
|
||||
{"niggli_reduce", py_niggli_reduce, METH_VARARGS, "Niggli reduction"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -363,7 +365,7 @@ static PyObject * get_spacegroup_type(PyObject *self, PyObject *args)
|
|||
PyObject *array;
|
||||
SpglibSpacegroupType symbols;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i",&hall_number)) {
|
||||
if (!PyArg_ParseTuple(args, "i", &hall_number)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -819,3 +821,18 @@ static PyObject * relocate_BZ_grid_address(PyObject *self, PyObject *args)
|
|||
|
||||
return PyLong_FromLong((long) num_ir_gp);
|
||||
}
|
||||
|
||||
static PyObject * py_niggli_reduce(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyArrayObject* lattice_py;
|
||||
double eps;
|
||||
if (!PyArg_ParseTuple(args, "Od", &lattice_py, &eps)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
double (*lattice)[3] = (double(*)[3])PyArray_DATA(lattice_py);
|
||||
|
||||
int result = spg_niggli_reduce(lattice, eps);
|
||||
|
||||
return PyLong_FromLong((long) result);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,8 @@ static VecDBL *
|
|||
translate_atoms_in_trimmed_lattice(SPGCONST Cell * cell,
|
||||
SPGCONST double prim_lat[3][3]);
|
||||
static int * get_overlap_table(const VecDBL * position,
|
||||
SPGCONST Cell * cell,
|
||||
const int cell_size,
|
||||
const int * cell_types,
|
||||
SPGCONST Cell * trimmed_cell,
|
||||
const double symprec);
|
||||
|
||||
|
@ -67,7 +68,13 @@ Cell * cel_alloc_cell(const int size)
|
|||
{
|
||||
Cell *cell;
|
||||
int i, j;
|
||||
|
||||
|
||||
cell = NULL;
|
||||
|
||||
if (size < 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cell = NULL;
|
||||
|
||||
if ((cell = (Cell*) malloc(sizeof(Cell))) == NULL) {
|
||||
|
@ -81,23 +88,21 @@ Cell * cel_alloc_cell(const int size)
|
|||
}
|
||||
}
|
||||
cell->size = size;
|
||||
|
||||
if (size > 0) {
|
||||
if ((cell->types = (int *) malloc(sizeof(int) * size)) == NULL) {
|
||||
warning_print("spglib: Memory could not be allocated.");
|
||||
free(cell);
|
||||
cell = NULL;
|
||||
return NULL;
|
||||
}
|
||||
if ((cell->position =
|
||||
(double (*)[3]) malloc(sizeof(double[3]) * size)) == NULL) {
|
||||
warning_print("spglib: Memory could not be allocated.");
|
||||
free(cell->types);
|
||||
cell->types = NULL;
|
||||
free(cell);
|
||||
cell = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((cell->types = (int *) malloc(sizeof(int) * size)) == NULL) {
|
||||
warning_print("spglib: Memory could not be allocated.");
|
||||
free(cell);
|
||||
cell = NULL;
|
||||
return NULL;
|
||||
}
|
||||
if ((cell->position =
|
||||
(double (*)[3]) malloc(sizeof(double[3]) * size)) == NULL) {
|
||||
warning_print("spglib: Memory could not be allocated.");
|
||||
free(cell->types);
|
||||
cell->types = NULL;
|
||||
free(cell);
|
||||
cell = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cell;
|
||||
|
@ -105,14 +110,17 @@ Cell * cel_alloc_cell(const int size)
|
|||
|
||||
void cel_free_cell(Cell * cell)
|
||||
{
|
||||
if (cell->size > 0) {
|
||||
free(cell->position);
|
||||
cell->position = NULL;
|
||||
free(cell->types);
|
||||
cell->types = NULL;
|
||||
if (cell != NULL) {
|
||||
if (cell->position != NULL) {
|
||||
free(cell->position);
|
||||
cell->position = NULL;
|
||||
}
|
||||
if (cell->types != NULL) {
|
||||
free(cell->types);
|
||||
cell->types = NULL;
|
||||
}
|
||||
free(cell);
|
||||
}
|
||||
free (cell);
|
||||
cell = NULL;
|
||||
}
|
||||
|
||||
void cel_set_cell(Cell * cell,
|
||||
|
@ -135,7 +143,7 @@ Cell * cel_copy_cell(SPGCONST Cell * cell)
|
|||
Cell * cell_new;
|
||||
|
||||
cell_new = NULL;
|
||||
|
||||
|
||||
if ((cell_new = cel_alloc_cell(cell->size)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -162,7 +170,7 @@ int cel_is_overlap(const double a[3],
|
|||
}
|
||||
|
||||
mat_multiply_matrix_vector_d3(v_diff, lattice, v_diff);
|
||||
if ( mat_norm_squared_d3(v_diff) < symprec * symprec) {
|
||||
if (mat_norm_squared_d3(v_diff) < symprec * symprec) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
|
@ -196,8 +204,8 @@ static Cell * trim_cell(int * mapping_table,
|
|||
overlap_table = NULL;
|
||||
trimmed_cell = NULL;
|
||||
|
||||
ratio = mat_Nint(mat_get_determinant_d3(cell->lattice) /
|
||||
mat_get_determinant_d3(trimmed_lattice));
|
||||
ratio = abs(mat_Nint(mat_get_determinant_d3(cell->lattice) /
|
||||
mat_get_determinant_d3(trimmed_lattice)));
|
||||
|
||||
/* Check if cell->size is dividable by ratio */
|
||||
if ((cell->size / ratio) * ratio != cell->size) {
|
||||
|
@ -212,17 +220,21 @@ static Cell * trim_cell(int * mapping_table,
|
|||
trimmed_lattice))
|
||||
== NULL) {
|
||||
cel_free_cell(trimmed_cell);
|
||||
trimmed_cell = NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
mat_copy_matrix_d3(trimmed_cell->lattice, trimmed_lattice);
|
||||
|
||||
if ((overlap_table = get_overlap_table(position,
|
||||
cell,
|
||||
cell->size,
|
||||
cell->types,
|
||||
trimmed_cell,
|
||||
symprec)) == NULL) {
|
||||
mat_free_VecDBL(position);
|
||||
position = NULL;
|
||||
cel_free_cell(trimmed_cell);
|
||||
trimmed_cell = NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -243,6 +255,7 @@ static Cell * trim_cell(int * mapping_table,
|
|||
overlap_table);
|
||||
|
||||
mat_free_VecDBL(position);
|
||||
position = NULL;
|
||||
free(overlap_table);
|
||||
|
||||
return trimmed_cell;
|
||||
|
@ -281,7 +294,7 @@ static void set_positions(Cell * trimmed_cell,
|
|||
trimmed_cell->position[j][l] += position->vec[i][l];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
multi = position->size / trimmed_cell->size;
|
||||
|
@ -327,7 +340,8 @@ translate_atoms_in_trimmed_lattice(SPGCONST Cell * cell,
|
|||
|
||||
/* Return NULL if failed */
|
||||
static int * get_overlap_table(const VecDBL * position,
|
||||
SPGCONST Cell * cell,
|
||||
const int cell_size,
|
||||
const int * cell_types,
|
||||
SPGCONST Cell * trimmed_cell,
|
||||
const double symprec)
|
||||
{
|
||||
|
@ -337,18 +351,18 @@ static int * get_overlap_table(const VecDBL * position,
|
|||
|
||||
trim_tolerance = symprec;
|
||||
|
||||
ratio = cell->size / trimmed_cell->size;
|
||||
ratio = cell_size / trimmed_cell->size;
|
||||
|
||||
if ((overlap_table = (int*)malloc(sizeof(int) * cell->size)) == NULL) {
|
||||
if ((overlap_table = (int*)malloc(sizeof(int) * cell_size)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
for (attempt = 0; attempt < 100; attempt++) {
|
||||
for (i = 0; i < cell->size; i++) {
|
||||
for (i = 0; i < cell_size; i++) {
|
||||
overlap_table[i] = -1;
|
||||
num_overlap = 0;
|
||||
for (j = 0; j < cell->size; j++) {
|
||||
if (cell->types[i] == cell->types[j]) {
|
||||
for (j = 0; j < cell_size; j++) {
|
||||
if (cell_types[i] == cell_types[j]) {
|
||||
if (cel_is_overlap(position->vec[i],
|
||||
position->vec[j],
|
||||
trimmed_cell->lattice,
|
||||
|
@ -379,12 +393,12 @@ static int * get_overlap_table(const VecDBL * position,
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < cell->size; i++) {
|
||||
for (i = 0; i < cell_size; i++) {
|
||||
if (overlap_table[i] != i) {
|
||||
continue;
|
||||
}
|
||||
count = 0;
|
||||
for (j = 0; j < cell->size; j++) {
|
||||
for (j = 0; j < cell_size; j++) {
|
||||
if (i == overlap_table[j]) {
|
||||
count++;
|
||||
}
|
||||
|
|
|
@ -252,7 +252,9 @@ int kpt_get_stabilized_reciprocal_mesh(int grid_address[][3],
|
|||
rot_reciprocal_q);
|
||||
|
||||
mat_free_MatINT(rot_reciprocal_q);
|
||||
rot_reciprocal_q = NULL;
|
||||
mat_free_MatINT(rot_reciprocal);
|
||||
rot_reciprocal = NULL;
|
||||
return num_ir;
|
||||
}
|
||||
|
||||
|
@ -362,6 +364,7 @@ static MatINT *get_point_group_reciprocal(const MatINT * rotations,
|
|||
if ((unique_rot = (int*)malloc(sizeof(int) * rot_reciprocal->size)) == NULL) {
|
||||
warning_print("spglib: Memory of unique_rot could not be allocated.");
|
||||
mat_free_MatINT(rot_reciprocal);
|
||||
rot_reciprocal = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,396 +0,0 @@
|
|||
/* Copyright (C) 2010 Atsushi Togo */
|
||||
/* All rights reserved. */
|
||||
|
||||
/* This file is part of spglib. */
|
||||
|
||||
/* Redistribution and use in source and binary forms, with or without */
|
||||
/* modification, are permitted provided that the following conditions */
|
||||
/* are met: */
|
||||
|
||||
/* * Redistributions of source code must retain the above copyright */
|
||||
/* notice, this list of conditions and the following disclaimer. */
|
||||
|
||||
/* * Redistributions in binary form must reproduce the above copyright */
|
||||
/* notice, this list of conditions and the following disclaimer in */
|
||||
/* the documentation and/or other materials provided with the */
|
||||
/* distribution. */
|
||||
|
||||
/* * Neither the name of the phonopy project nor the names of its */
|
||||
/* contributors may be used to endorse or promote products derived */
|
||||
/* from this software without specific prior written permission. */
|
||||
|
||||
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
|
||||
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
|
||||
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
|
||||
/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
|
||||
/* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
|
||||
/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
|
||||
/* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
|
||||
/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
|
||||
/* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
|
||||
/* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
|
||||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "lattice.h"
|
||||
#include "mathfunc.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
static int get_Delaunay_reduction(double red_lattice[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
SPGCONST double symprec);
|
||||
static int get_Delaunay_reduction_basis(double basis[4][3],
|
||||
const double symprec);
|
||||
static void get_Delaunay_shortest_vectors(double basis[4][3],
|
||||
const double symprec);
|
||||
static void get_exteneded_basis(double basis[4][3],
|
||||
SPGCONST double lattice[3][3]);
|
||||
static int get_Delaunay_reduction_2D(double red_lattice[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const int unique_axis,
|
||||
const double symprec);
|
||||
static int get_Delaunay_reduction_basis_2D(double basis[3][3],
|
||||
const double symprec);
|
||||
static void get_Delaunay_shortest_vectors_2D(double basis[3][3],
|
||||
const double unique_vec[3],
|
||||
const double symprec);
|
||||
static void get_exteneded_basis_2D(double basis[3][3],
|
||||
SPGCONST double lattice[3][2]);
|
||||
|
||||
/* Return 0 if failed */
|
||||
int lat_smallest_lattice_vector(double min_lattice[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const double symprec)
|
||||
{
|
||||
debug_print("lat_smallest_lattice_vector (tolerance = %f):\n", symprec);
|
||||
|
||||
return get_Delaunay_reduction(min_lattice, lattice, symprec);
|
||||
}
|
||||
|
||||
int lat_smallest_lattice_vector_2D(double min_lattice[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const int unique_axis,
|
||||
const double symprec)
|
||||
{
|
||||
debug_print("lat_smallest_lattice_vector_2D:\n");
|
||||
return get_Delaunay_reduction_2D(min_lattice, lattice, unique_axis, symprec);
|
||||
}
|
||||
|
||||
/* Delaunay reduction */
|
||||
/* Reference can be found in International table A. */
|
||||
/* Return 0 if failed */
|
||||
static int get_Delaunay_reduction(double red_lattice[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const double symprec)
|
||||
{
|
||||
int i, j;
|
||||
double volume, sum;
|
||||
double basis[4][3];
|
||||
|
||||
get_exteneded_basis(basis, lattice);
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
sum += basis[i][j] * basis[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (get_Delaunay_reduction_basis(basis, symprec)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
get_Delaunay_shortest_vectors(basis, symprec);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
red_lattice[i][j] = basis[j][i];
|
||||
}
|
||||
}
|
||||
|
||||
volume = mat_get_determinant_d3(red_lattice);
|
||||
if (mat_Dabs(volume) < symprec) {
|
||||
warning_print("spglib: Minimum lattice has no volume (line %d, %s).\n", __LINE__, __FILE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (volume < 0) {
|
||||
/* Flip axes */
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
red_lattice[i][j] = -red_lattice[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_Delaunay_shortest_vectors(double basis[4][3],
|
||||
const double symprec)
|
||||
{
|
||||
int i, j;
|
||||
double tmpmat[3][3], b[7][3], tmpvec[3];
|
||||
|
||||
/* Search in the set {b1, b2, b3, b4, b1+b2, b2+b3, b3+b1} */
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
b[i][j] = basis[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
b[4][i] = basis[0][i] + basis[1][i];
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
b[5][i] = basis[1][i] + basis[2][i];
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
b[6][i] = basis[2][i] + basis[0][i];
|
||||
}
|
||||
|
||||
/* Bubble sort */
|
||||
for (i = 0; i < 6; i++) {
|
||||
for (j = 0; j < 6; j++) {
|
||||
if (mat_norm_squared_d3(b[j]) > mat_norm_squared_d3(b[j+1])) {
|
||||
mat_copy_vector_d3(tmpvec, b[j]);
|
||||
mat_copy_vector_d3(b[j], b[j+1]);
|
||||
mat_copy_vector_d3(b[j+1], tmpvec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 2; i < 7; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
tmpmat[j][0] = b[0][j];
|
||||
tmpmat[j][1] = b[1][j];
|
||||
tmpmat[j][2] = b[i][j];
|
||||
}
|
||||
if (mat_Dabs(mat_get_determinant_d3(tmpmat)) > symprec) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
basis[0][j] = b[0][j];
|
||||
basis[1][j] = b[1][j];
|
||||
basis[2][j] = b[i][j];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int get_Delaunay_reduction_basis(double basis[4][3],
|
||||
const double symprec)
|
||||
{
|
||||
int i, j, k, l;
|
||||
double dot_product;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = i+1; j < 4; j++) {
|
||||
dot_product = 0.0;
|
||||
for (k = 0; k < 3; k++) {
|
||||
dot_product += basis[i][k] * basis[j][k];
|
||||
}
|
||||
if (dot_product > symprec) {
|
||||
for (k = 0; k < 4; k++) {
|
||||
if (! (k == i || k == j)) {
|
||||
for (l = 0; l < 3; l++) {
|
||||
basis[k][l] += basis[i][l];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (k = 0; k < 3; k++) {
|
||||
basis[i][k] = -basis[i][k];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void get_exteneded_basis(double basis[4][3],
|
||||
SPGCONST double lattice[3][3])
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
basis[i][j] = lattice[j][i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
basis[3][i] = -lattice[i][0] -lattice[i][1] -lattice[i][2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int get_Delaunay_reduction_2D(double red_lattice[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const int unique_axis,
|
||||
const double symprec)
|
||||
{
|
||||
int i, j, k;
|
||||
double volume;
|
||||
double basis[3][3], lattice_2D[3][2], unique_vec[3];
|
||||
|
||||
k = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
unique_vec[i] = lattice[i][unique_axis];
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (i != unique_axis) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
lattice_2D[j][k] = lattice[j][i];
|
||||
}
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
get_exteneded_basis_2D(basis, lattice_2D);
|
||||
|
||||
while (1) {
|
||||
if (get_Delaunay_reduction_basis_2D(basis, symprec)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
get_Delaunay_shortest_vectors_2D(basis, unique_vec, symprec);
|
||||
|
||||
k = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (i == unique_axis) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
red_lattice[j][i] = lattice[j][i];
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < 3; j++) {
|
||||
red_lattice[j][i] = basis[k][j];
|
||||
}
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
volume = mat_get_determinant_d3(red_lattice);
|
||||
if (mat_Dabs(volume) < symprec) {
|
||||
warning_print("spglib: Minimum lattice has no volume (line %d, %s).\n", __LINE__, __FILE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (volume < 0) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
red_lattice[i][unique_axis] = -red_lattice[i][unique_axis];
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_Delaunay_reduction_basis_2D(double basis[3][3],
|
||||
const double symprec)
|
||||
{
|
||||
int i, j, k, l;
|
||||
double dot_product;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = i + 1; j < 3; j++) {
|
||||
dot_product = 0.0;
|
||||
for (k = 0; k < 3; k++) {
|
||||
dot_product += basis[i][k] * basis[j][k];
|
||||
}
|
||||
if (dot_product > symprec) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
if (! (k == i || k == j)) {
|
||||
for (l = 0; l < 3; l++) {
|
||||
basis[k][l] += 2 * basis[i][l];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (k = 0; k < 3; k++) {
|
||||
basis[i][k] = -basis[i][k];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void get_Delaunay_shortest_vectors_2D(double basis[3][3],
|
||||
const double unique_vec[3],
|
||||
const double symprec)
|
||||
{
|
||||
int i, j;
|
||||
double b[4][3], tmpmat[3][3];
|
||||
double tmpvec[3];
|
||||
|
||||
/* Search in the set {b1, b2, b3, b1+b2} */
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
b[i][j] = basis[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
b[3][i] = basis[0][i] + basis[1][i];
|
||||
}
|
||||
|
||||
/* Bubble sort */
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
if (mat_norm_squared_d3(b[j]) > mat_norm_squared_d3(b[j + 1])) {
|
||||
mat_copy_vector_d3(tmpvec, b[j]);
|
||||
mat_copy_vector_d3(b[j], b[j + 1]);
|
||||
mat_copy_vector_d3(b[j + 1], tmpvec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
tmpmat[i][0] = b[0][i];
|
||||
tmpmat[i][1] = unique_vec[i];
|
||||
}
|
||||
|
||||
for (i = 1; i < 4; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
tmpmat[j][2] = b[i][j];
|
||||
}
|
||||
if (mat_Dabs(mat_get_determinant_d3(tmpmat)) > symprec) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
basis[0][j] = b[0][j];
|
||||
basis[1][j] = b[i][j];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void get_exteneded_basis_2D(double basis[3][3],
|
||||
SPGCONST double lattice[3][2])
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
basis[i][j] = lattice[j][i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
basis[2][i] = -lattice[i][0] -lattice[i][1];
|
||||
}
|
||||
}
|
|
@ -455,7 +455,6 @@ void mat_free_MatINT(MatINT * matint)
|
|||
matint->mat = NULL;
|
||||
}
|
||||
free(matint);
|
||||
matint = NULL;
|
||||
}
|
||||
|
||||
VecDBL * mat_alloc_VecDBL(const int size)
|
||||
|
@ -490,7 +489,6 @@ void mat_free_VecDBL(VecDBL * vecdbl)
|
|||
vecdbl->vec = NULL;
|
||||
}
|
||||
free(vecdbl);
|
||||
vecdbl = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,41 +38,59 @@
|
|||
#include <string.h>
|
||||
#include "niggli.h"
|
||||
|
||||
static double A, B, C, eta, xi, zeta, eps;
|
||||
static int l, m, n;
|
||||
static double *tmat = NULL;
|
||||
static double *lattice = NULL;
|
||||
#define NIGGLI_MAX_NUM_LOOP 100
|
||||
|
||||
static int initialize(const double *lattice_, const double eps_);
|
||||
static void finalize(double *lattice_);
|
||||
static void reset(void);
|
||||
static void step0(void);
|
||||
static int step1(void);
|
||||
static int step2(void);
|
||||
static int step3(void);
|
||||
static int step4(void);
|
||||
static int step5(void);
|
||||
static int step6(void);
|
||||
static int step7(void);
|
||||
static int step8(void);
|
||||
static void set_parameters(void);
|
||||
static void set_angle_types(void);
|
||||
typedef struct {
|
||||
double A;
|
||||
double B;
|
||||
double C;
|
||||
double eta;
|
||||
double xi;
|
||||
double zeta;
|
||||
double eps;
|
||||
int l;
|
||||
int m;
|
||||
int n;
|
||||
double *tmat;
|
||||
double *lattice;
|
||||
} NiggliParams;
|
||||
|
||||
static NiggliParams * initialize(const double *lattice_, const double eps_);
|
||||
static void finalize(double *lattice_, NiggliParams *p);
|
||||
static int reset(NiggliParams *p);
|
||||
static int step1(NiggliParams *p);
|
||||
static int step2(NiggliParams *p);
|
||||
static int step3(NiggliParams *p);
|
||||
static int step4(NiggliParams *p);
|
||||
static int step5(NiggliParams *p);
|
||||
static int step6(NiggliParams *p);
|
||||
static int step7(NiggliParams *p);
|
||||
static int step8(NiggliParams *p);
|
||||
static int set_parameters(NiggliParams *p);
|
||||
static void set_angle_types(NiggliParams *p);
|
||||
static double * get_transpose(const double *M);
|
||||
static double * get_metric(const double *M);
|
||||
static double * multiply_matrices(const double *A, const double *B);
|
||||
|
||||
#ifdef NIGGLI_DEBUG
|
||||
#define debug_print(...) printf(__VA_ARGS__)
|
||||
static void debug_show(void);
|
||||
static void debug_show(void)
|
||||
static void debug_show(const int j, const NiggliParams *p);
|
||||
static void debug_show(const int j, const NiggliParams *p)
|
||||
{
|
||||
int i;
|
||||
printf("%f %f %f %f %f %f\n", A, B, C, xi, eta, zeta);
|
||||
printf("%d %d %d\n", l, m, n);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
printf("%f %f %f\n", lattice[i * 3], lattice[i * 3 + 1], lattice[i * 3 + 2]);
|
||||
/* int i; */
|
||||
|
||||
if (j < 0) {
|
||||
printf("Finish: ");
|
||||
} else {
|
||||
printf("Step %d: ", j);
|
||||
}
|
||||
printf("%f %f %f %f %f %f\n", p->A, p->B, p->C, p->xi, p->eta, p->zeta);
|
||||
|
||||
/* printf("%d %d %d\n", p->l, p->m, p->n); */
|
||||
/* for (i = 0; i < 3; i++) { */
|
||||
/* printf("%f %f %f\n", */
|
||||
/* p->lattice[i * 3], p->lattice[i * 3 + 1], p->lattice[i * 3 + 2]); */
|
||||
/* } */
|
||||
}
|
||||
#else
|
||||
#define debug_print(...)
|
||||
|
@ -86,280 +104,303 @@ static void debug_show(void)
|
|||
#define warning_print(...)
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------*/
|
||||
/* Version: niggli-[major].[minor].[micro] */
|
||||
/*--------------------------------------------*/
|
||||
int niggli_get_major_version(void)
|
||||
{
|
||||
return NIGGLI_MAJOR_VERSION;
|
||||
}
|
||||
|
||||
int niggli_get_minor_version(void)
|
||||
{
|
||||
return NIGGLI_MINOR_VERSION;
|
||||
}
|
||||
|
||||
int niggli_get_micro_version(void)
|
||||
{
|
||||
return NIGGLI_MICRO_VERSION;
|
||||
}
|
||||
|
||||
/* return 0 if failed */
|
||||
int niggli_reduce(double *lattice_, const double eps_)
|
||||
{
|
||||
int i;
|
||||
int i, j, succeeded;
|
||||
NiggliParams *p;
|
||||
int (*steps[8])(NiggliParams *p) = {step1, step2, step3, step4,
|
||||
step5, step6, step7, step8};
|
||||
|
||||
if (! initialize(lattice_, eps_)) {
|
||||
p = NULL;
|
||||
succeeded = 0;
|
||||
|
||||
if ((p = initialize(lattice_, eps_)) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
step0();
|
||||
/* Step 0 */
|
||||
if (! set_parameters(p)) {
|
||||
goto ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < NIGGLI_MAX_NUM_LOOP; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
if ((*steps[j])(p)) {
|
||||
debug_show(j + 1, p);
|
||||
if (! reset(p)) {goto ret;}
|
||||
if (j == 1 || j == 4 || j == 5 || j == 6 || j == 7) {break;}
|
||||
}
|
||||
}
|
||||
if (j == 8) {
|
||||
succeeded = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
debug_show(-1, p);
|
||||
|
||||
ret:
|
||||
finalize(lattice_, p);
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
static NiggliParams * initialize(const double *lattice_, const double eps_)
|
||||
{
|
||||
NiggliParams * p;
|
||||
|
||||
p = NULL;
|
||||
|
||||
if ((p = (NiggliParams*)malloc(sizeof(NiggliParams))) == NULL) {
|
||||
warning_print("niggli: Memory could not be allocated.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
p->A = 0;
|
||||
p->B = 0;
|
||||
p->C = 0;
|
||||
p->eta = 0;
|
||||
p->xi = 0;
|
||||
p->zeta = 0;
|
||||
p->eps = 0;
|
||||
p->l = 0;
|
||||
p->m = 0;
|
||||
p->n = 0;
|
||||
p->tmat = NULL;
|
||||
p->lattice = NULL;
|
||||
|
||||
if ((p->tmat = (double*)malloc(sizeof(double) * 9)) == NULL) {
|
||||
warning_print("niggli: Memory could not be allocated.");
|
||||
free(p);
|
||||
p = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p->eps = eps_;
|
||||
if ((p->lattice = (double*)malloc(sizeof(double) * 9)) == NULL) {
|
||||
warning_print("niggli: Memory could not be allocated.");
|
||||
free(p->tmat);
|
||||
p->tmat = NULL;
|
||||
free(p);
|
||||
p = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (step1()) {
|
||||
debug_print("step1\n");
|
||||
debug_show();
|
||||
debug_print("\n");
|
||||
}
|
||||
memcpy(p->lattice, lattice_, sizeof(double) * 9);
|
||||
|
||||
if (step2()) {
|
||||
debug_print("step2\n");
|
||||
debug_show();
|
||||
debug_print("\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (step3()) {
|
||||
debug_print("step3\n");
|
||||
debug_show();
|
||||
debug_print("\n");
|
||||
}
|
||||
|
||||
if (step4()) {
|
||||
debug_print("step4\n");
|
||||
debug_show();
|
||||
debug_print("\n");
|
||||
}
|
||||
|
||||
if (step5()) {
|
||||
debug_print("step5\n");
|
||||
debug_show();
|
||||
debug_print("\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (step6()) {
|
||||
debug_print("step6\n");
|
||||
debug_show();
|
||||
debug_print("\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (step7()) {
|
||||
debug_print("step7\n");
|
||||
debug_show();
|
||||
debug_print("\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (step8()) {
|
||||
debug_print("step7\n");
|
||||
debug_show();
|
||||
debug_print("\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
finalize(lattice_);
|
||||
return 1;
|
||||
return p;
|
||||
}
|
||||
|
||||
static int initialize(const double *lattice_, const double eps_)
|
||||
static void finalize(double *lattice_, NiggliParams *p)
|
||||
{
|
||||
if ((tmat = (double*)malloc(sizeof(double) * 9)) == NULL) {
|
||||
warning_print("niggli: Memory could not be allocated.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
eps = eps_;
|
||||
if ((lattice = (double*)malloc(sizeof(double) * 9)) == NULL) {
|
||||
warning_print("niggli: Memory could not be allocated.");
|
||||
free(tmat);
|
||||
tmat = NULL;
|
||||
return 0;
|
||||
}
|
||||
memcpy(lattice, lattice_, sizeof(double) * 9);
|
||||
|
||||
return 1;
|
||||
free(p->tmat);
|
||||
p->tmat = NULL;
|
||||
memcpy(lattice_, p->lattice, sizeof(double) * 9);
|
||||
free(p->lattice);
|
||||
p->lattice = NULL;
|
||||
free(p);
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
static void finalize(double *lattice_)
|
||||
{
|
||||
free(tmat);
|
||||
tmat = NULL;
|
||||
memcpy(lattice_, lattice, sizeof(double) * 9);
|
||||
free(lattice);
|
||||
lattice = NULL;
|
||||
}
|
||||
|
||||
static void reset(void)
|
||||
static int reset(NiggliParams *p)
|
||||
{
|
||||
double *lat_tmp;
|
||||
|
||||
lat_tmp = NULL;
|
||||
|
||||
lat_tmp = multiply_matrices(lattice, tmat);
|
||||
|
||||
memcpy(lattice, lat_tmp, sizeof(double) * 9);
|
||||
step0();
|
||||
if ((lat_tmp = multiply_matrices(p->lattice, p->tmat)) == NULL) {return 0;}
|
||||
memcpy(p->lattice, lat_tmp, sizeof(double) * 9);
|
||||
free(lat_tmp);
|
||||
lat_tmp = NULL;
|
||||
|
||||
return set_parameters(p);
|
||||
}
|
||||
|
||||
static void step0(void)
|
||||
{
|
||||
set_parameters();
|
||||
set_angle_types();
|
||||
}
|
||||
|
||||
static int step1(void)
|
||||
{
|
||||
if (A > B + eps ||
|
||||
(! (fabs(A -B) > eps) && fabs(xi) > fabs(eta) + eps)) {
|
||||
tmat[0] = 0, tmat[1] = -1, tmat[2] = 0;
|
||||
tmat[3] = -1, tmat[4] = 0, tmat[5] = 0;
|
||||
tmat[6] = 0, tmat[7] = 0, tmat[8] = -1;
|
||||
reset();
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step2(void)
|
||||
{
|
||||
if (B > C + eps ||
|
||||
(! (fabs(B - C) > eps) && fabs(eta) > fabs(zeta) + eps)) {
|
||||
tmat[0] = -1, tmat[1] = 0, tmat[2] = 0;
|
||||
tmat[3] = 0, tmat[4] = 0, tmat[5] = -1;
|
||||
tmat[6] = 0, tmat[7] = -1, tmat[8] = 0;
|
||||
reset();
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step3(void)
|
||||
{
|
||||
int i, j, k;
|
||||
if (l * m * n == 1) {
|
||||
if (l == -1) {i = -1;} else {i = 1;}
|
||||
if (m == -1) {j = -1;} else {j = 1;}
|
||||
if (n == -1) {k = -1;} else {k = 1;}
|
||||
tmat[0] = i, tmat[1] = 0, tmat[2] = 0;
|
||||
tmat[3] = 0, tmat[4] = j, tmat[5] = 0;
|
||||
tmat[6] = 0, tmat[7] = 0, tmat[8] = k;
|
||||
reset();
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step4(void)
|
||||
{
|
||||
int i, j, k;
|
||||
if (l * m * n == 0 || l * m * n == -1) {
|
||||
if (l == -1) {i = -1;} else {i = 1;}
|
||||
if (m == -1) {j = -1;} else {j = 1;}
|
||||
if (n == -1) {k = -1;} else {k = 1;}
|
||||
|
||||
if (i * j * k == -1) {
|
||||
if (l == 0) {i = -1;}
|
||||
if (m == 0) {j = -1;}
|
||||
if (n == 0) {k = -1;}
|
||||
}
|
||||
|
||||
tmat[0] = i, tmat[1] = 0, tmat[2] = 0;
|
||||
tmat[3] = 0, tmat[4] = j, tmat[5] = 0;
|
||||
tmat[6] = 0, tmat[7] = 0, tmat[8] = k;
|
||||
reset();
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step5(void)
|
||||
{
|
||||
if (fabs(xi) > B + eps ||
|
||||
(! (fabs(B - xi) > eps) && 2 * eta < zeta - eps) ||
|
||||
(! (fabs(B + xi) > eps) && zeta < -eps)) {
|
||||
tmat[0] = 1, tmat[1] = 0, tmat[2] = 0;
|
||||
tmat[3] = 0, tmat[4] = 1, tmat[5] = 0;
|
||||
tmat[6] = 0, tmat[7] = 0, tmat[8] = 1;
|
||||
if (xi > 0) {tmat[5] = -1;}
|
||||
if (xi < 0) {tmat[5] = 1;}
|
||||
reset();
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step6(void)
|
||||
{
|
||||
if (fabs(eta) > A + eps ||
|
||||
(! (fabs(A - eta) > eps) && 2 * xi < zeta - eps) ||
|
||||
(! (fabs(A + eta) > eps) && zeta < -eps)) {
|
||||
tmat[0] = 1, tmat[1] = 0, tmat[2] = 0;
|
||||
tmat[3] = 0, tmat[4] = 1, tmat[5] = 0;
|
||||
tmat[6] = 0, tmat[7] = 0, tmat[8] = 1;
|
||||
if (eta > 0) {tmat[2] = -1;}
|
||||
if (eta < 0) {tmat[2] = 1;}
|
||||
reset();
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step7(void)
|
||||
{
|
||||
if (fabs(zeta) > A + eps ||
|
||||
(! (fabs(A - zeta) > eps) && 2 * xi < eta - eps) ||
|
||||
(! (fabs(A + zeta) > eps) && eta < -eps)) {
|
||||
tmat[0] = 1, tmat[1] = 0, tmat[2] = 0;
|
||||
tmat[3] = 0, tmat[4] = 1, tmat[5] = 0;
|
||||
tmat[6] = 0, tmat[7] = 0, tmat[8] = 1;
|
||||
if (zeta > 0) {tmat[1] = -1;}
|
||||
if (zeta < 0) {tmat[1] = 1;}
|
||||
reset();
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step8(void)
|
||||
{
|
||||
if (xi + eta + zeta + A + B < -eps ||
|
||||
(! (fabs(xi + eta + zeta + A + B) > eps) && 2 * (A + eta) + zeta > eps)) {
|
||||
tmat[0] = 1, tmat[1] = 0, tmat[2] = 1;
|
||||
tmat[3] = 0, tmat[4] = 1, tmat[5] = 1;
|
||||
tmat[6] = 0, tmat[7] = 0, tmat[8] = 1;
|
||||
reset();
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static void set_angle_types(void)
|
||||
{
|
||||
l = 0, m = 0, n = 0;
|
||||
if (xi < -eps) {l = -1;}
|
||||
if (xi > eps) {l = 1;}
|
||||
if (eta < -eps) {m = -1;}
|
||||
if (eta > eps) {m = 1;}
|
||||
if (zeta < -eps) {n = -1;}
|
||||
if (zeta > eps) {n = 1;}
|
||||
}
|
||||
|
||||
static void set_parameters(void)
|
||||
static int set_parameters(NiggliParams *p)
|
||||
{
|
||||
double *G;
|
||||
|
||||
G = NULL;
|
||||
|
||||
G = get_metric(lattice);
|
||||
if ((G = get_metric(p->lattice)) == NULL) {return 0;}
|
||||
|
||||
A = G[0];
|
||||
B = G[4];
|
||||
C = G[8];
|
||||
xi = G[5] * 2;
|
||||
eta = G[2] * 2;
|
||||
zeta = G[1] * 2;
|
||||
p->A = G[0];
|
||||
p->B = G[4];
|
||||
p->C = G[8];
|
||||
p->xi = G[5] * 2;
|
||||
p->eta = G[2] * 2;
|
||||
p->zeta = G[1] * 2;
|
||||
|
||||
free(G);
|
||||
G = NULL;
|
||||
|
||||
set_angle_types(p);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void set_angle_types(NiggliParams *p)
|
||||
{
|
||||
p->l = 0;
|
||||
p->m = 0;
|
||||
p->n = 0;
|
||||
if (p->xi < -p->eps) {p->l = -1;}
|
||||
if (p->xi > p->eps) {p->l = 1;}
|
||||
if (p->eta < -p->eps) {p->m = -1;}
|
||||
if (p->eta > p->eps) {p->m = 1;}
|
||||
if (p->zeta < -p->eps) {p->n = -1;}
|
||||
if (p->zeta > p->eps) {p->n = 1;}
|
||||
}
|
||||
|
||||
static int step1(NiggliParams *p)
|
||||
{
|
||||
if (p->A > p->B + p->eps ||
|
||||
(! (fabs(p->A - p->B) > p->eps) &&
|
||||
fabs(p->xi) > fabs(p->eta) + p->eps)) {
|
||||
p->tmat[0] = 0, p->tmat[1] = -1, p->tmat[2] = 0;
|
||||
p->tmat[3] = -1, p->tmat[4] = 0, p->tmat[5] = 0;
|
||||
p->tmat[6] = 0, p->tmat[7] = 0, p->tmat[8] = -1;
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step2(NiggliParams *p)
|
||||
{
|
||||
if (p->B > p->C + p->eps ||
|
||||
(! (fabs(p->B - p->C) > p->eps)
|
||||
&& fabs(p->eta) > fabs(p->zeta) + p->eps)) {
|
||||
p->tmat[0] = -1, p->tmat[1] = 0, p->tmat[2] = 0;
|
||||
p->tmat[3] = 0, p->tmat[4] = 0, p->tmat[5] = -1;
|
||||
p->tmat[6] = 0, p->tmat[7] = -1, p->tmat[8] = 0;
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step3(NiggliParams *p)
|
||||
{
|
||||
int i, j, k;
|
||||
if (p->l * p->m * p->n == 1) {
|
||||
if (p->l == -1) {i = -1;} else {i = 1;}
|
||||
if (p->m == -1) {j = -1;} else {j = 1;}
|
||||
if (p->n == -1) {k = -1;} else {k = 1;}
|
||||
p->tmat[0] = i, p->tmat[1] = 0, p->tmat[2] = 0;
|
||||
p->tmat[3] = 0, p->tmat[4] = j, p->tmat[5] = 0;
|
||||
p->tmat[6] = 0, p->tmat[7] = 0, p->tmat[8] = k;
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step4(NiggliParams *p)
|
||||
{
|
||||
int i, j, k, r;
|
||||
|
||||
if (p->l == -1 && p->m == -1 && p->n == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (p->l * p->m * p->n == 0 || p->l * p->m * p->n == -1) {
|
||||
i = 1;
|
||||
j = 1;
|
||||
k = 1;
|
||||
r = -1; /* 0: i, 1: j, 2: k */
|
||||
if (p->l == 1) {i = -1;}
|
||||
if (p->l == 0) {r = 0;}
|
||||
if (p->m == 1) {j = -1;}
|
||||
if (p->m == 0) {r = 1;}
|
||||
if (p->n == 1) {k = -1;}
|
||||
if (p->n == 0) {r = 2;}
|
||||
|
||||
if (i * j * k == -1) {
|
||||
if (r == 0) {i = -1;}
|
||||
if (r == 1) {j = -1;}
|
||||
if (r == 2) {k = -1;}
|
||||
}
|
||||
|
||||
p->tmat[0] = i, p->tmat[1] = 0, p->tmat[2] = 0;
|
||||
p->tmat[3] = 0, p->tmat[4] = j, p->tmat[5] = 0;
|
||||
p->tmat[6] = 0, p->tmat[7] = 0, p->tmat[8] = k;
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step5(NiggliParams *p)
|
||||
{
|
||||
if (fabs(p->xi) > p->B + p->eps ||
|
||||
(! (fabs(p->B - p->xi) > p->eps) && 2 * p->eta < p->zeta - p->eps) ||
|
||||
(! (fabs(p->B + p->xi) > p->eps) && p->zeta < -p->eps)) {
|
||||
p->tmat[0] = 1, p->tmat[1] = 0, p->tmat[2] = 0;
|
||||
p->tmat[3] = 0, p->tmat[4] = 1, p->tmat[5] = 0;
|
||||
p->tmat[6] = 0, p->tmat[7] = 0, p->tmat[8] = 1;
|
||||
if (p->xi > 0) {p->tmat[5] = -1;}
|
||||
if (p->xi < 0) {p->tmat[5] = 1;}
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step6(NiggliParams *p)
|
||||
{
|
||||
if (fabs(p->eta) > p->A + p->eps ||
|
||||
(! (fabs(p->A - p->eta) > p->eps) && 2 * p->xi < p->zeta - p->eps) ||
|
||||
(! (fabs(p->A + p->eta) > p->eps) && p->zeta < -p->eps)) {
|
||||
p->tmat[0] = 1, p->tmat[1] = 0, p->tmat[2] = 0;
|
||||
p->tmat[3] = 0, p->tmat[4] = 1, p->tmat[5] = 0;
|
||||
p->tmat[6] = 0, p->tmat[7] = 0, p->tmat[8] = 1;
|
||||
if (p->eta > 0) {p->tmat[2] = -1;}
|
||||
if (p->eta < 0) {p->tmat[2] = 1;}
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step7(NiggliParams *p)
|
||||
{
|
||||
if (fabs(p->zeta) > p->A + p->eps ||
|
||||
(! (fabs(p->A - p->zeta) > p->eps) && 2 * p->xi < p->eta - p->eps) ||
|
||||
(! (fabs(p->A + p->zeta) > p->eps) && p->eta < -p->eps)) {
|
||||
p->tmat[0] = 1, p->tmat[1] = 0, p->tmat[2] = 0;
|
||||
p->tmat[3] = 0, p->tmat[4] = 1, p->tmat[5] = 0;
|
||||
p->tmat[6] = 0, p->tmat[7] = 0, p->tmat[8] = 1;
|
||||
if (p->zeta > 0) {p->tmat[1] = -1;}
|
||||
if (p->zeta < 0) {p->tmat[1] = 1;}
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static int step8(NiggliParams *p)
|
||||
{
|
||||
if (p->xi + p->eta + p->zeta + p->A + p->B < -p->eps ||
|
||||
(! (fabs(p->xi + p->eta + p->zeta + p->A + p->B) > p->eps) &&
|
||||
2 * (p->A + p->eta) + p->zeta > p->eps)) {
|
||||
p->tmat[0] = 1, p->tmat[1] = 0, p->tmat[2] = 1;
|
||||
p->tmat[3] = 0, p->tmat[4] = 1, p->tmat[5] = 1;
|
||||
p->tmat[6] = 0, p->tmat[7] = 0, p->tmat[8] = 1;
|
||||
return 1;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
static double * get_transpose(const double *M)
|
||||
|
@ -379,6 +420,7 @@ static double * get_transpose(const double *M)
|
|||
M_T[i * 3 + j] = M[j * 3 + i];
|
||||
}
|
||||
}
|
||||
|
||||
return M_T;
|
||||
}
|
||||
|
||||
|
@ -389,9 +431,9 @@ static double * get_metric(const double *M)
|
|||
G = NULL;
|
||||
M_T = NULL;
|
||||
|
||||
M_T = get_transpose(M);
|
||||
if ((M_T = get_transpose(M)) == NULL) {return NULL;}
|
||||
if ((G = multiply_matrices(M_T, M)) == NULL) {return NULL;}
|
||||
|
||||
G = multiply_matrices(M_T, M);
|
||||
free(M_T);
|
||||
M_T = NULL;
|
||||
|
||||
|
@ -418,5 +460,6 @@ static double * multiply_matrices(const double *L, const double *R)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return M;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "lattice.h"
|
||||
#include "pointgroup.h"
|
||||
#include "symmetry.h"
|
||||
#include "mathfunc.h"
|
||||
|
@ -376,8 +375,6 @@ static int rot_axes[][3] = {
|
|||
|
||||
static int get_pointgroup_number_by_rotations(SPGCONST int rotations[][3][3],
|
||||
const int num_rotations);
|
||||
static PointSymmetry get_pointsymmetry(SPGCONST int rotations[][3][3],
|
||||
const int num_rotations);
|
||||
static int get_pointgroup_number(SPGCONST PointSymmetry * pointsym);
|
||||
static int get_pointgroup_class_table(int table[10],
|
||||
SPGCONST PointSymmetry * pointsym);
|
||||
|
@ -442,7 +439,7 @@ Pointgroup ptg_get_transformation_matrix(int transform_mat[3][3],
|
|||
|
||||
if (pg_num > 0) {
|
||||
pointgroup = ptg_get_pointgroup(pg_num);
|
||||
pointsym = get_pointsymmetry(rotations, num_rotations);
|
||||
pointsym = ptg_get_pointsymmetry(rotations, num_rotations);
|
||||
get_axes(axes, pointgroup.laue, &pointsym);
|
||||
set_transformation_matrix(transform_mat, axes);
|
||||
} else {
|
||||
|
@ -472,17 +469,8 @@ Pointgroup ptg_get_pointgroup(const int pointgroup_number)
|
|||
return pointgroup;
|
||||
}
|
||||
|
||||
static int get_pointgroup_number_by_rotations(SPGCONST int rotations[][3][3],
|
||||
const int num_rotations)
|
||||
{
|
||||
PointSymmetry pointsym;
|
||||
|
||||
pointsym = get_pointsymmetry(rotations, num_rotations);
|
||||
return get_pointgroup_number(&pointsym);
|
||||
}
|
||||
|
||||
static PointSymmetry get_pointsymmetry(SPGCONST int rotations[][3][3],
|
||||
const int num_rotations)
|
||||
PointSymmetry ptg_get_pointsymmetry(SPGCONST int rotations[][3][3],
|
||||
const int num_rotations)
|
||||
{
|
||||
int i, j;
|
||||
PointSymmetry pointsym;
|
||||
|
@ -503,6 +491,15 @@ static PointSymmetry get_pointsymmetry(SPGCONST int rotations[][3][3],
|
|||
return pointsym;
|
||||
}
|
||||
|
||||
static int get_pointgroup_number_by_rotations(SPGCONST int rotations[][3][3],
|
||||
const int num_rotations)
|
||||
{
|
||||
PointSymmetry pointsym;
|
||||
|
||||
pointsym = ptg_get_pointsymmetry(rotations, num_rotations);
|
||||
return get_pointgroup_number(&pointsym);
|
||||
}
|
||||
|
||||
static int get_pointgroup_number(SPGCONST PointSymmetry * pointsym)
|
||||
{
|
||||
int i, j, pg_num, counter;
|
||||
|
@ -739,7 +736,7 @@ static int laue2m(int axes[3],
|
|||
static int lauemmm(int axes[3],
|
||||
SPGCONST PointSymmetry * pointsym)
|
||||
{
|
||||
int i, count, axis, tmpval;
|
||||
int i, count, axis;
|
||||
int prop_rot[3][3];
|
||||
|
||||
|
||||
|
@ -1024,7 +1021,7 @@ static int laue3m(int axes[3],
|
|||
static int lauem3m(int axes[3],
|
||||
SPGCONST PointSymmetry * pointsym)
|
||||
{
|
||||
int i, count, axis, tmpval;
|
||||
int i, count, axis;
|
||||
int prop_rot[3][3];
|
||||
|
||||
for (i = 0; i < 3; i++) { axes[i] = -1; }
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "cell.h"
|
||||
#include "lattice.h"
|
||||
#include "delaunay.h"
|
||||
#include "mathfunc.h"
|
||||
#include "primitive.h"
|
||||
#include "symmetry.h"
|
||||
|
@ -94,6 +94,10 @@ Primitive * prm_alloc_primitive(const int size)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
primitive->mapping_table[i] = -1;
|
||||
}
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
|
@ -107,9 +111,9 @@ void prm_free_primitive(Primitive * primitive)
|
|||
|
||||
if (primitive->cell != NULL) {
|
||||
cel_free_cell(primitive->cell);
|
||||
primitive->cell = NULL;
|
||||
}
|
||||
free(primitive);
|
||||
primitive = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,6 +143,7 @@ static Primitive * get_primitive(SPGCONST Cell * cell, const double symprec)
|
|||
|
||||
tolerance = symprec;
|
||||
for (attempt = 0; attempt < 100; attempt++) {
|
||||
debug_print("get_primitive (attempt = %d):\n", attempt);
|
||||
if ((pure_trans = sym_get_pure_translation(cell, tolerance)) == NULL) {
|
||||
goto cont;
|
||||
}
|
||||
|
@ -161,6 +166,7 @@ static Primitive * get_primitive(SPGCONST Cell * cell, const double symprec)
|
|||
}
|
||||
|
||||
mat_free_VecDBL(pure_trans);
|
||||
pure_trans = NULL;
|
||||
|
||||
cont:
|
||||
tolerance *= REDUCE_RATE;
|
||||
|
@ -176,6 +182,7 @@ static Primitive * get_primitive(SPGCONST Cell * cell, const double symprec)
|
|||
mat_inverse_matrix_d3(inv_lat, cell->lattice, 0);
|
||||
mat_multiply_matrix_d3(primitive->t_mat, primitive->cell->lattice, inv_lat);
|
||||
mat_free_VecDBL(pure_trans);
|
||||
pure_trans = NULL;
|
||||
return primitive;
|
||||
}
|
||||
|
||||
|
@ -188,20 +195,18 @@ static Cell * get_cell_with_smallest_lattice(SPGCONST Cell * cell,
|
|||
Cell * smallest_cell;
|
||||
|
||||
debug_print("get_cell_with_smallest_lattice:\n");
|
||||
|
||||
|
||||
smallest_cell = NULL;
|
||||
|
||||
if (!lat_smallest_lattice_vector(min_lat,
|
||||
cell->lattice,
|
||||
symprec)) {
|
||||
goto err;
|
||||
if (!del_delaunay_reduce(min_lat, cell->lattice, symprec)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mat_inverse_matrix_d3(inv_lat, min_lat, 0);
|
||||
mat_multiply_matrix_d3(trans_mat, inv_lat, cell->lattice);
|
||||
|
||||
if ((smallest_cell = cel_alloc_cell(cell->size)) == NULL) {
|
||||
goto err;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mat_copy_matrix_d3(smallest_cell->lattice, min_lat);
|
||||
|
@ -210,14 +215,11 @@ static Cell * get_cell_with_smallest_lattice(SPGCONST Cell * cell,
|
|||
mat_multiply_matrix_vector_d3(smallest_cell->position[i],
|
||||
trans_mat, cell->position[i]);
|
||||
for (j = 0; j < 3; j++) {
|
||||
cell->position[i][j] = mat_Dmod1(cell->position[i][j]);
|
||||
smallest_cell->position[i][j] = mat_Dmod1(smallest_cell->position[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
return smallest_cell;
|
||||
|
||||
err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return NULL if failed */
|
||||
|
@ -230,7 +232,7 @@ static Cell * get_primitive_cell(int * mapping_table,
|
|||
double prim_lat[3][3], smallest_lat[3][3];
|
||||
Cell * primitive_cell;
|
||||
|
||||
debug_print("get_primitive:\n");
|
||||
debug_print("get_primitive_cell:\n");
|
||||
|
||||
primitive_cell = NULL;
|
||||
|
||||
|
@ -245,7 +247,7 @@ static Cell * get_primitive_cell(int * mapping_table,
|
|||
goto not_found;
|
||||
}
|
||||
|
||||
if (! lat_smallest_lattice_vector(smallest_lat, prim_lat, symprec)) {
|
||||
if (! del_delaunay_reduce(smallest_lat, prim_lat, symprec)) {
|
||||
goto not_found;
|
||||
}
|
||||
|
||||
|
@ -290,12 +292,13 @@ static int get_primitive_lattice_vectors_iterative(double prim_lattice[3][3],
|
|||
for (i = 0; i < pure_trans->size; i++) {
|
||||
mat_copy_vector_d3(pure_trans_reduced->vec[i], pure_trans->vec[i]);
|
||||
}
|
||||
|
||||
|
||||
for (attempt = 0; attempt < 100; attempt++) {
|
||||
multi = pure_trans_reduced->size;
|
||||
|
||||
if ((vectors = get_translation_candidates(pure_trans_reduced)) == NULL) {
|
||||
mat_free_VecDBL(pure_trans_reduced);
|
||||
pure_trans_reduced = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -306,7 +309,9 @@ static int get_primitive_lattice_vectors_iterative(double prim_lattice[3][3],
|
|||
tolerance)) {
|
||||
|
||||
mat_free_VecDBL(vectors);
|
||||
vectors = NULL;
|
||||
mat_free_VecDBL(pure_trans_reduced);
|
||||
pure_trans_reduced = NULL;
|
||||
|
||||
goto found;
|
||||
|
||||
|
@ -314,7 +319,9 @@ static int get_primitive_lattice_vectors_iterative(double prim_lattice[3][3],
|
|||
|
||||
if ((tmp_vec = mat_alloc_VecDBL(multi)) == NULL) {
|
||||
mat_free_VecDBL(vectors);
|
||||
vectors = NULL;
|
||||
mat_free_VecDBL(pure_trans_reduced);
|
||||
pure_trans_reduced = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -322,19 +329,22 @@ static int get_primitive_lattice_vectors_iterative(double prim_lattice[3][3],
|
|||
mat_copy_vector_d3(tmp_vec->vec[i], pure_trans_reduced->vec[i]);
|
||||
}
|
||||
mat_free_VecDBL(pure_trans_reduced);
|
||||
pure_trans_reduced = NULL;
|
||||
|
||||
pure_trans_reduced = sym_reduce_pure_translation(cell,
|
||||
tmp_vec,
|
||||
tolerance);
|
||||
|
||||
mat_free_VecDBL(tmp_vec);
|
||||
tmp_vec = NULL;
|
||||
mat_free_VecDBL(vectors);
|
||||
vectors = NULL;
|
||||
|
||||
if (pure_trans_reduced == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
warning_print("Tolerance is reduced to %f (%d), size = %d\n",
|
||||
warning_print("Tolerance is reduced to %f (%d), num_pure_trans = %d\n",
|
||||
tolerance, attempt, pure_trans_reduced->size);
|
||||
|
||||
tolerance *= REDUCE_RATE;
|
||||
|
@ -342,6 +352,7 @@ static int get_primitive_lattice_vectors_iterative(double prim_lattice[3][3],
|
|||
}
|
||||
|
||||
mat_free_VecDBL(pure_trans_reduced);
|
||||
pure_trans_reduced = NULL;
|
||||
|
||||
fail:
|
||||
return 0;
|
||||
|
@ -417,7 +428,7 @@ static int get_primitive_lattice_vectors(double prim_lattice[3][3],
|
|||
}
|
||||
mat_multiply_matrix_d3(prim_lattice, cell->lattice, relative_lattice);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static VecDBL * get_translation_candidates(const VecDBL * pure_trans)
|
||||
|
@ -432,7 +443,7 @@ static VecDBL * get_translation_candidates(const VecDBL * pure_trans)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* store pure translations in original cell */
|
||||
/* store pure translations in original cell */
|
||||
/* as trial primitive lattice vectors */
|
||||
for (i = 0; i < multi - 1; i++) {
|
||||
mat_copy_vector_d3(vectors->vec[i], pure_trans->vec[i + 1]);
|
||||
|
@ -452,4 +463,3 @@ static VecDBL * get_translation_candidates(const VecDBL * pure_trans)
|
|||
|
||||
return vectors;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,12 +116,13 @@ static int search_equivalent_atom(const int atom_index,
|
|||
SPGCONST Cell * cell,
|
||||
const Symmetry *symmetry,
|
||||
const double symprec);
|
||||
static Symmetry * reduce_symmetry_in_frame(const int frame[3],
|
||||
SPGCONST Symmetry *prim_sym,
|
||||
SPGCONST int t_mat[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const int multiplicity,
|
||||
const double symprec);
|
||||
static Symmetry *
|
||||
recover_symmetry_in_original_cell(const int frame[3],
|
||||
SPGCONST Symmetry *prim_sym,
|
||||
SPGCONST int t_mat[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const int multiplicity,
|
||||
const double symprec);
|
||||
static VecDBL * get_lattice_translations(const int frame[3],
|
||||
SPGCONST double inv_tmat[3][3]);
|
||||
static VecDBL *
|
||||
|
@ -212,7 +213,7 @@ Cell * get_Wyckoff_positions(int * wyckoffs,
|
|||
wyckoffs_bravais = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if ((bravais = get_bravais_exact_positions_and_lattice
|
||||
(wyckoffs_bravais,
|
||||
equiv_atoms_bravais,
|
||||
|
@ -225,7 +226,7 @@ Cell * get_Wyckoff_positions(int * wyckoffs,
|
|||
for (i = 0; i < cell->size; i++) {
|
||||
wyckoffs[i] = wyckoffs_bravais[mapping_table[i]];
|
||||
}
|
||||
|
||||
|
||||
spgdb_get_operation_index(operation_index, spacegroup->hall_number);
|
||||
num_prim_sym = operation_index[0] / (bravais->size / primitive->size);
|
||||
|
||||
|
@ -247,12 +248,12 @@ Cell * get_Wyckoff_positions(int * wyckoffs,
|
|||
}
|
||||
}
|
||||
|
||||
ret:
|
||||
ret:
|
||||
free(equiv_atoms_bravais);
|
||||
equiv_atoms_bravais = NULL;
|
||||
free(wyckoffs_bravais);
|
||||
wyckoffs_bravais = NULL;
|
||||
|
||||
|
||||
return bravais;
|
||||
}
|
||||
|
||||
|
@ -323,6 +324,7 @@ get_bravais_exact_positions_and_lattice(int * wyckoffs,
|
|||
spacegroup->hall_number,
|
||||
symprec)) == NULL) {
|
||||
sym_free_symmetry(conv_sym);
|
||||
conv_sym = NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -338,13 +340,16 @@ get_bravais_exact_positions_and_lattice(int * wyckoffs,
|
|||
equiv_atoms_prim);
|
||||
|
||||
mat_free_VecDBL(exact_positions);
|
||||
exact_positions = NULL;
|
||||
sym_free_symmetry(conv_sym);
|
||||
conv_sym = NULL;
|
||||
err:
|
||||
free(wyckoffs_prim);
|
||||
wyckoffs_prim = NULL;
|
||||
free(equiv_atoms_prim);
|
||||
equiv_atoms_prim = NULL;
|
||||
cel_free_cell(conv_prim);
|
||||
conv_prim = NULL;
|
||||
|
||||
return bravais;
|
||||
}
|
||||
|
@ -379,7 +384,7 @@ static Cell * expand_positions(int * wyckoffs,
|
|||
conv_prim->position[j]);
|
||||
for (k = 0; k < 3; k++) {
|
||||
bravais->position[num_atom][k] += conv_sym->trans[i][k];
|
||||
bravais->position[num_atom][k] =
|
||||
bravais->position[num_atom][k] =
|
||||
mat_Dmod1(bravais->position[num_atom][k]);
|
||||
}
|
||||
wyckoffs[num_atom] = wyckoffs_prim[j];
|
||||
|
@ -398,7 +403,7 @@ static Cell * expand_positions(int * wyckoffs,
|
|||
static int get_number_of_pure_translation(SPGCONST Symmetry * conv_sym)
|
||||
{
|
||||
int i, num_pure_trans = 0;
|
||||
|
||||
|
||||
for (i = 0; i < conv_sym->size; i++) {
|
||||
if (mat_check_identity_matrix_i3(identity, conv_sym->rot[i])) {
|
||||
num_pure_trans++;
|
||||
|
@ -423,7 +428,7 @@ static Cell * get_conventional_primitive(SPGCONST Spacegroup * spacegroup,
|
|||
|
||||
mat_inverse_matrix_d3(inv_brv, spacegroup->bravais_lattice, 0);
|
||||
mat_multiply_matrix_d3(trans_mat, inv_brv, primitive->lattice);
|
||||
|
||||
|
||||
for (i = 0; i < primitive->size; i++) {
|
||||
conv_prim->types[i] = primitive->types[i];
|
||||
mat_multiply_matrix_vector_d3(conv_prim->position[i],
|
||||
|
@ -446,7 +451,7 @@ static void get_conventional_lattice(double lattice[3][3],
|
|||
Pointgroup pointgroup;
|
||||
|
||||
pointgroup = ptg_get_pointgroup(spacegroup->pointgroup_number);
|
||||
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
lattice[i][j] = 0;
|
||||
|
@ -539,7 +544,7 @@ static void set_monocli(double lattice[3][3],
|
|||
debug_print("beta %f\n", beta);
|
||||
debug_print_matrix_d3(lattice);
|
||||
}
|
||||
|
||||
|
||||
static void set_ortho(double lattice[3][3],
|
||||
SPGCONST double metric[3][3])
|
||||
{
|
||||
|
@ -663,24 +668,27 @@ get_refined_symmetry_operations(SPGCONST Cell * cell,
|
|||
|
||||
if ((prim_sym = get_primitive_db_symmetry(t_mat, conv_sym)) == NULL) {
|
||||
sym_free_symmetry(conv_sym);
|
||||
conv_sym = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sym_free_symmetry(conv_sym);
|
||||
conv_sym = NULL;
|
||||
|
||||
/* Input cell symmetry from primitive symmetry */
|
||||
mat_multiply_matrix_d3(t_mat, inv_prim_lat, cell->lattice);
|
||||
mat_cast_matrix_3d_to_3i(t_mat_int, t_mat);
|
||||
get_surrounding_frame(frame, t_mat_int);
|
||||
|
||||
symmetry = reduce_symmetry_in_frame(frame,
|
||||
prim_sym,
|
||||
t_mat_int,
|
||||
cell->lattice,
|
||||
cell->size / primitive->size,
|
||||
symprec);
|
||||
symmetry = recover_symmetry_in_original_cell(frame,
|
||||
prim_sym,
|
||||
t_mat_int,
|
||||
cell->lattice,
|
||||
cell->size / primitive->size,
|
||||
symprec);
|
||||
|
||||
sym_free_symmetry(prim_sym);
|
||||
prim_sym = NULL;
|
||||
|
||||
return symmetry;
|
||||
}
|
||||
|
@ -802,13 +810,14 @@ static Symmetry * get_primitive_db_symmetry(SPGCONST double t_mat[3][3],
|
|||
r_prim = NULL;
|
||||
t_prim = NULL;
|
||||
prim_sym = NULL;
|
||||
|
||||
|
||||
if ((r_prim = mat_alloc_MatINT(conv_sym->size)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((t_prim = mat_alloc_VecDBL(conv_sym->size)) == NULL) {
|
||||
mat_free_MatINT(r_prim);
|
||||
r_prim = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -850,7 +859,9 @@ static Symmetry * get_primitive_db_symmetry(SPGCONST double t_mat[3][3],
|
|||
|
||||
ret:
|
||||
mat_free_MatINT(r_prim);
|
||||
r_prim = NULL;
|
||||
mat_free_VecDBL(t_prim);
|
||||
t_prim = NULL;
|
||||
|
||||
return prim_sym;
|
||||
}
|
||||
|
@ -908,12 +919,13 @@ static void get_corners(int corners[3][8],
|
|||
}
|
||||
}
|
||||
|
||||
static Symmetry * reduce_symmetry_in_frame(const int frame[3],
|
||||
SPGCONST Symmetry *prim_sym,
|
||||
SPGCONST int t_mat[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const int multiplicity,
|
||||
const double symprec)
|
||||
static Symmetry *
|
||||
recover_symmetry_in_original_cell(const int frame[3],
|
||||
SPGCONST Symmetry *prim_sym,
|
||||
SPGCONST int t_mat[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const int multiplicity,
|
||||
const double symprec)
|
||||
{
|
||||
Symmetry *symmetry, *t_sym;
|
||||
double inv_tmat[3][3], tmp_mat[3][3];
|
||||
|
@ -935,6 +947,7 @@ static Symmetry * reduce_symmetry_in_frame(const int frame[3],
|
|||
lattice_trans,
|
||||
symprec)) == NULL) {
|
||||
mat_free_VecDBL(lattice_trans);
|
||||
lattice_trans = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -944,7 +957,9 @@ static Symmetry * reduce_symmetry_in_frame(const int frame[3],
|
|||
prim_sym,
|
||||
symprec)) == NULL) {
|
||||
mat_free_VecDBL(pure_trans);
|
||||
pure_trans = NULL;
|
||||
mat_free_VecDBL(lattice_trans);
|
||||
lattice_trans = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -953,8 +968,11 @@ static Symmetry * reduce_symmetry_in_frame(const int frame[3],
|
|||
}
|
||||
|
||||
mat_free_VecDBL(lattice_trans);
|
||||
lattice_trans = NULL;
|
||||
mat_free_VecDBL(pure_trans);
|
||||
pure_trans = NULL;
|
||||
sym_free_symmetry(t_sym);
|
||||
t_sym = NULL;
|
||||
|
||||
return symmetry;
|
||||
}
|
||||
|
@ -987,7 +1005,7 @@ static VecDBL * get_lattice_translations(const int frame[3],
|
|||
lattice_trans->vec[num_trans]);
|
||||
for (l = 0; l < 3; l++) {
|
||||
lattice_trans->vec[num_trans][l] =
|
||||
mat_Dmod1(lattice_trans->vec[num_trans][l]);
|
||||
mat_Dmod1(lattice_trans->vec[num_trans][l]);
|
||||
}
|
||||
num_trans++;
|
||||
}
|
||||
|
@ -1004,7 +1022,7 @@ remove_overlapping_lattice_points(SPGCONST double lattice[3][3],
|
|||
{
|
||||
int i, j, is_found, num_pure_trans;
|
||||
VecDBL *pure_trans, *t;
|
||||
|
||||
|
||||
pure_trans = NULL;
|
||||
t = NULL;
|
||||
|
||||
|
@ -1030,6 +1048,7 @@ remove_overlapping_lattice_points(SPGCONST double lattice[3][3],
|
|||
|
||||
if ((pure_trans = mat_alloc_VecDBL(num_pure_trans)) == NULL) {
|
||||
mat_free_VecDBL(t);
|
||||
t = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1037,6 +1056,7 @@ remove_overlapping_lattice_points(SPGCONST double lattice[3][3],
|
|||
mat_copy_vector_d3(pure_trans->vec[i], t->vec[i]);
|
||||
}
|
||||
mat_free_VecDBL(t);
|
||||
t = NULL;
|
||||
|
||||
return pure_trans;
|
||||
}
|
||||
|
@ -1048,7 +1068,7 @@ get_symmetry_in_original_cell(SPGCONST int t_mat[3][3],
|
|||
SPGCONST double lattice[3][3],
|
||||
SPGCONST Symmetry *prim_sym,
|
||||
const double symprec)
|
||||
{
|
||||
{
|
||||
int i, size_sym_orig;
|
||||
double tmp_rot_d[3][3], tmp_lat_d[3][3], tmp_lat_i[3][3], tmp_mat[3][3];
|
||||
int tmp_rot_i[3][3];
|
||||
|
@ -1091,6 +1111,7 @@ get_symmetry_in_original_cell(SPGCONST int t_mat[3][3],
|
|||
|
||||
if ((t_red_sym = sym_alloc_symmetry(size_sym_orig)) == NULL) {
|
||||
sym_free_symmetry(t_sym);
|
||||
t_sym = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1100,6 +1121,7 @@ get_symmetry_in_original_cell(SPGCONST int t_mat[3][3],
|
|||
}
|
||||
|
||||
sym_free_symmetry(t_sym);
|
||||
t_sym = NULL;
|
||||
|
||||
t_sym = t_red_sym;
|
||||
t_red_sym = NULL;
|
||||
|
|
|
@ -288,5 +288,6 @@ static int get_Wyckoff_notation(double position[3],
|
|||
|
||||
end:
|
||||
mat_free_VecDBL(pos_rot);
|
||||
pos_rot = NULL;
|
||||
return wyckoff_letter;
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cell.h"
|
||||
#include "delaunay.h"
|
||||
#include "hall_symbol.h"
|
||||
#include "lattice.h"
|
||||
#include "mathfunc.h"
|
||||
#include "niggli.h"
|
||||
#include "pointgroup.h"
|
||||
|
@ -316,11 +316,12 @@ Primitive * spa_get_spacegroup(Spacegroup * spacegroup,
|
|||
primitive->tolerance);
|
||||
if (spacegroup->number > 0) {
|
||||
break;
|
||||
} else {
|
||||
prm_free_primitive(primitive);
|
||||
primitive = NULL;
|
||||
}
|
||||
|
||||
prm_free_primitive(primitive);
|
||||
|
||||
cont:
|
||||
cont:
|
||||
warning_print("spglib: Attempt %d tolerance = %f failed.",
|
||||
attempt, tolerance);
|
||||
warning_print(" (line %d, %s).\n", __LINE__, __FILE__);
|
||||
|
@ -343,13 +344,13 @@ Spacegroup spa_get_spacegroup_with_hall_number(SPGCONST Primitive * primitive,
|
|||
int num_candidates;
|
||||
int candidate[1];
|
||||
Spacegroup spacegroup;
|
||||
|
||||
|
||||
spacegroup.number = 0;
|
||||
|
||||
if (hall_number < 1 || hall_number > 530) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
num_candidates = 1;
|
||||
candidate[0] = hall_number;
|
||||
spacegroup = search_spacegroup(primitive->cell,
|
||||
|
@ -434,6 +435,7 @@ static Spacegroup search_spacegroup(SPGCONST Cell * primitive,
|
|||
double origin_shift[3];
|
||||
Spacegroup spacegroup;
|
||||
Symmetry *symmetry;
|
||||
PointSymmetry pointsym;
|
||||
|
||||
debug_print("search_spacegroup (tolerance = %f):\n", symprec);
|
||||
|
||||
|
@ -445,6 +447,15 @@ static Spacegroup search_spacegroup(SPGCONST Cell * primitive,
|
|||
goto ret;
|
||||
}
|
||||
|
||||
pointsym = ptg_get_pointsymmetry(symmetry->rot, symmetry->size);
|
||||
if (pointsym.size < symmetry->size) {
|
||||
warning_print("spglib: Point symmetry of primitive cell is broken. ");
|
||||
warning_print("(line %d, %s).\n", __LINE__, __FILE__);
|
||||
sym_free_symmetry(symmetry);
|
||||
symmetry = NULL;
|
||||
goto ret;
|
||||
}
|
||||
|
||||
hall_number = iterative_search_hall_number(origin_shift,
|
||||
conv_lattice,
|
||||
candidates,
|
||||
|
@ -453,6 +464,7 @@ static Spacegroup search_spacegroup(SPGCONST Cell * primitive,
|
|||
symmetry,
|
||||
symprec);
|
||||
sym_free_symmetry(symmetry);
|
||||
symmetry = NULL;
|
||||
spacegroup = get_spacegroup(hall_number, origin_shift, conv_lattice);
|
||||
|
||||
ret:
|
||||
|
@ -466,7 +478,7 @@ static Spacegroup get_spacegroup(const int hall_number,
|
|||
{
|
||||
Spacegroup spacegroup;
|
||||
SpacegroupType spacegroup_type;
|
||||
|
||||
|
||||
spacegroup.number = 0;
|
||||
spacegroup_type = spgdb_get_spacegroup_type(hall_number);
|
||||
|
||||
|
@ -540,6 +552,7 @@ static int iterative_search_hall_number(double origin_shift[3],
|
|||
sym_reduced,
|
||||
symprec);
|
||||
sym_free_symmetry(sym_reduced);
|
||||
sym_reduced = NULL;
|
||||
if (hall_number > 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -627,6 +640,7 @@ static int search_hall_number(double origin_shift[3],
|
|||
}
|
||||
|
||||
sym_free_symmetry(conv_symmetry);
|
||||
conv_symmetry = NULL;
|
||||
|
||||
return hall_number;
|
||||
|
||||
|
@ -683,10 +697,10 @@ static int change_basis_monocli(int int_transform_mat[3][3],
|
|||
{
|
||||
double smallest_lattice[3][3], inv_lattice[3][3], transform_mat[3][3];
|
||||
|
||||
if (! lat_smallest_lattice_vector_2D(smallest_lattice,
|
||||
conv_lattice,
|
||||
1, /* unique axis of b */
|
||||
symprec)) {
|
||||
if (! del_delaunay_reduce_2D(smallest_lattice,
|
||||
conv_lattice,
|
||||
1, /* unique axis of b */
|
||||
symprec)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -707,7 +721,7 @@ get_initial_conventional_symmetry(const Centering centering,
|
|||
debug_print("get_initial_conventional_symmetry\n");
|
||||
|
||||
conv_symmetry = NULL;
|
||||
|
||||
|
||||
if (centering == R_CENTER) {
|
||||
/* hP for rhombohedral */
|
||||
conv_symmetry = get_conventional_symmetry(transform_mat,
|
||||
|
@ -736,7 +750,7 @@ static int match_hall_symbol_db(double origin_shift[3],
|
|||
SpacegroupType spacegroup_type;
|
||||
Symmetry * changed_symmetry;
|
||||
double changed_lattice[3][3], inv_lattice[3][3], transform_mat[3][3];
|
||||
|
||||
|
||||
changed_symmetry = NULL;
|
||||
|
||||
spacegroup_type = spgdb_get_spacegroup_type(hall_number);
|
||||
|
@ -757,7 +771,7 @@ static int match_hall_symbol_db(double origin_shift[3],
|
|||
symmetry,
|
||||
symprec)) {return 1;}
|
||||
break;
|
||||
|
||||
|
||||
case ORTHO:
|
||||
if (spacegroup_type.number == 48 ||
|
||||
spacegroup_type.number == 50 ||
|
||||
|
@ -766,7 +780,7 @@ static int match_hall_symbol_db(double origin_shift[3],
|
|||
spacegroup_type.number == 70) { /* uncount origin shift */
|
||||
num_hall_types /= 2;
|
||||
}
|
||||
|
||||
|
||||
if (num_hall_types == 1) {
|
||||
if (match_hall_symbol_db_ortho(origin_shift,
|
||||
lattice,
|
||||
|
@ -815,7 +829,8 @@ static int match_hall_symbol_db(double origin_shift[3],
|
|||
changed_symmetry,
|
||||
2,
|
||||
symprec);
|
||||
sym_free_symmetry(changed_symmetry);
|
||||
sym_free_symmetry(changed_symmetry);
|
||||
changed_symmetry = NULL;
|
||||
if (is_found) {
|
||||
mat_copy_matrix_d3(lattice, changed_lattice);
|
||||
return 1;
|
||||
|
@ -843,7 +858,7 @@ static int match_hall_symbol_db(double origin_shift[3],
|
|||
centering,
|
||||
symmetry,
|
||||
symprec)) {return 1;}
|
||||
|
||||
|
||||
if (hall_number == 501) { /* Try another basis for No.205 */
|
||||
mat_multiply_matrix_d3(changed_lattice,
|
||||
lattice,
|
||||
|
@ -861,13 +876,14 @@ static int match_hall_symbol_db(double origin_shift[3],
|
|||
changed_symmetry,
|
||||
symprec);
|
||||
sym_free_symmetry(changed_symmetry);
|
||||
changed_symmetry = NULL;
|
||||
if (is_found) {
|
||||
mat_copy_matrix_d3(lattice, changed_lattice);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case TRIGO:
|
||||
if (centering == R_CENTER) {
|
||||
if (hall_number == 433 ||
|
||||
|
@ -893,6 +909,7 @@ static int match_hall_symbol_db(double origin_shift[3],
|
|||
changed_symmetry,
|
||||
symprec);
|
||||
sym_free_symmetry(changed_symmetry);
|
||||
changed_symmetry = NULL;
|
||||
if (is_found) {
|
||||
mat_copy_matrix_d3(lattice, changed_lattice);
|
||||
return 1;
|
||||
|
@ -932,7 +949,7 @@ static int match_hall_symbol_db_monocli(double origin_shift[3],
|
|||
double changed_lattice[3][3];
|
||||
|
||||
changed_symmetry = NULL;
|
||||
|
||||
|
||||
for (i = 0; i < 18; i++) {
|
||||
if (centering == C_FACE) {
|
||||
changed_centering = change_of_centering_monocli[i];
|
||||
|
@ -970,6 +987,7 @@ static int match_hall_symbol_db_monocli(double origin_shift[3],
|
|||
changed_symmetry,
|
||||
symprec);
|
||||
sym_free_symmetry(changed_symmetry);
|
||||
changed_symmetry = NULL;
|
||||
if (is_found) {
|
||||
mat_copy_matrix_d3(lattice, changed_lattice);
|
||||
return 1;
|
||||
|
@ -996,14 +1014,14 @@ static int match_hall_symbol_db_ortho(double origin_shift[3],
|
|||
double changed_lattice[3][3];
|
||||
|
||||
changed_symmetry = NULL;
|
||||
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (centering == C_FACE) {
|
||||
changed_centering = change_of_centering_ortho[i];
|
||||
} else {
|
||||
changed_centering = centering;
|
||||
}
|
||||
|
||||
|
||||
mat_multiply_matrix_d3(changed_lattice,
|
||||
lattice,
|
||||
change_of_basis_ortho[i]);
|
||||
|
@ -1034,7 +1052,7 @@ static int match_hall_symbol_db_ortho(double origin_shift[3],
|
|||
}
|
||||
if (norms[0] > norms[1] || norms[1] > norms[2]) {continue;}
|
||||
}
|
||||
|
||||
|
||||
if ((changed_symmetry = get_conventional_symmetry(change_of_basis_ortho[i],
|
||||
PRIMITIVE,
|
||||
symmetry)) == NULL) {
|
||||
|
@ -1048,6 +1066,7 @@ static int match_hall_symbol_db_ortho(double origin_shift[3],
|
|||
changed_symmetry,
|
||||
symprec);
|
||||
sym_free_symmetry(changed_symmetry);
|
||||
changed_symmetry = NULL;
|
||||
if (is_found) {
|
||||
mat_copy_matrix_d3(lattice, changed_lattice);
|
||||
return 1;
|
||||
|
@ -1135,7 +1154,7 @@ static Symmetry * get_conventional_symmetry(SPGCONST double transform_mat[3][3],
|
|||
shift[1][2] = 2. / 3;
|
||||
multi = 3;
|
||||
}
|
||||
|
||||
|
||||
if (centering == FACE) {
|
||||
shift[0][0] = 0;
|
||||
shift[0][1] = 0.5;
|
||||
|
@ -1263,7 +1282,7 @@ static Centering get_base_center(SPGCONST int transform_mat[3][3])
|
|||
|
||||
/* A center */
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (abs(transform_mat[i][0]) == 1 &&
|
||||
if (abs(transform_mat[i][0]) == 1 &&
|
||||
transform_mat[i][1] == 0 &&
|
||||
transform_mat[i][2] == 0) {
|
||||
centering = A_FACE;
|
||||
|
@ -1274,7 +1293,7 @@ static Centering get_base_center(SPGCONST int transform_mat[3][3])
|
|||
/* B center */
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (transform_mat[i][0] == 0 &&
|
||||
abs(transform_mat[i][1]) == 1 &&
|
||||
abs(transform_mat[i][1]) == 1 &&
|
||||
transform_mat[i][2] == 0) {
|
||||
centering = B_FACE;
|
||||
goto end;
|
||||
|
@ -1283,7 +1302,7 @@ static Centering get_base_center(SPGCONST int transform_mat[3][3])
|
|||
|
||||
/* body center */
|
||||
if (abs(transform_mat[0][0]) +
|
||||
abs(transform_mat[0][1]) +
|
||||
abs(transform_mat[0][1]) +
|
||||
abs(transform_mat[0][2]) == 2) {
|
||||
centering = BODY;
|
||||
goto end;
|
||||
|
|
|
@ -531,15 +531,15 @@ static const SpacegroupType spacegroup_types[] = {
|
|||
{197, "T^3 ", "I 2 2 3 ", "I 2 3 ", "I 2 3 ", "I23 ", " ", BODY, 28 }, /* 491 */
|
||||
{198, "T^4 ", "P 2ac 2ab 3 ", "P 2_1 3 ", "P 2_1 3 ", "P2_13 ", " ", PRIMITIVE, 28 }, /* 492 */
|
||||
{199, "T^5 ", "I 2b 2c 3 ", "I 2_1 3 ", "I 2_1 3 ", "I2_13 ", " ", BODY, 28 }, /* 493 */
|
||||
{200, "Th^1 ", "-P 2 2 3 ", "P m 3 ", "P 2/m -3 ", "Pm3 ", " ", PRIMITIVE, 29 }, /* 494 */
|
||||
{201, "Th^2 ", "P 2 2 3 -1n ", "P n 3 ", "P 2/n -3 ", "Pn3 ", "1 ", PRIMITIVE, 29 }, /* 495 */
|
||||
{201, "Th^2 ", "-P 2ab 2bc 3 ", "P n 3 ", "P 2/n -3 ", "Pn3 ", "2 ", PRIMITIVE, 29 }, /* 496 */
|
||||
{202, "Th^3 ", "-F 2 2 3 ", "F m 3 ", "F 2/m -3 ", "Fm3 ", " ", FACE, 29 }, /* 497 */
|
||||
{203, "Th^4 ", "F 2 2 3 -1d ", "F d 3 ", "F 2/d -3 ", "Fd3 ", "1 ", FACE, 29 }, /* 498 */
|
||||
{203, "Th^4 ", "-F 2uv 2vw 3 ", "F d 3 ", "F 2/d -3 ", "Fd3 ", "2 ", FACE, 29 }, /* 499 */
|
||||
{204, "Th^5 ", "-I 2 2 3 ", "I m 3 ", "I 2/m -3 ", "Im3 ", " ", BODY, 29 }, /* 500 */
|
||||
{205, "Th^6 ", "-P 2ac 2ab 3 ", "P a 3 ", "P 2_1/a -3 ", "Pa3 ", " ", PRIMITIVE, 29 }, /* 501 */
|
||||
{206, "Th^7 ", "-I 2b 2c 3 ", "I a 3 ", "I 2_1/a -3 ", "Ia3 ", " ", BODY, 29 }, /* 502 */
|
||||
{200, "Th^1 ", "-P 2 2 3 ", "P m -3 ", "P 2/m -3 ", "Pm-3 ", " ", PRIMITIVE, 29 }, /* 494 */
|
||||
{201, "Th^2 ", "P 2 2 3 -1n ", "P n -3 ", "P 2/n -3 ", "Pn-3 ", "1 ", PRIMITIVE, 29 }, /* 495 */
|
||||
{201, "Th^2 ", "-P 2ab 2bc 3 ", "P n -3 ", "P 2/n -3 ", "Pn-3 ", "2 ", PRIMITIVE, 29 }, /* 496 */
|
||||
{202, "Th^3 ", "-F 2 2 3 ", "F m -3 ", "F 2/m -3 ", "Fm-3 ", " ", FACE, 29 }, /* 497 */
|
||||
{203, "Th^4 ", "F 2 2 3 -1d ", "F d -3 ", "F 2/d -3 ", "Fd-3 ", "1 ", FACE, 29 }, /* 498 */
|
||||
{203, "Th^4 ", "-F 2uv 2vw 3 ", "F d -3 ", "F 2/d -3 ", "Fd-3 ", "2 ", FACE, 29 }, /* 499 */
|
||||
{204, "Th^5 ", "-I 2 2 3 ", "I m -3 ", "I 2/m -3 ", "Im-3 ", " ", BODY, 29 }, /* 500 */
|
||||
{205, "Th^6 ", "-P 2ac 2ab 3 ", "P a -3 ", "P 2_1/a -3 ", "Pa-3 ", " ", PRIMITIVE, 29 }, /* 501 */
|
||||
{206, "Th^7 ", "-I 2b 2c 3 ", "I a -3 ", "I 2_1/a -3 ", "Ia-3 ", " ", BODY, 29 }, /* 502 */
|
||||
{207, "O^1 ", "P 4 2 3 ", "P 4 3 2 ", "P 4 3 2 ", "P432 ", " ", PRIMITIVE, 30 }, /* 503 */
|
||||
{208, "O^2 ", "P 4n 2 3 ", "P 4_2 3 2 ", "P 4_2 3 2 ", "P4_232 ", " ", PRIMITIVE, 30 }, /* 504 */
|
||||
{209, "O^3 ", "F 4 2 3 ", "F 4 3 2 ", "F 4 3 2 ", "F432 ", " ", FACE, 30 }, /* 505 */
|
||||
|
@ -8575,7 +8575,7 @@ SpacegroupType spgdb_get_spacegroup_type(const int hall_number)
|
|||
|
||||
spgtype.number = 0;
|
||||
|
||||
if (0 < hall_number || hall_number < 531) {
|
||||
if (0 < hall_number && hall_number < 531) {
|
||||
spgtype = spacegroup_types[hall_number];
|
||||
} else {
|
||||
spgtype = spacegroup_types[0];
|
||||
|
|
|
@ -37,10 +37,11 @@
|
|||
#include <string.h>
|
||||
#include "cell.h"
|
||||
#include "debug.h"
|
||||
#include "delaunay.h"
|
||||
#include "kgrid.h"
|
||||
#include "kpoint.h"
|
||||
#include "lattice.h"
|
||||
#include "mathfunc.h"
|
||||
#include "niggli.h"
|
||||
#include "pointgroup.h"
|
||||
#include "spglib.h"
|
||||
#include "primitive.h"
|
||||
|
@ -467,14 +468,6 @@ int spgat_get_multiplicity(SPGCONST double lattice[3][3],
|
|||
symprec);
|
||||
}
|
||||
|
||||
/* Return 0 if failed */
|
||||
int spg_get_smallest_lattice(double smallest_lattice[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const double symprec)
|
||||
{
|
||||
return lat_smallest_lattice_vector(smallest_lattice, lattice, symprec);
|
||||
}
|
||||
|
||||
/* Return 0 if failed */
|
||||
int spg_get_international(char symbol[11],
|
||||
SPGCONST double lattice[3][3],
|
||||
|
@ -591,6 +584,7 @@ int spg_get_symmetry_from_database(int rotations[192][3][3],
|
|||
size = symmetry->size;
|
||||
|
||||
sym_free_symmetry(symmetry);
|
||||
symmetry = NULL;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@ -742,6 +736,24 @@ int spgat_refine_cell(double lattice[3][3],
|
|||
symprec);
|
||||
}
|
||||
|
||||
int spg_delaunay_reduce(double lattice[3][3], const double symprec)
|
||||
{
|
||||
int i, j, succeeded;
|
||||
double red_lattice[3][3];
|
||||
|
||||
succeeded = del_delaunay_reduce(red_lattice, lattice, symprec);
|
||||
|
||||
if (succeeded) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
lattice[i][j] = red_lattice[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
/*---------*/
|
||||
/* kpoints */
|
||||
/*---------*/
|
||||
|
@ -832,6 +844,7 @@ int spg_get_grid_points_by_rotations(int rot_grid_points[],
|
|||
mesh,
|
||||
is_shift);
|
||||
mat_free_MatINT(rot);
|
||||
rot = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -863,6 +876,7 @@ int spg_get_BZ_grid_points_by_rotations(int rot_grid_points[],
|
|||
is_shift,
|
||||
bz_map);
|
||||
mat_free_MatINT(rot);
|
||||
rot = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -882,64 +896,35 @@ int spg_relocate_BZ_grid_address(int bz_grid_address[][3],
|
|||
is_shift);
|
||||
}
|
||||
|
||||
/* /\*--------------------*\/ */
|
||||
/* /\* tetrahedron method *\/ */
|
||||
/* /\*--------------------*\/ */
|
||||
/* void spg_get_neighboring_grid_points(int relative_grid_points[], */
|
||||
/* const int grid_point, */
|
||||
/* SPGCONST int relative_grid_address[][3], */
|
||||
/* const int num_relative_grid_address, */
|
||||
/* const int mesh[3], */
|
||||
/* SPGCONST int bz_grid_address[][3], */
|
||||
/* const int bz_map[]) */
|
||||
/* { */
|
||||
/* thm_get_neighboring_grid_points(relative_grid_points, */
|
||||
/* grid_point, */
|
||||
/* relative_grid_address, */
|
||||
/* num_relative_grid_address, */
|
||||
/* mesh, */
|
||||
/* bz_grid_address, */
|
||||
/* bz_map); */
|
||||
/* } */
|
||||
/*--------*/
|
||||
/* Niggli */
|
||||
/*--------*/
|
||||
/* Return 0 if failed */
|
||||
int spg_niggli_reduce(double lattice[3][3], const double symprec)
|
||||
{
|
||||
int i, j, succeeded;
|
||||
double vals[9];
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
vals[i * 3 + j] = lattice[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
/* void */
|
||||
/* spg_get_tetrahedra_relative_grid_address(int relative_grid_address[24][4][3], */
|
||||
/* SPGCONST double rec_lattice[3][3]) */
|
||||
/* { */
|
||||
/* thm_get_relative_grid_address(relative_grid_address, rec_lattice); */
|
||||
/* } */
|
||||
succeeded = niggli_reduce(vals, symprec);
|
||||
|
||||
/* void */
|
||||
/* spg_get_all_tetrahedra_relative_grid_address */
|
||||
/* (int relative_grid_address[4][24][4][3]) */
|
||||
/* { */
|
||||
/* thm_get_all_relative_grid_address(relative_grid_address); */
|
||||
/* } */
|
||||
if (succeeded) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
lattice[i][j] = vals[i * 3 + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
/* double */
|
||||
/* spg_get_tetrahedra_integration_weight(const double omega, */
|
||||
/* SPGCONST double tetrahedra_omegas[24][4], */
|
||||
/* const char function) */
|
||||
/* { */
|
||||
/* return thm_get_integration_weight(omega, */
|
||||
/* tetrahedra_omegas, */
|
||||
/* function); */
|
||||
/* } */
|
||||
|
||||
/* void */
|
||||
/* spg_get_tetrahedra_integration_weight_at_omegas */
|
||||
/* (double integration_weights[], */
|
||||
/* const int num_omegas, */
|
||||
/* const double omegas[], */
|
||||
/* SPGCONST double tetrahedra_omegas[24][4], */
|
||||
/* const char function) */
|
||||
/* { */
|
||||
/* thm_get_integration_weight_at_omegas(integration_weights, */
|
||||
/* num_omegas, */
|
||||
/* omegas, */
|
||||
/* tetrahedra_omegas, */
|
||||
/* function); */
|
||||
/* } */
|
||||
|
||||
|
||||
/*=======*/
|
||||
|
@ -974,6 +959,7 @@ static SpglibDataset * get_dataset(SPGCONST double lattice[3][3],
|
|||
}
|
||||
|
||||
dataset->spacegroup_number = 0;
|
||||
dataset->hall_number = 0;
|
||||
strcpy(dataset->international_symbol, "");
|
||||
strcpy(dataset->hall_symbol, "");
|
||||
strcpy(dataset->setting, "");
|
||||
|
@ -1000,10 +986,15 @@ static SpglibDataset * get_dataset(SPGCONST double lattice[3][3],
|
|||
|
||||
cel_set_cell(cell, lattice, position, types);
|
||||
|
||||
primitive = spa_get_spacegroup(&spacegroup, cell, symprec);
|
||||
|
||||
if ((spacegroup.number > 0) && (primitive != NULL)) {
|
||||
if ((primitive = spa_get_spacegroup(&spacegroup, cell, symprec)) == NULL) {
|
||||
cel_free_cell(cell);
|
||||
cell = NULL;
|
||||
free(dataset);
|
||||
dataset = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (spacegroup.number > 0) {
|
||||
/* With hall_number > 0, specific choice is searched. */
|
||||
if (hall_number > 0) {
|
||||
spacegroup_type = spgdb_get_spacegroup_type(hall_number);
|
||||
|
@ -1031,14 +1022,18 @@ static SpglibDataset * get_dataset(SPGCONST double lattice[3][3],
|
|||
}
|
||||
}
|
||||
|
||||
cel_free_cell(cell);
|
||||
prm_free_primitive(primitive);
|
||||
primitive = NULL;
|
||||
cel_free_cell(cell);
|
||||
cell = NULL;
|
||||
|
||||
return dataset;
|
||||
|
||||
err:
|
||||
cel_free_cell(cell);
|
||||
cell = NULL;
|
||||
prm_free_primitive(primitive);
|
||||
primitive = NULL;
|
||||
free(dataset);
|
||||
dataset = NULL;
|
||||
return NULL;
|
||||
|
@ -1150,7 +1145,9 @@ static int set_dataset(SpglibDataset * dataset,
|
|||
}
|
||||
|
||||
cel_free_cell(bravais);
|
||||
bravais = NULL;
|
||||
sym_free_symmetry(symmetry);
|
||||
symmetry = NULL;
|
||||
|
||||
dataset->pointgroup_number = spacegroup->pointgroup_number;
|
||||
pointgroup = ptg_get_pointgroup(spacegroup->pointgroup_number);
|
||||
|
@ -1165,6 +1162,7 @@ static int set_dataset(SpglibDataset * dataset,
|
|||
}
|
||||
if (bravais != NULL) {
|
||||
cel_free_cell(bravais);
|
||||
bravais = NULL;
|
||||
}
|
||||
if (dataset->equivalent_atoms != NULL) {
|
||||
free(dataset->equivalent_atoms);
|
||||
|
@ -1184,6 +1182,7 @@ static int set_dataset(SpglibDataset * dataset,
|
|||
}
|
||||
if (symmetry != NULL) {
|
||||
sym_free_symmetry(symmetry);
|
||||
symmetry = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1268,12 +1267,14 @@ static int get_symmetry_with_collinear_spin(int rotation[][3][3],
|
|||
0,
|
||||
symprec)) == NULL) {
|
||||
cel_free_cell(cell);
|
||||
cell = NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((sym_nonspin = sym_alloc_symmetry(dataset->n_operations)) == NULL) {
|
||||
spg_free_dataset(dataset);
|
||||
cel_free_cell(cell);
|
||||
cell = NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -1289,11 +1290,14 @@ static int get_symmetry_with_collinear_spin(int rotation[][3][3],
|
|||
spins,
|
||||
symprec)) == NULL) {
|
||||
sym_free_symmetry(sym_nonspin);
|
||||
sym_nonspin = NULL;
|
||||
cel_free_cell(cell);
|
||||
cell = NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
sym_free_symmetry(sym_nonspin);
|
||||
sym_nonspin = NULL;
|
||||
|
||||
if (symmetry->size > max_size) {
|
||||
fprintf(stderr, "spglib: Indicated max size(=%d) is less than number ",
|
||||
|
@ -1311,7 +1315,9 @@ static int get_symmetry_with_collinear_spin(int rotation[][3][3],
|
|||
|
||||
ret:
|
||||
sym_free_symmetry(symmetry);
|
||||
symmetry = NULL;
|
||||
cel_free_cell(cell);
|
||||
cell = NULL;
|
||||
|
||||
return size;
|
||||
|
||||
|
@ -1402,6 +1408,7 @@ static int standardize_primitive(double lattice[3][3],
|
|||
centering,
|
||||
symprec);
|
||||
cel_free_cell(bravais);
|
||||
bravais = NULL;
|
||||
|
||||
if (primitive == NULL) {
|
||||
goto err;
|
||||
|
@ -1411,6 +1418,7 @@ static int standardize_primitive(double lattice[3][3],
|
|||
num_prim_atom = primitive->size;
|
||||
|
||||
cel_free_cell(primitive);
|
||||
primitive = NULL;
|
||||
|
||||
return num_prim_atom;
|
||||
|
||||
|
@ -1501,6 +1509,7 @@ static int get_standardized_cell(double lattice[3][3],
|
|||
symprec);
|
||||
spg_free_dataset(dataset);
|
||||
cel_free_cell(cell);
|
||||
cell = NULL;
|
||||
|
||||
if (std_cell == NULL) {
|
||||
goto err;
|
||||
|
@ -1510,6 +1519,7 @@ static int get_standardized_cell(double lattice[3][3],
|
|||
num_std_atom = std_cell->size;
|
||||
|
||||
cel_free_cell(std_cell);
|
||||
std_cell = NULL;
|
||||
|
||||
return num_std_atom;
|
||||
|
||||
|
@ -1563,12 +1573,14 @@ static int get_international(char symbol[11],
|
|||
|
||||
if ((primitive = spa_get_spacegroup(&spacegroup, cell, symprec)) != NULL) {
|
||||
prm_free_primitive(primitive);
|
||||
primitive = NULL;
|
||||
if (spacegroup.number > 0) {
|
||||
strcpy(symbol, spacegroup.international_short);
|
||||
}
|
||||
}
|
||||
|
||||
cel_free_cell(cell);
|
||||
cell = NULL;
|
||||
|
||||
return spacegroup.number;
|
||||
}
|
||||
|
@ -1596,12 +1608,14 @@ static int get_schoenflies(char symbol[10],
|
|||
|
||||
if ((primitive = spa_get_spacegroup(&spacegroup, cell, symprec)) != NULL) {
|
||||
prm_free_primitive(primitive);
|
||||
primitive = NULL;
|
||||
if (spacegroup.number > 0) {
|
||||
strcpy(symbol, spacegroup.schoenflies);
|
||||
}
|
||||
}
|
||||
|
||||
cel_free_cell(cell);
|
||||
cell = NULL;
|
||||
|
||||
return spacegroup.number;
|
||||
}
|
||||
|
@ -1632,6 +1646,7 @@ static int get_symmetry_numerical(int rotation[][3][3],
|
|||
|
||||
if ((symmetry = sym_get_operation(cell, symprec)) == NULL) {
|
||||
cel_free_cell(cell);
|
||||
cell = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1650,7 +1665,9 @@ static int get_symmetry_numerical(int rotation[][3][3],
|
|||
|
||||
ret:
|
||||
sym_free_symmetry(symmetry);
|
||||
symmetry = NULL;
|
||||
cel_free_cell(cell);
|
||||
cell = NULL;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@ -1688,7 +1705,6 @@ static int get_ir_reciprocal_mesh(int grid_address[][3],
|
|||
int num_ir, i;
|
||||
MatINT *rotations, *rot_reciprocal;
|
||||
|
||||
|
||||
dataset = get_dataset(lattice,
|
||||
position,
|
||||
types,
|
||||
|
@ -1711,7 +1727,9 @@ static int get_ir_reciprocal_mesh(int grid_address[][3],
|
|||
is_shift,
|
||||
rot_reciprocal);
|
||||
mat_free_MatINT(rot_reciprocal);
|
||||
rot_reciprocal = NULL;
|
||||
mat_free_MatINT(rotations);
|
||||
rotations = NULL;
|
||||
spg_free_dataset(dataset);
|
||||
return num_ir;
|
||||
}
|
||||
|
@ -1749,6 +1767,7 @@ static int get_stabilized_reciprocal_mesh(int grid_address[][3],
|
|||
qpoints);
|
||||
|
||||
mat_free_MatINT(rot_real);
|
||||
rot_real = NULL;
|
||||
|
||||
return num_ir;
|
||||
}
|
||||
|
|
|
@ -147,7 +147,9 @@ static Symmetry * get_collinear_operations(SPGCONST Symmetry *sym_nonspin,
|
|||
}
|
||||
|
||||
mat_free_MatINT(rot);
|
||||
rot = NULL;
|
||||
mat_free_VecDBL(trans);
|
||||
trans = NULL;
|
||||
|
||||
return symmetry;
|
||||
}
|
||||
|
|
|
@ -36,18 +36,18 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "cell.h"
|
||||
#include "lattice.h"
|
||||
#include "delaunay.h"
|
||||
#include "mathfunc.h"
|
||||
#include "symmetry.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#define NUM_ATOMS_CRITERION_FOR_OPENMP 1000
|
||||
#define REDUCE_RATE 0.95
|
||||
#define ANGLE_REDUCE_RATE 0.95
|
||||
#define PI 3.14159265358979323846
|
||||
/* Tolerance of angle between lattice vectors in degrees */
|
||||
/* Negative value invokes converter from symprec. */
|
||||
static double angle_tolerance = -1.0;
|
||||
static double angle_tolerance = -1.0;
|
||||
|
||||
static int relative_axes[][3] = {
|
||||
{ 1, 0, 0},
|
||||
|
@ -88,10 +88,12 @@ static VecDBL * get_translation(SPGCONST int rot[3][3],
|
|||
const double symprec,
|
||||
const int is_identity);
|
||||
static Symmetry * get_operations(SPGCONST Cell *primitive,
|
||||
const double symprec);
|
||||
const double symprec,
|
||||
const double angle_symprec);
|
||||
static Symmetry * reduce_operation(SPGCONST Cell * primitive,
|
||||
SPGCONST Symmetry * symmetry,
|
||||
const double symprec);
|
||||
const double symprec,
|
||||
const double angle_symprec);
|
||||
static int search_translation_part(int lat_point_atoms[],
|
||||
SPGCONST Cell * cell,
|
||||
SPGCONST int rot[3][3],
|
||||
|
@ -115,10 +117,12 @@ get_space_group_operations(SPGCONST PointSymmetry *lattice_sym,
|
|||
static void set_axes(int axes[3][3],
|
||||
const int a1, const int a2, const int a3);
|
||||
static PointSymmetry get_lattice_symmetry(SPGCONST double cell_lattice[3][3],
|
||||
const double symprec);
|
||||
const double symprec,
|
||||
const double angle_symprec);
|
||||
static int is_identity_metric(SPGCONST double metric_rotated[3][3],
|
||||
SPGCONST double metric_orig[3][3],
|
||||
const double symprec);
|
||||
const double symprec,
|
||||
const double angle_symprec);
|
||||
static double get_angle(SPGCONST double metric[3][3],
|
||||
const int i,
|
||||
const int j);
|
||||
|
@ -160,7 +164,7 @@ Symmetry * sym_alloc_symmetry(const int size)
|
|||
free(symmetry);
|
||||
symmetry = NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return symmetry;
|
||||
}
|
||||
|
@ -174,7 +178,6 @@ void sym_free_symmetry(Symmetry *symmetry)
|
|||
symmetry->trans = NULL;
|
||||
}
|
||||
free(symmetry);
|
||||
symmetry = NULL;
|
||||
}
|
||||
|
||||
/* Return NULL if failed */
|
||||
|
@ -184,7 +187,7 @@ Symmetry * sym_get_operation(SPGCONST Cell * primitive,
|
|||
|
||||
debug_print("sym_get_operations:\n");
|
||||
|
||||
return get_operations(primitive, symprec);
|
||||
return get_operations(primitive, symprec, angle_tolerance);
|
||||
}
|
||||
|
||||
/* Return NULL if failed */
|
||||
|
@ -192,7 +195,7 @@ Symmetry * sym_reduce_operation(SPGCONST Cell * primitive,
|
|||
SPGCONST Symmetry * symmetry,
|
||||
const double symprec)
|
||||
{
|
||||
return reduce_operation(primitive, symmetry, symprec);
|
||||
return reduce_operation(primitive, symmetry, symprec, angle_tolerance);
|
||||
}
|
||||
|
||||
/* Return NULL if failed */
|
||||
|
@ -208,6 +211,8 @@ VecDBL * sym_get_pure_translation(SPGCONST Cell *cell,
|
|||
pure_trans = NULL;
|
||||
|
||||
if ((pure_trans = get_translation(identity, cell, symprec, 1)) == NULL) {
|
||||
warning_print("spglib: get_translation failed (line %d, %s).\n",
|
||||
__LINE__, __FILE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -235,7 +240,7 @@ VecDBL * sym_reduce_pure_translation(SPGCONST Cell * cell,
|
|||
symmetry = NULL;
|
||||
symmetry_reduced = NULL;
|
||||
pure_trans_reduced = NULL;
|
||||
|
||||
|
||||
multi = pure_trans->size;
|
||||
|
||||
if ((symmetry = sym_alloc_symmetry(multi)) == NULL) {
|
||||
|
@ -247,24 +252,29 @@ VecDBL * sym_reduce_pure_translation(SPGCONST Cell * cell,
|
|||
mat_copy_vector_d3(symmetry->trans[i], pure_trans->vec[i]);
|
||||
}
|
||||
|
||||
if ((symmetry_reduced = reduce_operation(cell, symmetry, symprec)) == NULL) {
|
||||
if ((symmetry_reduced =
|
||||
reduce_operation(cell, symmetry, symprec, angle_tolerance)) == NULL) {
|
||||
sym_free_symmetry(symmetry);
|
||||
symmetry = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sym_free_symmetry(symmetry);
|
||||
symmetry = NULL;
|
||||
multi = symmetry_reduced->size;
|
||||
|
||||
if ((pure_trans_reduced = mat_alloc_VecDBL(multi)) == NULL) {
|
||||
sym_free_symmetry(symmetry_reduced);
|
||||
symmetry_reduced = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < multi; i++) {
|
||||
mat_copy_vector_d3(pure_trans_reduced->vec[i], symmetry_reduced->trans[i]);
|
||||
}
|
||||
sym_free_symmetry(symmetry_reduced);
|
||||
|
||||
symmetry_reduced = NULL;
|
||||
|
||||
return pure_trans_reduced;
|
||||
}
|
||||
|
||||
|
@ -289,7 +299,8 @@ double sym_get_angle_tolerance(void)
|
|||
/* transformed to those of original input cells, if the input cell */
|
||||
/* was not a primitive cell. */
|
||||
static Symmetry * get_operations(SPGCONST Cell *primitive,
|
||||
const double symprec)
|
||||
const double symprec,
|
||||
const double angle_symprec)
|
||||
{
|
||||
PointSymmetry lattice_sym;
|
||||
Symmetry *symmetry;
|
||||
|
@ -298,26 +309,27 @@ static Symmetry * get_operations(SPGCONST Cell *primitive,
|
|||
|
||||
symmetry = NULL;
|
||||
|
||||
lattice_sym = get_lattice_symmetry(primitive->lattice, symprec);
|
||||
lattice_sym = get_lattice_symmetry(primitive->lattice,
|
||||
symprec,
|
||||
angle_symprec);
|
||||
if (lattice_sym.size == 0) {
|
||||
debug_print("get_lattice_symmetry failed.\n");
|
||||
goto end;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((symmetry = get_space_group_operations(&lattice_sym,
|
||||
primitive,
|
||||
symprec)) == NULL) {
|
||||
goto end;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
end:
|
||||
return symmetry;
|
||||
}
|
||||
|
||||
/* Return NULL if failed */
|
||||
static Symmetry * reduce_operation(SPGCONST Cell * primitive,
|
||||
SPGCONST Symmetry * symmetry,
|
||||
const double symprec)
|
||||
const double symprec,
|
||||
const double angle_symprec)
|
||||
{
|
||||
int i, j, num_sym;
|
||||
Symmetry * sym_reduced;
|
||||
|
@ -331,7 +343,12 @@ static Symmetry * reduce_operation(SPGCONST Cell * primitive,
|
|||
rot = NULL;
|
||||
trans = NULL;
|
||||
|
||||
point_symmetry = get_lattice_symmetry(primitive->lattice, symprec);
|
||||
point_symmetry = get_lattice_symmetry(primitive->lattice,
|
||||
symprec,
|
||||
angle_symprec);
|
||||
if (point_symmetry.size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((rot = mat_alloc_MatINT(symmetry->size)) == NULL) {
|
||||
return NULL;
|
||||
|
@ -339,9 +356,10 @@ static Symmetry * reduce_operation(SPGCONST Cell * primitive,
|
|||
|
||||
if ((trans = mat_alloc_VecDBL(symmetry->size)) == NULL) {
|
||||
mat_free_MatINT(rot);
|
||||
rot = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
num_sym = 0;
|
||||
for (i = 0; i < point_symmetry.size; i++) {
|
||||
for (j = 0; j < symmetry->size; j++) {
|
||||
|
@ -368,7 +386,9 @@ static Symmetry * reduce_operation(SPGCONST Cell * primitive,
|
|||
}
|
||||
|
||||
mat_free_MatINT(rot);
|
||||
rot = NULL;
|
||||
mat_free_VecDBL(trans);
|
||||
trans = NULL;
|
||||
|
||||
return sym_reduced;
|
||||
}
|
||||
|
@ -497,7 +517,7 @@ static VecDBL * get_translation(SPGCONST int rot[3][3],
|
|||
ret:
|
||||
free(is_found);
|
||||
is_found = NULL;
|
||||
|
||||
|
||||
return trans;
|
||||
}
|
||||
|
||||
|
@ -546,7 +566,7 @@ static int is_overlap_all_atoms(const double trans[3],
|
|||
double pos_rot[3], d_frac[3], d[3];
|
||||
|
||||
symprec2 = symprec * symprec;
|
||||
|
||||
|
||||
for (i = 0; i < cell->size; i++) {
|
||||
if (is_identity) { /* Identity matrix is treated as special for speed-up. */
|
||||
for (j = 0; j < 3; j++) {
|
||||
|
@ -600,11 +620,11 @@ static int get_index_with_least_atoms(const Cell *cell)
|
|||
warning_print("spglib: Memory could not be allocated ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < cell->size; i++) {
|
||||
mapping[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < cell->size; i++) {
|
||||
for (j = 0; j < cell->size; j++) {
|
||||
if (cell->types[i] == cell->types[j]) {
|
||||
|
@ -613,7 +633,7 @@ static int get_index_with_least_atoms(const Cell *cell)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
min = mapping[0];
|
||||
min_index = 0;
|
||||
for (i = 0; i < cell->size; i++) {
|
||||
|
@ -643,7 +663,7 @@ get_space_group_operations(SPGCONST PointSymmetry *lattice_sym,
|
|||
|
||||
trans = NULL;
|
||||
symmetry = NULL;
|
||||
|
||||
|
||||
if ((trans = (VecDBL**) malloc(sizeof(VecDBL*) * lattice_sym->size))
|
||||
== NULL) {
|
||||
warning_print("spglib: Memory could not be allocated ");
|
||||
|
@ -687,6 +707,7 @@ get_space_group_operations(SPGCONST PointSymmetry *lattice_sym,
|
|||
for (i = 0; i < lattice_sym->size; i++) {
|
||||
if (trans[i] != NULL) {
|
||||
mat_free_VecDBL(trans[i]);
|
||||
trans[i] = NULL;
|
||||
}
|
||||
}
|
||||
free(trans);
|
||||
|
@ -696,9 +717,11 @@ get_space_group_operations(SPGCONST PointSymmetry *lattice_sym,
|
|||
}
|
||||
|
||||
static PointSymmetry get_lattice_symmetry(SPGCONST double cell_lattice[3][3],
|
||||
const double symprec)
|
||||
const double symprec,
|
||||
const double angle_symprec)
|
||||
{
|
||||
int i, j, k, num_sym;
|
||||
int i, j, k, attempt, num_sym;
|
||||
double angle_tol;
|
||||
int axes[3][3];
|
||||
double lattice[3][3], min_lattice[3][3];
|
||||
double metric[3][3], metric_orig[3][3];
|
||||
|
@ -706,54 +729,62 @@ static PointSymmetry get_lattice_symmetry(SPGCONST double cell_lattice[3][3],
|
|||
|
||||
debug_print("get_lattice_symmetry:\n");
|
||||
|
||||
if (! lat_smallest_lattice_vector(min_lattice,
|
||||
cell_lattice,
|
||||
symprec)) {
|
||||
lattice_sym.size = 0;
|
||||
|
||||
if (! del_delaunay_reduce(min_lattice, cell_lattice, symprec)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
mat_get_metric(metric_orig, min_lattice);
|
||||
angle_tol = angle_symprec;
|
||||
|
||||
num_sym = 0;
|
||||
for (i = 0; i < 26; i++) {
|
||||
for (j = 0; j < 26; j++) {
|
||||
for (k = 0; k < 26; k++) {
|
||||
set_axes(axes, i, j, k);
|
||||
if (! ((mat_get_determinant_i3(axes) == 1) ||
|
||||
(mat_get_determinant_i3(axes) == -1))) {
|
||||
continue;
|
||||
}
|
||||
mat_multiply_matrix_di3(lattice, min_lattice, axes);
|
||||
mat_get_metric(metric, lattice);
|
||||
|
||||
if (is_identity_metric(metric, metric_orig, symprec)) {
|
||||
mat_copy_matrix_i3(lattice_sym.rot[num_sym], axes);
|
||||
num_sym++;
|
||||
}
|
||||
|
||||
if (num_sym > 48) {
|
||||
warning_print("spglib: Too many lattice symmetries was found.\n");
|
||||
warning_print(" Tolerance may be too large ");
|
||||
warning_print("(line %d, %s).\n", __LINE__, __FILE__);
|
||||
goto err;
|
||||
for (attempt = 0; attempt < 100; attempt++) {
|
||||
num_sym = 0;
|
||||
for (i = 0; i < 26; i++) {
|
||||
for (j = 0; j < 26; j++) {
|
||||
for (k = 0; k < 26; k++) {
|
||||
set_axes(axes, i, j, k);
|
||||
if (! ((mat_get_determinant_i3(axes) == 1) ||
|
||||
(mat_get_determinant_i3(axes) == -1))) {
|
||||
continue;
|
||||
}
|
||||
mat_multiply_matrix_di3(lattice, min_lattice, axes);
|
||||
mat_get_metric(metric, lattice);
|
||||
|
||||
if (is_identity_metric(metric, metric_orig, symprec, angle_tol)) {
|
||||
if (num_sym > 47) {
|
||||
angle_tol *= ANGLE_REDUCE_RATE;
|
||||
warning_print("spglib: Too many lattice symmetries was found.\n");
|
||||
warning_print(" Reduce angle tolerance to %f", angle_tol);
|
||||
warning_print(" (line %d, %s).\n", __LINE__, __FILE__);
|
||||
goto next_attempt;
|
||||
}
|
||||
|
||||
mat_copy_matrix_i3(lattice_sym.rot[num_sym], axes);
|
||||
num_sym++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num_sym < 49 || angle_tol < 0) {
|
||||
lattice_sym.size = num_sym;
|
||||
return transform_pointsymmetry(&lattice_sym, cell_lattice, min_lattice);
|
||||
}
|
||||
|
||||
next_attempt:
|
||||
;
|
||||
}
|
||||
|
||||
lattice_sym.size = num_sym;
|
||||
return transform_pointsymmetry(&lattice_sym,
|
||||
cell_lattice,
|
||||
min_lattice);
|
||||
|
||||
err:
|
||||
lattice_sym.size = 0;
|
||||
debug_print("get_lattice_symmetry failed.\n");
|
||||
return lattice_sym;
|
||||
}
|
||||
|
||||
static int is_identity_metric(SPGCONST double metric_rotated[3][3],
|
||||
SPGCONST double metric_orig[3][3],
|
||||
const double symprec)
|
||||
const double symprec,
|
||||
const double angle_symprec)
|
||||
{
|
||||
int i, j, k;
|
||||
int elem_sets[3][2] = {{0, 1},
|
||||
|
@ -769,13 +800,13 @@ static int is_identity_metric(SPGCONST double metric_rotated[3][3],
|
|||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
j = elem_sets[i][0];
|
||||
k = elem_sets[i][1];
|
||||
if (angle_tolerance > 0) {
|
||||
if (angle_symprec > 0) {
|
||||
if (mat_Dabs(get_angle(metric_orig, j, k) -
|
||||
get_angle(metric_rotated, j, k)) > angle_tolerance) {
|
||||
get_angle(metric_rotated, j, k)) > angle_symprec) {
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
|
@ -824,6 +855,8 @@ transform_pointsymmetry(SPGCONST PointSymmetry * lat_sym_orig,
|
|||
double trans_mat[3][3], inv_mat[3][3], drot[3][3];
|
||||
PointSymmetry lat_sym_new;
|
||||
|
||||
lat_sym_new.size = 0;
|
||||
|
||||
mat_inverse_matrix_d3(inv_mat, original_lattice, 0);
|
||||
mat_multiply_matrix_d3(trans_mat, inv_mat, new_lattice);
|
||||
|
||||
|
@ -856,7 +889,6 @@ transform_pointsymmetry(SPGCONST PointSymmetry * lat_sym_orig,
|
|||
return lat_sym_new;
|
||||
|
||||
err:
|
||||
lat_sym_new.size = 0;
|
||||
return lat_sym_new;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
/* Copyright (C) 2010 Atsushi Togo */
|
||||
/* All rights reserved. */
|
||||
|
||||
/* This file is part of spglib. */
|
||||
|
||||
/* Redistribution and use in source and binary forms, with or without */
|
||||
/* modification, are permitted provided that the following conditions */
|
||||
/* are met: */
|
||||
|
||||
/* * Redistributions of source code must retain the above copyright */
|
||||
/* notice, this list of conditions and the following disclaimer. */
|
||||
|
||||
/* * Redistributions in binary form must reproduce the above copyright */
|
||||
/* notice, this list of conditions and the following disclaimer in */
|
||||
/* the documentation and/or other materials provided with the */
|
||||
/* distribution. */
|
||||
|
||||
/* * Neither the name of the phonopy project nor the names of its */
|
||||
/* contributors may be used to endorse or promote products derived */
|
||||
/* from this software without specific prior written permission. */
|
||||
|
||||
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
|
||||
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
|
||||
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
|
||||
/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
|
||||
/* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
|
||||
/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
|
||||
/* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
|
||||
/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
|
||||
/* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
|
||||
/* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
|
||||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#ifndef __lattice_H__
|
||||
#define __lattice_H__
|
||||
|
||||
#include "mathfunc.h"
|
||||
|
||||
int lat_smallest_lattice_vector(double lattice_new[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const double symprec);
|
||||
int lat_smallest_lattice_vector_2D(double min_lattice[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const int unique_axis,
|
||||
const double symprec);
|
||||
|
||||
#endif
|
|
@ -35,6 +35,13 @@
|
|||
#ifndef __NIGGLI_H__
|
||||
#define __NIGGLI_H__
|
||||
|
||||
#define NIGGLI_MAJOR_VERSION 0
|
||||
#define NIGGLI_MINOR_VERSION 1
|
||||
#define NIGGLI_MICRO_VERSION 2
|
||||
|
||||
int niggli_get_major_version(void);
|
||||
int niggli_get_minor_version(void);
|
||||
int niggli_get_micro_version(void);
|
||||
int niggli_reduce(double *lattice_, const double eps_);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#define __pointgroup_H__
|
||||
|
||||
#include "mathfunc.h"
|
||||
#include "symmetry.h"
|
||||
|
||||
typedef enum {
|
||||
HOLOHEDRY_NONE,
|
||||
|
@ -74,4 +75,6 @@ Pointgroup ptg_get_transformation_matrix(int transform_mat[3][3],
|
|||
SPGCONST int rotations[][3][3],
|
||||
const int num_rotations);
|
||||
Pointgroup ptg_get_pointgroup(const int pointgroup_number);
|
||||
PointSymmetry ptg_get_pointsymmetry(SPGCONST int rotations[][3][3],
|
||||
const int num_rotations);
|
||||
#endif
|
||||
|
|
|
@ -245,12 +245,6 @@ int spgat_get_multiplicity(SPGCONST double lattice[3][3],
|
|||
const double symprec,
|
||||
const double angle_tolerance);
|
||||
|
||||
/* Considering periodicity of crystal, one of the possible smallest */
|
||||
/* lattice is searched. The lattice is stored in ``smallest_lattice``. */
|
||||
int spg_get_smallest_lattice(double smallest_lattice[3][3],
|
||||
SPGCONST double lattice[3][3],
|
||||
const double symprec);
|
||||
|
||||
/* Space group is found in international table symbol (``symbol``) and */
|
||||
/* number (return value). 0 is returned when it fails. */
|
||||
int spg_get_international(char symbol[11],
|
||||
|
@ -321,11 +315,9 @@ int spgat_standardize_cell(double lattice[3][3],
|
|||
const double symprec,
|
||||
const double angle_tolerance);
|
||||
|
||||
/************/
|
||||
/* Obsolete */
|
||||
/************/
|
||||
/* A primitive cell is found from an input cell. Be careful that */
|
||||
/* ``lattice``, ``position``, and ``types`` are overwritten. */
|
||||
/* This is a wrapper of spg_standardize_cell. */
|
||||
/* A primitive cell is found from an input cell. */
|
||||
/* Be careful that ``lattice``, ``position``, and ``types`` are overwritten. */
|
||||
/* ``num_atom`` is returned as return value. */
|
||||
/* When any primitive cell is not found, 0 is returned. */
|
||||
int spg_find_primitive(double lattice[3][3],
|
||||
|
@ -341,9 +333,7 @@ int spgat_find_primitive(double lattice[3][3],
|
|||
const double symprec,
|
||||
const double angle_tolerance);
|
||||
|
||||
/************/
|
||||
/* Obsolete */
|
||||
/************/
|
||||
/* This is a wrapper of spg_standardize_cell. */
|
||||
/* Bravais lattice with internal atomic points are returned. */
|
||||
/* The arrays are require to have 4 times larger memory space */
|
||||
/* those of input cell. */
|
||||
|
@ -362,6 +352,9 @@ int spgat_refine_cell(double lattice[3][3],
|
|||
const double symprec,
|
||||
const double angle_tolerance);
|
||||
|
||||
/* Delaunay reduction for lattice parameters */
|
||||
/* ``lattice`` is overwritten when the redution ends succeeded. */
|
||||
int spg_delaunay_reduce(double lattice[3][3], const double symprec);
|
||||
|
||||
/*---------*/
|
||||
/* kpoints */
|
||||
|
@ -475,26 +468,11 @@ void spg_get_neighboring_grid_points(int relative_grid_points[],
|
|||
SPGCONST int bz_grid_address[][3],
|
||||
const int bz_map[]);
|
||||
|
||||
/* /\*--------------------*\/ */
|
||||
/* /\* tetrahedron method *\/ */
|
||||
/* /\*--------------------*\/ */
|
||||
/* void */
|
||||
/* spg_get_tetrahedra_relative_grid_address(int relative_grid_address[24][4][3], */
|
||||
/* SPGCONST double rec_lattice[3][3]); */
|
||||
/* void */
|
||||
/* spg_get_all_tetrahedra_relative_grid_address */
|
||||
/* (int relative_grid_address[4][24][4][3]); */
|
||||
/* double */
|
||||
/* spg_get_tetrahedra_integration_weight(const double omega, */
|
||||
/* SPGCONST double tetrahedra_omegas[24][4], */
|
||||
/* const char function); */
|
||||
/* void */
|
||||
/* spg_get_tetrahedra_integration_weight_at_omegas */
|
||||
/* (double integration_weights[], */
|
||||
/* const int num_omegas, */
|
||||
/* const double omegas[], */
|
||||
/* SPGCONST double tetrahedra_omegas[24][4], */
|
||||
/* const char function); */
|
||||
/*--------*/
|
||||
/* Niggli */
|
||||
/*--------*/
|
||||
/* Return 0 if failed */
|
||||
int spg_niggli_reduce(double lattice[3][3], const double symprec);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#define SPGLIB_MAJOR_VERSION 1
|
||||
#define SPGLIB_MINOR_VERSION 9
|
||||
#define SPGLIB_MICRO_VERSION 0
|
||||
#define SPGLIB_MICRO_VERSION 2
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -38,29 +38,46 @@ import numpy as np
|
|||
def get_version():
|
||||
return tuple(spg.version())
|
||||
|
||||
def get_symmetry(bulk, use_magmoms=False, symprec=1e-5, angle_tolerance=-1.0):
|
||||
"""
|
||||
Return symmetry operations as hash.
|
||||
Hash key 'rotations' gives the numpy integer array
|
||||
of the rotation matrices for scaled positions
|
||||
Hash key 'translations' gives the numpy double array
|
||||
of the translation vectors in scaled positions
|
||||
def get_symmetry(cell, use_magmoms=False, symprec=1e-5, angle_tolerance=-1.0):
|
||||
"""This gives crystal symmetry operations from a crystal structure.
|
||||
|
||||
Args:
|
||||
cell: Crystal structrue given either in Atoms object or tuple.
|
||||
In the case given by a tuple, it has to follow the form below,
|
||||
(Lattice parameters in a 3x3 array (see the detail below),
|
||||
Fractional atomic positions in an Nx3 array,
|
||||
Integer numbers to distinguish species in a length N array,
|
||||
(optional) Collinear magnetic moments in a length N array),
|
||||
where N is the number of atoms.
|
||||
Lattice parameters are given in the form:
|
||||
[[a_x, a_y, a_z],
|
||||
[b_x, b_y, b_z],
|
||||
[c_x, c_y, c_z]]
|
||||
use_magmoms:
|
||||
bool: If True, collinear magnetic polarizatin is considered.
|
||||
symprec:
|
||||
float: Symmetry search tolerance in the unit of length.
|
||||
angle_tolerance:
|
||||
float: Symmetry search tolerance in the unit of angle deg.
|
||||
If the value is negative, an internally optimized routine
|
||||
is used to judge symmetry.
|
||||
|
||||
Return:
|
||||
dictionary: Rotation parts and translation parts.
|
||||
|
||||
'rotations': Gives the numpy 'intc' array of the rotation matrices.
|
||||
'translations': Gives the numpy 'double' array of fractional
|
||||
translations with respect to a, b, c axes.
|
||||
"""
|
||||
|
||||
# Atomic positions have to be specified by scaled positions for spglib.
|
||||
positions = np.array(bulk.get_scaled_positions(), dtype='double', order='C')
|
||||
lattice = np.array(bulk.get_cell().T, dtype='double', order='C')
|
||||
numbers = np.array(bulk.get_atomic_numbers(), dtype='intc')
|
||||
|
||||
# Get number of symmetry operations and allocate symmetry operations
|
||||
# multi = spg.multiplicity(cell, positions, numbers, symprec)
|
||||
multi = 48 * bulk.get_number_of_atoms()
|
||||
lattice, positions, numbers, magmoms = _expand_cell(
|
||||
cell, use_magmoms=use_magmoms)
|
||||
multi = 48 * len(positions)
|
||||
rotation = np.zeros((multi, 3, 3), dtype='intc')
|
||||
translation = np.zeros((multi, 3), dtype='double')
|
||||
|
||||
# Get symmetry operations
|
||||
if use_magmoms:
|
||||
magmoms = bulk.get_magnetic_moments()
|
||||
equivalent_atoms = np.zeros(len(magmoms), dtype='intc')
|
||||
num_sym = spg.symmetry_with_collinear_spin(rotation,
|
||||
translation,
|
||||
|
@ -90,7 +107,7 @@ def get_symmetry(bulk, use_magmoms=False, symprec=1e-5, angle_tolerance=-1.0):
|
|||
'translations': np.array(translation[:num_sym],
|
||||
dtype='double', order='C')}
|
||||
|
||||
def get_symmetry_dataset(bulk, symprec=1e-5, angle_tolerance=-1.0):
|
||||
def get_symmetry_dataset(cell, symprec=1e-5, angle_tolerance=-1.0):
|
||||
"""
|
||||
number: International space group number
|
||||
international: International symbol
|
||||
|
@ -109,10 +126,8 @@ def get_symmetry_dataset(bulk, symprec=1e-5, angle_tolerance=-1.0):
|
|||
Standardized unit cell
|
||||
pointgroup_number, pointgroup_symbol: Point group number (see get_pointgroup)
|
||||
"""
|
||||
positions = np.array(bulk.get_scaled_positions(), dtype='double', order='C')
|
||||
lattice = np.array(bulk.get_cell().T, dtype='double', order='C')
|
||||
numbers = np.array(bulk.get_atomic_numbers(), dtype='intc')
|
||||
|
||||
|
||||
lattice, positions, numbers, _ = _expand_cell(cell)
|
||||
keys = ('number',
|
||||
'hall_number',
|
||||
'international',
|
||||
|
@ -158,13 +173,13 @@ def get_symmetry_dataset(bulk, symprec=1e-5, angle_tolerance=-1.0):
|
|||
|
||||
return dataset
|
||||
|
||||
def get_spacegroup(bulk, symprec=1e-5, angle_tolerance=-1.0, symbol_type=0):
|
||||
def get_spacegroup(cell, symprec=1e-5, angle_tolerance=-1.0, symbol_type=0):
|
||||
"""
|
||||
Return space group in international table symbol and number
|
||||
as a string.
|
||||
"""
|
||||
|
||||
dataset = get_symmetry_dataset(bulk,
|
||||
dataset = get_symmetry_dataset(cell,
|
||||
symprec=symprec,
|
||||
angle_tolerance=angle_tolerance)
|
||||
symbols = spg.spacegroup_type(dataset['hall_number'])
|
||||
|
@ -215,7 +230,7 @@ def get_pointgroup(rotations):
|
|||
# (symbol, pointgroup_number, transformation_matrix)
|
||||
return spg.pointgroup(np.array(rotations, dtype='intc', order='C'))
|
||||
|
||||
def standardize_cell(bulk,
|
||||
def standardize_cell(cell,
|
||||
to_primitive=0,
|
||||
no_idealize=0,
|
||||
symprec=1e-5,
|
||||
|
@ -223,16 +238,17 @@ def standardize_cell(bulk,
|
|||
"""
|
||||
Return standardized cell
|
||||
"""
|
||||
# Atomic positions have to be specified by scaled positions for spglib.
|
||||
num_atom = bulk.get_number_of_atoms()
|
||||
lattice = np.array(bulk.get_cell().T, dtype='double', order='C')
|
||||
pos = np.zeros((num_atom * 4, 3), dtype='double')
|
||||
pos[:num_atom] = bulk.get_scaled_positions()
|
||||
|
||||
lattice, _positions, _numbers, _ = _expand_cell(cell)
|
||||
|
||||
# Atomic positions have to be specified by scaled positions for spglib.
|
||||
num_atom = len(_positions)
|
||||
positions = np.zeros((num_atom * 4, 3), dtype='double', order='C')
|
||||
positions[:num_atom] = _positions
|
||||
numbers = np.zeros(num_atom * 4, dtype='intc')
|
||||
numbers[:num_atom] = np.array(bulk.get_atomic_numbers(), dtype='intc')
|
||||
numbers[:num_atom] = _numbers
|
||||
num_atom_std = spg.standardize_cell(lattice,
|
||||
pos,
|
||||
positions,
|
||||
numbers,
|
||||
num_atom,
|
||||
to_primitive,
|
||||
|
@ -241,45 +257,41 @@ def standardize_cell(bulk,
|
|||
angle_tolerance)
|
||||
|
||||
return (np.array(lattice.T, dtype='double', order='C'),
|
||||
np.array(pos[:num_atom_std], dtype='double', order='C'),
|
||||
np.array(positions[:num_atom_std], dtype='double', order='C'),
|
||||
np.array(numbers[:num_atom_std], dtype='intc'))
|
||||
|
||||
def refine_cell(bulk, symprec=1e-5, angle_tolerance=-1.0):
|
||||
def refine_cell(cell, symprec=1e-5, angle_tolerance=-1.0):
|
||||
"""
|
||||
Return refined cell
|
||||
"""
|
||||
# Atomic positions have to be specified by scaled positions for spglib.
|
||||
num_atom = bulk.get_number_of_atoms()
|
||||
lattice = np.array(bulk.get_cell().T, dtype='double', order='C')
|
||||
pos = np.zeros((num_atom * 4, 3), dtype='double')
|
||||
pos[:num_atom] = bulk.get_scaled_positions()
|
||||
|
||||
lattice, _positions, _numbers, _ = _expand_cell(cell)
|
||||
|
||||
# Atomic positions have to be specified by scaled positions for spglib.
|
||||
num_atom = len(_positions)
|
||||
positions = np.zeros((num_atom * 4, 3), dtype='double', order='C')
|
||||
positions[:num_atom] = _positions
|
||||
numbers = np.zeros(num_atom * 4, dtype='intc')
|
||||
numbers[:num_atom] = np.array(bulk.get_atomic_numbers(), dtype='intc')
|
||||
numbers[:num_atom] = _numbers
|
||||
num_atom_std = spg.refine_cell(lattice,
|
||||
pos,
|
||||
positions,
|
||||
numbers,
|
||||
num_atom,
|
||||
symprec,
|
||||
angle_tolerance)
|
||||
|
||||
return (np.array(lattice.T, dtype='double', order='C'),
|
||||
np.array(pos[:num_atom_std], dtype='double', order='C'),
|
||||
np.array(positions[:num_atom_std], dtype='double', order='C'),
|
||||
np.array(numbers[:num_atom_std], dtype='intc'))
|
||||
|
||||
def find_primitive(bulk, symprec=1e-5, angle_tolerance=-1.0):
|
||||
def find_primitive(cell, symprec=1e-5, angle_tolerance=-1.0):
|
||||
"""
|
||||
A primitive cell in the input cell is searched and returned
|
||||
as an object of Atoms class.
|
||||
If no primitive cell is found, (None, None, None) is returned.
|
||||
"""
|
||||
|
||||
# Atomic positions have to be specified by scaled positions for spglib.
|
||||
positions = np.array(bulk.get_scaled_positions(), dtype='double', order='C')
|
||||
lattice = np.array(bulk.get_cell().T, dtype='double', order='C')
|
||||
numbers = np.array(bulk.get_atomic_numbers(), dtype='intc')
|
||||
|
||||
# lattice is transposed with respect to the definition of Atoms class
|
||||
lattice, positions, numbers, _ = _expand_cell(cell)
|
||||
num_atom_prim = spg.primitive(lattice,
|
||||
positions,
|
||||
numbers,
|
||||
|
@ -317,7 +329,7 @@ def get_grid_point_from_address(grid_address, mesh):
|
|||
|
||||
|
||||
def get_ir_reciprocal_mesh(mesh,
|
||||
bulk,
|
||||
cell,
|
||||
is_shift=np.zeros(3, dtype='intc'),
|
||||
is_time_reversal=True,
|
||||
symprec=1e-5):
|
||||
|
@ -327,6 +339,7 @@ def get_ir_reciprocal_mesh(mesh,
|
|||
is_shift=[0, 0, 0] gives Gamma center mesh.
|
||||
"""
|
||||
|
||||
lattice, positions, numbers, _ = _expand_cell(cell)
|
||||
mapping = np.zeros(np.prod(mesh), dtype='intc')
|
||||
mesh_points = np.zeros((np.prod(mesh), 3), dtype='intc')
|
||||
spg.ir_reciprocal_mesh(
|
||||
|
@ -335,9 +348,9 @@ def get_ir_reciprocal_mesh(mesh,
|
|||
np.array(mesh, dtype='intc'),
|
||||
np.array(is_shift, dtype='intc'),
|
||||
is_time_reversal * 1,
|
||||
np.array(bulk.get_cell().T, dtype='double', order='C'),
|
||||
np.array(bulk.get_scaled_positions(), dtype='double', order='C'),
|
||||
np.array(bulk.get_atomic_numbers(), dtype='intc'),
|
||||
lattice,
|
||||
positions,
|
||||
numbers,
|
||||
symprec)
|
||||
|
||||
return mapping, mesh_points
|
||||
|
@ -457,3 +470,49 @@ def get_stabilized_reciprocal_mesh(mesh,
|
|||
qpoints)
|
||||
|
||||
return mapping, mesh_points
|
||||
|
||||
def niggli_reduce(lattice, eps=1e-5):
|
||||
"""Run Niggli reduction
|
||||
|
||||
Args:
|
||||
lattice: Lattice parameters in the form of
|
||||
[[a_x, a_y, a_z],
|
||||
[b_x, b_y, b_z],
|
||||
[c_x, c_y, c_z]]
|
||||
eps: Tolerance.
|
||||
|
||||
Returns:
|
||||
if the Niggli reduction succeeded:
|
||||
Reduced lattice parameters are given as a numpy 'double' array:
|
||||
[[a_x, a_y, a_z],
|
||||
[b_x, b_y, b_z],
|
||||
[c_x, c_y, c_z]]
|
||||
otherwise returns None.
|
||||
"""
|
||||
niggli_lattice = np.array(np.transpose(lattice), dtype='double', order='C')
|
||||
result = spg.niggli_reduce(niggli_lattice, float(eps))
|
||||
if result == 0:
|
||||
return None
|
||||
else:
|
||||
return np.array(np.transpose(niggli_lattice), dtype='double', order='C')
|
||||
|
||||
def _expand_cell(cell, use_magmoms=False):
|
||||
if isinstance(cell, tuple):
|
||||
lattice = np.array(np.transpose(cell[0]), dtype='double', order='C')
|
||||
positions = np.array(cell[1], dtype='double', order='C')
|
||||
numbers = np.array(cell[2], dtype='intc')
|
||||
if len(cell) > 3 and use_magmoms:
|
||||
magmoms = np.array(cell[3], dtype='double')
|
||||
else:
|
||||
magmoms = None
|
||||
else:
|
||||
lattice = np.array(cell.get_cell().T, dtype='double', order='C')
|
||||
positions = np.array(cell.get_scaled_positions(),
|
||||
dtype='double', order='C')
|
||||
numbers = np.array(cell.get_atomic_numbers(), dtype='intc')
|
||||
if use_magmoms:
|
||||
magmoms = np.array(cell.get_magnetic_moments(), dtype='double')
|
||||
else:
|
||||
magmoms = None
|
||||
|
||||
return (lattice, positions, numbers, magmoms)
|
||||
|
|
2
setup.py
2
setup.py
|
@ -62,10 +62,10 @@ extension_spglib = Extension(
|
|||
extra_link_args=extra_link_args_spglib,
|
||||
sources=['c/_spglib.c',
|
||||
'c/spglib/cell.c',
|
||||
'c/spglib/delaunay.c',
|
||||
'c/spglib/hall_symbol.c',
|
||||
'c/spglib/kgrid.c',
|
||||
'c/spglib/kpoint.c',
|
||||
'c/spglib/lattice.c',
|
||||
'c/spglib/mathfunc.c',
|
||||
'c/spglib/niggli.c',
|
||||
'c/spglib/pointgroup.c',
|
||||
|
|
Loading…
Reference in New Issue