#include #include "ruby.h" #include "spglib.h" VALUE Getspg = Qnil; void Init_getspg(void); VALUE method_getspg(VALUE self, VALUE r_size, VALUE r_lattice, VALUE r_position, VALUE r_types, VALUE r_symprec, VALUE r_angle_symprec); VALUE method_getptg(VALUE self, VALUE r_rotations); VALUE method_find_primitive(VALUE self, VALUE r_lattice, VALUE r_position, VALUE r_types, VALUE r_symprec, VALUE r_angle_symprec); VALUE method_get_dataset(VALUE self, VALUE r_lattice, VALUE r_position, VALUE r_types, VALUE r_hall_num, VALUE r_symprec, VALUE r_angle_symprec); VALUE method_get_symmetry(VALUE self, VALUE r_lattice, VALUE r_position, VALUE r_types, VALUE r_symprec, VALUE r_angle_symprec); VALUE method_standardize_cell(VALUE self, VALUE r_lattice, VALUE r_position, VALUE r_types, VALUE r_to_primitive, VALUE r_leave_distrtion, VALUE r_symprec, VALUE r_angle_symprec); void Init_getspg(void) { Getspg = rb_define_module("Getspg"); rb_define_method(Getspg, "getptg", method_getptg, 1); rb_define_method(Getspg, "find_primitive", method_find_primitive, 5); rb_define_method(Getspg, "get_dataset", method_get_dataset, 6); rb_define_method(Getspg, "get_symmetry", method_get_symmetry, 5); } VALUE method_getptg(VALUE self, VALUE r_rotations) { int i, j, k, size, ptg_num; char symbol[6]; int trans_mat[3][3]; VALUE array, matrix, vector; size = RARRAY_LEN( r_rotations ); int rotations[size][3][3]; for ( i = 0; i < size; i++ ) { for ( j = 0; j < 3; j++ ) { for ( k = 0; k < 3; k++ ) { rotations[i][j][k] = NUM2INT( rb_ary_entry( rb_ary_entry( rb_ary_entry( r_rotations, i ), j ), k ) ); } } } ptg_num = spg_get_pointgroup( symbol, trans_mat, rotations, size ); array = rb_ary_new(); rb_ary_push( array, rb_str_new2( symbol ) ); rb_ary_push( array, INT2NUM( ptg_num ) ); matrix = rb_ary_new(); for ( i = 0; i < 3; i++) { vector = rb_ary_new(); for ( j = 0; j < 3; j++ ) { rb_ary_push( vector, INT2NUM( trans_mat[i][j] ) ); } rb_ary_push( matrix, vector); } rb_ary_push( array, matrix ); return array; } VALUE method_find_primitive(VALUE self, VALUE r_lattice, VALUE r_position, VALUE r_types, VALUE r_symprec, VALUE r_angle_symprec) { int i, j, num_atom, num_prim_atom; double symprec, lattice[3][3]; VALUE array, vector, lat_ary, pos_ary, typ_ary; num_atom = RARRAY_LEN(r_types); double position[num_atom][3]; int types[num_atom]; symprec = NUM2DBL(r_symprec); for (i = 0; i < num_atom; i++) { for (j = 0; j < 3; j++) { position[i][j] = NUM2DBL(rb_ary_entry(rb_ary_entry(r_position, i), j)); types[i] = NUM2DBL(rb_ary_entry(r_types, i)); } } for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { lattice[i][j] = NUM2DBL(rb_ary_entry(rb_ary_entry(r_lattice, i), j)); } } num_prim_atom = spgat_standardize_cell(lattice, position, types, num_atom, 1, 0, symprec, NUM2DBL(r_angle_symprec)); array = rb_ary_new(); lat_ary = rb_ary_new(); for (i = 0; i < 3 ; i++) { vector = rb_ary_new(); for (j = 0; j < 3; j++) { rb_ary_push(vector, rb_float_new(lattice[i][j])); } rb_ary_push(lat_ary, vector); } rb_ary_push(array, lat_ary); pos_ary = rb_ary_new(); typ_ary = rb_ary_new(); for (i = 0; i < num_prim_atom; i++) { vector = rb_ary_new(); rb_ary_push(typ_ary, INT2NUM(types[i])); for (j = 0; j < 3 ; j++) { rb_ary_push(vector, rb_float_new(position[i][j])); } rb_ary_push(pos_ary, vector); } rb_ary_push(array, pos_ary); rb_ary_push(array, typ_ary); return array; } VALUE method_get_dataset(VALUE self, VALUE r_lattice, VALUE r_position, VALUE r_types, VALUE r_hall_num, VALUE r_symprec, VALUE r_angle_symprec) { int i, j, k, num_atom; double symprec, lattice[3][3]; SpglibDataset *dataset; VALUE mat, vec, row, array, r_tmat, r_oshift, r_rot, r_trans, r_wyckoffs, r_std_lattice, r_std_positions, r_std_types; num_atom = RARRAY_LEN(r_types); double position[num_atom][3]; int types[num_atom]; symprec = NUM2DBL(r_symprec); for (i = 0; i < num_atom; i++) { for (j = 0; j < 3; j++) { position[i][j] = NUM2DBL(rb_ary_entry(rb_ary_entry(r_position, i), j)); types[i] = NUM2DBL(rb_ary_entry(r_types, i)); } } for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { lattice[i][j] = NUM2DBL(rb_ary_entry(rb_ary_entry(r_lattice, i), j)); } } dataset = spgat_get_dataset_with_hall_number(lattice, position, types, num_atom, NUM2INT(r_hall_num), symprec, NUM2DBL(r_angle_symprec)); array = rb_ary_new(); if (dataset == NULL) { goto err; } rb_ary_push(array, INT2NUM(dataset->spacegroup_number)); rb_ary_push(array, rb_str_new2(dataset->international_symbol)); rb_ary_push(array, INT2NUM(dataset->hall_number)); rb_ary_push(array, rb_str_new2(dataset->hall_symbol)); rb_ary_push(array, rb_str_new2(dataset->choice)); /* Transformation_matrix */ r_tmat = rb_ary_new(); for (i = 0; i < 3; i++) { row = rb_ary_new(); for (j = 0; j < 3; j++) { rb_ary_push(row, rb_float_new(dataset->transformation_matrix[i][j])); } rb_ary_push(r_tmat, row); } rb_ary_push(array, r_tmat); /* Origin shift */ r_oshift = rb_ary_new(); for (i = 0; i < 3; i++) { rb_ary_push(r_oshift, rb_float_new(dataset->origin_shift[i])); } rb_ary_push(array, r_oshift); /* Rotations, translations */ r_rot = rb_ary_new(); r_trans = rb_ary_new(); for (i = 0; i < dataset->n_operations; i++) { mat = rb_ary_new(); vec = rb_ary_new(); for (j = 0; j < 3; j++) { rb_ary_push(vec, rb_float_new(dataset->translations[i][j])); row = rb_ary_new(); for (k = 0; k < 3; k++) { rb_ary_push(row, rb_float_new(dataset->rotations[i][j][k])); } rb_ary_push(mat, row); } rb_ary_push(r_trans, vec); rb_ary_push(r_rot, mat); } rb_ary_push(array, r_rot); rb_ary_push(array, r_trans); /* Wyckoff letters */ r_wyckoffs = rb_ary_new(); for (i = 0; i < dataset->n_atoms; i++) { r_wyckoffs = rb_ary_push(r_wyckoffs, INT2NUM(dataset->wyckoffs[i])); } rb_ary_push(array, r_wyckoffs); /* Bravais lattice */ r_std_lattice = rb_ary_new(); for (i = 0; i < 3; i++) { vec = rb_ary_new(); for (j = 0; j < 3; j++) { rb_ary_push(vec, rb_float_new(dataset->std_lattice[i][j])); } rb_ary_push(r_std_lattice, vec); } rb_ary_push(array, r_std_lattice); r_std_positions = rb_ary_new(); r_std_types = rb_ary_new(); for (i = 0; i < dataset->n_std_atoms; i++) { vec = rb_ary_new(); for (j = 0; j < 3; j++) { rb_ary_push(vec, rb_float_new(dataset->std_positions[i][j])); } rb_ary_push(r_std_positions, vec); rb_ary_push(r_std_types, INT2NUM(dataset->std_types[i])); } rb_ary_push(array, r_std_types); rb_ary_push(array, r_std_positions); spg_free_dataset(dataset); err: return array; } VALUE method_get_symmetry(VALUE self, VALUE r_lattice, VALUE r_position, VALUE r_types, VALUE r_symprec, VALUE r_angle_symprec) { int i, j, k, num_atom, num_sym; double symprec, lattice[3][3]; VALUE mat, vec, row, array, r_rot, r_trans; num_atom = RARRAY_LEN(r_types); double position[num_atom][3]; int types[num_atom]; int max_num_sym = num_atom * 48; int rotations[max_num_sym][3][3]; double translations[max_num_sym][3]; symprec = NUM2DBL(r_symprec); for (i = 0; i < num_atom; i++) { for (j = 0; j < 3; j++) { position[i][j] = NUM2DBL(rb_ary_entry(rb_ary_entry(r_position, i), j)); types[i] = NUM2DBL(rb_ary_entry(r_types, i)); } } for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { lattice[i][j] = NUM2DBL(rb_ary_entry(rb_ary_entry(r_lattice, i), j)); } } num_sym = spgat_get_symmetry(rotations, translations, max_num_sym, lattice, position, types, num_atom, symprec, NUM2DBL(r_angle_symprec)); array = rb_ary_new(); /* Rotations, translations */ r_rot = rb_ary_new(); r_trans = rb_ary_new(); for (i = 0; i < num_sym; i++) { mat = rb_ary_new(); vec = rb_ary_new(); for (j = 0; j < 3; j++) { rb_ary_push(vec, rb_float_new(translations[i][j])); row = rb_ary_new(); for (k = 0; k < 3; k++) { rb_ary_push(row, rb_float_new(rotations[i][j][k])); } rb_ary_push(mat, row); } rb_ary_push(r_trans, vec); rb_ary_push(r_rot, mat); } rb_ary_push(array, r_rot); rb_ary_push(array, r_trans); return array; } VALUE method_standardize_cell(VALUE self, VALUE r_lattice, VALUE r_position, VALUE r_types, VALUE r_to_primitive, VALUE r_leave_distrtion, VALUE r_symprec, VALUE r_angle_symprec) { }