1 /* Copyright (C) 2008 Atsushi Togo */
2 /* All rights reserved. */
3
4 /* This file is part of spglib. */
5
6 /* Redistribution and use in source and binary forms, with or without */
7 /* modification, are permitted provided that the following conditions */
8 /* are met: */
9
10 /* * Redistributions of source code must retain the above copyright */
11 /* notice, this list of conditions and the following disclaimer. */
12
13 /* * Redistributions in binary form must reproduce the above copyright */
14 /* notice, this list of conditions and the following disclaimer in */
15 /* the documentation and/or other materials provided with the */
16 /* distribution. */
17
18 /* * Neither the name of the spglib project nor the names of its */
19 /* contributors may be used to endorse or promote products derived */
20 /* from this software without specific prior written permission. */
21
22 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26 /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28 /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30 /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31 /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32 /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33 /* POSSIBILITY OF SUCH DAMAGE. */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stddef.h>
39 #include "arithmetic.h"
40 #include "cell.h"
41 #include "debug.h"
42 #include "delaunay.h"
43 #include "determination.h"
44 #include "kgrid.h"
45 #include "kpoint.h"
46 #include "mathfunc.h"
47 #include "niggli.h"
48 #include "pointgroup.h"
49 #include "spglib.h"
50 #include "primitive.h"
51 #include "refinement.h"
52 #include "spacegroup.h"
53 #include "spg_database.h"
54 #include "spin.h"
55 #include "symmetry.h"
56 #include "version.h"
57
58 /*-------*/
59 /* error */
60 /*-------*/
61 static SpglibError spglib_error_code = SPGLIB_SUCCESS;
62
63 typedef struct {
64 SpglibError error;
65 char *message;
66 } SpglibErrorMessage;
67
68 static SpglibErrorMessage spglib_error_message[] = {
69 {SPGLIB_SUCCESS, "no error"},
70 {SPGERR_SPACEGROUP_SEARCH_FAILED, "spacegroup search failed"},
71 {SPGERR_CELL_STANDARDIZATION_FAILED, "cell standardization failed"},
72 {SPGERR_SYMMETRY_OPERATION_SEARCH_FAILED, "symmetry operation search failed"},
73 {SPGERR_ATOMS_TOO_CLOSE, "too close distance between atoms"},
74 {SPGERR_POINTGROUP_NOT_FOUND, "pointgroup not found"},
75 {SPGERR_NIGGLI_FAILED, "Niggli reduction failed"},
76 {SPGERR_DELAUNAY_FAILED, "Delaunay reduction failed"},
77 {SPGERR_ARRAY_SIZE_SHORTAGE, "array size shortage"},
78 {SPGERR_NONE, ""},
79 };
80
81 /*---------*/
82 /* general */
83 /*---------*/
84 static SpglibDataset * get_dataset(SPGCONST double lattice[3][3],
85 SPGCONST double position[][3],
86 const int types[],
87 const int num_atom,
88 const int hall_number,
89 const double symprec,
90 const double angle_tolerance);
91 static SpglibDataset * init_dataset(void);
92 static int set_dataset(SpglibDataset * dataset,
93 const Cell * cell,
94 const Primitive * primitive,
95 SPGCONST Spacegroup * spacegroup,
96 ExactStructure *exstr);
97 static int get_symmetry_from_dataset(int rotation[][3][3],
98 double translation[][3],
99 const int max_size,
100 SPGCONST double lattice[3][3],
101 SPGCONST double position[][3],
102 const int types[],
103 const int num_atom,
104 const double symprec,
105 const double angle_tolerance);
106 static int get_symmetry_with_site_tensors(int rotation[][3][3],
107 double translation[][3],
108 int equivalent_atoms[],
109 double primitive_lattice[3][3],
110 int *spin_flips,
111 const int run_symmetry_search,
112 const int num_operations,
113 SPGCONST double lattice[3][3],
114 SPGCONST double position[][3],
115 const int types[],
116 const double *tensors,
117 const int tensor_rank,
118 const int num_atom,
119 const int is_magnetic,
120 const double symprec,
121 const double angle_tolerance);
122 static int get_multiplicity(SPGCONST double lattice[3][3],
123 SPGCONST double position[][3],
124 const int types[],
125 const int num_atom,
126 const double symprec,
127 const double angle_tolerance);
128 static int standardize_primitive(double lattice[3][3],
129 double position[][3],
130 int types[],
131 const int num_atom,
132 const double symprec,
133 const double angle_tolerance);
134 static int standardize_cell(double lattice[3][3],
135 double position[][3],
136 int types[],
137 const int num_atom,
138 const int num_array_size,
139 const double symprec,
140 const double angle_tolerance);
141 static int get_standardized_cell(double lattice[3][3],
142 double position[][3],
143 int types[],
144 const int num_atom,
145 const int num_array_size,
146 const int to_primitive,
147 const double symprec,
148 const double angle_tolerance);
149 static Centering get_centering(int hall_number);
150 static void set_cell(double lattice[3][3],
151 double position[][3],
152 int types[],
153 Cell * cell);
154 static int get_international(char symbol[11],
155 SPGCONST double lattice[3][3],
156 SPGCONST double position[][3],
157 const int types[],
158 const int num_atom,
159 const double symprec,
160 const double angle_tolerance);
161 static int get_schoenflies(char symbol[7],
162 SPGCONST double lattice[3][3],
163 SPGCONST double position[][3],
164 const int types[], const int num_atom,
165 const double symprec,
166 const double angle_tolerance);
167
168 /*---------*/
169 /* kpoints */
170 /*---------*/
171 static int get_ir_reciprocal_mesh(int grid_address[][3],
172 int ir_mapping_table[],
173 const int mesh[3],
174 const int is_shift[3],
175 const int is_time_reversal,
176 SPGCONST double lattice[3][3],
177 SPGCONST double position[][3],
178 const int types[],
179 const int num_atom,
180 const double symprec,
181 const double angle_tolerance);
182 static size_t get_dense_ir_reciprocal_mesh(int grid_address[][3],
183 size_t ir_mapping_table[],
184 const int mesh[3],
185 const int is_shift[3],
186 const int is_time_reversal,
187 SPGCONST double lattice[3][3],
188 SPGCONST double position[][3],
189 const int types[],
190 const size_t num_atom,
191 const double symprec,
192 const double angle_tolerance);
193
194 static int get_stabilized_reciprocal_mesh(int grid_address[][3],
195 int ir_mapping_table[],
196 const int mesh[3],
197 const int is_shift[3],
198 const int is_time_reversal,
199 const int num_rot,
200 SPGCONST int rotations[][3][3],
201 const size_t num_q,
202 SPGCONST double qpoints[][3]);
203 static size_t get_dense_stabilized_reciprocal_mesh(int grid_address[][3],
204 size_t ir_mapping_table[],
205 const int mesh[3],
206 const int is_shift[3],
207 const int is_time_reversal,
208 const size_t num_rot,
209 SPGCONST int rotations[][3][3],
210 const size_t num_q,
211 SPGCONST double qpoints[][3]);
212
213 /*========*/
214 /* global */
215 /*========*/
216
217 /*-----------------------------------------*/
218 /* Version: spglib-[major].[minor].[micro] */
219 /*-----------------------------------------*/
spg_get_major_version(void)220 int spg_get_major_version(void)
221 {
222 spglib_error_code = SPGLIB_SUCCESS;
223 return SPGLIB_MAJOR_VERSION;
224 }
225
spg_get_minor_version(void)226 int spg_get_minor_version(void)
227 {
228 spglib_error_code = SPGLIB_SUCCESS;
229 return SPGLIB_MINOR_VERSION;
230 }
231
spg_get_micro_version(void)232 int spg_get_micro_version(void)
233 {
234 spglib_error_code = SPGLIB_SUCCESS;
235 return SPGLIB_MICRO_VERSION;
236 }
237
238 /*-------*/
239 /* error */
240 /*-------*/
spg_get_error_code(void)241 SpglibError spg_get_error_code(void)
242 {
243 return spglib_error_code;
244 }
245
spg_get_error_message(SpglibError error)246 char * spg_get_error_message(SpglibError error)
247 {
248 int i;
249
250 for (i = 0; i < 100; i++) {
251 if (SPGERR_NONE == spglib_error_message[i].error) {
252 break;
253 }
254
255 if (error == spglib_error_message[i].error) {
256 return spglib_error_message[i].message;
257 }
258 }
259
260 return NULL;
261 }
262
263 /*---------*/
264 /* general */
265 /*---------*/
266 /* Return NULL if failed */
spg_get_dataset(SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec)267 SpglibDataset * spg_get_dataset(SPGCONST double lattice[3][3],
268 SPGCONST double position[][3],
269 const int types[],
270 const int num_atom,
271 const double symprec)
272 {
273 return get_dataset(lattice,
274 position,
275 types,
276 num_atom,
277 0,
278 symprec,
279 -1.0);
280 }
281
282 /* Return NULL if failed */
spgat_get_dataset(SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec,const double angle_tolerance)283 SpglibDataset * spgat_get_dataset(SPGCONST double lattice[3][3],
284 SPGCONST double position[][3],
285 const int types[],
286 const int num_atom,
287 const double symprec,
288 const double angle_tolerance)
289 {
290 return get_dataset(lattice,
291 position,
292 types,
293 num_atom,
294 0,
295 symprec,
296 angle_tolerance);
297 }
298
299 /* Return NULL if failed */
spg_get_dataset_with_hall_number(SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const int hall_number,const double symprec)300 SpglibDataset * spg_get_dataset_with_hall_number(SPGCONST double lattice[3][3],
301 SPGCONST double position[][3],
302 const int types[],
303 const int num_atom,
304 const int hall_number,
305 const double symprec)
306 {
307 return get_dataset(lattice,
308 position,
309 types,
310 num_atom,
311 hall_number,
312 symprec,
313 -1.0);
314 }
315
316 /* Return NULL if failed */
317 SpglibDataset *
spgat_get_dataset_with_hall_number(SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const int hall_number,const double symprec,const double angle_tolerance)318 spgat_get_dataset_with_hall_number(SPGCONST double lattice[3][3],
319 SPGCONST double position[][3],
320 const int types[],
321 const int num_atom,
322 const int hall_number,
323 const double symprec,
324 const double angle_tolerance)
325 {
326 return get_dataset(lattice,
327 position,
328 types,
329 num_atom,
330 hall_number,
331 symprec,
332 angle_tolerance);
333 }
334
spg_free_dataset(SpglibDataset * dataset)335 void spg_free_dataset(SpglibDataset *dataset)
336 {
337 if (dataset->n_operations > 0) {
338 free(dataset->rotations);
339 dataset->rotations = NULL;
340 free(dataset->translations);
341 dataset->translations = NULL;
342 dataset->n_operations = 0;
343 }
344
345 if (dataset->n_atoms > 0) {
346 free(dataset->wyckoffs);
347 dataset->wyckoffs = NULL;
348 free(dataset->equivalent_atoms);
349 dataset->equivalent_atoms = NULL;
350 free(dataset->crystallographic_orbits);
351 dataset->crystallographic_orbits = NULL;
352 free(dataset->site_symmetry_symbols);
353 dataset->site_symmetry_symbols = NULL;
354 free(dataset->mapping_to_primitive);
355 dataset->mapping_to_primitive = NULL;
356 dataset->n_atoms = 0;
357 }
358
359 if (dataset->n_std_atoms > 0) {
360 free(dataset->std_positions);
361 dataset->std_positions = NULL;
362 free(dataset->std_types);
363 dataset->std_types = NULL;
364 free(dataset->std_mapping_to_primitive);
365 dataset->std_mapping_to_primitive = NULL;
366 dataset->n_std_atoms = 0;
367 }
368
369 dataset->spacegroup_number = 0;
370 dataset->hall_number = 0;
371 strcpy(dataset->international_symbol, "");
372 strcpy(dataset->hall_symbol, "");
373 strcpy(dataset->choice, "");
374
375 free(dataset);
376 }
377
378 /* Return 0 if failed */
spg_get_symmetry(int rotation[][3][3],double translation[][3],const int max_size,SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec)379 int spg_get_symmetry(int rotation[][3][3],
380 double translation[][3],
381 const int max_size,
382 SPGCONST double lattice[3][3],
383 SPGCONST double position[][3],
384 const int types[],
385 const int num_atom,
386 const double symprec)
387 {
388 return get_symmetry_from_dataset(rotation,
389 translation,
390 max_size,
391 lattice,
392 position,
393 types,
394 num_atom,
395 symprec,
396 -1.0);
397 }
398
399 /* Return 0 if failed */
spgat_get_symmetry(int rotation[][3][3],double translation[][3],const int max_size,SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec,const double angle_tolerance)400 int spgat_get_symmetry(int rotation[][3][3],
401 double translation[][3],
402 const int max_size,
403 SPGCONST double lattice[3][3],
404 SPGCONST double position[][3],
405 const int types[],
406 const int num_atom,
407 const double symprec,
408 const double angle_tolerance)
409 {
410 return get_symmetry_from_dataset(rotation,
411 translation,
412 max_size,
413 lattice,
414 position,
415 types,
416 num_atom,
417 symprec,
418 angle_tolerance);
419 }
420
421 /* Return 0 if failed */
spg_get_symmetry_with_collinear_spin(int rotation[][3][3],double translation[][3],int equivalent_atoms[],const int max_size,SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const double spins[],const int num_atom,const double symprec)422 int spg_get_symmetry_with_collinear_spin(int rotation[][3][3],
423 double translation[][3],
424 int equivalent_atoms[],
425 const int max_size,
426 SPGCONST double lattice[3][3],
427 SPGCONST double position[][3],
428 const int types[],
429 const double spins[],
430 const int num_atom,
431 const double symprec)
432 {
433 int succeeded;
434 double primitive_lattice[3][3];
435 int *spin_flips;
436
437 if ((spin_flips = (int*) malloc(sizeof(int) * max_size))
438 == NULL) {
439 warning_print("spglib: Memory could not be allocated.");
440 return 0;
441 }
442
443 succeeded = get_symmetry_with_site_tensors(rotation,
444 translation,
445 equivalent_atoms,
446 primitive_lattice,
447 spin_flips,
448 1,
449 max_size,
450 lattice,
451 position,
452 types,
453 spins,
454 0,
455 num_atom,
456 1,
457 symprec,
458 -1.0);
459 free(spin_flips);
460 spin_flips = NULL;
461
462 return succeeded;
463 }
464
465 /* Return 0 if failed */
spgat_get_symmetry_with_collinear_spin(int rotation[][3][3],double translation[][3],int equivalent_atoms[],const int max_size,SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const double spins[],const int num_atom,const double symprec,const double angle_tolerance)466 int spgat_get_symmetry_with_collinear_spin(int rotation[][3][3],
467 double translation[][3],
468 int equivalent_atoms[],
469 const int max_size,
470 SPGCONST double lattice[3][3],
471 SPGCONST double position[][3],
472 const int types[],
473 const double spins[],
474 const int num_atom,
475 const double symprec,
476 const double angle_tolerance)
477 {
478 int succeeded;
479 double primitive_lattice[3][3];
480 int *spin_flips;
481
482 if ((spin_flips = (int*) malloc(sizeof(int) * max_size))
483 == NULL) {
484 warning_print("spglib: Memory could not be allocated.");
485 return 0;
486 }
487
488 succeeded = get_symmetry_with_site_tensors(rotation,
489 translation,
490 equivalent_atoms,
491 primitive_lattice,
492 spin_flips,
493 1,
494 max_size,
495 lattice,
496 position,
497 types,
498 spins,
499 0,
500 num_atom,
501 1,
502 symprec,
503 angle_tolerance);
504
505 free(spin_flips);
506 spin_flips = NULL;
507
508 return succeeded;
509 }
510
511 /* Return 0 if failed */
spg_get_symmetry_with_site_tensors(int rotation[][3][3],double translation[][3],int equivalent_atoms[],double primitive_lattice[3][3],int * spin_flips,const int num_operations,SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const double * tensors,const int tensor_rank,const int num_atom,const int is_magnetic,const double symprec)512 int spg_get_symmetry_with_site_tensors(int rotation[][3][3],
513 double translation[][3],
514 int equivalent_atoms[],
515 double primitive_lattice[3][3],
516 int *spin_flips,
517 const int num_operations,
518 SPGCONST double lattice[3][3],
519 SPGCONST double position[][3],
520 const int types[],
521 const double *tensors,
522 const int tensor_rank,
523 const int num_atom,
524 const int is_magnetic,
525 const double symprec)
526 {
527 return get_symmetry_with_site_tensors(rotation,
528 translation,
529 equivalent_atoms,
530 primitive_lattice,
531 spin_flips,
532 0,
533 num_operations,
534 lattice,
535 position,
536 types,
537 tensors,
538 tensor_rank,
539 num_atom,
540 is_magnetic,
541 symprec,
542 -1.0);
543 }
544
spgat_get_symmetry_with_site_tensors(int rotation[][3][3],double translation[][3],int equivalent_atoms[],double primitive_lattice[3][3],int * spin_flips,const int num_operations,SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const double * tensors,const int tensor_rank,const int num_atom,const int is_magnetic,const double symprec,const double angle_tolerance)545 int spgat_get_symmetry_with_site_tensors(int rotation[][3][3],
546 double translation[][3],
547 int equivalent_atoms[],
548 double primitive_lattice[3][3],
549 int *spin_flips,
550 const int num_operations,
551 SPGCONST double lattice[3][3],
552 SPGCONST double position[][3],
553 const int types[],
554 const double *tensors,
555 const int tensor_rank,
556 const int num_atom,
557 const int is_magnetic,
558 const double symprec,
559 const double angle_tolerance)
560 {
561 return get_symmetry_with_site_tensors(rotation,
562 translation,
563 equivalent_atoms,
564 primitive_lattice,
565 spin_flips,
566 0,
567 num_operations,
568 lattice,
569 position,
570 types,
571 tensors,
572 tensor_rank,
573 num_atom,
574 is_magnetic,
575 symprec,
576 angle_tolerance);
577 }
578
spg_get_hall_number_from_symmetry(SPGCONST int rotation[][3][3],SPGCONST double translation[][3],const int num_operations,const double symprec)579 int spg_get_hall_number_from_symmetry(SPGCONST int rotation[][3][3],
580 SPGCONST double translation[][3],
581 const int num_operations,
582 const double symprec)
583 {
584 int i, hall_number;
585 Symmetry *symmetry;
586 Symmetry *prim_symmetry;
587
588 symmetry = NULL;
589 prim_symmetry = NULL;
590 hall_number = 0;
591
592 if ((symmetry = sym_alloc_symmetry(num_operations)) == NULL) {
593 return 0;
594 }
595
596 for (i = 0; i < num_operations; i++) {
597 mat_copy_matrix_i3(symmetry->rot[i], rotation[i]);
598 mat_copy_vector_d3(symmetry->trans[i], translation[i]);
599 }
600
601 prim_symmetry = prm_get_primitive_symmetry(symmetry, symprec);
602 sym_free_symmetry(symmetry);
603 symmetry = NULL;
604
605 if (prim_symmetry == NULL) {
606 return 0;
607 }
608
609 hall_number = spa_search_spacegroup_with_symmetry(prim_symmetry, symprec);
610
611 if (hall_number) {
612 spglib_error_code = SPGLIB_SUCCESS;
613 } else {
614 spglib_error_code = SPGERR_SPACEGROUP_SEARCH_FAILED;
615 }
616
617 sym_free_symmetry(prim_symmetry);
618 prim_symmetry = NULL;
619
620 return hall_number;
621 }
622
623 /* Return 0 if failed */
spg_get_multiplicity(SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec)624 int spg_get_multiplicity(SPGCONST double lattice[3][3],
625 SPGCONST double position[][3],
626 const int types[],
627 const int num_atom,
628 const double symprec)
629 {
630 return get_multiplicity(lattice,
631 position,
632 types,
633 num_atom,
634 symprec,
635 -1.0);
636 }
637
638 /* Return 0 if failed */
spgat_get_multiplicity(SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec,const double angle_tolerance)639 int spgat_get_multiplicity(SPGCONST double lattice[3][3],
640 SPGCONST double position[][3],
641 const int types[],
642 const int num_atom,
643 const double symprec,
644 const double angle_tolerance)
645 {
646 return get_multiplicity(lattice,
647 position,
648 types,
649 num_atom,
650 symprec,
651 angle_tolerance);
652 }
653
654 /* Return 0 if failed */
spg_get_international(char symbol[11],SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec)655 int spg_get_international(char symbol[11],
656 SPGCONST double lattice[3][3],
657 SPGCONST double position[][3],
658 const int types[],
659 const int num_atom,
660 const double symprec)
661 {
662 return get_international(symbol,
663 lattice,
664 position,
665 types,
666 num_atom,
667 symprec,
668 -1.0);
669 }
670
671 /* Return 0 if failed */
spgat_get_international(char symbol[11],SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec,const double angle_tolerance)672 int spgat_get_international(char symbol[11],
673 SPGCONST double lattice[3][3],
674 SPGCONST double position[][3],
675 const int types[],
676 const int num_atom,
677 const double symprec,
678 const double angle_tolerance)
679 {
680 return get_international(symbol,
681 lattice,
682 position,
683 types,
684 num_atom,
685 symprec,
686 angle_tolerance);
687 }
688
689 /* Return 0 if failed */
spg_get_schoenflies(char symbol[7],SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec)690 int spg_get_schoenflies(char symbol[7],
691 SPGCONST double lattice[3][3],
692 SPGCONST double position[][3],
693 const int types[],
694 const int num_atom,
695 const double symprec)
696 {
697 return get_schoenflies(symbol,
698 lattice,
699 position,
700 types,
701 num_atom,
702 symprec,
703 -1.0);
704 }
705
706 /* Return 0 if failed */
spgat_get_schoenflies(char symbol[7],SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec,const double angle_tolerance)707 int spgat_get_schoenflies(char symbol[7],
708 SPGCONST double lattice[3][3],
709 SPGCONST double position[][3],
710 const int types[],
711 const int num_atom,
712 const double symprec,
713 const double angle_tolerance)
714 {
715 return get_schoenflies(symbol,
716 lattice,
717 position,
718 types,
719 num_atom,
720 symprec,
721 angle_tolerance);
722 }
723
724 /* Return 0 if failed */
spg_get_pointgroup(char symbol[6],int transform_mat[3][3],SPGCONST int rotations[][3][3],const int num_rotations)725 int spg_get_pointgroup(char symbol[6],
726 int transform_mat[3][3],
727 SPGCONST int rotations[][3][3],
728 const int num_rotations)
729 {
730 Pointgroup pointgroup;
731
732 pointgroup = ptg_get_transformation_matrix(transform_mat,
733 rotations,
734 num_rotations);
735
736 if (pointgroup.number == 0) {
737 spglib_error_code = SPGERR_POINTGROUP_NOT_FOUND;
738 return 0;
739 }
740
741 memcpy(symbol, pointgroup.symbol, 6);
742
743 spglib_error_code = SPGLIB_SUCCESS;
744 return pointgroup.number;
745 }
746
747 /* Return 0 if failed */
spg_get_symmetry_from_database(int rotations[192][3][3],double translations[192][3],const int hall_number)748 int spg_get_symmetry_from_database(int rotations[192][3][3],
749 double translations[192][3],
750 const int hall_number)
751 {
752 int i, size;
753 Symmetry *symmetry;
754
755 symmetry = NULL;
756
757 if ((symmetry = spgdb_get_spacegroup_operations(hall_number)) == NULL) {
758 goto err;
759 }
760
761 for (i = 0; i < symmetry->size; i++) {
762 mat_copy_matrix_i3(rotations[i], symmetry->rot[i]);
763 mat_copy_vector_d3(translations[i], symmetry->trans[i]);
764 }
765 size = symmetry->size;
766
767 sym_free_symmetry(symmetry);
768 symmetry = NULL;
769
770 spglib_error_code = SPGLIB_SUCCESS;
771 return size;
772
773 err:
774 spglib_error_code = SPGERR_SPACEGROUP_SEARCH_FAILED;
775 return 0;
776 }
777
778 /* Return spglibtype.number = 0 if failed */
spg_get_spacegroup_type(const int hall_number)779 SpglibSpacegroupType spg_get_spacegroup_type(const int hall_number)
780 {
781 SpglibSpacegroupType spglibtype;
782 SpacegroupType spgtype;
783 Pointgroup pointgroup;
784 int arth_number;
785 char arth_symbol[7];
786
787 spglibtype.number = 0;
788 strcpy(spglibtype.schoenflies, "");
789 strcpy(spglibtype.hall_symbol, "");
790 strcpy(spglibtype.choice, "");
791 strcpy(spglibtype.international, "");
792 strcpy(spglibtype.international_full, "");
793 strcpy(spglibtype.international_short, "");
794 strcpy(spglibtype.pointgroup_international, "");
795 strcpy(spglibtype.pointgroup_schoenflies, "");
796 spglibtype.arithmetic_crystal_class_number = 0;
797 strcpy(spglibtype.arithmetic_crystal_class_symbol, "");
798
799 if (0 < hall_number && hall_number < 531) {
800 spgtype = spgdb_get_spacegroup_type(hall_number);
801 spglibtype.number = spgtype.number;
802 memcpy(spglibtype.schoenflies, spgtype.schoenflies, 7);
803 memcpy(spglibtype.hall_symbol, spgtype.hall_symbol, 17);
804 memcpy(spglibtype.choice, spgtype.choice, 6);
805 memcpy(spglibtype.international, spgtype.international, 32);
806 memcpy(spglibtype.international_full, spgtype.international_full, 20);
807 memcpy(spglibtype.international_short, spgtype.international_short, 11);
808 pointgroup = ptg_get_pointgroup(spgtype.pointgroup_number);
809 memcpy(spglibtype.pointgroup_international, pointgroup.symbol, 6);
810 memcpy(spglibtype.pointgroup_schoenflies, pointgroup.schoenflies, 4);
811 arth_number = arth_get_symbol(arth_symbol, spgtype.number);
812 spglibtype.arithmetic_crystal_class_number = arth_number;
813 memcpy(spglibtype.arithmetic_crystal_class_symbol, arth_symbol, 7);
814 spglib_error_code = SPGLIB_SUCCESS;
815 } else {
816 spglib_error_code = SPGERR_SPACEGROUP_SEARCH_FAILED;
817 }
818
819 return spglibtype;
820 }
821
822 /* Return 0 if failed */
spg_standardize_cell(double lattice[3][3],double position[][3],int types[],const int num_atom,const int to_primitive,const int no_idealize,const double symprec)823 int spg_standardize_cell(double lattice[3][3],
824 double position[][3],
825 int types[],
826 const int num_atom,
827 const int to_primitive,
828 const int no_idealize,
829 const double symprec)
830 {
831 return spgat_standardize_cell(lattice,
832 position,
833 types,
834 num_atom,
835 to_primitive,
836 no_idealize,
837 symprec,
838 -1.0);
839 }
840
841 /* Return 0 if failed */
spgat_standardize_cell(double lattice[3][3],double position[][3],int types[],const int num_atom,const int to_primitive,const int no_idealize,const double symprec,const double angle_tolerance)842 int spgat_standardize_cell(double lattice[3][3],
843 double position[][3],
844 int types[],
845 const int num_atom,
846 const int to_primitive,
847 const int no_idealize,
848 const double symprec,
849 const double angle_tolerance)
850 {
851 if (to_primitive) {
852 if (no_idealize) {
853 return get_standardized_cell(lattice,
854 position,
855 types,
856 num_atom,
857 0,
858 1,
859 symprec,
860 angle_tolerance);
861 } else {
862 return standardize_primitive(lattice,
863 position,
864 types,
865 num_atom,
866 symprec,
867 angle_tolerance);
868 }
869 } else {
870 if (no_idealize) {
871 return get_standardized_cell(lattice,
872 position,
873 types,
874 num_atom,
875 0,
876 0,
877 symprec,
878 angle_tolerance);
879 } else {
880 return standardize_cell(lattice,
881 position,
882 types,
883 num_atom,
884 0,
885 symprec,
886 angle_tolerance);
887 }
888 }
889 }
890
891 /* Return 0 if failed */
spg_find_primitive(double lattice[3][3],double position[][3],int types[],const int num_atom,const double symprec)892 int spg_find_primitive(double lattice[3][3],
893 double position[][3],
894 int types[],
895 const int num_atom,
896 const double symprec)
897 {
898 return standardize_primitive(lattice,
899 position,
900 types,
901 num_atom,
902 symprec,
903 -1.0);
904 }
905
906 /* Return 0 if failed */
spgat_find_primitive(double lattice[3][3],double position[][3],int types[],const int num_atom,const double symprec,const double angle_tolerance)907 int spgat_find_primitive(double lattice[3][3],
908 double position[][3],
909 int types[],
910 const int num_atom,
911 const double symprec,
912 const double angle_tolerance)
913 {
914 return standardize_primitive(lattice,
915 position,
916 types,
917 num_atom,
918 symprec,
919 angle_tolerance);
920 }
921
922 /* Return 0 if failed */
spg_refine_cell(double lattice[3][3],double position[][3],int types[],const int num_atom,const double symprec)923 int spg_refine_cell(double lattice[3][3],
924 double position[][3],
925 int types[],
926 const int num_atom,
927 const double symprec)
928 {
929 return standardize_cell(lattice,
930 position,
931 types,
932 num_atom,
933 0,
934 symprec,
935 -1.0);
936 }
937
938 /* Return 0 if failed */
spgat_refine_cell(double lattice[3][3],double position[][3],int types[],const int num_atom,const double symprec,const double angle_tolerance)939 int spgat_refine_cell(double lattice[3][3],
940 double position[][3],
941 int types[],
942 const int num_atom,
943 const double symprec,
944 const double angle_tolerance)
945 {
946 return standardize_cell(lattice,
947 position,
948 types,
949 num_atom,
950 0,
951 symprec,
952 angle_tolerance);
953 }
954
spg_delaunay_reduce(double lattice[3][3],const double symprec)955 int spg_delaunay_reduce(double lattice[3][3], const double symprec)
956 {
957 int i, j, succeeded;
958 double red_lattice[3][3];
959
960 succeeded = del_delaunay_reduce(red_lattice, lattice, symprec);
961
962 if (succeeded) {
963 for (i = 0; i < 3; i++) {
964 for (j = 0; j < 3; j++) {
965 lattice[i][j] = red_lattice[i][j];
966 }
967 }
968 spglib_error_code = SPGLIB_SUCCESS;
969 } else {
970 spglib_error_code = SPGERR_DELAUNAY_FAILED;
971 }
972
973 return succeeded;
974 }
975
976 /*---------*/
977 /* kpoints */
978 /*---------*/
spg_get_grid_point_from_address(const int grid_address[3],const int mesh[3])979 int spg_get_grid_point_from_address(const int grid_address[3],
980 const int mesh[3])
981 {
982 int address_double[3];
983 int is_shift[3];
984
985 is_shift[0] = 0;
986 is_shift[1] = 0;
987 is_shift[2] = 0;
988 kgd_get_grid_address_double_mesh(address_double,
989 grid_address,
990 mesh,
991 is_shift);
992 return kgd_get_grid_point_double_mesh(address_double, mesh);
993 }
994
spg_get_dense_grid_point_from_address(const int grid_address[3],const int mesh[3])995 size_t spg_get_dense_grid_point_from_address(const int grid_address[3],
996 const int mesh[3])
997 {
998 int address_double[3];
999 int is_shift[3];
1000
1001 is_shift[0] = 0;
1002 is_shift[1] = 0;
1003 is_shift[2] = 0;
1004 kgd_get_grid_address_double_mesh(address_double,
1005 grid_address,
1006 mesh,
1007 is_shift);
1008 return kgd_get_dense_grid_point_double_mesh(address_double, mesh);
1009 }
1010
spg_get_ir_reciprocal_mesh(int grid_address[][3],int ir_mapping_table[],const int mesh[3],const int is_shift[3],const int is_time_reversal,SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec)1011 int spg_get_ir_reciprocal_mesh(int grid_address[][3],
1012 int ir_mapping_table[],
1013 const int mesh[3],
1014 const int is_shift[3],
1015 const int is_time_reversal,
1016 SPGCONST double lattice[3][3],
1017 SPGCONST double position[][3],
1018 const int types[],
1019 const int num_atom,
1020 const double symprec)
1021 {
1022 return get_ir_reciprocal_mesh(grid_address,
1023 ir_mapping_table,
1024 mesh,
1025 is_shift,
1026 is_time_reversal,
1027 lattice,
1028 position,
1029 types,
1030 num_atom,
1031 symprec,
1032 -1.0);
1033 }
1034
spg_get_dense_ir_reciprocal_mesh(int grid_address[][3],size_t ir_mapping_table[],const int mesh[3],const int is_shift[3],const int is_time_reversal,SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec)1035 size_t spg_get_dense_ir_reciprocal_mesh(int grid_address[][3],
1036 size_t ir_mapping_table[],
1037 const int mesh[3],
1038 const int is_shift[3],
1039 const int is_time_reversal,
1040 SPGCONST double lattice[3][3],
1041 SPGCONST double position[][3],
1042 const int types[],
1043 const int num_atom,
1044 const double symprec)
1045 {
1046 return get_dense_ir_reciprocal_mesh(grid_address,
1047 ir_mapping_table,
1048 mesh,
1049 is_shift,
1050 is_time_reversal,
1051 lattice,
1052 position,
1053 types,
1054 num_atom,
1055 symprec,
1056 -1.0);
1057 }
1058
spg_get_stabilized_reciprocal_mesh(int grid_address[][3],int ir_mapping_table[],const int mesh[3],const int is_shift[3],const int is_time_reversal,const int num_rot,SPGCONST int rotations[][3][3],const int num_q,SPGCONST double qpoints[][3])1059 int spg_get_stabilized_reciprocal_mesh(int grid_address[][3],
1060 int ir_mapping_table[],
1061 const int mesh[3],
1062 const int is_shift[3],
1063 const int is_time_reversal,
1064 const int num_rot,
1065 SPGCONST int rotations[][3][3],
1066 const int num_q,
1067 SPGCONST double qpoints[][3])
1068 {
1069 return get_stabilized_reciprocal_mesh(grid_address,
1070 ir_mapping_table,
1071 mesh,
1072 is_shift,
1073 is_time_reversal,
1074 num_rot,
1075 rotations,
1076 num_q,
1077 qpoints);
1078 }
1079
spg_get_dense_stabilized_reciprocal_mesh(int grid_address[][3],size_t ir_mapping_table[],const int mesh[3],const int is_shift[3],const int is_time_reversal,const int num_rot,SPGCONST int rotations[][3][3],const int num_q,SPGCONST double qpoints[][3])1080 size_t spg_get_dense_stabilized_reciprocal_mesh(int grid_address[][3],
1081 size_t ir_mapping_table[],
1082 const int mesh[3],
1083 const int is_shift[3],
1084 const int is_time_reversal,
1085 const int num_rot,
1086 SPGCONST int rotations[][3][3],
1087 const int num_q,
1088 SPGCONST double qpoints[][3])
1089 {
1090 return get_dense_stabilized_reciprocal_mesh(grid_address,
1091 ir_mapping_table,
1092 mesh,
1093 is_shift,
1094 is_time_reversal,
1095 num_rot,
1096 rotations,
1097 num_q,
1098 qpoints);
1099 }
1100
spg_get_dense_grid_points_by_rotations(size_t rot_grid_points[],const int address_orig[3],const int num_rot,SPGCONST int rot_reciprocal[][3][3],const int mesh[3],const int is_shift[3])1101 void spg_get_dense_grid_points_by_rotations(size_t rot_grid_points[],
1102 const int address_orig[3],
1103 const int num_rot,
1104 SPGCONST int rot_reciprocal[][3][3],
1105 const int mesh[3],
1106 const int is_shift[3])
1107 {
1108 kpt_get_dense_grid_points_by_rotations(rot_grid_points,
1109 address_orig,
1110 rot_reciprocal,
1111 num_rot,
1112 mesh,
1113 is_shift);
1114 }
1115
spg_get_dense_BZ_grid_points_by_rotations(size_t rot_grid_points[],const int address_orig[3],const int num_rot,SPGCONST int rot_reciprocal[][3][3],const int mesh[3],const int is_shift[3],const size_t bz_map[])1116 void spg_get_dense_BZ_grid_points_by_rotations(size_t rot_grid_points[],
1117 const int address_orig[3],
1118 const int num_rot,
1119 SPGCONST int rot_reciprocal[][3][3],
1120 const int mesh[3],
1121 const int is_shift[3],
1122 const size_t bz_map[])
1123 {
1124 kpt_get_dense_BZ_grid_points_by_rotations(rot_grid_points,
1125 address_orig,
1126 rot_reciprocal,
1127 num_rot,
1128 mesh,
1129 is_shift,
1130 bz_map);
1131 }
1132
spg_relocate_BZ_grid_address(int bz_grid_address[][3],int bz_map[],SPGCONST int grid_address[][3],const int mesh[3],SPGCONST double rec_lattice[3][3],const int is_shift[3])1133 int spg_relocate_BZ_grid_address(int bz_grid_address[][3],
1134 int bz_map[],
1135 SPGCONST int grid_address[][3],
1136 const int mesh[3],
1137 SPGCONST double rec_lattice[3][3],
1138 const int is_shift[3])
1139 {
1140 return kpt_relocate_BZ_grid_address(bz_grid_address,
1141 bz_map,
1142 grid_address,
1143 mesh,
1144 rec_lattice,
1145 is_shift);
1146 }
1147
spg_relocate_dense_BZ_grid_address(int bz_grid_address[][3],size_t bz_map[],SPGCONST int grid_address[][3],const int mesh[3],SPGCONST double rec_lattice[3][3],const int is_shift[3])1148 size_t spg_relocate_dense_BZ_grid_address(int bz_grid_address[][3],
1149 size_t bz_map[],
1150 SPGCONST int grid_address[][3],
1151 const int mesh[3],
1152 SPGCONST double rec_lattice[3][3],
1153 const int is_shift[3])
1154 {
1155 return kpt_relocate_dense_BZ_grid_address(bz_grid_address,
1156 bz_map,
1157 grid_address,
1158 mesh,
1159 rec_lattice,
1160 is_shift);
1161 }
1162
1163 /*--------*/
1164 /* Niggli */
1165 /*--------*/
1166 /* Return 0 if failed */
spg_niggli_reduce(double lattice[3][3],const double symprec)1167 int spg_niggli_reduce(double lattice[3][3], const double symprec)
1168 {
1169 int i, j, succeeded;
1170 double vals[9];
1171
1172 for (i = 0; i < 3; i++) {
1173 for (j = 0; j < 3; j++) {
1174 vals[i * 3 + j] = lattice[i][j];
1175 }
1176 }
1177
1178 succeeded = niggli_reduce(vals, symprec);
1179
1180 if (succeeded) {
1181 for (i = 0; i < 3; i++) {
1182 for (j = 0; j < 3; j++) {
1183 lattice[i][j] = vals[i * 3 + j];
1184 }
1185 }
1186 spglib_error_code = SPGLIB_SUCCESS;
1187 } else {
1188 spglib_error_code = SPGERR_NIGGLI_FAILED;
1189 }
1190
1191 return succeeded;
1192 }
1193
1194
1195
1196
1197 /*=======*/
1198 /* local */
1199 /*=======*/
1200
1201 /*---------*/
1202 /* general */
1203 /*---------*/
1204 /* Return NULL if failed */
get_dataset(SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const int hall_number,const double symprec,const double angle_tolerance)1205 static SpglibDataset * get_dataset(SPGCONST double lattice[3][3],
1206 SPGCONST double position[][3],
1207 const int types[],
1208 const int num_atom,
1209 const int hall_number,
1210 const double symprec,
1211 const double angle_tolerance)
1212 {
1213 SpglibDataset *dataset;
1214 Cell *cell;
1215 DataContainer *container;
1216
1217 dataset = NULL;
1218 cell = NULL;
1219 container = NULL;
1220
1221 if ((dataset = init_dataset()) == NULL) {
1222 goto not_found;
1223 }
1224
1225 if ((cell = cel_alloc_cell(num_atom)) == NULL) {
1226 free(dataset);
1227 dataset = NULL;
1228 goto not_found;
1229 }
1230
1231 cel_set_cell(cell, lattice, position, types);
1232 if (cel_any_overlap_with_same_type(cell, symprec)) {
1233 cel_free_cell(cell);
1234 cell = NULL;
1235 free(dataset);
1236 dataset = NULL;
1237 goto atoms_too_close;
1238 }
1239
1240 if ((container = det_determine_all(cell,
1241 hall_number,
1242 symprec,
1243 angle_tolerance))
1244 != NULL) {
1245 if (set_dataset(dataset,
1246 cell,
1247 container->primitive,
1248 container->spacegroup,
1249 container->exact_structure)) {
1250 det_free_container(container);
1251 container = NULL;
1252 cel_free_cell(cell);
1253 cell = NULL;
1254 goto found;
1255 }
1256 det_free_container(container);
1257 container = NULL;
1258 }
1259
1260 cel_free_cell(cell);
1261 cell = NULL;
1262 free(dataset);
1263 dataset = NULL;
1264
1265 not_found:
1266 spglib_error_code = SPGERR_SPACEGROUP_SEARCH_FAILED;
1267 return NULL;
1268
1269 atoms_too_close:
1270 spglib_error_code = SPGERR_ATOMS_TOO_CLOSE;
1271 return NULL;
1272
1273 found:
1274
1275 spglib_error_code = SPGLIB_SUCCESS;
1276 return dataset;
1277 }
1278
init_dataset(void)1279 static SpglibDataset * init_dataset(void)
1280 {
1281 int i, j;
1282 SpglibDataset *dataset;
1283
1284 dataset = NULL;
1285
1286 if ((dataset = (SpglibDataset*) malloc(sizeof(SpglibDataset))) == NULL) {
1287 warning_print("spglib: Memory could not be allocated.");
1288 return NULL;
1289 }
1290
1291 dataset->spacegroup_number = 0;
1292 dataset->hall_number = 0;
1293 strcpy(dataset->international_symbol, "");
1294 strcpy(dataset->hall_symbol, "");
1295 strcpy(dataset->choice, "");
1296 dataset->origin_shift[0] = 0;
1297 dataset->origin_shift[1] = 0;
1298 dataset->origin_shift[2] = 0;
1299 dataset->n_atoms = 0;
1300 dataset->wyckoffs = NULL;
1301 dataset->equivalent_atoms = NULL;
1302 dataset->crystallographic_orbits = NULL;
1303 dataset->mapping_to_primitive = NULL;
1304 dataset->n_operations = 0;
1305 dataset->rotations = NULL;
1306 dataset->translations = NULL;
1307 dataset->n_std_atoms = 0;
1308 dataset->std_positions = NULL;
1309 dataset->std_types = NULL;
1310 for (i = 0; i < 3; i++) {
1311 for (j = 0; j < 3; j++) {
1312 dataset->std_rotation_matrix[i][j] = 0;
1313 }
1314 }
1315 dataset->std_mapping_to_primitive = NULL;
1316 /* dataset->pointgroup_number = 0; */
1317 strcpy(dataset->pointgroup_symbol, "");
1318
1319 return dataset;
1320 }
1321
1322 /* Return 0 if failed */
set_dataset(SpglibDataset * dataset,const Cell * cell,const Primitive * primitive,SPGCONST Spacegroup * spacegroup,ExactStructure * exstr)1323 static int set_dataset(SpglibDataset * dataset,
1324 const Cell * cell,
1325 const Primitive * primitive,
1326 SPGCONST Spacegroup * spacegroup,
1327 ExactStructure *exstr)
1328 {
1329 int i, j;
1330 double inv_lat[3][3];
1331 Pointgroup pointgroup;
1332
1333 /* Spacegroup type, transformation matrix, origin shift */
1334 dataset->n_atoms = cell->size;
1335 dataset->spacegroup_number = spacegroup->number;
1336 dataset->hall_number = spacegroup->hall_number;
1337 memcpy(dataset->international_symbol, spacegroup->international_short, 11);
1338 memcpy(dataset->hall_symbol, spacegroup->hall_symbol, 17);
1339 memcpy(dataset->choice, spacegroup->choice, 6);
1340 mat_inverse_matrix_d3(inv_lat, spacegroup->bravais_lattice, 0);
1341 mat_multiply_matrix_d3(dataset->transformation_matrix,
1342 inv_lat, cell->lattice);
1343 mat_copy_vector_d3(dataset->origin_shift, spacegroup->origin_shift);
1344
1345 dataset->n_operations = exstr->symmetry->size;
1346
1347 if ((dataset->rotations =
1348 (int (*)[3][3]) malloc(sizeof(int[3][3]) * dataset->n_operations))
1349 == NULL) {
1350 warning_print("spglib: Memory could not be allocated.");
1351 goto err;
1352 }
1353
1354 if ((dataset->translations =
1355 (double (*)[3]) malloc(sizeof(double[3]) * dataset->n_operations))
1356 == NULL) {
1357 warning_print("spglib: Memory could not be allocated.");
1358 goto err;
1359 }
1360
1361 for (i = 0; i < exstr->symmetry->size; i++) {
1362 mat_copy_matrix_i3(dataset->rotations[i], exstr->symmetry->rot[i]);
1363 mat_copy_vector_d3(dataset->translations[i], exstr->symmetry->trans[i]);
1364 }
1365
1366 /* Wyckoff positions */
1367 if ((dataset->wyckoffs = (int*) malloc(sizeof(int) * dataset->n_atoms))
1368 == NULL) {
1369 warning_print("spglib: Memory could not be allocated.");
1370 goto err;
1371 }
1372
1373 if ((dataset->site_symmetry_symbols =
1374 (char(*)[7]) malloc(sizeof(char[7]) * dataset->n_atoms)) == NULL) {
1375 warning_print("spglib: Memory could not be allocated.");
1376 goto err;
1377 }
1378
1379 if ((dataset->equivalent_atoms =
1380 (int*) malloc(sizeof(int) * dataset->n_atoms)) == NULL) {
1381 warning_print("spglib: Memory could not be allocated.");
1382 goto err;
1383 }
1384
1385 if ((dataset->crystallographic_orbits =
1386 (int*) malloc(sizeof(int) * dataset->n_atoms)) == NULL) {
1387 warning_print("spglib: Memory could not be allocated.");
1388 goto err;
1389 }
1390
1391 for (i = 0; i < dataset->n_atoms; i++) {
1392 dataset->wyckoffs[i] = exstr->wyckoffs[i];
1393 for (j = 0; j < 7; j++) {
1394 dataset->site_symmetry_symbols[i][j] = exstr->site_symmetry_symbols[i][j];
1395 }
1396 dataset->equivalent_atoms[i] = exstr->equivalent_atoms[i];
1397 dataset->crystallographic_orbits[i] = exstr->crystallographic_orbits[i];
1398 }
1399
1400 if ((dataset->mapping_to_primitive =
1401 (int*) malloc(sizeof(int) * dataset->n_atoms)) == NULL) {
1402 warning_print("spglib: Memory could not be allocated.");
1403 goto err;
1404 }
1405
1406 debug_print("[line %d, %s]\n", __LINE__, __FILE__);
1407 debug_print("refined cell after ref_get_Wyckoff_positions\n");
1408 debug_print_matrix_d3(exstr->bravais->lattice);
1409 #ifdef SPGDEBUG
1410 for (i = 0; i < exstr->bravais->size; i++) {
1411 printf("%d: %f %f %f\n",
1412 exstr->bravais->types[i],
1413 exstr->bravais->position[i][0],
1414 exstr->bravais->position[i][1],
1415 exstr->bravais->position[i][2]);
1416 }
1417 #endif
1418
1419 mat_copy_matrix_d3(dataset->primitive_lattice, primitive->cell->lattice);
1420 for (i = 0; i < dataset->n_atoms; i++) {
1421 dataset->mapping_to_primitive[i] = primitive->mapping_table[i];
1422 }
1423
1424 dataset->n_std_atoms = exstr->bravais->size;
1425 mat_copy_matrix_d3(dataset->std_lattice, exstr->bravais->lattice);
1426
1427 if ((dataset->std_positions =
1428 (double (*)[3]) malloc(sizeof(double[3]) * dataset->n_std_atoms))
1429 == NULL) {
1430 warning_print("spglib: Memory could not be allocated.");
1431 goto err;
1432 }
1433
1434 if ((dataset->std_types = (int*) malloc(sizeof(int) * dataset->n_std_atoms))
1435 == NULL) {
1436 warning_print("spglib: Memory could not be allocated.");
1437 goto err;
1438 }
1439
1440 if ((dataset->std_mapping_to_primitive =
1441 (int*) malloc(sizeof(int) * dataset->n_std_atoms)) == NULL) {
1442 warning_print("spglib: Memory could not be allocated.");
1443 goto err;
1444 }
1445
1446 for (i = 0; i < dataset->n_std_atoms; i++) {
1447 mat_copy_vector_d3(dataset->std_positions[i], exstr->bravais->position[i]);
1448 dataset->std_types[i] = exstr->bravais->types[i];
1449 dataset->std_mapping_to_primitive[i] = exstr->std_mapping_to_primitive[i];
1450 }
1451
1452 mat_copy_matrix_d3(dataset->std_rotation_matrix, exstr->rotation);
1453
1454 /* dataset->pointgroup_number = spacegroup->pointgroup_number; */
1455 pointgroup = ptg_get_pointgroup(spacegroup->pointgroup_number);
1456 memcpy(dataset->pointgroup_symbol, pointgroup.symbol, 6);
1457
1458 return 1;
1459
1460 err:
1461 if (dataset->std_positions != NULL) {
1462 free(dataset->std_positions);
1463 dataset->std_positions = NULL;
1464 }
1465 if (dataset->std_mapping_to_primitive != NULL) {
1466 free(dataset->std_mapping_to_primitive);
1467 dataset->std_mapping_to_primitive = NULL;
1468 }
1469 if (dataset->equivalent_atoms != NULL) {
1470 free(dataset->equivalent_atoms);
1471 dataset->equivalent_atoms = NULL;
1472 }
1473 if (dataset->crystallographic_orbits != NULL) {
1474 free(dataset->crystallographic_orbits);
1475 dataset->crystallographic_orbits = NULL;
1476 }
1477 if (dataset->mapping_to_primitive != NULL) {
1478 free(dataset->mapping_to_primitive);
1479 dataset->mapping_to_primitive = NULL;
1480 }
1481 if (dataset->site_symmetry_symbols != NULL) {
1482 free(dataset->site_symmetry_symbols);
1483 dataset->site_symmetry_symbols = NULL;
1484 }
1485 if (dataset->wyckoffs != NULL) {
1486 free(dataset->wyckoffs);
1487 dataset->wyckoffs = NULL;
1488 }
1489 if (dataset->translations != NULL) {
1490 free(dataset->translations);
1491 dataset->translations = NULL;
1492 }
1493 if (dataset->rotations != NULL) {
1494 free(dataset->rotations);
1495 dataset->rotations = NULL;
1496 }
1497
1498 return 0;
1499 }
1500
1501 /* Return 0 if failed */
get_symmetry_from_dataset(int rotation[][3][3],double translation[][3],const int max_size,SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec,const double angle_tolerance)1502 static int get_symmetry_from_dataset(int rotation[][3][3],
1503 double translation[][3],
1504 const int max_size,
1505 SPGCONST double lattice[3][3],
1506 SPGCONST double position[][3],
1507 const int types[],
1508 const int num_atom,
1509 const double symprec,
1510 const double angle_tolerance)
1511 {
1512 int i, num_sym;
1513 SpglibDataset *dataset;
1514
1515 num_sym = 0;
1516 dataset = NULL;
1517
1518 if ((dataset = get_dataset(lattice,
1519 position,
1520 types,
1521 num_atom,
1522 0,
1523 symprec,
1524 angle_tolerance)) == NULL) {
1525 return 0;
1526 }
1527
1528 if (dataset->n_operations > max_size) {
1529 fprintf(stderr,
1530 "spglib: Indicated max size(=%d) is less than number ", max_size);
1531 fprintf(stderr,
1532 "spglib: of symmetry operations(=%d).\n", dataset->n_operations);
1533 goto err;
1534 }
1535
1536 num_sym = dataset->n_operations;
1537 for (i = 0; i < num_sym; i++) {
1538 mat_copy_matrix_i3(rotation[i], dataset->rotations[i]);
1539 mat_copy_vector_d3(translation[i], dataset->translations[i]);
1540 }
1541
1542 spg_free_dataset(dataset);
1543 dataset = NULL;
1544 return num_sym;
1545
1546 err:
1547 spg_free_dataset(dataset);
1548 dataset = NULL;
1549 spglib_error_code = SPGERR_ARRAY_SIZE_SHORTAGE;
1550 return 0;
1551 }
1552
1553 /* Return 0 if failed */
get_symmetry_with_site_tensors(int rotation[][3][3],double translation[][3],int equivalent_atoms[],double primitive_lattice[3][3],int * spin_flips,const int run_symmetry_search,const int num_operations,SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const double * tensors,const int tensor_rank,const int num_atom,const int is_magnetic,const double symprec,const double angle_tolerance)1554 static int get_symmetry_with_site_tensors(int rotation[][3][3],
1555 double translation[][3],
1556 int equivalent_atoms[],
1557 double primitive_lattice[3][3],
1558 int *spin_flips,
1559 const int run_symmetry_search,
1560 const int num_operations,
1561 SPGCONST double lattice[3][3],
1562 SPGCONST double position[][3],
1563 const int types[],
1564 const double *tensors,
1565 const int tensor_rank,
1566 const int num_atom,
1567 const int is_magnetic,
1568 const double symprec,
1569 const double angle_tolerance)
1570 {
1571 int i, size;
1572 Symmetry *symmetry, *sym_nonspin;
1573 Cell *cell;
1574 SpglibDataset *dataset;
1575
1576 size = 0;
1577 symmetry = NULL;
1578 sym_nonspin = NULL;
1579 cell = NULL;
1580 dataset = NULL;
1581
1582 if (run_symmetry_search) {
1583 if ((dataset = get_dataset(lattice,
1584 position,
1585 types,
1586 num_atom,
1587 0,
1588 symprec,
1589 angle_tolerance)) == NULL) {
1590 goto err;
1591 }
1592
1593 if ((sym_nonspin = sym_alloc_symmetry(dataset->n_operations)) == NULL) {
1594 spg_free_dataset(dataset);
1595 dataset = NULL;
1596 goto err;
1597 }
1598
1599 for (i = 0; i < dataset->n_operations; i++) {
1600 mat_copy_matrix_i3(sym_nonspin->rot[i], dataset->rotations[i]);
1601 mat_copy_vector_d3(sym_nonspin->trans[i], dataset->translations[i]);
1602 }
1603 spg_free_dataset(dataset);
1604 dataset = NULL;
1605 } else {
1606 if ((sym_nonspin = sym_alloc_symmetry(num_operations)) == NULL) {
1607 goto err;
1608 }
1609 for (i = 0; i < num_operations; i++) {
1610 mat_copy_matrix_i3(sym_nonspin->rot[i], rotation[i]);
1611 mat_copy_vector_d3(sym_nonspin->trans[i], translation[i]);
1612 }
1613 }
1614
1615 if ((cell = cel_alloc_cell(num_atom)) == NULL) {
1616 goto err;
1617 }
1618 cel_set_cell(cell, lattice, position, types);
1619 symmetry = spn_get_operations_with_site_tensors(equivalent_atoms,
1620 primitive_lattice,
1621 spin_flips,
1622 sym_nonspin,
1623 cell,
1624 tensors,
1625 tensor_rank,
1626 is_magnetic,
1627 symprec,
1628 angle_tolerance);
1629
1630 sym_free_symmetry(sym_nonspin);
1631 sym_nonspin = NULL;
1632 cel_free_cell(cell);
1633 cell = NULL;
1634
1635 if (symmetry == NULL) {
1636 goto err;
1637 }
1638
1639 if (symmetry->size > num_operations) {
1640 fprintf(stderr, "spglib: Indicated max size(=%d) is less than number ",
1641 num_operations);
1642 fprintf(stderr, "spglib: of symmetry operations(=%d).\n", symmetry->size);
1643 sym_free_symmetry(symmetry);
1644 symmetry = NULL;
1645 goto array_size_shortage_err;
1646 }
1647
1648 for (i = 0; i < symmetry->size; i++) {
1649 mat_copy_matrix_i3(rotation[i], symmetry->rot[i]);
1650 mat_copy_vector_d3(translation[i], symmetry->trans[i]);
1651 }
1652 size = symmetry->size;
1653
1654 sym_free_symmetry(symmetry);
1655 symmetry = NULL;
1656 spglib_error_code = SPGLIB_SUCCESS;
1657
1658 return size;
1659
1660 err:
1661 spglib_error_code = SPGERR_SYMMETRY_OPERATION_SEARCH_FAILED;
1662 return 0;
1663
1664 array_size_shortage_err:
1665 spglib_error_code = SPGERR_ARRAY_SIZE_SHORTAGE;
1666 return 0;
1667
1668 }
1669
1670 /* Return 0 if failed */
get_multiplicity(SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec,const double angle_tolerance)1671 static int get_multiplicity(SPGCONST double lattice[3][3],
1672 SPGCONST double position[][3],
1673 const int types[],
1674 const int num_atom,
1675 const double symprec,
1676 const double angle_tolerance)
1677 {
1678 int size;
1679 SpglibDataset *dataset;
1680
1681 size = 0;
1682 dataset = NULL;
1683
1684 if ((dataset = get_dataset(lattice,
1685 position,
1686 types,
1687 num_atom,
1688 0,
1689 symprec,
1690 angle_tolerance)) == NULL) {
1691 return 0;
1692 }
1693
1694 size = dataset->n_operations;
1695 spg_free_dataset(dataset);
1696 dataset = NULL;
1697
1698 return size;
1699 }
1700
standardize_primitive(double lattice[3][3],double position[][3],int types[],const int num_atom,const double symprec,const double angle_tolerance)1701 static int standardize_primitive(double lattice[3][3],
1702 double position[][3],
1703 int types[],
1704 const int num_atom,
1705 const double symprec,
1706 const double angle_tolerance)
1707 {
1708 int i, num_prim_atom;
1709 int *mapping_table;
1710 Centering centering;
1711 SpglibDataset *dataset;
1712 Cell *primitive, *bravais;
1713
1714 double identity[3][3] = {{ 1, 0, 0 },
1715 { 0, 1, 0 },
1716 { 0, 0, 1 }};
1717
1718 num_prim_atom = 0;
1719 mapping_table = NULL;
1720 dataset = NULL;
1721 primitive = NULL;
1722 bravais = NULL;
1723
1724 if ((dataset = get_dataset(lattice,
1725 position,
1726 types,
1727 num_atom,
1728 0,
1729 symprec,
1730 angle_tolerance)) == NULL) {
1731 return 0;
1732 }
1733
1734 if ((centering = get_centering(dataset->hall_number)) == CENTERING_ERROR) {
1735 spg_free_dataset(dataset);
1736 dataset = NULL;
1737 goto err;
1738 }
1739
1740 if ((bravais = cel_alloc_cell(dataset->n_std_atoms)) == NULL) {
1741 spg_free_dataset(dataset);
1742 dataset = NULL;
1743 goto err;
1744 }
1745
1746 cel_set_cell(bravais,
1747 dataset->std_lattice,
1748 dataset->std_positions,
1749 dataset->std_types);
1750
1751 spg_free_dataset(dataset);
1752 dataset = NULL;
1753
1754 if ((mapping_table = (int*) malloc(sizeof(int) * bravais->size)) == NULL) {
1755 warning_print("spglib: Memory could not be allocated ");
1756 cel_free_cell(bravais);
1757 bravais = NULL;
1758 goto err;
1759 }
1760
1761 primitive = spa_transform_to_primitive(mapping_table,
1762 bravais,
1763 identity,
1764 centering,
1765 symprec);
1766
1767 for (i = 0; i < primitive->size; i++) {
1768 /* This is an assertion. */
1769 if (mapping_table[i] != i) {
1770 warning_print("spglib: spa_transform_to_primitive failed.");
1771 warning_print("Unexpected atom index mapping to primitive (%d != %d).\n",
1772 mapping_table[i], i);
1773 warning_print(" (line %d, %s).\n", __LINE__, __FILE__);
1774 free(mapping_table);
1775 mapping_table = NULL;
1776 cel_free_cell(bravais);
1777 bravais = NULL;
1778 goto err;
1779 }
1780 }
1781
1782 free(mapping_table);
1783 mapping_table = NULL;
1784 cel_free_cell(bravais);
1785 bravais = NULL;
1786
1787 if (primitive == NULL) {
1788 goto err;
1789 }
1790
1791 set_cell(lattice, position, types, primitive);
1792 num_prim_atom = primitive->size;
1793
1794 cel_free_cell(primitive);
1795 primitive = NULL;
1796
1797 return num_prim_atom;
1798
1799 err:
1800 spglib_error_code = SPGERR_CELL_STANDARDIZATION_FAILED;
1801 return 0;
1802 }
1803
standardize_cell(double lattice[3][3],double position[][3],int types[],const int num_atom,const int num_array_size,const double symprec,const double angle_tolerance)1804 static int standardize_cell(double lattice[3][3],
1805 double position[][3],
1806 int types[],
1807 const int num_atom,
1808 const int num_array_size,
1809 const double symprec,
1810 const double angle_tolerance)
1811 {
1812 int i, n_std_atoms;
1813 SpglibDataset *dataset;
1814
1815 n_std_atoms = 0;
1816 dataset = NULL;
1817
1818 if ((dataset = get_dataset(lattice,
1819 position,
1820 types,
1821 num_atom,
1822 0,
1823 symprec,
1824 angle_tolerance)) == NULL) {
1825 goto err;
1826 }
1827
1828 if (num_array_size > 0) {
1829 if (num_atom < dataset->n_std_atoms) {
1830 goto array_size_shortage_err;
1831 }
1832 }
1833
1834 n_std_atoms = dataset->n_std_atoms;
1835 mat_copy_matrix_d3(lattice, dataset->std_lattice);
1836 for (i = 0; i < dataset->n_std_atoms; i++) {
1837 types[i] = dataset->std_types[i];
1838 mat_copy_vector_d3(position[i], dataset->std_positions[i]);
1839 }
1840
1841 spg_free_dataset(dataset);
1842 dataset = NULL;
1843
1844 return n_std_atoms;
1845
1846 err:
1847 spglib_error_code = SPGERR_CELL_STANDARDIZATION_FAILED;
1848 return 0;
1849
1850 array_size_shortage_err:
1851 spglib_error_code = SPGERR_ARRAY_SIZE_SHORTAGE;
1852 return 0;
1853 }
1854
get_standardized_cell(double lattice[3][3],double position[][3],int types[],const int num_atom,const int num_array_size,const int to_primitive,const double symprec,const double angle_tolerance)1855 static int get_standardized_cell(double lattice[3][3],
1856 double position[][3],
1857 int types[],
1858 const int num_atom,
1859 const int num_array_size,
1860 const int to_primitive,
1861 const double symprec,
1862 const double angle_tolerance)
1863 {
1864 int i, num_std_atom, num_prim_atom;
1865 int *mapping_table;
1866 SpglibDataset *dataset;
1867 Cell *std_cell, *cell, *primitive;
1868 Centering centering;
1869
1870 num_std_atom = 0;
1871 mapping_table = NULL;
1872 dataset = NULL;
1873 std_cell = NULL;
1874 cell = NULL;
1875 primitive = NULL;
1876
1877 if ((dataset = get_dataset(lattice,
1878 position,
1879 types,
1880 num_atom,
1881 0,
1882 symprec,
1883 angle_tolerance)) == NULL) {
1884 goto err;
1885 }
1886
1887 if ((centering = get_centering(dataset->hall_number)) == CENTERING_ERROR) {
1888 goto err;
1889 }
1890
1891 if ((cell = cel_alloc_cell(num_atom)) == NULL) {
1892 spg_free_dataset(dataset);
1893 dataset = NULL;
1894 goto err;
1895 }
1896
1897 cel_set_cell(cell, lattice, position, types);
1898
1899 if ((mapping_table = (int*) malloc(sizeof(int) * cell->size)) == NULL) {
1900 warning_print("spglib: Memory could not be allocated ");
1901 cel_free_cell(cell);
1902 cell = NULL;
1903 spg_free_dataset(dataset);
1904 dataset = NULL;
1905 goto err;
1906 }
1907
1908 if ((primitive = spa_transform_to_primitive(mapping_table,
1909 cell,
1910 dataset->transformation_matrix,
1911 centering,
1912 symprec)) == NULL) {
1913 warning_print("spglib: spa_transform_to_primitive failed.");
1914 warning_print(" (line %d, %s).\n", __LINE__, __FILE__);
1915 }
1916
1917 for (i = 0; i < cell->size; i++) {
1918 /* This is an assertion. */
1919 if (mapping_table[i] != dataset->mapping_to_primitive[i]) {
1920 warning_print("spglib: spa_transform_to_primitive failed.");
1921 warning_print("Unexpected atom index mapping to primitive (%d != %d).\n",
1922 mapping_table[i], dataset->mapping_to_primitive[i]);
1923 warning_print(" (line %d, %s).\n", __LINE__, __FILE__);
1924 free(mapping_table);
1925 mapping_table = NULL;
1926 cel_free_cell(cell);
1927 cell = NULL;
1928 spg_free_dataset(dataset);
1929 dataset = NULL;
1930 goto err;
1931 }
1932 }
1933
1934 free(mapping_table);
1935 mapping_table = NULL;
1936 cel_free_cell(cell);
1937 cell = NULL;
1938 spg_free_dataset(dataset);
1939 dataset = NULL;
1940
1941 if (primitive == NULL) {
1942 goto err;
1943 }
1944
1945 if (to_primitive || centering == PRIMITIVE) {
1946 set_cell(lattice, position, types, primitive);
1947 num_prim_atom = primitive->size;
1948 cel_free_cell(primitive);
1949 primitive = NULL;
1950 return num_prim_atom;
1951 }
1952
1953 if ((std_cell = spa_transform_from_primitive(primitive, centering, symprec))
1954 == NULL) {
1955 warning_print("spglib: spa_transform_from_primitive failed.");
1956 warning_print(" (line %d, %s).\n", __LINE__, __FILE__);
1957 }
1958 cel_free_cell(primitive);
1959 primitive = NULL;
1960
1961 if (std_cell == NULL) {
1962 goto err;
1963 }
1964
1965 if (num_array_size > 0) {
1966 if (num_array_size < std_cell->size) {
1967 cel_free_cell(std_cell);
1968 std_cell = NULL;
1969 goto array_size_shortage_err;
1970 }
1971 }
1972
1973 num_std_atom = std_cell->size;
1974 set_cell(lattice, position, types, std_cell);
1975 cel_free_cell(std_cell);
1976 std_cell = NULL;
1977 return num_std_atom;
1978
1979 err:
1980 spglib_error_code = SPGERR_CELL_STANDARDIZATION_FAILED;
1981 return 0;
1982
1983 array_size_shortage_err:
1984 spglib_error_code = SPGERR_ARRAY_SIZE_SHORTAGE;
1985 return 0;
1986 }
1987
set_cell(double lattice[3][3],double position[][3],int types[],Cell * cell)1988 static void set_cell(double lattice[3][3],
1989 double position[][3],
1990 int types[],
1991 Cell * cell)
1992 {
1993 int i;
1994
1995 mat_copy_matrix_d3(lattice, cell->lattice);
1996 for (i = 0; i < cell->size; i++) {
1997 types[i] = cell->types[i];
1998 mat_copy_vector_d3(position[i], cell->position[i]);
1999 }
2000 }
2001
get_centering(int hall_number)2002 static Centering get_centering(int hall_number)
2003 {
2004 SpacegroupType spgtype;
2005
2006 spgtype = spgdb_get_spacegroup_type(hall_number);
2007
2008 return spgtype.centering;
2009 }
2010
get_international(char symbol[11],SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec,const double angle_tolerance)2011 static int get_international(char symbol[11],
2012 SPGCONST double lattice[3][3],
2013 SPGCONST double position[][3],
2014 const int types[],
2015 const int num_atom,
2016 const double symprec,
2017 const double angle_tolerance)
2018 {
2019 SpglibDataset *dataset;
2020 int number;
2021
2022 dataset = NULL;
2023
2024 if ((dataset = get_dataset(lattice,
2025 position,
2026 types,
2027 num_atom,
2028 0,
2029 symprec,
2030 angle_tolerance)) == NULL) {
2031 goto err;
2032 }
2033
2034 if (dataset->spacegroup_number > 0) {
2035 number = dataset->spacegroup_number;
2036 memcpy(symbol, dataset->international_symbol, 11);
2037
2038 spg_free_dataset(dataset);
2039 dataset = NULL;
2040 } else {
2041 spg_free_dataset(dataset);
2042 dataset = NULL;
2043 goto err;
2044 }
2045
2046 spglib_error_code = SPGLIB_SUCCESS;
2047 return number;
2048
2049 err:
2050 spglib_error_code = SPGERR_SPACEGROUP_SEARCH_FAILED;
2051 return 0;
2052 }
2053
get_schoenflies(char symbol[7],SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec,const double angle_tolerance)2054 static int get_schoenflies(char symbol[7],
2055 SPGCONST double lattice[3][3],
2056 SPGCONST double position[][3],
2057 const int types[],
2058 const int num_atom,
2059 const double symprec,
2060 const double angle_tolerance)
2061 {
2062 SpglibDataset *dataset;
2063 SpglibSpacegroupType spgtype;
2064 int number;
2065
2066 dataset = NULL;
2067
2068 if ((dataset = get_dataset(lattice,
2069 position,
2070 types,
2071 num_atom,
2072 0,
2073 symprec,
2074 angle_tolerance)) == NULL) {
2075 goto err;
2076 }
2077
2078 if (dataset->spacegroup_number > 0) {
2079 number = dataset->spacegroup_number;
2080 spgtype = spg_get_spacegroup_type(dataset->hall_number);
2081 memcpy(symbol, spgtype.schoenflies, 7);
2082 spg_free_dataset(dataset);
2083 dataset = NULL;
2084 } else {
2085 spg_free_dataset(dataset);
2086 dataset = NULL;
2087 goto err;
2088 }
2089
2090 spglib_error_code = SPGLIB_SUCCESS;
2091 return number;
2092
2093 err:
2094 spglib_error_code = SPGERR_SPACEGROUP_SEARCH_FAILED;
2095 return 0;
2096 }
2097
2098
2099 /*---------*/
2100 /* kpoints */
2101 /*---------*/
get_ir_reciprocal_mesh(int grid_address[][3],int ir_mapping_table[],const int mesh[3],const int is_shift[3],const int is_time_reversal,SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const int num_atom,const double symprec,const double angle_tolerance)2102 static int get_ir_reciprocal_mesh(int grid_address[][3],
2103 int ir_mapping_table[],
2104 const int mesh[3],
2105 const int is_shift[3],
2106 const int is_time_reversal,
2107 SPGCONST double lattice[3][3],
2108 SPGCONST double position[][3],
2109 const int types[],
2110 const int num_atom,
2111 const double symprec,
2112 const double angle_tolerance)
2113 {
2114 SpglibDataset *dataset;
2115 int num_ir, i;
2116 MatINT *rotations, *rot_reciprocal;
2117
2118 if ((dataset = get_dataset(lattice,
2119 position,
2120 types,
2121 num_atom,
2122 0,
2123 symprec,
2124 angle_tolerance)) == NULL) {
2125 return 0;
2126 }
2127
2128 if ((rotations = mat_alloc_MatINT(dataset->n_operations)) == NULL) {
2129 spg_free_dataset(dataset);
2130 dataset = NULL;
2131 return 0;
2132 }
2133
2134 for (i = 0; i < dataset->n_operations; i++) {
2135 mat_copy_matrix_i3(rotations->mat[i], dataset->rotations[i]);
2136 }
2137 rot_reciprocal = kpt_get_point_group_reciprocal(rotations, is_time_reversal);
2138 num_ir = kpt_get_irreducible_reciprocal_mesh(grid_address,
2139 ir_mapping_table,
2140 mesh,
2141 is_shift,
2142 rot_reciprocal);
2143 mat_free_MatINT(rot_reciprocal);
2144 rot_reciprocal = NULL;
2145 mat_free_MatINT(rotations);
2146 rotations = NULL;
2147 spg_free_dataset(dataset);
2148 dataset = NULL;
2149 return num_ir;
2150 }
2151
get_dense_ir_reciprocal_mesh(int grid_address[][3],size_t ir_mapping_table[],const int mesh[3],const int is_shift[3],const int is_time_reversal,SPGCONST double lattice[3][3],SPGCONST double position[][3],const int types[],const size_t num_atom,const double symprec,const double angle_tolerance)2152 static size_t get_dense_ir_reciprocal_mesh(int grid_address[][3],
2153 size_t ir_mapping_table[],
2154 const int mesh[3],
2155 const int is_shift[3],
2156 const int is_time_reversal,
2157 SPGCONST double lattice[3][3],
2158 SPGCONST double position[][3],
2159 const int types[],
2160 const size_t num_atom,
2161 const double symprec,
2162 const double angle_tolerance)
2163 {
2164 SpglibDataset *dataset;
2165 int i;
2166 size_t num_ir;
2167 MatINT *rotations, *rot_reciprocal;
2168
2169 if ((dataset = get_dataset(lattice,
2170 position,
2171 types,
2172 num_atom,
2173 0,
2174 symprec,
2175 angle_tolerance)) == NULL) {
2176 return 0;
2177 }
2178
2179 if ((rotations = mat_alloc_MatINT(dataset->n_operations)) == NULL) {
2180 spg_free_dataset(dataset);
2181 dataset = NULL;
2182 return 0;
2183 }
2184
2185 for (i = 0; i < dataset->n_operations; i++) {
2186 mat_copy_matrix_i3(rotations->mat[i], dataset->rotations[i]);
2187 }
2188 rot_reciprocal = kpt_get_point_group_reciprocal(rotations, is_time_reversal);
2189 num_ir = kpt_get_dense_irreducible_reciprocal_mesh(grid_address,
2190 ir_mapping_table,
2191 mesh,
2192 is_shift,
2193 rot_reciprocal);
2194 mat_free_MatINT(rot_reciprocal);
2195 rot_reciprocal = NULL;
2196 mat_free_MatINT(rotations);
2197 rotations = NULL;
2198 spg_free_dataset(dataset);
2199 dataset = NULL;
2200 return num_ir;
2201 }
2202
get_stabilized_reciprocal_mesh(int grid_address[][3],int map[],const int mesh[3],const int is_shift[3],const int is_time_reversal,const int num_rot,SPGCONST int rotations[][3][3],const size_t num_q,SPGCONST double qpoints[][3])2203 static int get_stabilized_reciprocal_mesh(int grid_address[][3],
2204 int map[],
2205 const int mesh[3],
2206 const int is_shift[3],
2207 const int is_time_reversal,
2208 const int num_rot,
2209 SPGCONST int rotations[][3][3],
2210 const size_t num_q,
2211 SPGCONST double qpoints[][3])
2212 {
2213 MatINT *rot_real;
2214 int i, num_ir;
2215
2216 rot_real = NULL;
2217
2218 if ((rot_real = mat_alloc_MatINT(num_rot)) == NULL) {
2219 return 0;
2220 }
2221
2222 for (i = 0; i < num_rot; i++) {
2223 mat_copy_matrix_i3(rot_real->mat[i], rotations[i]);
2224 }
2225
2226 num_ir = kpt_get_stabilized_reciprocal_mesh(grid_address,
2227 map,
2228 mesh,
2229 is_shift,
2230 is_time_reversal,
2231 rot_real,
2232 num_q,
2233 qpoints);
2234
2235 mat_free_MatINT(rot_real);
2236 rot_real = NULL;
2237
2238 return num_ir;
2239 }
2240
get_dense_stabilized_reciprocal_mesh(int grid_address[][3],size_t ir_mapping_table[],const int mesh[3],const int is_shift[3],const int is_time_reversal,const size_t num_rot,SPGCONST int rotations[][3][3],const size_t num_q,SPGCONST double qpoints[][3])2241 static size_t get_dense_stabilized_reciprocal_mesh(int grid_address[][3],
2242 size_t ir_mapping_table[],
2243 const int mesh[3],
2244 const int is_shift[3],
2245 const int is_time_reversal,
2246 const size_t num_rot,
2247 SPGCONST int rotations[][3][3],
2248 const size_t num_q,
2249 SPGCONST double qpoints[][3])
2250 {
2251 MatINT *rot_real;
2252 size_t i, num_ir;
2253
2254 rot_real = NULL;
2255
2256 if ((rot_real = mat_alloc_MatINT(num_rot)) == NULL) {
2257 return 0;
2258 }
2259
2260 for (i = 0; i < num_rot; i++) {
2261 mat_copy_matrix_i3(rot_real->mat[i], rotations[i]);
2262 }
2263
2264 num_ir = kpt_get_dense_stabilized_reciprocal_mesh(grid_address,
2265 ir_mapping_table,
2266 mesh,
2267 is_shift,
2268 is_time_reversal,
2269 rot_real,
2270 num_q,
2271 qpoints);
2272
2273 mat_free_MatINT(rot_real);
2274 rot_real = NULL;
2275
2276 return num_ir;
2277 }
2278