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 phonopy 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 #ifndef __spglib_H__
36 #define __spglib_H__
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 /* SPGCONST is used instead of 'const' so to avoid gcc warning. */
42 /* However there should be better way than this way.... */
43 #ifndef SPGCONST
44 #define SPGCONST
45 #endif
46 
47 /*
48   ------------------------------------------------------------------
49 
50   lattice: Lattice vectors (in Cartesian)
51 
52   [ [ a_x, b_x, c_x ],
53     [ a_y, b_y, c_y ],
54     [ a_z, b_z, c_z ] ]
55 
56   position: Atomic positions (in fractional coordinates)
57 
58   [ [ x1_a, x1_b, x1_c ],
59     [ x2_a, x2_b, x2_c ],
60     [ x3_a, x3_b, x3_c ],
61     ...                   ]
62 
63   types: Atom types, i.e., species identified by number
64 
65   [ type_1, type_2, type_3, ... ]
66 
67   rotation: Rotation matricies of symmetry operations
68 
69   each rotation is:
70   [ [ r_aa, r_ab, r_ac ],
71     [ r_ba, r_bb, r_bc ],
72     [ r_ca, r_cb, r_cc ] ]
73 
74   translation: Translation vectors of symmetry operations
75 
76   each translation is:
77   [ t_a, t_b, t_c ]
78 
79   symprec: Tolerance of atomic positions (in fractional coordinate)
80   in finding symmetry operations
81 
82   ------------------------------------------------------------------
83 
84   Definitio of the operation:
85   r : rotation     3x3 matrix
86   t : translation  vector
87 
88   x_new = r * x + t:
89   [ x_new_a ]   [ r_aa, r_ab, r_ac ]   [ x_a ]   [ t_a ]
90   [ x_new_b ] = [ r_ba, r_bb, r_bc ] * [ x_b ] + [ t_b ]
91   [ x_new_c ]   [ r_ca, r_cb, r_cc ]   [ x_c ]   [ t_c ]
92 
93   ------------------------------------------------------------------
94 */
95 
96 typedef enum {
97   SPGLIB_SUCCESS = 0,
98   SPGERR_SPACEGROUP_SEARCH_FAILED,
99   SPGERR_CELL_STANDARDIZATION_FAILED,
100   SPGERR_SYMMETRY_OPERATION_SEARCH_FAILED,
101   SPGERR_ATOMS_TOO_CLOSE,
102   SPGERR_POINTGROUP_NOT_FOUND,
103   SPGERR_NIGGLI_FAILED,
104   SPGERR_DELAUNAY_FAILED,
105   SPGERR_ARRAY_SIZE_SHORTAGE,
106   SPGERR_NONE,
107 } SpglibError;
108 
109 typedef struct {
110   int spacegroup_number;
111   int hall_number;
112   char international_symbol[11];
113   char hall_symbol[17];
114   char choice[6];
115   double transformation_matrix[3][3];
116   double origin_shift[3];
117   int n_operations;
118   int (*rotations)[3][3];
119   double (*translations)[3];
120   int n_atoms;
121   int *wyckoffs;
122   int *equivalent_atoms;
123   int *mapping_to_primitive;
124   int n_std_atoms;
125   double std_lattice[3][3];
126   int *std_types;
127   double (*std_positions)[3];
128   int *std_mapping_to_primitive;
129   /* int pointgroup_number; */
130   char pointgroup_symbol[6];
131 } SpglibDataset;
132 
133 typedef struct {
134   int number;
135   char international_short[11];
136   char international_full[20];
137   char international[32];
138   char schoenflies[7];
139   char hall_symbol[17];
140   char choice[6];
141   char pointgroup_international[6];
142   char pointgroup_schoenflies[4];
143   int arithmetic_crystal_class_number;
144   char arithmetic_crystal_class_symbol[7];
145 } SpglibSpacegroupType;
146 
147 int spg_get_major_version(void);
148 int spg_get_minor_version(void);
149 int spg_get_micro_version(void);
150 
151 SpglibError spg_get_error_code(void);
152 char * spg_get_error_message(SpglibError spglib_error);
153 
154 SpglibDataset * spg_get_dataset(SPGCONST double lattice[3][3],
155                                 SPGCONST double position[][3],
156                                 const int types[],
157                                 const int num_atom,
158                                 const double symprec);
159 
160 SpglibDataset * spgat_get_dataset(SPGCONST double lattice[3][3],
161                                   SPGCONST double position[][3],
162                                   const int types[],
163                                   const int num_atom,
164                                   const double symprec,
165                                   const double angle_tolerance);
166 
167 /* hall_number = 0 gives the same as spg_get_dataset. */
168 SpglibDataset * spg_get_dataset_with_hall_number(SPGCONST double lattice[3][3],
169                                                  SPGCONST double position[][3],
170                                                  const int types[],
171                                                  const int num_atom,
172                                                  const int hall_number,
173                                                  const double symprec);
174 
175 /* hall_number = 0 gives the same as spgat_get_dataset. */
176 SpglibDataset *
177 spgat_get_dataset_with_hall_number(SPGCONST double lattice[3][3],
178                                    SPGCONST double position[][3],
179                                    const int types[],
180                                    const int num_atom,
181                                    const int hall_number,
182                                    const double symprec,
183                                    const double angle_tolerance);
184 
185 void spg_free_dataset(SpglibDataset *dataset);
186 
187 /* Find symmetry operations. The operations are stored in */
188 /* ``rotatiion`` and ``translation``. The number of operations is */
189 /* return as the return value. Rotations and translations are */
190 /* given in fractional coordinates, and ``rotation[i]`` and */
191 /* ``translation[i]`` with same index give a symmetry oprations, */
192 /* i.e., these have to be used togather. */
193 int spg_get_symmetry(int rotation[][3][3],
194                      double translation[][3],
195                      const int max_size,
196                      SPGCONST double lattice[3][3],
197                      SPGCONST double position[][3],
198                      const int types[],
199                      const int num_atom,
200                      const double symprec);
201 
202 int spgat_get_symmetry(int rotation[][3][3],
203                        double translation[][3],
204                        const int max_size,
205                        SPGCONST double lattice[3][3],
206                        SPGCONST double position[][3],
207                        const int types[],
208                        const int num_atom,
209                        const double symprec,
210                        const double angle_tolerance);
211 
212 /* Find symmetry operations with collinear spins on atoms. */
213 int spg_get_symmetry_with_collinear_spin(int rotation[][3][3],
214                                          double translation[][3],
215                                          int equivalent_atoms[],
216                                          const int max_size,
217                                          SPGCONST double lattice[3][3],
218                                          SPGCONST double position[][3],
219                                          const int types[],
220                                          const double spins[],
221                                          const int num_atom,
222                                          const double symprec);
223 
224 int spgat_get_symmetry_with_collinear_spin(int rotation[][3][3],
225                                            double translation[][3],
226                                            int equivalent_atoms[],
227                                            const int max_size,
228                                            SPGCONST double lattice[3][3],
229                                            SPGCONST double position[][3],
230                                            const int types[],
231                                            const double spins[],
232                                            const int num_atom,
233                                            const double symprec,
234                                            const double angle_tolerance);
235 
236 /* Space group type (hall_number) is searched from symmetry operations. */
237 int spg_get_hall_number_from_symmetry(SPGCONST int rotation[][3][3],
238                                       SPGCONST double translation[][3],
239                                       const int num_operations,
240                                       const double symprec);
241 
242 /* Return exact number of symmetry operations. This function may */
243 /* be used in advance to allocate memoery space for symmetry */
244 /* operations. */
245 int spg_get_multiplicity(SPGCONST double lattice[3][3],
246                          SPGCONST double position[][3],
247                          const int types[],
248                          const int num_atom,
249                          const double symprec);
250 
251 int spgat_get_multiplicity(SPGCONST double lattice[3][3],
252                            SPGCONST double position[][3],
253                            const int types[],
254                            const int num_atom,
255                            const double symprec,
256                            const double angle_tolerance);
257 
258 /* Space group is found in international table symbol (``symbol``) and */
259 /* number (return value). 0 is returned when it fails. */
260 int spg_get_international(char symbol[11],
261                           SPGCONST double lattice[3][3],
262                           SPGCONST double position[][3],
263                           const int types[],
264                           const int num_atom,
265                           const double symprec);
266 
267 int spgat_get_international(char symbol[11],
268                             SPGCONST double lattice[3][3],
269                             SPGCONST double position[][3],
270                             const int types[],
271                             const int num_atom,
272                             const double symprec,
273                             const double angle_tolerance);
274 
275 /* Space group is found in schoenflies (``symbol``) and as number (return */
276 /* value).  0 is returned when it fails. */
277 int spg_get_schoenflies(char symbol[7],
278                         SPGCONST double lattice[3][3],
279                         SPGCONST double position[][3],
280                         const int types[],
281                         const int num_atom,
282                         const double symprec);
283 
284 int spgat_get_schoenflies(char symbol[7],
285                           SPGCONST double lattice[3][3],
286                           SPGCONST double position[][3],
287                           const int types[],
288                           const int num_atom,
289                           const double symprec,
290                           const double angle_tolerance);
291 
292 /* Point group symbol is obtained from the rotation part of */
293 /* symmetry operations */
294 int spg_get_pointgroup(char symbol[6],
295                        int trans_mat[3][3],
296                        SPGCONST int rotations[][3][3],
297                        const int num_rotations);
298 
299 /* Space-group operations in built-in database are accessed by index */
300 /* of hall symbol. The index is defined as number from 1 to 530. */
301 /* The muximum number of symmetry operations is 192. */
302 int spg_get_symmetry_from_database(int rotations[192][3][3],
303                                    double translations[192][3],
304                                    const int hall_number);
305 
306 /* Space-group type information is accessed by index of hall symbol. */
307 /* The index is defined as number from 1 to 530. */
308 SpglibSpacegroupType spg_get_spacegroup_type(const int hall_number);
309 
310 
311 int spg_standardize_cell(double lattice[3][3],
312                          double position[][3],
313                          int types[],
314                          const int num_atom,
315                          const int to_primitive,
316                          const int no_idealize,
317                          const double symprec);
318 
319 int spgat_standardize_cell(double lattice[3][3],
320                            double position[][3],
321                            int types[],
322                            const int num_atom,
323                            const int to_primitive,
324                            const int no_idealize,
325                            const double symprec,
326                            const double angle_tolerance);
327 
328 /* This is a wrapper of spg_standardize_cell. */
329 /* A primitive cell is found from an input cell. */
330 /* Be careful that ``lattice``, ``position``, and ``types`` are overwritten. */
331 /* ``num_atom`` is returned as return value. */
332 /* When any primitive cell is not found, 0 is returned. */
333 int spg_find_primitive(double lattice[3][3],
334                        double position[][3],
335                        int types[],
336                        const int num_atom,
337                        const double symprec);
338 
339 int spgat_find_primitive(double lattice[3][3],
340                          double position[][3],
341                          int types[],
342                          const int num_atom,
343                          const double symprec,
344                          const double angle_tolerance);
345 
346 /* This is a wrapper of spg_standardize_cell. */
347 /* Bravais lattice with internal atomic points are returned. */
348 /* The arrays are require to have 4 times larger memory space */
349 /* those of input cell. */
350 /* When bravais lattice could not be found, or could not be */
351 /* symmetrized, 0 is returned. */
352 int spg_refine_cell(double lattice[3][3],
353                     double position[][3],
354                     int types[],
355                     const int num_atom,
356                     const double symprec);
357 
358 int spgat_refine_cell(double lattice[3][3],
359                       double position[][3],
360                       int types[],
361                       const int num_atom,
362                       const double symprec,
363                       const double angle_tolerance);
364 
365 /* Delaunay reduction for lattice parameters */
366 /* ``lattice`` is overwritten when the redution ends succeeded. */
367 int spg_delaunay_reduce(double lattice[3][3], const double symprec);
368 
369 /*---------*/
370 /* kpoints */
371 /*---------*/
372 
373 /* Translate grid address to grid point index in the kspclib definition */
374 /* (see the comment in kgrid.h.) */
375 /* A q-point in fractional coordinates is given as */
376 /* ((grid_address * 2 + (shift != 0)) / (mesh * 2)). */
377 /* Each element of shift[] is 0 or non-zero. */
378 int spg_get_grid_point_from_address(const int grid_address[3],
379                                     const int mesh[3]);
380 
381 /* Irreducible reciprocal grid points are searched from uniform */
382 /* mesh grid points specified by ``mesh`` and ``is_shift``. */
383 /* ``mesh`` stores three integers. Reciprocal primitive vectors */
384 /* are divided by the number stored in ``mesh`` with (0,0,0) point */
385 /* centering. The centering can be shifted only half of one mesh */
386 /* by setting 1 for each ``is_shift`` element. If 0 is set for */
387 /* ``is_shift``, it means there is no shift. This limitation of */
388 /* shifting enables the irreducible k-point search significantly */
389 /* faster when the mesh is very dense. */
390 
391 /* The reducible uniform grid points are returned in reduced */
392 /* coordinates as ``grid_address``. A map between reducible and */
393 /* irreducible points are returned as ``map`` as in the indices of */
394 /* ``grid_address``. The number of the irreducible k-points are */
395 /* returned as the return value.  The time reversal symmetry is */
396 /* imposed by setting ``is_time_reversal`` 1. */
397 int spg_get_ir_reciprocal_mesh(int grid_address[][3],
398                                int map[],
399                                const int mesh[3],
400                                const int is_shift[3],
401                                const int is_time_reversal,
402                                SPGCONST double lattice[3][3],
403                                SPGCONST double position[][3],
404                                const int types[],
405                                const int num_atom,
406                                const double symprec);
407 
408 /* The irreducible k-points are searched from unique k-point mesh */
409 /* grids from real space lattice vectors and rotation matrices of */
410 /* symmetry operations in real space with stabilizers. The */
411 /* stabilizers are written in reduced coordinates. Number of the */
412 /* stabilizers are given by ``num_q``. Reduced k-points are stored */
413 /* in ``map`` as indices of ``grid_address``. The number of the */
414 /* reduced k-points with stabilizers are returned as the return */
415 /* value. */
416 int spg_get_stabilized_reciprocal_mesh(int grid_address[][3],
417                                        int map[],
418                                        const int mesh[3],
419                                        const int is_shift[3],
420                                        const int is_time_reversal,
421                                        const int num_rot,
422                                        SPGCONST int rotations[][3][3],
423                                        const int num_q,
424                                        SPGCONST double qpoints[][3]);
425 
426 /* Rotation operations in reciprocal space ``rot_reciprocal`` are applied */
427 /* to a grid address ``address_orig`` and resulting grid points are stored in */
428 /* ``rot_grid_points``. Return 0 if failed. */
429 int spg_get_grid_points_by_rotations(int rot_grid_points[],
430                                      const int address_orig[3],
431                                      const int num_rot,
432                                      SPGCONST int rot_reciprocal[][3][3],
433                                      const int mesh[3],
434                                      const int is_shift[3]);
435 
436 int spg_get_BZ_grid_points_by_rotations(int rot_grid_points[],
437                                         const int address_orig[3],
438                                         const int num_rot,
439                                         SPGCONST int rot_reciprocal[][3][3],
440                                         const int mesh[3],
441                                         const int is_shift[3],
442                                         const int bz_map[]);
443 
444 /* Grid addresses are relocated inside Brillouin zone. */
445 /* Number of ir-grid-points inside Brillouin zone is returned. */
446 /* It is assumed that the following arrays have the shapes of */
447 /*   bz_grid_address[prod(mesh + 1)][3] */
448 /*   bz_map[prod(mesh * 2)] */
449 /* where grid_address[prod(mesh)][3]. */
450 /* Each element of grid_address is mapped to each element of */
451 /* bz_grid_address with keeping element order. bz_grid_address has */
452 /* larger memory space to represent BZ surface even if some points */
453 /* on a surface are translationally equivalent to the other points */
454 /* on the other surface. Those equivalent points are added successively */
455 /* as grid point numbers to bz_grid_address. Those added grid points */
456 /* are stored after the address of end point of grid_address, i.e. */
457 /*                                                                       */
458 /* |-----------------array size of bz_grid_address---------------------| */
459 /* |--grid addresses similar to grid_address--|--newly added ones--|xxx| */
460 /*                                                                       */
461 /* where xxx means the memory space that may not be used. Number of grid */
462 /* points stored in bz_grid_address is returned. */
463 /* bz_map is used to recover grid point index expanded to include BZ */
464 /* surface from grid address. The grid point indices are mapped to */
465 /* (mesh[0] * 2) x (mesh[1] * 2) x (mesh[2] * 2) space (bz_map). */
466 int spg_relocate_BZ_grid_address(int bz_grid_address[][3],
467                                  int bz_map[],
468                                  SPGCONST int grid_address[][3],
469                                  const int mesh[3],
470                                  SPGCONST double rec_lattice[3][3],
471                                  const int is_shift[3]);
472 
473 void spg_get_neighboring_grid_points(int relative_grid_points[],
474                                      const int grid_point,
475                                      SPGCONST int relative_grid_address[][3],
476                                      const int num_relative_grid_address,
477                                      const int mesh[3],
478                                      SPGCONST int bz_grid_address[][3],
479                                      const int bz_map[]);
480 
481 /*--------*/
482 /* Niggli */
483 /*--------*/
484 /* Return 0 if failed */
485 int spg_niggli_reduce(double lattice[3][3], const double symprec);
486 
487 #ifdef __cplusplus
488 }
489 #endif
490 #endif
491