1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include "openmx_common.h"
5 #include "mpi.h"
6
7
8 #define debug 0 /* ??? */
9 #define debug1 0 /* for general verbose output */
10 #define debug2 0 /* for symmetry with atomic arrangement */
11 #define debug3 0 /* for lattice vector symmetry */
12 #define debug4 0 /* for generating k points */
13 #define debug5 0 /* open the files for comparision */
14 double pi,smallvalue;
15
16 void MP_Special_Kpt(/* input */
17 int atom_num, /* Number of total atoms in cell. Read from OpenMX */
18 int atom_type, /* Number of elements in cell. Read from OpenMX */
19 /* Lattice vectors. Read from openMX
20 VectorA --> Read_in_Lattice[0][0:2]
21 VectorB --> Read_in_Lattice[1][0:2]
22 VectorC --> Read_in_Lattice[2][0:2]
23 */
24 double **Read_in_Lattice,
25 double **Read_in_Atom_Pos,
26 int inversion_flag,
27 int knum_i, int knum_j, int knum_k, /* number of k-points along a,b,c-axis */
28 int *Read_in_Species
29 /* implicit output
30 num_non_eq_kpt,
31 NE_KGrids1, NE_KGrids2, NE_KGrids3,
32 NE_T_k_op */ );
33
34
35
36 double Cal_Cell_Volume(double **lattice_vector);
37 void Cal_Reciprocal_Vectors(double **latt_vec, double **rec_latt_vec);
38 void Symmetry_Operation_Transform(int ***InputSymop, int ***OutputSymop, int op_num,
39 double **In_Lattice, double **Out_Lattice);
40 void Chk_Shorter_Lattice_Vector(double **rlatt);
41 int Bravais_Type(double **lattice_vector,double *cell_parameters);
42 int Finding_Bravais_Lattice_Type(double **lattice_vector, double *cell_parameters);
43 void Matrix_Copy23(int **source,int n_source,int ***symop, int k_symop);
44 void Matrix_Copy32(int **target,int n_target,int ***symop, int k_symop);
45 void Matrix_Copy22(int **source,int **target, int dim);
46 int Matrix_Equal(int **m1, int **m2, int dim);
47 void Matrix_Productor(int dim, int **m1, int **m2, int **pro);
48 int Symmtry_Operator_Generation(int ***symgen,int gen_num,int ***symop);
49 int Bravais_Lattice_Symmetry(int bravais_type, int ***symop);
50 void Ascend_Ordering(double *xyz_value, int *ordering, int tot_atom);
51 void Ordering_Atomic_Position(double **atomic_position, int start_atom_indx, int end_atom_indx);
52 int Chk_Pure_Point_Group_Op(int **exop, double **atomic_position, int *atom_species,
53 int atom_num, int atom_type, double *trans_vec);
54 void Get_Symmetry_Operation(int ***symop, int *opnum, double **atomic_position, int *atom_species,
55 int atom_num, int atom_type, int *num_pnt_op, double **trans_op_vec);
56 int Chk_Primitive_Cell(int bravais_type, double *cell_parameters, double **lattice_vector,
57 double **atomic_position, int *atom_species,int atom_num, int atom_type,
58 double **platt, double **ptran_vec, double *pcell_parameters,int *npcell);
59 int Generate_MP_Special_Kpt(int knum_i, int knum_j, int knum_k, int ***sym_op, int op_num,
60 int ***pureGsym, int pureG_num, double *shift,
61 double *KGrids1, double *KGrids2, double *KGrids3, int *T_k_op);
62 void Atomic_Coordinates_Transform(double **Read_in_Atom_Pos, double **atomic_position, int atom_num,
63 double **Read_in_Lattice, double **lattice_vector);
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Generating_MP_Special_Kpt(int atomnum,int SpeciesNum,double tv[4][4],double ** Gxyz,double * InitN_USpin,double * InitN_DSpin,double criterion_geo,int SpinP_switch,int * WhatSpecies,int knum_i,int knum_j,int knum_k)78 void Generating_MP_Special_Kpt(/* input */
79 int atomnum,
80 int SpeciesNum,
81 double tv[4][4],
82 double **Gxyz,
83 double *InitN_USpin,
84 double *InitN_DSpin,
85 double criterion_geo,
86 int SpinP_switch,
87 int *WhatSpecies,
88 int knum_i, int knum_j, int knum_k
89 /* implicit output
90 num_non_eq_kpt,
91 NE_KGrids1, NE_KGrids2, NE_KGrids3,
92 NE_T_k_op */ )
93 {
94 int i,j,k,wan;
95 int myid,numprocs;
96 int MG_SpeciesNum;
97 int *MG_WhatSpecies;
98 int inversion_flag;
99 double **Read_in_Lattice;
100 double **Read_in_Atom_Pos, **rlatt;
101 int *Read_in_Species;
102 int *check_flag;
103
104 /***************************************************************
105 print stdout
106 ***************************************************************/
107
108 /* MPI */
109 MPI_Comm_size(MPI_COMM_WORLD1,&numprocs);
110 MPI_Comm_rank(MPI_COMM_WORLD1,&myid);
111
112 if (myid==Host_ID){
113 printf("\n");
114 printf("*******************************************************\n");
115 printf(" Generation of Monkhorst-Pack k-points\n");
116 printf("*******************************************************\n\n");
117 }
118
119 /***************************************************************
120 allocation of arrays
121 ***************************************************************/
122
123 Read_in_Atom_Pos = (double**)malloc(sizeof(double*)*(atomnum+1));
124 for (i=0; i<(atomnum+1); i++){
125 Read_in_Atom_Pos[i] = (double*)malloc(sizeof(double)*3);
126 }
127
128 Read_in_Lattice = (double**)malloc(sizeof(double*)*3);
129 for(i=0; i<3; i++){
130 Read_in_Lattice[i]=(double*)malloc(sizeof(double)*3);
131 }
132
133 rlatt = (double**)malloc(sizeof(double*)*3);
134 for(i=0; i<3; i++){
135 rlatt[i]=(double*)malloc(sizeof(double)*3);
136 }
137
138 /* set inversion_flag */
139
140 inversion_flag = (int)(0*(SpinP_switch==0 || SpinP_switch==1)+(SpinP_switch==3));
141
142 /* copy tv to Read_in_Lattice */
143
144 for (i=0; i<3; i++){
145 for (j=0; j<3; j++){
146 Read_in_Lattice[i][j] = tv[i+1][j+1];
147 rlatt[i][j]=0.0;
148 }
149 }
150
151 /* calculation of reciprocal lattice vectors */
152
153 pi=PI;
154 Cal_Reciprocal_Vectors(Read_in_Lattice, rlatt);
155
156 for(i=0;i<3;i++){
157 rlatt[i][0]=rlatt[i][0]/2.0/pi;
158 rlatt[i][1]=rlatt[i][1]/2.0/pi;
159 rlatt[i][2]=rlatt[i][2]/2.0/pi;
160 }
161
162 if(debug1==1){
163 printf("Reciprocal lattice:\n");
164 for(i=0;i<3;i++){
165 printf("K%1d (%10.5f, %10.5f, %10.5f)\n",i+1,rlatt[i][0],rlatt[i][1],rlatt[i][2]);
166 }
167 }
168
169 /***************************************************************
170 redefinition of species by considering magnetic structure
171 ***************************************************************/
172
173 /* non-magnetic case */
174
175 if (SpinP_switch==0){
176
177 MG_WhatSpecies = (int*)malloc(sizeof(int)*(atomnum+1));
178 MG_SpeciesNum = SpeciesNum;
179 Read_in_Species = (int*)malloc(sizeof(int)*(MG_SpeciesNum+1));
180
181 for (i=1; i<=atomnum; i++){
182 MG_WhatSpecies[i] = WhatSpecies[i];
183 }
184 }
185
186 /* collinear magnetic case */
187 else if (SpinP_switch==1){
188
189 /* allocation of array */
190
191 MG_WhatSpecies = (int*)malloc(sizeof(int)*(atomnum+1));
192
193 check_flag = (int*)malloc(sizeof(int)*(atomnum+1));
194 for (i=1; i<=atomnum; i++) check_flag[i] = 0;
195
196 k = 0;
197
198 for (i=1; i<=atomnum; i++){
199
200 if (check_flag[i]==0){
201
202 wan = WhatSpecies[i];
203 MG_WhatSpecies[i] = k;
204 check_flag[i] = 1;
205
206 for (j=i+1; j<=atomnum; j++){
207
208 if ( check_flag[j]==0
209 &&
210 WhatSpecies[j]==wan
211 &&
212 (criterion_geo>fabs(InitN_USpin[i]-InitN_USpin[j]))
213 &&
214 (criterion_geo>fabs(InitN_DSpin[i]-InitN_DSpin[j]))
215 )
216 {
217 MG_WhatSpecies[j] = k;
218 check_flag[j] = 1;
219 }
220 }
221
222 k++;
223 }
224 }
225
226 MG_SpeciesNum = k;
227 Read_in_Species = (int*)malloc(sizeof(int)*(MG_SpeciesNum+1));
228
229 /* freeing of array */
230 free(check_flag);
231 }
232
233 /* non-collinear magnetic case */
234 else if (SpinP_switch==3){
235
236 MG_WhatSpecies = (int*)malloc(sizeof(int)*(atomnum+1));
237 MG_SpeciesNum = atomnum;
238 Read_in_Species = (int*)malloc(sizeof(int)*(MG_SpeciesNum+1));
239
240 for (i=1; i<=atomnum; i++){
241 MG_WhatSpecies[i] = i-1;
242 }
243 }
244
245 /*
246 printf("MG_SpeciesNum=%2d\n",MG_SpeciesNum);
247 for (i=1; i<=atomnum; i++){
248 printf("i=%3d MG_WhatSpecies=%3d\n",i,MG_WhatSpecies[i]);
249 }
250 */
251
252 /***************************************************************
253 copy tv to Read_in_Lattice
254 ***************************************************************/
255
256 k = 0;
257 for (i=0; i<MG_SpeciesNum; i++){
258 for (j=1; j<=atomnum; j++){
259
260 wan = MG_WhatSpecies[j];
261
262 if (wan==i){
263 Read_in_Atom_Pos[k][0] = Gxyz[j][1]*rlatt[0][0]+Gxyz[j][2]*rlatt[0][1]+Gxyz[j][3]*rlatt[0][2];
264 Read_in_Atom_Pos[k][1] = Gxyz[j][1]*rlatt[1][0]+Gxyz[j][2]*rlatt[1][1]+Gxyz[j][3]*rlatt[1][2];
265 Read_in_Atom_Pos[k][2] = Gxyz[j][1]*rlatt[2][0]+Gxyz[j][2]*rlatt[2][1]+Gxyz[j][3]*rlatt[2][2];
266 k++;
267 }
268 }
269
270 Read_in_Species[i] = k;
271 }
272
273 if(debug3==1){
274 for(i=0;i<MG_SpeciesNum;i++){
275 if(i==0){
276 k=0;
277 }else{
278 k=Read_in_Species[i-1];
279 }
280 for(j=k;j<Read_in_Species[i];j++){
281 printf("Species %2d (%10.5f,%10.5f,%10.5f)\n",i,Read_in_Atom_Pos[j][0],Read_in_Atom_Pos[j][1],Read_in_Atom_Pos[j][2]);
282 }
283 }
284 }
285
286 /***************************************************************
287 call Generating_MP_Special_Kpt
288 ***************************************************************/
289
290 smallvalue = criterion_geo;
291 MP_Special_Kpt(/* input */
292 atomnum,
293 MG_SpeciesNum,
294 Read_in_Lattice,
295 Read_in_Atom_Pos,
296 inversion_flag,
297 knum_i,knum_j,knum_k,
298 Read_in_Species
299 /* implicit output
300 num_non_eq_kpt,
301 NE_KGrids1, NE_KGrids2, NE_KGrids3,
302 NE_T_k_op */ );
303
304 /***************************************************************
305 freeing of arrays
306 ***************************************************************/
307
308 free(Read_in_Species);
309 free(MG_WhatSpecies);
310
311 for (i=0; i<(atomnum+1); i++){
312 free(Read_in_Atom_Pos[i]);
313 }
314 free(Read_in_Atom_Pos);
315
316 for(i=0; i<3; i++){
317 free(rlatt[i]);
318 }
319 free(rlatt);
320
321 for(i=0; i<3; i++){
322 free(Read_in_Lattice[i]);
323 }
324 free(Read_in_Lattice);
325
326
327 }
328
329
330
331
MP_Special_Kpt(int atom_num,int atom_type,double ** Read_in_Lattice,double ** Read_in_Atom_Pos,int inversion_flag,int knum_i,int knum_j,int knum_k,int * Read_in_Species)332 void MP_Special_Kpt(/* input */
333 int atom_num, /* Number of total atoms in cell. Read from OpenMX */
334 int atom_type, /* Number of elements in cell. Read from OpenMX */
335 /* Lattice vectors. Read from openMX
336 VectorA --> Read_in_Lattice[0][0:2]
337 VectorB --> Read_in_Lattice[1][0:2]
338 VectorC --> Read_in_Lattice[2][0:2]
339 */
340 double **Read_in_Lattice,
341 double **Read_in_Atom_Pos,
342 int inversion_flag,
343 int knum_i, int knum_j, int knum_k, /* number of k-points along a,b,c-axis */
344 int *Read_in_Species
345 /* implicit output
346 num_non_eq_kpt,
347 NE_KGrids1, NE_KGrids2, NE_KGrids3,
348 NE_T_k_op */ )
349 {
350 /* matrix for symmetry operation.
351 rsym_op is for storing crystal symmetry operation matrix defined in original lattice vectors space
352 Gsym_op is for those defined in reciprocal space of original lattice vectors
353 pureGsys is for those from puer reciprocal lattice vectors
354 ksym_op is the symmetry operation matrix in reciprocal space including time-inversion symmetry.
355 sym_op is for temporary storage.
356 */
357 int ***sym_op, ***rsym_op, ***Gsym_op, ***pureGsym, ***ksym_op;
358 /* number of symmetry operation matrix */
359 int op_num, op_num_max, op_num_original, ksym_num, pureG_num;
360 /* number of pure point group operation matrix */
361 int num_pure_pnt_op;
362 /* Translation operation vectors associated with pure point group operation found from
363 real crystal structure
364 */
365 double **trans_op_vec;
366 /* for detecting and applying inversion symmetry */
367 int inversion_sym, **inv, **tmpsym, **tmpisym;
368
369 /* The following is defined to read VASP files and do comparision*/
370 int ***vasp_symop;
371 int vasp_opnum;
372 double **vasp_transopvec;
373 int vasp_numpurepntop;
374 int opok,transok;
375 int kopen,iopen,jopen;
376
377
378 /* total number of non-equivalent k points. Return to openMX */
379 int kpt_num;
380 /* coordinates of non-equivalent k points. Return to openMX */
381 /*
382 double *KGrids1, *KGrids2, *KGrids3;
383 */
384 /* T_k_op is weight of each non-equivalent k point. Return to openMX */
385 /*
386 int *T_k_op;
387 */
388
389 int *tmpWeight;
390
391 int shift_keep;/* shift is for shifting of k points */
392 /* Temporary array used for generating k points*/
393 double *tmpK1,*tmpK2,*tmpK3;
394 double ktmp[3], kx, ky, kz, shift[3], tmp_shift[3];
395
396 /* rlatt is used for reciprocal lattice vector.
397 platt is used for primitive unit cell vector
398 lattice_vector is used for storing the interchanged
399 or updated lattice vectors after identifying its
400 bravaise lattice type. */
401 double **rlatt, **platt, **lattice_vector, **klatt;
402
403 /* bravais_type is the Bravais lattice type of inputted lattice vectors
404 pcell_brav is the primitive uint cell's bravais lattice type. */
405 int bravais_type, pcell_brav;
406 /* Number of primitive unit cell contained in the original lattice */
407 int npcell;
408 /*cell_parameters is for unit cell's lattice parameters:
409 cell_parameters[0] length of a vector
410 cell_parameters[1] length of b vector
411 cell_parameters[2] length of c vector
412 cell_parameters[3] angle between b and c vector in radian (alpha)
413 cell_parameters[4] angle between a and c vector in radian (beta)
414 cell_parameters[5] angle between a and b vector in radian (gamma)
415 pcell_parameters is for primitive cell parameters.
416 */
417 double pcell_parameters[6], cell_parameters[6];
418 /* volume of unit cell */
419 double cell_vol;
420 /* Used when trying to find the primitive unit cell.
421 It has the same structure as atomic_position while
422 it is 2 elements larger.
423 */
424 double **ptran_vec;
425 /* Temporary array used for finding lattice type and primitive unit cell */
426 double con_cell[6], cos1,cos2,cos3;
427
428
429 /* Read_in_Atom_Pos: Atomic postions in crystal structure read from openMX.
430 These corrdinats are supposed to be in fractional coordinates and all atoms
431 of same elements should be stored successively. The last atom of each element
432 is indicated by Read_in_Species array.
433 The map is as follwoing:
434 atom index x,y,z
435 | |
436 | |
437 \|/ \|/
438 Read_in_Atom_Pos[atom0_of_element_0][0:2]
439 Read_in_Atom_Pos[atom1_of_element_0][0:2]
440 Read_in_Atom_Pos[atom2_of_element_0][0:2]
441 Read_in_Atom_Pos[atom0_of_element_1][0:2] <--- Read_in_Species[element0]
442 Read_in_Atom_Pos[atom1_of_element_1][0:2]
443 Read_in_Atom_Pos[atom2_of_element_1][0:2]
444 Read_in_Atom_Pos[atom3_of_element_1][0:2]
445 Read_in_Atom_Pos[atom0_of_element_2][0:2] <--- Read_in_Species[element1]
446 Read_in_Atom_Pos[atom1_of_element_2][0:2]
447
448 */
449
450 /* atomic_position[atom_indx][0:2] coordinates of atom with index as atom_indx. */
451 double **atomic_position;
452 /* This array stores the atomic index of different species in atomic_position array.
453 Atoms of element 0 is stored with index from 0 to atom_species[0]-1 in atomic_position[atom_indx][3].
454 Atoms of element 1 is stored from atom_species[0] to atom_species[1]-1
455 Atoms of element i is stored from atom_species[i-1] to atom_species[i]-1.
456 Atoms with atom_indx equal to j can be termined to be element i as following:
457 Searching atom_species[] array, if atom_species[i-1]< j+1 <=atom_species[i], then this
458 atom belongs to species i
459 */
460 int *atom_species;
461 /* Temporary used variables */
462 int i,j,k,r,p,s;
463 int whetherNonEquiv;
464 char c;
465 FILE *fp;
466 int myid,numprocs;
467
468 /* MPI */
469 MPI_Comm_size(mpi_comm_level1,&numprocs);
470 MPI_Comm_rank(mpi_comm_level1,&myid);
471
472 pi=PI;
473
474 lattice_vector=(double**)malloc(sizeof(double*)*3);
475 rlatt=(double**)malloc(sizeof(double*)*3);
476 platt=(double**)malloc(sizeof(double*)*3);
477 klatt=(double**)malloc(sizeof(double*)*3);
478 for(i=0;i<3;i++){
479 lattice_vector[i]=(double*)malloc(sizeof(double)*3);
480 platt[i]=(double*)malloc(sizeof(double)*3);
481 rlatt[i]=(double*)malloc(sizeof(double)*3);
482 klatt[i]=(double*)malloc(sizeof(double)*3);
483 }
484
485 op_num_max = 48;
486
487 sym_op = (int***)malloc(sizeof(int**)*op_num_max);
488 for(k=0; k<op_num_max; k++){
489 sym_op[k] = (int**)malloc(sizeof(int*)*3);
490 for(i=0; i<3; i++){
491 sym_op[k][i] = (int*)malloc(sizeof(int)*3);
492 for(j=0; j<3; j++) sym_op[k][i][j] = 0;
493 }
494 }
495
496 pureGsym = (int***)malloc(sizeof(int**)*op_num_max);
497 for(k=0; k<op_num_max; k++){
498 pureGsym[k] = (int**)malloc(sizeof(int*)*3);
499 for(i=0; i<3; i++){
500 pureGsym[k][i] = (int*)malloc(sizeof(int)*3);
501 for(j=0; j<3; j++) pureGsym[k][i][j] = 0;
502 }
503 }
504
505 trans_op_vec = (double**)malloc(sizeof(double*)*op_num_max);
506 for(k=0; k<op_num_max; k++){
507 trans_op_vec[k]=(double*)malloc(sizeof(double)*3);
508 for(i=0; i<3; i++) trans_op_vec[k][i] = 0.0;
509 }
510
511 if(atom_num<atom_type){
512 printf("Error!\nAtomic number should not be smaller than atomic species number.\n");
513 return;
514 }
515
516 atomic_position = (double**)malloc(sizeof(double*)*(atom_num+2));
517 for(k=0; k<(atom_num+2); k++){
518 atomic_position[k] = (double*)malloc(sizeof(double)*3);
519 for(i=0; i<3; i++) atomic_position[k][i] = 0.0;
520 }
521
522 ptran_vec=(double**)malloc(sizeof(double*)*(atom_num+2));
523 for(k=0; k<(atom_num+2); k++){
524 ptran_vec[k]=(double*)malloc(sizeof(double)*3);
525 for(i=0; i<3; i++) ptran_vec[k][i] = 0.0;
526 }
527
528 atom_species=(int*)malloc(sizeof(int)*atom_type);
529 for(i=0; i<atom_type; i++) atom_species[i]=0;
530
531 for(i=0;i<atom_num;i++){
532 for(j=0;j<3;j++){
533 atomic_position[i][j]=Read_in_Atom_Pos[i][j];
534 }
535 }
536
537 for(i=0;i<atom_type;i++){
538 atom_species[i]=Read_in_Species[i];
539 }
540
541 /*******************************************
542 for debugging
543 *******************************************/
544
545 if (debug5){
546
547 r=15;
548 switch(r){
549 case 1:
550 /* sc */
551 Read_in_Lattice[0][0]=1.0; Read_in_Lattice[0][1]=0.0; Read_in_Lattice[0][2]=0.0;
552 Read_in_Lattice[1][0]=0.0; Read_in_Lattice[1][1]=1.0; Read_in_Lattice[1][2]=0.0;
553 Read_in_Lattice[2][0]=0.0; Read_in_Lattice[2][1]=0.0; Read_in_Lattice[2][2]=1.0;
554 if((fp=fopen("sc.dat","wt"))==NULL){
555 printf("Error in open file\n");
556 return;
557 }
558 break;
559 case 2:
560 /*bcc */
561 Read_in_Lattice[0][0]=-0.5; Read_in_Lattice[0][1]=0.5; Read_in_Lattice[0][2]=0.5;
562 Read_in_Lattice[1][0]=0.5; Read_in_Lattice[1][1]=-0.5; Read_in_Lattice[1][2]=0.5;
563 Read_in_Lattice[2][0]=0.5; Read_in_Lattice[2][1]=0.5; Read_in_Lattice[2][2]=-0.5;
564 if((fp=fopen("bcc.dat","wt"))==NULL){
565 printf("Error in open file\n");
566 return;
567 }
568 break;
569 case 3:
570 /* fcc */
571 Read_in_Lattice[0][0]=0.0; Read_in_Lattice[0][1]=1.5; Read_in_Lattice[0][2]=1.5;
572 Read_in_Lattice[1][0]=1.5; Read_in_Lattice[1][1]=0.0; Read_in_Lattice[1][2]=1.5;
573 Read_in_Lattice[2][0]=1.5; Read_in_Lattice[2][1]=1.5; Read_in_Lattice[2][2]=0.0;
574 if((fp=fopen("fcc.dat","wt"))==NULL){
575 printf("Error in open file\n");
576 return;
577 }
578 break;
579 case 4:
580 /* hP */
581 Read_in_Lattice[0][0]=1.0; Read_in_Lattice[0][1]=-1.0; Read_in_Lattice[0][2]=0.0;
582 Read_in_Lattice[1][0]=-1.0; Read_in_Lattice[1][1]=0.0; Read_in_Lattice[1][2]=1.0;
583 Read_in_Lattice[2][0]=-1.0; Read_in_Lattice[2][1]=-1.0; Read_in_Lattice[2][2]=-1.0;
584 if((fp=fopen("hP.dat","wt"))==NULL){
585 printf("Error in open file\n");
586 return;
587 }
588 break;
589 case 5:
590 /* tP */
591 Read_in_Lattice[0][0]=1.0; Read_in_Lattice[0][1]=0.0; Read_in_Lattice[0][2]=0.0;
592 Read_in_Lattice[1][0]=0.0; Read_in_Lattice[1][1]=1.0; Read_in_Lattice[1][2]=0.0;
593 Read_in_Lattice[2][0]=0.0; Read_in_Lattice[2][1]=0.0; Read_in_Lattice[2][2]=2.0;
594 if((fp=fopen("tP.dat","wt"))==NULL){
595 printf("Error in open file\n");
596 return;
597 }
598 break;
599 case 6:
600 /* tI */
601 Read_in_Lattice[0][0]=-0.5; Read_in_Lattice[0][1]=0.5; Read_in_Lattice[0][2]=1.0;
602 Read_in_Lattice[1][0]=0.5; Read_in_Lattice[1][1]=-0.5; Read_in_Lattice[1][2]=1.0;
603 Read_in_Lattice[2][0]=0.5; Read_in_Lattice[2][1]=0.5; Read_in_Lattice[2][2]=-1.0;
604 if((fp=fopen("tI.dat","wt"))==NULL){
605 printf("Error in open file\n");
606 return;
607 }
608 break;
609 case 7:
610 /* hR */
611 Read_in_Lattice[0][0]=0.7848063699; Read_in_Lattice[0][1]=0.2957148683; Read_in_Lattice[0][2]=0.544639035;
612 Read_in_Lattice[1][0]=0.0; Read_in_Lattice[1][1]=0.8386705679; Read_in_Lattice[1][2]=0.544639035;
613 Read_in_Lattice[2][0]=0.0; Read_in_Lattice[2][1]=0.0; Read_in_Lattice[2][2]=1.0;
614 if((fp=fopen("hR.dat","wt"))==NULL){
615 printf("Error in open file\n");
616 return;
617 }
618 break;
619 case 8:
620 /* oP */
621 Read_in_Lattice[0][0]=4.0; Read_in_Lattice[0][1]=0.0; Read_in_Lattice[0][2]=0.0;
622 Read_in_Lattice[1][0]=0.0; Read_in_Lattice[1][1]=2.0; Read_in_Lattice[1][2]=0.0;
623 Read_in_Lattice[2][0]=0.0; Read_in_Lattice[2][1]=0.0; Read_in_Lattice[2][2]=3.0;
624
625 if((fp=fopen("oP.dat","wt"))==NULL){
626 printf("Error in open file\n");
627 return;
628 }
629 break;
630 case 9:
631 /* oI */
632 Read_in_Lattice[0][0]=-0.5; Read_in_Lattice[0][1]=1.0; Read_in_Lattice[0][2]=1.5;
633 Read_in_Lattice[1][0]=0.5; Read_in_Lattice[1][1]=-1.0; Read_in_Lattice[1][2]=1.5;
634 Read_in_Lattice[2][0]=0.5; Read_in_Lattice[2][1]=1.0; Read_in_Lattice[2][2]=-1.5;
635 if((fp=fopen("oI.dat","wt"))==NULL){
636 printf("Error in open file\n");
637 return;
638 }
639 break;
640 case 10:
641 /* oF */
642 Read_in_Lattice[0][0]=0.0; Read_in_Lattice[0][1]=1.0; Read_in_Lattice[0][2]=1.5;
643 Read_in_Lattice[1][0]=0.5; Read_in_Lattice[1][1]=0.0; Read_in_Lattice[1][2]=1.5;
644 Read_in_Lattice[2][0]=0.5; Read_in_Lattice[2][1]=1.0; Read_in_Lattice[2][2]=0.0;
645 if((fp=fopen("oF.dat","wt"))==NULL){
646 printf("Error in open file\n");
647 return;
648 }
649 break;
650 case 11:
651 /* oC */
652 Read_in_Lattice[0][0]=1.5; Read_in_Lattice[0][1]=1.0; Read_in_Lattice[0][2]=0.0;
653 Read_in_Lattice[1][0]=-1.5; Read_in_Lattice[1][1]=1.0; Read_in_Lattice[1][2]=0.0;
654 Read_in_Lattice[2][0]=0.0; Read_in_Lattice[2][1]=0.0; Read_in_Lattice[2][2]=3.0;
655 if((fp=fopen("oC.dat","wt"))==NULL){
656 printf("Error in open file\n");
657 return;
658 }
659 break;
660 case 12:
661 /* mP */
662 Read_in_Lattice[0][0]=1.0; Read_in_Lattice[0][1]=-0.5; Read_in_Lattice[0][2]=0.0;
663 Read_in_Lattice[1][0]=-0.2; Read_in_Lattice[1][1]=2.0; Read_in_Lattice[1][2]=0.0;
664 Read_in_Lattice[2][0]=0.0; Read_in_Lattice[2][1]=0.0; Read_in_Lattice[2][2]=3.0;
665 if((fp=fopen("mP.dat","wt"))==NULL){
666 printf("Error in open file\n");
667 return;
668 }
669 break;
670 case 13:
671 /* mB */
672 Read_in_Lattice[0][0]=0.0; Read_in_Lattice[0][1]=1.0; Read_in_Lattice[0][2]=-1.5;
673 Read_in_Lattice[1][0]=0.0; Read_in_Lattice[1][1]=1.0; Read_in_Lattice[1][2]=1.5;
674 Read_in_Lattice[2][0]=0.9993908270; Read_in_Lattice[2][1]=-0.0348994967; Read_in_Lattice[2][2]=0.0;
675 if((fp=fopen("mB.dat","wt"))==NULL){
676 printf("Error in open file\n");
677 return;
678 }
679 break;
680 case 14:
681 /* aP triclinic */
682 Read_in_Lattice[0][0]= 0.7546287487; Read_in_Lattice[0][1]=-0.1317556090; Read_in_Lattice[0][2]= 0.6427876097;
683 Read_in_Lattice[1][0]= 0.7546287487; Read_in_Lattice[1][1]= 1.3309517942; Read_in_Lattice[1][2]=-0.9932156702;
684 Read_in_Lattice[2][0]=-0.7546287487; Read_in_Lattice[2][1]= 1.5944630122; Read_in_Lattice[2][2]= 0.7212091104;
685
686 if((fp=fopen("aP.dat","wt"))==NULL){
687 printf("Error in open file\n");
688 return;
689 }
690 break;
691 default:
692 if((fp=fopen("sym.dat","wt"))==NULL){
693 printf("Error in open file\n");
694 return;
695 }
696 break;
697 }/*End of swich bravais_type and initialize Read_in_Lattice */
698
699 /*******************************************
700 for debugging
701 *******************************************/
702 }
703
704
705 /* First step: Determin the bravais lattice type*/
706 /* Using lattice_vector instead of original one, since lattice_vector
707 would be changed according to convential choice of lattice vectors */
708 for(i=0;i<3;i++){
709 for(j=0;j<3;j++){
710 lattice_vector[i][j]=Read_in_Lattice[i][j];
711 }
712 }
713 for(i=0;i<6;i++){
714 cell_parameters[i]=0.0;
715 pcell_parameters[i]=0.0;
716 }
717 bravais_type=Finding_Bravais_Lattice_Type(lattice_vector,cell_parameters);
718
719 if (myid==Host_ID){
720
721 switch(bravais_type){
722 case 1:
723 /* sc */
724 printf(" Found a simple cubic lattice.\n");
725 break;
726 case 2:
727 /*bcc */
728 printf(" Found a body-centered cubic lattice.\n");
729 break;
730 case 3:
731 /* fcc */
732 printf(" Found a face-centered cubic lattice.\n");
733 break;
734 case 4:
735 /* hP */
736 printf(" Found a primitive hexagonal lattice.\n");
737 break;
738 case 5:
739 /* tP */
740 printf(" Found a primitive tetragonal lattice.\n");
741 break;
742 case 6:
743 /* tI */
744 printf(" Found a body-centered tetragonal lattice.\n");
745 break;
746 case 7:
747 /* hR */
748 printf(" Found a rhombohedral lattice.\n");
749 break;
750 case 8:
751 /* oP */
752 printf(" Found a primitive orthorhombic lattice.\n");
753 break;
754 case 9:
755 /* oI */
756 printf(" Found a body-centered orthorhombic lattice.\n");
757 break;
758 case 10:
759 /* oF */
760 printf(" Found a face-centered orthorhombic lattice.\n");
761 break;
762 case 11:
763 /* oC */
764 printf(" Found a base-centered orthorhombic lattice.\n");
765 break;
766 case 12:
767 /* mP */
768 printf(" Found a primitive monoclinic lattice.\n");
769 break;
770 case 13:
771 /* mB */
772 printf(" Found a base-centered monoclinic lattice.\n");
773 break;
774 case 14:
775 /* aP triclinic */
776 printf(" Found a primitive triclinic lattice.\n");
777 break;
778 }
779
780 printf(" Lattice parameters are:\n");
781 for(i=0;i<6;i++){
782 if(cell_parameters[i]!=0.0){
783 if(i==0){
784 printf(" a=%10.5f\n",cell_parameters[i]);
785 }else if(i==1){
786 printf(" b/a=%10.5f\n",cell_parameters[i]);
787 }else if(i==2){
788 printf(" c/a=%10.5f\n",cell_parameters[i]);
789 }else{
790 if(fabs(cos(cell_parameters[i]))>smallvalue){
791 if(i==3){
792 printf(" Alpha is %10.5f and cos(Alpha) is %10.5f.\n",cell_parameters[i]/pi*180.0,cos(cell_parameters[i]));
793 }else if(i==4){
794 printf(" Beta is %10.5f and cos(Beta) is %10.5f.\n",cell_parameters[i]/pi*180.0,cos(cell_parameters[i]));
795 }else{
796 printf(" Gamma is %10.5f and cos(Gamma) is %10.5f.\n",cell_parameters[i]/pi*180.0,cos(cell_parameters[i]));
797 }
798 }
799 }
800 }
801 }
802 printf(" Lattice vectors are:\n");
803 for(i=0;i<3;i++){
804 printf(" (%5.2f, %5.2f, %5.2f)\n",lattice_vector[i][0],lattice_vector[i][1],lattice_vector[i][2]);
805 }
806 printf(" The volume of unit cell is %10.5f\n",Cal_Cell_Volume(lattice_vector));
807
808 }
809
810 /*Second(optional):
811 Check whether the inputed unit cell is a primitive cell or not.
812 INPUT
813 bravais_type Bravais lattice type
814 cell_parameters a, b, c length and angles between vectors
815 lattice_vector the original lattice vectors
816 atomic_position the atomic positions transformed from OpenMX
817 atom_species the indicator of last atom's index of each species in atomic_position
818 atom_num number of atoms in atomic_position array
819 atom_type number of species in array atom_species
820
821 OUTPUT
822 platt the primitive lattice vectors founded
823 ptran_vec array to store the translation vectors for each atom
824 pcell_parameters the cell parameters for primitive cell
825 npcell number of primitive cell in cell defined by lattice_vector
826 */
827 pcell_brav=Chk_Primitive_Cell(bravais_type,cell_parameters,Read_in_Lattice,
828 atomic_position,atom_species,atom_num,atom_type,
829 platt,ptran_vec,pcell_parameters,&npcell);
830
831 if (myid==Host_ID){
832
833 printf(" In Chk_Primitive_Cell,\n the found primitive cell is ");
834
835 switch(pcell_brav){
836
837 case 1:
838 /* sc */
839 printf(" a simple cubic lattice.\n");
840 break;
841 case 2:
842 /*bcc */
843 printf(" a body-centered cubic lattice.\n");
844 break;
845 case 3:
846 /* fcc */
847 printf(" a face-centered cubic lattice.\n");
848 break;
849 case 4:
850 /* hP */
851 printf(" a primitive hexagonal lattice.\n");
852 break;
853 case 5:
854 /* tP */
855 printf(" a primitive tetragonal lattice.\n");
856 break;
857 case 6:
858 /* tI */
859 printf(" a body-centered tetragonal lattice.\n");
860 break;
861 case 7:
862 /* hR */
863 printf(" a rhombohedral lattice.\n");
864 break;
865 case 8:
866 /* oP */
867 printf(" a primitive orthorhombic lattice.\n");
868 break;
869 case 9:
870 /* oI */
871 printf(" a body-centered orthorhombic lattice.\n");
872 break;
873 case 10:
874 /* oF */
875 printf(" a face-centered orthorhombic lattice.\n");
876 break;
877 case 11:
878 /* oC */
879 printf(" a base-centered orthorhombic lattice.\n");
880 break;
881 case 12:
882 /* mP */
883 printf(" a primitive monoclinic lattice.\n");
884 break;
885 case 13:
886 /* mB */
887 printf(" a base-centered monoclinic lattice.\n");
888 break;
889 case 14:
890 /* aP triclinic */
891 printf(" a primitive triclinic lattice.\n");
892 break;
893 }
894 printf(" Primitive lattice vectors are:\n");
895 for(i=0;i<3;i++){
896 printf(" P%1d (%10.5f,%10.5f,%10.5f)\n",i+1,platt[i][0],platt[i][1],platt[i][2]);
897 }
898 printf(" There are %2d primitive cells contained in your original cell.\n",npcell);
899
900 }
901
902 /* If the lattice vectors above have been interchanged or modified, the atomic position
903 which stored as fractrion coordinates should also be changed.*/
904 if(debug2==1){
905 printf("Transfer atomic coordinates.\n");
906 printf("Original:\n");
907 for(i=0;i<atom_num;i++){
908 printf("atom%2d %10.5f, %10.5f, %10.5f\n",i+1,Read_in_Atom_Pos[i][0],Read_in_Atom_Pos[i][1],Read_in_Atom_Pos[i][2]);
909 }
910 }
911
912 Atomic_Coordinates_Transform(Read_in_Atom_Pos, atomic_position, atom_num,
913 Read_in_Lattice, lattice_vector);
914
915 if(debug2==1){
916 printf("Transfered:\n");
917 for(i=0;i<atom_num;i++){
918 printf("atom%2d %10.5f, %10.5f, %10.5f\n",i+1,atomic_position[i][0],atomic_position[i][1],atomic_position[i][2]);
919 }
920 }
921
922 /*Bravais_Lattice_Symmetry generates the symmetry operation of the pure bravais lattice determined above,
923 without consideration of actual atomic arrangement (lattice basis)
924 Input
925 bravais_type
926 OUTPUT
927 sym_op symmetry operation matrix
928 op_num number of symmetry operation
929 */
930
931 op_num=Bravais_Lattice_Symmetry(bravais_type,sym_op);
932
933 if (debug5){
934
935 for(k=0;k<op_num;k++){
936 fprintf(fp," openmx %2d\n",k+1);
937 for(i=0;i<3;i++){
938 fprintf(fp," %4d%4d%4d\n",sym_op[k][i][0],sym_op[k][i][1],sym_op[k][i][2]);
939 }
940 }
941 fclose(fp);
942 }
943 if(debug1==1){
944 printf("In subroutine Bravais_Lattice_Symmetry:\n");
945 printf("Totally found %4d symmtry operations\n",op_num);
946 }
947 if(debug1 == 1){
948 for(k=0;k<op_num;k++){
949 for(i=0;i<3;i++){
950 for(j=0;j<3;j++){
951 if(sym_op[k][i][j]!=0){
952 printf(" sym_op[%2d][%1d][%1d]=%2d.0 ;\n",k,i,j,sym_op[k][i][j]);
953 }
954 }
955 }
956 }
957 }
958
959
960 /* Find the possible symmetry operations according to the atomic arrangement
961 (lattic basis, atomic_position) from the pool of symmetry operations
962 (sym_op[op_num][3][3]) found from pure bravais lattice. sym_op matix is changed
963 after Get_Symmetry_Operation. Totally it returns op_num operations while the first
964 num_pure_pnt_op is the pure point symmetry operation. The left are those connected
965 with translation vectors, which are stored in trans_op[op_num-num_pure_pnt_op][3].
966 */
967
968 Get_Symmetry_Operation(sym_op,&op_num,atomic_position,atom_species,atom_num,atom_type,&num_pure_pnt_op,trans_op_vec);
969
970 if(debug3==1){
971 printf("In subroutine Get_Symmetry_Operation:\n");
972 }
973
974 if (myid==Host_ID){
975 printf(" Found allowed symmetry operation number is %2d.\n",op_num);
976 printf(" Among them there are %2d pure point group operations.\n",num_pure_pnt_op);
977 }
978
979 if(debug5){
980 if((fp=fopen("getgrp.dat","wt"))==NULL){
981 printf("Error in open file\n");
982 return;
983 }
984 fprintf(fp,"GETGRP tot number is %2d\n",op_num);
985 fprintf(fp,"GETGRP pure point num %2d\n",num_pure_pnt_op);
986 for(k=0;k<num_pure_pnt_op;k++){
987 for(i=0;i<3;i++){
988 for(j=0;j<3;j++){
989 if(sym_op[k][i][j]!=0){
990 fprintf(fp," purepoint[%2d][%1d][%1d]=%2d.0 ;\n",k,i,j,sym_op[k][i][j]);
991 }
992 }
993 }
994 }
995 }
996
997 if(debug5){
998
999 for(k=num_pure_pnt_op;k<op_num;k++){
1000 for(i=0;i<3;i++){
1001 for(j=0;j<3;j++){
1002 if(sym_op[k][i][j]!=0){
1003 fprintf(fp," space[%2d][%1d][%1d]=%2d.0 ;\n",k,i,j,sym_op[k][i][j]);
1004 }
1005 }
1006 }
1007 fprintf(fp," Translation vector:%10.5f%10.5f%10.5f\n",trans_op_vec[k][0],trans_op_vec[k][1],trans_op_vec[k][2]);
1008 }
1009 fclose(fp);
1010 }
1011
1012 if(debug5){
1013 /* Reading the output from VASP to make comparision */
1014 if((fp=fopen("vasp.dat","rt"))==NULL){
1015 printf("Error in open file\n");
1016 return;
1017 }
1018 fscanf(fp,"%d",&vasp_opnum);
1019 fscanf(fp,"%d",&vasp_numpurepntop);
1020 /* printf("%d\n",vasp_opnum);
1021 printf("%d",vasp_numpurepntop); */
1022
1023 if(vasp_opnum!=op_num){
1024 printf("Different in total operation number. %2d vs. %2d\n",vasp_opnum,op_num);
1025 /* return; */
1026 }
1027 if(vasp_numpurepntop!=num_pure_pnt_op){
1028 printf("Different in pure point group operation number. %2d vs. %2d\n",vasp_numpurepntop,num_pure_pnt_op);
1029 /* return; */
1030 }
1031
1032 vasp_symop=(int***)malloc(sizeof(int**)*vasp_opnum);
1033 vasp_transopvec=(double**)malloc(sizeof(double*)*vasp_opnum);
1034 for(k=0;k<vasp_opnum;k++){
1035 vasp_symop[k]=(int**)malloc(sizeof(int*)*3);
1036 vasp_transopvec[k]=(double*)malloc(sizeof(double)*3);
1037 for(i=0;i<3;i++){
1038 vasp_symop[k][i]=(int*)malloc(sizeof(int)*3);
1039 vasp_transopvec[k][i]=0.0;
1040 }
1041 }
1042 for (k=0; k<vasp_opnum; k++){
1043 for (i=0;i<3;i++){
1044 for (j=0;j<3;j++){
1045 vasp_symop[k][i][j]=0;
1046 }
1047 }
1048 }
1049 /* c=getchar(); */
1050 for(k=0;k<vasp_opnum;k++){
1051 for(i=0;i<3;i++){
1052 fscanf(fp,"%2d%2d%2d",&vasp_symop[k][i][0],&vasp_symop[k][i][1],&vasp_symop[k][i][2]);
1053
1054 }
1055 fscanf(fp,"%lf%lf%lf",&vasp_transopvec[k][0],&vasp_transopvec[k][1],&vasp_transopvec[k][2]);
1056
1057 }
1058 /* after reading, Now comparing */
1059
1060 transok=0;
1061 for(k=0;k<vasp_opnum;k++){/* for each operation from vasp */
1062 for(kopen=0;kopen<vasp_opnum;kopen++){ /*scan those from openMX */
1063 opok=kopen;
1064 for(i=0;i<3;i++){
1065 for(j=0;j<3;j++){
1066 if(vasp_symop[k][i][j]!=sym_op[kopen][i][j]){
1067 opok=-1;/* if there is one element not equal, then non-equal */
1068 }
1069 }
1070 }
1071 if(opok==kopen){
1072 break;
1073 }
1074 }
1075 if(opok!=-1){/* opok remember that equals*/
1076 printf("SYMOP vasp %2d == openMX %d ",k,opok);
1077 if(fabs(vasp_transopvec[k][0]-trans_op_vec[opok][0])<smallvalue
1078 &&fabs(vasp_transopvec[k][1]-trans_op_vec[opok][1])<smallvalue
1079 &&fabs(vasp_transopvec[k][2]-trans_op_vec[opok][2])<smallvalue){
1080 printf("trans vec also equal\n");
1081 }else{
1082 printf("************TRANS VECTOR NOT EQUAL***************\n");
1083 }
1084 }else{
1085 printf("!!!!!!!!!!!!!!!!%2d NO SAME!!!!!!!!!!!\n",k);
1086 }
1087 }/* end comparision */
1088
1089 for(k=0;k<vasp_opnum; k++){
1090 for(i=0; i<3; i++){
1091 free(vasp_symop[k][i]);
1092 }
1093 free(vasp_symop[k]);
1094 free(vasp_transopvec[k]);
1095 }
1096 free(vasp_symop);
1097 free(vasp_transopvec);
1098 } /* end of debug5 */
1099
1100 /* Now, we can generate the k-points and their weights */
1101 kpt_num = 0;
1102
1103 if (myid==Host_ID){
1104 printf(" Sampling grids are %3dx%3dx%3d\n",knum_i, knum_j, knum_k);
1105 }
1106
1107 tmpK1=(double*)malloc(sizeof(double)*(8*knum_i*knum_j*knum_k));
1108 tmpK2=(double*)malloc(sizeof(double)*(8*knum_i*knum_j*knum_k));
1109 tmpK3=(double*)malloc(sizeof(double)*(8*knum_i*knum_j*knum_k));
1110 tmpWeight=(int*)malloc(sizeof(int)*(8*knum_i*knum_j*knum_k));
1111
1112 for(i=0;i<(8*knum_i*knum_j*knum_k);i++){
1113 tmpK1[i]=-1234567;
1114 tmpK2[i]=-1234567;
1115 tmpK3[i]=-1234567;
1116 tmpWeight[i]=0;
1117 }
1118
1119 /* Transfer the symmetry operation into original lattice vector */
1120 /* Here op_num must be equal or smaller than 48*/
1121
1122 op_num_original = op_num;
1123
1124 Gsym_op = (int***)malloc(sizeof(int**)*op_num_original);
1125 for(k=0; k<op_num_original; k++){
1126 Gsym_op[k] = (int**)malloc(sizeof(int*)*3);
1127 for(i=0; i<3; i++){
1128 Gsym_op[k][i] = (int*)malloc(sizeof(int)*3);
1129 for(j=0; j<3; j++) Gsym_op[k][i][j] = 0;
1130 }
1131 }
1132
1133 rsym_op = (int***)malloc(sizeof(int**)*op_num_original);
1134 for(k=0; k<op_num_original; k++){
1135 rsym_op[k] = (int**)malloc(sizeof(int*)*3);
1136 for(i=0; i<3; i++){
1137 rsym_op[k][i] = (int*)malloc(sizeof(int)*3);
1138 for(j=0; j<3; j++) rsym_op[k][i][j] = 0;
1139 }
1140 }
1141
1142 if(debug4==1){
1143 printf("Cryatal Lattice:\n");
1144 for(i=0;i<3;i++){
1145 printf("A%1d (%10.5f, %10.5f, %10.5f)\n",i+1,Read_in_Lattice[i][0],Read_in_Lattice[i][1],Read_in_Lattice[i][2]);
1146 }
1147 }
1148
1149 Symmetry_Operation_Transform(sym_op,rsym_op,op_num,lattice_vector,Read_in_Lattice);
1150
1151 /* The reciprocal lattice vectors */
1152 Cal_Reciprocal_Vectors(Read_in_Lattice, rlatt);
1153 for(i=0;i<3;i++){
1154 rlatt[i][0]=rlatt[i][0]/2.0/pi;
1155 rlatt[i][1]=rlatt[i][1]/2.0/pi;
1156 rlatt[i][2]=rlatt[i][2]/2.0/pi;
1157
1158 klatt[i][0]=rlatt[i][0]/knum_i;
1159 klatt[i][1]=rlatt[i][1]/knum_j;
1160 klatt[i][2]=rlatt[i][2]/knum_k;
1161 }
1162 if(debug1==1){
1163 printf("Reciprocal lattice:\n");
1164 for(i=0;i<3;i++){
1165 printf("K%1d (%10.5f, %10.5f, %10.5f)\n",i+1,rlatt[i][0],rlatt[i][1],rlatt[i][2]);
1166 }
1167 }
1168 if(debug4==1){
1169 printf("Basis of k-points:\n");
1170 for(i=0;i<3;i++){
1171 printf("K%1d (%10.5f, %10.5f, %10.5f)\n",i+1,klatt[i][0],klatt[i][1],klatt[i][2]);
1172 }
1173 }
1174
1175 /* Convert the symmetry operation from real space lattice to reciprocal lattice
1176 And now we have the symmetry operation matrix rsym_op and Gsym_op in both original
1177 real space lattice vectors and reciprocal lattice vectors, respectively.
1178 These symmetry operations are the real crystal structures symmetrical operations.
1179 */
1180 if(debug4==1){
1181 printf("before transfer rsym_op is:\n");
1182 for(k=0;k<op_num;k++){
1183 printf("openmx rsym_op %2d\n",k+1);
1184 printf("%2d %2d %2d \n",rsym_op[k][0][0],rsym_op[k][0][1],rsym_op[k][0][2]);
1185 printf("%2d %2d %2d \n",rsym_op[k][1][0],rsym_op[k][1][1],rsym_op[k][1][2]);
1186 printf("%2d %2d %2d \n",rsym_op[k][2][0],rsym_op[k][2][1],rsym_op[k][2][2]);
1187 }
1188 /* c=getchar(); */
1189 }
1190
1191 Symmetry_Operation_Transform(rsym_op,Gsym_op,op_num,Read_in_Lattice,rlatt);
1192
1193 if(debug4==1){
1194 printf("after transfer Gsym_op is:\n");
1195 for(k=0;k<op_num;k++){
1196 printf("openmx Gsym_op %2d\n",k+1);
1197 printf("%2d %2d %2d \n",Gsym_op[k][0][0],Gsym_op[k][0][1],Gsym_op[k][0][2]);
1198 printf("%2d %2d %2d \n",Gsym_op[k][1][0],Gsym_op[k][1][1],Gsym_op[k][1][2]);
1199 printf("%2d %2d %2d \n",Gsym_op[k][2][0],Gsym_op[k][2][1],Gsym_op[k][2][2]);
1200 }
1201 /* c=getchar(); */
1202 }
1203
1204 for(i=0;i<3;i++){
1205 rlatt[i][0]=rlatt[i][0]/knum_i;
1206 rlatt[i][1]=rlatt[i][1]/knum_j;
1207 rlatt[i][2]=rlatt[i][2]/knum_k;
1208 }
1209
1210 /* Get the lattice type of reciprocal lattice */
1211
1212 bravais_type=Finding_Bravais_Lattice_Type(rlatt,cell_parameters);
1213
1214 /* shift of grids: if total grid numer is even, shift 0.5
1215 if total grid number is odd, no shift
1216 */
1217
1218 shift[0] = 0.0;
1219 shift[1] = 0.0;
1220 shift[2] = 0.0;
1221
1222 shift[0]=shift[0]+0.5*fmod((double)(knum_i+1),2.0);
1223 shift[1]=shift[1]+0.5*fmod((double)(knum_j+1),2.0);
1224 shift[2]=shift[2]+0.5*fmod((double)(knum_k+1),2.0);
1225
1226 Cal_Reciprocal_Vectors(rlatt,platt);
1227 for(i=0;i<3;i++){
1228 platt[i][0]=platt[i][0]/2.0/pi;
1229 platt[i][1]=platt[i][1]/2.0/pi;
1230 platt[i][2]=platt[i][2]/2.0/pi;
1231 }
1232 if(debug4==1){
1233 printf("shift test\n");
1234 for(i=0;i<3;i++){
1235 printf("K%1d (%10.5f, %10.5f, %10.5f)\n",i+1,klatt[i][0],klatt[i][1],klatt[i][2]);
1236 }
1237 for(i=0;i<3;i++){
1238 printf("PINV%1d (%10.5f, %10.5f, %10.5f)\n",i+1,platt[i][0],platt[i][1],platt[i][2]);
1239 }
1240 }
1241 kx=shift[0]*klatt[0][0]+shift[1]*klatt[1][0]+shift[2]*klatt[2][0];
1242 ky=shift[0]*klatt[0][1]+shift[1]*klatt[1][1]+shift[2]*klatt[2][1];
1243 kz=shift[0]*klatt[0][2]+shift[1]*klatt[1][2]+shift[2]*klatt[2][2];
1244 if(debug4==1){
1245 printf("T (%10.5f, %10.5f, %10.5f)\n",kx,ky,kz);
1246 }
1247 tmp_shift[0]=kx*platt[0][0]+ky*platt[0][1]+kz*platt[0][2];
1248 tmp_shift[1]=kx*platt[1][0]+ky*platt[1][1]+kz*platt[1][2];
1249 tmp_shift[2]=kx*platt[2][0]+ky*platt[2][1]+kz*platt[2][2];
1250 if(debug4==1){
1251 printf("tmp shift (%10.5f, %10.5f, %10.5f)\n",tmp_shift[0],tmp_shift[1],tmp_shift[2]);
1252 }
1253 tmp_shift[0]=fmod(tmp_shift[0]+1000.25,1.0)-0.25;
1254 tmp_shift[1]=fmod(tmp_shift[1]+1000.25,1.0)-0.25;
1255 tmp_shift[2]=fmod(tmp_shift[2]+1000.25,1.0)-0.25;
1256
1257 kx=shift[0];ky=shift[1];kz=shift[2];
1258 shift[0]=tmp_shift[0];
1259 shift[1]=tmp_shift[1];
1260 shift[2]=tmp_shift[2];
1261
1262 if(debug4==1){
1263 printf("General checking shift is %10.5f, %10.5f, %10.5f\n",shift[0],shift[1],shift[2]);
1264 }
1265
1266 shift_keep=1;
1267 if( ((fabs(shift[0])>smallvalue) && (fabs(shift[0]-0.5)>smallvalue))
1268 ||((fabs(shift[1])>smallvalue) && (fabs(shift[1]-0.5)>smallvalue))
1269 ||((fabs(shift[2])>smallvalue) && (fabs(shift[2]-0.5)>smallvalue))
1270 ){
1271 shift_keep=0;
1272 }
1273
1274 if( (bravais_type==1 || bravais_type==3 || bravais_type==6 || bravais_type==7 || bravais_type==10)
1275 && ((fabs(shift[0])>smallvalue) || (fabs(shift[1])>smallvalue) || (fabs(shift[2])>smallvalue))
1276 && ((fabs(shift[0]-0.5)>smallvalue) || (fabs(shift[1]-0.5)>smallvalue) || (fabs(shift[2]-0.5)>smallvalue))){
1277 shift_keep=0;
1278 }
1279 if( bravais_type==2
1280 && ( (fabs(shift[0])>smallvalue) ||
1281 (fabs(shift[1])>smallvalue) ||
1282 (fabs(shift[2])>smallvalue)
1283 )
1284 ){
1285 shift_keep=0;
1286 }
1287 if( bravais_type==4 && ((fabs(shift[0])>smallvalue) || (fabs(shift[1])>smallvalue) || (fabs(shift[2])>smallvalue))){
1288 shift_keep=0;
1289 }
1290 if( (bravais_type==5 || bravais_type==11 || bravais_type==13)
1291 && ((fabs(shift[0])>smallvalue) || (fabs(shift[1])>smallvalue) || (fabs(shift[2])>smallvalue))
1292 && ((fabs(shift[0]-0.5)>smallvalue) || (fabs(shift[1]-0.5)>smallvalue) || (fabs(shift[2])>smallvalue))
1293 && ((fabs(shift[2]-0.5)>smallvalue) || (fabs(shift[0])>smallvalue) || (fabs(shift[1])>smallvalue))
1294 && ((fabs(shift[0]-0.5)>smallvalue) || (fabs(shift[1]-0.5)>smallvalue) || (fabs(shift[2]-0.5)>smallvalue))){
1295 shift_keep=0;
1296 }
1297 if( bravais_type==9
1298 && ((fabs(shift[0])>smallvalue) || (fabs(shift[1])>smallvalue) || (fabs(shift[2])>smallvalue))
1299 && ((fabs(shift[0]-0.5)>smallvalue) || (fabs(shift[1]-0.5)>smallvalue) || (fabs(shift[2])>smallvalue))
1300 && ((fabs(shift[0]-0.5)>smallvalue) || (fabs(shift[1])>smallvalue) || (fabs(shift[2]-0.5)>smallvalue))
1301 && ((fabs(shift[0])>smallvalue) || (fabs(shift[1]-0.5)>smallvalue) || (fabs(shift[2]-0.5)>smallvalue))){
1302 shift_keep=0;
1303 }
1304
1305 shift[0]=kx;shift[1]=ky;shift[2]=kz;
1306
1307 if(debug4==1){
1308 printf("shift_keep=%1d\n",shift_keep);
1309 }
1310 if(shift_keep==0){
1311 for(i=0;i<3;i++){
1312 atomic_position[0][i]=0.0;
1313 }
1314 atom_species[0]=1;
1315 pureG_num=Bravais_Lattice_Symmetry(bravais_type,sym_op);
1316 Get_Symmetry_Operation(sym_op,&pureG_num,atomic_position,atom_species,1,1,&num_pure_pnt_op,trans_op_vec);
1317
1318 Cal_Reciprocal_Vectors(Read_in_Lattice, platt);
1319 for(i=0;i<3;i++){
1320 platt[i][0]=platt[i][0]/2.0/pi;
1321 platt[i][1]=platt[i][1]/2.0/pi;
1322 platt[i][2]=platt[i][2]/2.0/pi;
1323 }
1324 if(debug4==1){
1325 for(i=0;i<3;i++){
1326 printf("K%1d (%10.5f, %10.5f, %10.5f)\n",i+1,platt[i][0],platt[i][1],platt[i][2]);
1327 }
1328 }
1329
1330 Symmetry_Operation_Transform(sym_op, pureGsym, pureG_num, rlatt, platt);
1331
1332 if(debug4==1){
1333 for(k=0;k<pureG_num;k++){
1334 printf("pureGsym %2d\n",k+1);
1335 printf("%2d %2d %2d \n",pureGsym[k][0][0],pureGsym[k][0][1],pureGsym[k][0][2]);
1336 printf("%2d %2d %2d \n",pureGsym[k][1][0],pureGsym[k][1][1],pureGsym[k][1][2]);
1337 printf("%2d %2d %2d \n",pureGsym[k][2][0],pureGsym[k][2][1],pureGsym[k][2][2]);
1338 }
1339 }
1340 }
1341 else{
1342 pureG_num=1;
1343 for(i=0;i<3;i++){
1344 for(j=0;j<3;j++){
1345 pureGsym[0][i][j]=0;
1346 }
1347 }
1348 pureGsym[0][0][0]=1;
1349 pureGsym[0][1][1]=1;
1350 pureGsym[0][2][2]=1;
1351 }
1352
1353 /* checking whether inversion symmetry exist or not
1354 but for non-collinear case, time-inversion symmtry should not be
1355 enforced.
1356 inversion_flag == 0 collinear calculation
1357 inversion_flag == 1 noncollinear calculation
1358 */
1359
1360 inversion_sym=0;
1361 for(k=0;k<op_num;k++){
1362 if(Gsym_op[k][0][0]==-1&&Gsym_op[k][0][1]==0&&Gsym_op[k][0][2]==0
1363 &&Gsym_op[k][1][0]==0&&Gsym_op[k][1][1]==-1&&Gsym_op[k][1][2]==0
1364 &&Gsym_op[k][2][0]==0&&Gsym_op[k][2][1]==0&&Gsym_op[k][2][2]==-1){inversion_sym=1;break;}
1365 }
1366
1367 /* c=getchar(); */
1368
1369 if (inversion_sym==0 && inversion_flag==0){
1370
1371 if(debug4==1){
1372 printf("Collinear case and inversion symmetry does not exist.\n");
1373 }
1374
1375 ksym_num = 2*op_num;
1376
1377 ksym_op = (int***)malloc(sizeof(int**)*ksym_num);
1378 for(k=0; k<ksym_num; k++){
1379 ksym_op[k] = (int**)malloc(sizeof(int*)*3);
1380 for(i=0; i<3; i++){
1381 ksym_op[k][i] = (int*)malloc(sizeof(int)*3);
1382 }
1383 }
1384
1385 inv=(int**)malloc(sizeof(int*)*3);
1386 tmpsym=(int**)malloc(sizeof(int*)*3);
1387 tmpisym=(int**)malloc(sizeof(int*)*3);
1388 for(i=0;i<3;i++){
1389 inv[i]=(int*)malloc(sizeof(int)*3);
1390 tmpsym[i]=(int*)malloc(sizeof(int)*3);
1391 tmpisym[i]=(int*)malloc(sizeof(int)*3);
1392 }
1393
1394 inv[0][0]=-1;inv[0][1]=0; inv[0][2]=0;
1395 inv[1][0]=0 ;inv[1][1]=-1;inv[1][2]=0;
1396 inv[2][0]=0 ;inv[2][1]=0; inv[2][2]=-1;
1397
1398 for(k=0; k<op_num; k++){
1399 Matrix_Copy32(tmpsym, 3, Gsym_op, k);
1400 Matrix_Productor(3, inv, tmpsym, tmpisym);
1401 Matrix_Copy23(tmpisym, 3, ksym_op, k+op_num);
1402 }
1403
1404 for(i=0;i<3;i++){
1405 free(inv[i]);
1406 free(tmpsym[i]);
1407 free(tmpisym[i]);
1408 }
1409 free(inv);
1410 free(tmpsym);
1411 free(tmpisym);
1412 }
1413
1414 else{ /*Inversion symmetry exists and noncollinear calculation.*/
1415
1416 if(debug4==1){
1417 if(inversion_sym==1){
1418 printf("Inversion does EXIST.\n");
1419 }else{
1420 printf("Noncollinear calculation.\n");
1421 }
1422 }
1423
1424 ksym_num = op_num;
1425
1426 ksym_op = (int***)malloc(sizeof(int**)*ksym_num);
1427
1428 for(k=0; k<ksym_num; k++){
1429 ksym_op[k] = (int**)malloc(sizeof(int*)*3);
1430 for(i=0; i<3; i++){
1431 ksym_op[k][i] = (int*)malloc(sizeof(int)*3);
1432 }
1433 }
1434
1435 }
1436
1437 for(k=0; k<op_num; k++){
1438 for (i=0;i<3;i++){
1439 for (j=0;j<3;j++){
1440 ksym_op[k][i][j] = Gsym_op[k][i][j]; /* ksym_op correspondes to G in VASP */
1441 }
1442 }
1443 }
1444
1445 if(debug4==1){
1446 for(k=0; k<ksym_num; k++){
1447 printf("openmx ksym_op %2d\n",k+1);
1448 printf("%2d %2d %2d \n",ksym_op[k][0][0],ksym_op[k][0][1],ksym_op[k][0][2]);
1449 printf("%2d %2d %2d \n",ksym_op[k][1][0],ksym_op[k][1][1],ksym_op[k][1][2]);
1450 printf("%2d %2d %2d \n",ksym_op[k][2][0],ksym_op[k][2][1],ksym_op[k][2][2]);
1451 }
1452 /* c=getchar(); */
1453 }
1454
1455 kpt_num = Generate_MP_Special_Kpt(knum_i, knum_j, knum_k, ksym_op,ksym_num, pureGsym, pureG_num,
1456 shift, tmpK1, tmpK2, tmpK3, tmpWeight);
1457
1458 num_non_eq_kpt = kpt_num;
1459
1460 NE_KGrids1 = (double*)malloc(sizeof(double)*kpt_num);
1461 NE_KGrids2 = (double*)malloc(sizeof(double)*kpt_num);
1462 NE_KGrids3 = (double*)malloc(sizeof(double)*kpt_num);
1463 NE_T_k_op = (int*)malloc(sizeof(int)*kpt_num);
1464 alloc_first[23] = 0;
1465
1466 for(k=0; k<kpt_num; k++){
1467 NE_KGrids1[k] = tmpK1[k];
1468 NE_KGrids2[k] = tmpK2[k];
1469 NE_KGrids3[k] = tmpK3[k];
1470 NE_T_k_op[k] = tmpWeight[k];
1471 tmpK1[k] = 0.0;
1472 tmpK2[k] = 0.0;
1473 tmpK3[k] = 0.0;
1474 tmpWeight[k] = 0;
1475 }
1476
1477 /* hmweng Output non-equivalent k points*/
1478
1479 if(debug5){
1480
1481 /* For comparing with VASP IBZKPT file */
1482 if((fp=fopen("IBZKPT","rt"))==NULL){
1483 printf("Error in open file\n");
1484 return;
1485 }
1486 fscanf(fp,"%d",&i);
1487
1488 if(i!=kpt_num){
1489 printf("K point number are different. VASP %2d vs. %2d\n",i,kpt_num);
1490 return;
1491 }
1492
1493 for(k=0;k<kpt_num;k++){
1494 fscanf(fp,"%lf%lf%lf%d",&tmpK1[k],&tmpK2[k],&tmpK3[k],&tmpWeight[k]);
1495 /* printf("%20.14f%20.14f%20.14f%14d\n",tmpK1[k],tmpK2[k],tmpK3[k],tmpWeight[k]); */
1496 }
1497 /* after reading, Now comparing */
1498
1499 for(k=0;k<kpt_num;k++){/* for each k point from vasp */
1500 for(kopen=0;kopen<kpt_num;kopen++){ /*scan those from openMX */
1501 opok=-1;
1502 if(fabs(tmpK1[k]-NE_KGrids1[kopen])<smallvalue
1503 &&fabs(tmpK2[k]-NE_KGrids2[kopen])<smallvalue
1504 &&fabs(tmpK3[k]-NE_KGrids3[kopen])<smallvalue
1505 &&tmpWeight[k]==NE_T_k_op[kopen]){
1506 opok=kopen;/* if there is one element not equal, then non-equal */
1507 }
1508 if(opok==kopen){
1509 break;
1510 }
1511 }
1512 if(opok!=-1){/* opok remember that equals*/
1513 printf("VASP k point %2d == openMX %2d\n",k,opok);
1514 }else{
1515 printf("!!!!!!!!!!!!!!!!%2d NO SAME!!!!!!!!!!!\n",k);
1516 }
1517 }/* end comparision */
1518
1519 } /* end of debug5 */
1520
1521 /* end output non-equivalent k points */
1522
1523 if (myid==Host_ID){
1524 printf("\n");
1525 printf(" Number of non-equivalent k points is %2d\n",kpt_num);
1526 printf(" Generated Monkhorst-Pack k-points with a weight\n\n");
1527 for(k=0;k<kpt_num;k++){
1528 printf("%20.14f%20.14f%20.14f%14d\n",NE_KGrids1[k],NE_KGrids2[k],NE_KGrids3[k],NE_T_k_op[k]);
1529 }
1530 }
1531
1532 free(tmpK1);
1533 free(tmpK2);
1534 free(tmpK3);
1535 free(tmpWeight);
1536
1537 for(i=0; i<3; i++){
1538 free(lattice_vector[i]);
1539 free(platt[i]);
1540 free(rlatt[i]);
1541 free(klatt[i]);
1542 }
1543
1544 free(lattice_vector);
1545 free(platt);
1546 free(rlatt);
1547 free(klatt);
1548
1549 for(k=0; k<op_num_original; k++){
1550 for(i=0; i<3; i++){
1551 free(Gsym_op[k][i]);
1552 }
1553 free(Gsym_op[k]);
1554 }
1555 free(Gsym_op);
1556
1557 for(k=0; k<op_num_original; k++){
1558 for(i=0; i<3; i++){
1559 free(rsym_op[k][i]);
1560 }
1561 free(rsym_op[k]);
1562 }
1563 free(rsym_op);
1564
1565 for(k=0; k<ksym_num; k++){
1566 for(i=0;i<3;i++){
1567 free(ksym_op[k][i]);
1568 }
1569 free(ksym_op[k]);
1570 }
1571 free(ksym_op);
1572
1573 for(k=0; k<op_num_max; k++){
1574 for(i=0; i<3; i++){
1575 free(sym_op[k][i]);
1576 }
1577 free(sym_op[k]);
1578 }
1579 free(sym_op);
1580
1581 for(k=0; k<op_num_max; k++){
1582 for(i=0; i<3; i++){
1583 free(pureGsym[k][i]);
1584 }
1585 free(pureGsym[k]);
1586 }
1587 free(pureGsym);
1588
1589 for(k=0; k<op_num_max; k++){
1590 free(trans_op_vec[k]);
1591 }
1592 free(trans_op_vec);
1593
1594 for(k=0; k<(atom_num+2); k++){
1595 free(atomic_position[k]);
1596 }
1597 free(atomic_position);
1598
1599 for(k=0; k<(atom_num+2); k++){
1600 free(ptran_vec[k]);
1601 }
1602 free(ptran_vec);
1603
1604 free(atom_species);
1605
1606 }
1607
1608
Cal_Cell_Volume(double ** lattice_vector)1609 double Cal_Cell_Volume(double **lattice_vector){
1610 /* calculate the volume determined by lattice_vector[3][3] */
1611 int i, j, k;
1612 double omega;
1613 omega = 0.0;
1614 for(i=0; i<3; i++){
1615 omega = omega + lattice_vector[0][i]*(lattice_vector[1][(i+1)%3]*lattice_vector[2][(i+2)%3]-lattice_vector[1][(i+2)%3]*lattice_vector[2][(i+1)%3]);
1616 /* debug
1617 printf("a%3d*(b%3d*c%3d-b%3d*c%3d)\n",i,(i+1)%3,(i+2)%3,(i+2)%3,(i+1)%3); */
1618 }
1619 return omega;
1620 }
1621
Cal_Reciprocal_Vectors(double ** latt_vec,double ** rec_latt_vec)1622 void Cal_Reciprocal_Vectors(double **latt_vec, double **rec_latt_vec)
1623 {
1624 /* calculating the reciprocal lattice vectors of inputted latt_vec. The unit is 2*pi/a */
1625 int i,j,k;
1626 double omega;
1627 omega=0.0;
1628 omega=Cal_Cell_Volume(latt_vec);
1629 for(i=0;i<3;i++){
1630 for(j=0;j<3;j++){
1631 rec_latt_vec[i][j]=latt_vec[(i+1)%3][(j+1)%3]*latt_vec[(i+2)%3][(j+2)%3]-latt_vec[(i+1)%3][(j+2)%3]*latt_vec[(i+2)%3][(j+1)%3];
1632 rec_latt_vec[i][j]=rec_latt_vec[i][j]*2*pi/omega;
1633 }
1634 }
1635 return;
1636 }
1637
1638
1639
Atomic_Coordinates_Transform(double ** Read_in_Atom_Pos,double ** atomic_position,int atom_num,double ** Read_in_Lattice,double ** lattice_vector)1640 void Atomic_Coordinates_Transform(double **Read_in_Atom_Pos, double **atomic_position, int atom_num,
1641 double **Read_in_Lattice, double **lattice_vector){
1642 /* Convert the atomic fractional coordinates from one lattice vectors (Read_in_Lattice) to another one (lattice_vector).*/
1643 int i,j,k;
1644 double r[3];
1645 double **rec_latt_vec;
1646
1647 rec_latt_vec=(double**)malloc(sizeof(double*)*3);
1648 for(i=0;i<3;i++){
1649 rec_latt_vec[i]=(double*)malloc(sizeof(double)*3);
1650 }
1651
1652 Cal_Reciprocal_Vectors(lattice_vector, rec_latt_vec);
1653
1654 for(i=0;i<3;i++){
1655 for(j=0;j<3;j++){
1656 rec_latt_vec[i][j]=rec_latt_vec[i][j]/2.0/pi;
1657 }
1658 }
1659
1660 for(i=0;i<atom_num;i++){
1661 r[0]=Read_in_Lattice[0][0]*Read_in_Atom_Pos[i][0]+Read_in_Lattice[1][0]*Read_in_Atom_Pos[i][1]+Read_in_Lattice[2][0]*Read_in_Atom_Pos[i][2];
1662 r[1]=Read_in_Lattice[0][1]*Read_in_Atom_Pos[i][0]+Read_in_Lattice[1][1]*Read_in_Atom_Pos[i][1]+Read_in_Lattice[2][1]*Read_in_Atom_Pos[i][2];
1663 r[2]=Read_in_Lattice[0][2]*Read_in_Atom_Pos[i][0]+Read_in_Lattice[1][2]*Read_in_Atom_Pos[i][1]+Read_in_Lattice[2][2]*Read_in_Atom_Pos[i][2];
1664 atomic_position[i][0]=rec_latt_vec[0][0]*r[0]+rec_latt_vec[0][1]*r[1]+rec_latt_vec[0][2]*r[2];
1665 atomic_position[i][1]=rec_latt_vec[1][0]*r[0]+rec_latt_vec[1][1]*r[1]+rec_latt_vec[1][2]*r[2];
1666 atomic_position[i][2]=rec_latt_vec[2][0]*r[0]+rec_latt_vec[2][1]*r[1]+rec_latt_vec[2][2]*r[2];
1667
1668 /*
1669 atomic_position[i][0]=atomic_position[i][0]-floor(atomic_position[i][0]);
1670 atomic_position[i][0]=fmod(atomic_position[i][0]+1000.5,1.0)-0.5;
1671
1672 atomic_position[i][1]=atomic_position[i][1]-floor(atomic_position[i][1]);
1673 atomic_position[i][1]=fmod(atomic_position[i][1]+1000.5,1.0)-0.5;
1674
1675 atomic_position[i][2]=atomic_position[i][2]-floor(atomic_position[i][2]);
1676 atomic_position[i][2]=fmod(atomic_position[i][2]+1000.5,1.0)-0.5;
1677 */
1678 }
1679
1680 for(i=0;i<3;i++){
1681 free(rec_latt_vec[i]);
1682 }
1683 free(rec_latt_vec);
1684
1685 return;
1686 }
1687
Symmetry_Operation_Transform(int *** InputSymop,int *** OutputSymop,int op_num,double ** In_Lattice,double ** Out_Lattice)1688 void Symmetry_Operation_Transform(int ***InputSymop, int ***OutputSymop, int op_num,
1689 double **In_Lattice, double **Out_Lattice){
1690 /* Convert the atomic fractional coordinates from one lattice vectors (Read_in_Lattice) to another one (lattice_vector).*/
1691 int i,j,k,kk,ibi;
1692 double Isym[3][3], Osym[3][3];
1693 double **rIn, **rOut, tmp;
1694 double adbi[3][3],bdai[3][3],prod[3][3],sum;
1695 char c;
1696
1697 rIn=(double**)malloc(sizeof(double*)*3);
1698 rOut=(double**)malloc(sizeof(double*)*3);
1699
1700 for(i=0;i<3;i++){
1701 rOut[i]=(double*)malloc(sizeof(double)*3);
1702 rIn[i]=(double*)malloc(sizeof(double)*3);
1703 }
1704
1705 Cal_Reciprocal_Vectors(In_Lattice, rIn);
1706 Cal_Reciprocal_Vectors(Out_Lattice, rOut);
1707 for(i=0;i<3;i++){
1708 for(j=0;j<3;j++){
1709 rIn[i][j]=rIn[i][j]/2.0/pi;
1710 rOut[i][j]=rOut[i][j]/2.0/pi;
1711 Isym[i][j]=0.0;
1712 Osym[i][j]=0.0;
1713 }
1714 }
1715 for(i=0;i<3;i++){
1716 for(j=0;j<3;j++){
1717 bdai[i][j]=Out_Lattice[i][0]*rIn[j][0]+Out_Lattice[i][1]*rIn[j][1]+Out_Lattice[i][2]*rIn[j][2];
1718 /* printf("bdotai[%1d][%1d]=%10.5f\n",i+1,j+1,bdai[i][j]); */
1719 }
1720 }
1721 for(i=0;i<3;i++){
1722 for(j=0;j<3;j++){
1723 adbi[i][j]=In_Lattice[i][0]*rOut[j][0]+In_Lattice[i][1]*rOut[j][1]+In_Lattice[i][2]*rOut[j][2];
1724 /* printf("adotbi[%1d][%1d]=%10.5f\n",i+1,j+1,adbi[i][j]); */
1725 }
1726 }
1727
1728 for(k=0; k<op_num; k++){
1729
1730 for(i=0;i<3;i++){
1731 for(j=0;j<3;j++){
1732 Isym[i][j]=(double)InputSymop[k][i][j];
1733 }
1734 }
1735
1736 for(i=0;i<3;i++){
1737 for(j=0;j<3;j++){
1738 sum=0.0;
1739 for(kk=0;kk<3;kk++){
1740 sum=sum+bdai[i][kk]*Isym[kk][j];
1741 }
1742 prod[i][j]=sum;
1743 }
1744 }
1745
1746 for(i=0;i<3;i++){
1747 for(j=0;j<3;j++){
1748 sum=0.0;
1749 for(kk=0;kk<3;kk++){
1750 sum=sum+prod[i][kk]*adbi[kk][j];
1751 }
1752 Osym[i][j]=sum;
1753 }
1754 }
1755
1756 for(i=0;i<3;i++){
1757 for(j=0;j<3;j++){
1758 /* printf("FLOAT=%20.18f\n",Osym[i][j]); */
1759 if(fabs(Osym[i][j]-1.0)<smallvalue){Osym[i][j]=1.0;}
1760 if(fabs(Osym[i][j]+1.0)<smallvalue){Osym[i][j]=-1.0;}
1761 OutputSymop[k][i][j]=(int)Osym[i][j];
1762 /* printf("OutputSymop[%2d][%1d][%1d]=%3d %20.18f\n",k,i,j,OutputSymop[k][i][j],Osym[i][j]); */
1763 Osym[i][j]=0.0;
1764 }
1765 }
1766
1767 }
1768
1769 for(i=0;i<3;i++){
1770 free(rOut[i]);
1771 free(rIn[i]);
1772 }
1773 free(rIn);
1774 free(rOut);
1775 }
1776
Chk_Shorter_Lattice_Vector(double ** rlatt)1777 void Chk_Shorter_Lattice_Vector(double **rlatt){
1778 int i,j,k;
1779 int shorter;
1780 double abc[3], alpha, beta, gamma, a, b, c;
1781 double ax,ay,az,bx,by,bz,cx,cy,cz,dx,dy,dz;
1782 double absv;
1783
1784 ax = rlatt[0][0];
1785 ay = rlatt[0][1];
1786 az = rlatt[0][2];
1787 bx = rlatt[1][0];
1788 by = rlatt[1][1];
1789 bz = rlatt[1][2];
1790 cx = rlatt[2][0];
1791 cy = rlatt[2][1];
1792 cz = rlatt[2][2];
1793
1794 for(k=0;k<3;k++){
1795 abc[k]=sqrt(rlatt[k][0]*rlatt[k][0]+rlatt[k][1]*rlatt[k][1]+rlatt[k][2]*rlatt[k][2]);
1796 }
1797 a=abc[0];b=abc[1];c=abc[2];
1798 dx=bx-cx; dy=by-cy; dz=bz-cz;
1799 alpha = acos((b*b+c*c-dx*dx-dy*dy-dz*dz)/(2.0*b*c));
1800
1801 dx=ax-cx; dy=ay-cy; dz=az-cz;
1802 beta = acos((a*a+c*c-dx*dx-dy*dy-dz*dz)/(2.0*a*c));
1803
1804 dx=ax-bx; dy=ay-by; dz=az-bz;
1805 gamma = acos((a*a+b*b-dx*dx-dy*dy-dz*dz)/(2.0*a*b));
1806
1807 shorter=1;i=0;j=0;
1808
1809 while(shorter==1){
1810 shorter=0;/* try to be confident with the present vectors */
1811 for(k=0;k<3;k++){/* for three vectors */
1812 j=0;
1813 while(1==1){/* for vector[k]-vector[(k+1+k%2)%3] */
1814 i++;
1815 rlatt[k][0]=rlatt[k][0]-rlatt[(k+1+k%2)%3][0];
1816 rlatt[k][1]=rlatt[k][1]-rlatt[(k+1+k%2)%3][1];
1817 rlatt[k][2]=rlatt[k][2]-rlatt[(k+1+k%2)%3][2];
1818 absv=sqrt(rlatt[k][0]*rlatt[k][0]+rlatt[k][1]*rlatt[k][1]+rlatt[k][2]*rlatt[k][2]);
1819 /* printf("%2d-%2d vector: new length is %10.5f, old one is %10.5f\n",k,(k+1)%3,absv,abc[k]); */
1820 if(absv>(abc[k]+smallvalue)){
1821 break; /* no search for vector[k]-vector[(k+1k%2)%3], break to + case */
1822 }
1823 if(absv<(abc[k]-smallvalue)){
1824 shorter=1; /* there is shorter choice. Then continue searching */
1825 abc[k]=absv;
1826 }
1827 j=1; /* in - case, found one, mark it and skip + case */
1828 }
1829 i++;
1830 rlatt[k][0]=rlatt[k][0]+rlatt[(k+1+k%2)%3][0];
1831 rlatt[k][1]=rlatt[k][1]+rlatt[(k+1+k%2)%3][1];
1832 rlatt[k][2]=rlatt[k][2]+rlatt[(k+1+k%2)%3][2];
1833 while(j==0){/*start + case if - case can not find shorter vector*/
1834 i++;
1835 rlatt[k][0]=rlatt[k][0]+rlatt[(k+1+k%2)%3][0];
1836 rlatt[k][1]=rlatt[k][1]+rlatt[(k+1+k%2)%3][1];
1837 rlatt[k][2]=rlatt[k][2]+rlatt[(k+1+k%2)%3][2];
1838 absv=sqrt(rlatt[k][0]*rlatt[k][0]+rlatt[k][1]*rlatt[k][1]+rlatt[k][2]*rlatt[k][2]);
1839 /* printf("%2d+%2d vector: new length is %10.5f, old one is %10.5f\n",k,(k+1)%3,absv,abc[k]);*/
1840 if(absv>(abc[k]+smallvalue)){
1841 break;/* no search for vector[k]+vector[(k+1+k%2)%3], break */
1842 }
1843 if(absv<(abc[k]-smallvalue)){
1844 shorter=1;
1845 abc[k]=absv;
1846 }
1847 }
1848 if(j==0){
1849 rlatt[k][0]=rlatt[k][0]-rlatt[(k+1+k%2)%3][0];
1850 rlatt[k][1]=rlatt[k][1]-rlatt[(k+1+k%2)%3][1];
1851 rlatt[k][2]=rlatt[k][2]-rlatt[(k+1+k%2)%3][2];
1852 }
1853 j=0;
1854 while(1==1){/* for vector[k]-vector[(k+2-k%2)%3] */
1855 i++;
1856 rlatt[k][0]=rlatt[k][0]-rlatt[(k+2-k%2)%3][0];
1857 rlatt[k][1]=rlatt[k][1]-rlatt[(k+2-k%2)%3][1];
1858 rlatt[k][2]=rlatt[k][2]-rlatt[(k+2-k%2)%3][2];
1859 absv=sqrt(rlatt[k][0]*rlatt[k][0]+rlatt[k][1]*rlatt[k][1]+rlatt[k][2]*rlatt[k][2]);
1860 /* printf("%2d-%2d vector: new length is %10.5f, old one is %10.5f\n",k,(k+2)%3,absv,abc[k]);*/
1861 if(absv>(abc[k]+smallvalue)){
1862 break; /* no search for vector[k]-vector[(k+2-k%2)%3], break to + case */
1863 }
1864 if(absv<(abc[k]-smallvalue)){
1865 shorter=1; /* there is shorter choice. Then continue searching */
1866 abc[k]=absv;
1867 }
1868 j=1; /* in - case, found one, mark it and skip + case */
1869 }
1870 i++;
1871 rlatt[k][0]=rlatt[k][0]+rlatt[(k+2-k%2)%3][0];
1872 rlatt[k][1]=rlatt[k][1]+rlatt[(k+2-k%2)%3][1];
1873 rlatt[k][2]=rlatt[k][2]+rlatt[(k+2-k%2)%3][2];
1874 while(j==0){/*start + case if - case can not find shorter vector*/
1875 i++;
1876 rlatt[k][0]=rlatt[k][0]+rlatt[(k+2-k%2)%3][0];
1877 rlatt[k][1]=rlatt[k][1]+rlatt[(k+2-k%2)%3][1];
1878 rlatt[k][2]=rlatt[k][2]+rlatt[(k+2-k%2)%3][2];
1879 absv=sqrt(rlatt[k][0]*rlatt[k][0]+rlatt[k][1]*rlatt[k][1]+rlatt[k][2]*rlatt[k][2]);
1880 /* printf("%2d+%2d vector: new length is %10.5f, old one is %10.5f\n",k,(k+2)%3,absv,abc[k]);*/
1881 if(absv>(abc[k]+smallvalue)){
1882 break;/* no search for vector[k]+vector[(k+2-k%2)%3], break */
1883 }
1884 if(absv<(abc[k]-smallvalue)){
1885 shorter=1;
1886 abc[k]=absv;
1887 }
1888 }
1889 if(j==0){
1890 rlatt[k][0]=rlatt[k][0]-rlatt[(k+2-k%2)%3][0];
1891 rlatt[k][1]=rlatt[k][1]-rlatt[(k+2-k%2)%3][1];
1892 rlatt[k][2]=rlatt[k][2]-rlatt[(k+2-k%2)%3][2];
1893 }
1894 }/*finished + and - case for all vectors*/
1895 }
1896
1897 ax = rlatt[0][0];
1898 ay = rlatt[0][1];
1899 az = rlatt[0][2];
1900 bx = rlatt[1][0];
1901 by = rlatt[1][1];
1902 bz = rlatt[1][2];
1903 cx = rlatt[2][0];
1904 cy = rlatt[2][1];
1905 cz = rlatt[2][2];
1906
1907 for(k=0;k<3;k++){
1908 abc[k]=sqrt(rlatt[k][0]*rlatt[k][0]+rlatt[k][1]*rlatt[k][1]+rlatt[k][2]*rlatt[k][2]);
1909 }
1910 a=abc[0];b=abc[1];c=abc[2];
1911 dx=bx-cx; dy=by-cy; dz=bz-cz;
1912 alpha = acos((b*b+c*c-dx*dx-dy*dy-dz*dz)/(2.0*b*c));
1913
1914 dx=ax-cx; dy=ay-cy; dz=az-cz;
1915 beta = acos((a*a+c*c-dx*dx-dy*dy-dz*dz)/(2.0*a*c));
1916
1917 dx=ax-bx; dy=ay-by; dz=az-bz;
1918 gamma = acos((a*a+b*b-dx*dx-dy*dy-dz*dz)/(2.0*a*b));
1919
1920 /* printf("After trying to find the shorter lattice vector, the lattice vectors are:\n");
1921 printf("a=%10.5f,b=%10.5f,c=%10.5f\n",abc[0],abc[1],abc[2]);
1922 printf("Angles:\n");
1923 printf("b-c alpha=%10.5f,cos(alpha)=%10.5f\n",alpha/pi*180.0,cos(alpha));
1924 printf("a-c beta=%10.5f,cos(beta)=%10.5f\n",beta/pi*180.0,cos(beta));
1925 printf("a-b gamma=%10.5f,cos(gamma)=%10.5f\n",gamma/pi*180.0,cos(gamma));
1926
1927 bra_typ=Bravais_Type(rlatt,cell_parameters);
1928 printf("This lattice type is %2d\n",bra_typ);
1929 */
1930 return;
1931 }
1932
Bravais_Type(double ** lattice_vector,double * cell_parameters)1933 int Bravais_Type(double **lattice_vector,double *cell_parameters){
1934 /*
1935 INPUT
1936 double lattice_vector[3][3] Lattice Vectors given by users;
1937
1938 OUTPUT
1939 int bravais_type Bravais Lattice Type: 1 --- Primitive cubic (cP) or simple-cubic sc
1940 2 --- Body-centered cubic (cI) bcc
1941 3 --- Face-centered cubic (cF) fcc
1942 4 --- Primitive hexagonal (hP)
1943 5 --- Primitive tetragonal (tP)
1944 6 --- Body-centerd tetragonal (tI)
1945 7 --- Rhombohedral (hR)
1946 8 --- Primitive orthorhombic (oP)
1947 9 --- Body-centered orthorhombic (oI)
1948 10 --- Face-centered orthorhombic (oF)
1949 11 --- Base-centered orthorhombic (oC)
1950 12 --- Primitive monoclinic (mP)
1951 13 --- Base-centred monoclinic (mB)
1952 14 --- Primitive triclinic (aP)
1953 Defined to be consistent with VASP.
1954 double cell_parameters[6] lattice parameters like a, b, c and alpha, beta, gamma
1955 */
1956 double cell_volume;
1957 double ax, ay, az, bx, by, bz, cx, cy, cz;
1958 double a, b, c, alpha, beta, gamma;
1959 double dx,dy,dz;
1960 int bravais_type,i,j,k;
1961 char ch;
1962 bravais_type=15;
1963 /* 1. Are the lattice vectors given in right-hand coordinates */
1964 cell_volume = Cal_Cell_Volume(lattice_vector);
1965 /*debug
1966 printf("cell volume is %10.5f\n",cell_volume);
1967 */
1968 if(fabs(cell_volume)<(smallvalue*smallvalue*smallvalue)){/* lattice volume is too small */
1969 printf("WARNING!!! The volume of given lattice is too small.\n");
1970 }
1971 if(cell_volume<0.0){/* not in right-hand coordinates, then reversing all the lattice vectors */
1972 lattice_vector[0][0]=-lattice_vector[0][0];
1973 lattice_vector[0][1]=-lattice_vector[0][1];
1974 lattice_vector[0][2]=-lattice_vector[0][2];
1975 lattice_vector[1][0]=-lattice_vector[1][0];
1976 lattice_vector[1][1]=-lattice_vector[1][1];
1977 lattice_vector[1][2]=-lattice_vector[1][2];
1978 lattice_vector[2][0]=-lattice_vector[2][0];
1979 lattice_vector[2][1]=-lattice_vector[2][1];
1980 lattice_vector[2][2]=-lattice_vector[2][2];
1981 }
1982 ax = lattice_vector[0][0];
1983 ay = lattice_vector[0][1];
1984 az = lattice_vector[0][2];
1985 bx = lattice_vector[1][0];
1986 by = lattice_vector[1][1];
1987 bz = lattice_vector[1][2];
1988 cx = lattice_vector[2][0];
1989 cy = lattice_vector[2][1];
1990 cz = lattice_vector[2][2];
1991 a = sqrt(ax*ax+ay*ay+az*az);
1992 b = sqrt(bx*bx+by*by+bz*bz);
1993 c = sqrt(cx*cx+cy*cy+cz*cz);
1994 dx=bx-cx; dy=by-cy; dz=bz-cz;
1995 alpha = acos((b*b+c*c-dx*dx-dy*dy-dz*dz)/(2.0*b*c));
1996
1997 dx=ax-cx; dy=ay-cy; dz=az-cz;
1998 beta = acos((a*a+c*c-dx*dx-dy*dy-dz*dz)/(2.0*a*c));
1999
2000 dx=ax-bx; dy=ay-by; dz=az-bz;
2001 gamma = acos((a*a+b*b-dx*dx-dy*dy-dz*dz)/(2.0*a*b));
2002 /*
2003 printf("vectors information:\n");
2004 printf("a=%10.5f, b=%10.5f, c=%10.5f\n",a,b,c);
2005 printf("Angles:\n");
2006 printf("b-c alpha=%10.5f,cos(alpha)=%10.5f\n",alpha/pi*180.0,cos(alpha));
2007 printf("a-c beta=%10.5f,cos(beta)=%10.5f\n",beta/pi*180.0,cos(beta));
2008 printf("a-b gamma=%10.5f,cos(gamma)=%10.5f\n",gamma/pi*180.0,cos(gamma));
2009 */
2010 for(i=0; i<6; i++){
2011 cell_parameters[i] = 0.0;
2012 }
2013 cell_parameters[3] = pi/2;
2014 cell_parameters[4] = pi/2;
2015 cell_parameters[5] = pi/2;
2016 if(fabs(alpha-beta)<smallvalue&&fabs(alpha-gamma)<smallvalue){
2017 /*if all three angles are equal, it would be cubic/tetragonal/orthorhombic or hR lattices*/
2018 if(fabs(alpha-pi/2.0)<smallvalue){
2019 /* if all three angles are right angles, it might be cubic/tetragonal/orthorhombic lattice*/
2020 if(fabs(a-b)<smallvalue&&fabs(b-c)<smallvalue){/* a=b=c and alpha=beta=gamma=90 degree, Primitive cubic (cP) */
2021 bravais_type=1;
2022 cell_parameters[0]=a;
2023 }else if(fabs(a-b)<smallvalue){
2024 /*two of a, b, c are equal, Primitive tetragonal (tP)*/
2025 /* Attention! Generally, the lattice vectors are chosen to have a=b
2026 If fabs(b-c)<smallvalue or fabs(a-c)<smallvalue){ */
2027 bravais_type = 5;
2028 /*if(fabs(a-b)<smallvalue){*/
2029 cell_parameters[0]=a;
2030 cell_parameters[2]=c/a;
2031 /*}else if(fabs(b-c)<smallvalue){
2032 cell_parameters[0]=b;
2033 cell_parameters[2]=a/b;
2034 }else{
2035 cell_parameters[0]=a;
2036 cell_parameters[2]=b/a;
2037 }*/
2038 }else if((c-b)>smallvalue && (b-a)>smallvalue){/* a,b,c are non-equivlent, primitive orthorhombic (oP) */
2039 /*Attention! Generally, lattic vectors are taken so that a, b, c are in ascending order.*/
2040 bravais_type = 8;
2041 cell_parameters[0]=a;
2042 cell_parameters[1]=b/a;
2043 cell_parameters[2]=c/a;
2044 }
2045 }else{/*all angles are equal but not right angle, it would be cF, cI, or hR*/
2046 if(fabs(a-b)<smallvalue&&fabs(b-c)<smallvalue){ /*all the vectors' length are equal */
2047 if(fabs(cos(alpha)-1.0/2.0)<smallvalue){/* if all angles are 60 degree, it is Face-centred cubic (cF) */
2048 bravais_type = 3;
2049 cell_parameters[0]=sqrt(2.0)*a;
2050 }else if(fabs(cos(alpha)+1.0/3.0)<smallvalue){/* if all angles are arccos(-1/3) degree, it is Body-centred cubic (cI) */
2051 bravais_type = 2;
2052 cell_parameters[0]=2.0*a/sqrt(3.0);
2053 }else{/* other angle, Rhombohedral (hR)*/
2054 bravais_type = 7;
2055 cell_parameters[0]=a;
2056 cell_parameters[3]=alpha;
2057 }
2058 }
2059 }
2060 }else if(fabs(beta-gamma)<smallvalue){
2061 /* two of three angles are equal. alpha==beta or alpha==gamma or beta==gamma*/
2062 /* Attention! Generally the lattice vectors are chosen so that alpha=beta */
2063 }else if(fabs(alpha-beta)<smallvalue){
2064 if(fabs(alpha-pi/2.0)<smallvalue){/* If two equal angles are right angle, it would be hP, oC or mP */
2065 if(fabs(a-b)<smallvalue){
2066 /*If the two vectors perpendicular and their lengths are equal, it would be hP or oC instead of mP*/
2067 if(fabs(cos(gamma)+1.0/2.0)<smallvalue){ /*If gamma is 120 degree, it is hP*/
2068 bravais_type = 4;
2069 cell_parameters[0]=a;
2070 cell_parameters[2]=c/a;
2071 }else{ /*gamma is other angel, oC*/
2072 /* Attention! Generally, gamma is taken as an obtuse angle. */
2073 if(cos(gamma)<-1.0*smallvalue){
2074 bravais_type = 11;
2075 cell_parameters[0]=sqrt(a*a+b*b+2.0*a*b*cos(gamma));
2076 cell_parameters[1]=sqrt(a*a+b*b-2.0*a*b*cos(gamma))/cell_parameters[0];
2077 cell_parameters[2]=c/cell_parameters[0];
2078 }
2079 }
2080 }else{/* mP */
2081 /*Attention! Generally, gamma is taken as an obtuse angle and special axis
2082 is conventionally labelled as 'b-axis' and a<c
2083 a->c, b->a, c->b*/
2084 if(cos(gamma)<-1.0*smallvalue && (a-b)>smallvalue){
2085 bravais_type = 12;
2086 cell_parameters[0]=b;
2087 cell_parameters[1]=c/b;
2088 cell_parameters[2]=a/b;
2089 cell_parameters[4]=gamma;
2090 cx = lattice_vector[0][0];
2091 cy = lattice_vector[0][1];
2092 cz = lattice_vector[0][2];
2093 ax = lattice_vector[1][0];
2094 ay = lattice_vector[1][1];
2095 az = lattice_vector[1][2];
2096 bx = lattice_vector[2][0];
2097 by = lattice_vector[2][1];
2098 bz = lattice_vector[2][2];
2099 /* printf("Attention! In primitive monoclinic case, adjust lattice vectors!\n"); */
2100 }
2101 }
2102 }else{/* two equal angles are other angle than right angle. */
2103 if(fabs(a-b)<smallvalue && fabs(a-c)<smallvalue){/*all vectors' length are equal, tI*/
2104 /* Additional criterions are: (a+b), (a+c) and (b+c) are orthogonal to one another,
2105 since the face constructed by a, b, c are diamond shape.
2106 (a+c)(b+c)=a.b+a.c+b.c+c.c=0
2107 (a+b)(a+c)=a.b+a.c+b.c+a.a=0
2108 (a+b)(b+c)=a.b+a.c+b.c+b.b=0
2109 Attention! Generally, the lattice vectors are chose so that |a+c|=|b+c|<|a+b|
2110 */
2111 /* debug
2112 printf("tI right\n");
2113 printf("%20.15f",a*a+c*c+2.0*a*c*cos(beta));
2114 printf("%20.15f",-(b*b+c*c+2.0*b*c*cos(alpha)));
2115 printf("%20.15f",fabs(a*a+c*c+2.0*a*c*cos(beta)-(a*a+b*b+2.0*a*b*cos(gamma))));
2116 printf("%20.15f",fabs(c*c+a*b*cos(gamma)+a*c*cos(beta)+b*c*cos(alpha)));
2117 */
2118 if(fabs(a*a+c*c+2.0*a*c*cos(beta)-(b*b+c*c+2.0*b*c*cos(alpha)))<smallvalue
2119 && fabs(a*a+c*c+2.0*a*c*cos(beta)-(a*a+b*b+2.0*a*b*cos(gamma)))>smallvalue
2120 && fabs(c*c+a*b*cos(gamma)+a*c*cos(beta)+b*c*cos(alpha))<smallvalue){
2121 bravais_type = 6;
2122 cell_parameters[0]=sqrt(c*c+a*a+2.0*a*c*cos(beta));
2123 cell_parameters[2]=sqrt(b*b+a*a+2.0*a*b*cos(gamma))/cell_parameters[0];
2124 }
2125 }else if(fabs(a-b)<smallvalue){/*only two vectors' length are equal, mB*/
2126 if(cos(alpha)<-1.0*smallvalue&&cos(beta)<-1.0*smallvalue){
2127 /* Attention! Generally, alpha and beta are taken as obtuse angles */
2128 bravais_type = 13;
2129 cell_parameters[0]=sqrt(b*b+a*a+2.0*a*b*cos(gamma));
2130 cell_parameters[1]=sqrt(b*b+a*a-2.0*a*b*cos(gamma))/cell_parameters[0];
2131 cell_parameters[2]=c/cell_parameters[0];
2132 cell_parameters[4]=acos(cos(alpha)/cos(gamma/2.0));
2133 }
2134 }
2135 }
2136 }else if(fabs(gamma-beta)<smallvalue){
2137 /*
2138 Attention! Generally the lattice vectors are chosen so that alpha=beta
2139 */
2140 }else{/* all of the angles are different */
2141 if(fabs(a-b)<smallvalue&&fabs(b-c)<smallvalue){/*all the vectors' length are equal, oI*/
2142 if(fabs(c*c+a*b*cos(gamma)+a*c*cos(beta)+b*c*cos(alpha))<smallvalue
2143 && (a*a+c*c+2.0*a*c*cos(beta)-(c*c+b*b+2.0*c*b*cos(alpha)))>smallvalue
2144 && (a*a+b*b+2.0*a*b*cos(gamma)-(a*a+c*c+2.0*a*c*cos(beta)))>smallvalue){
2145 /*Attention!
2146 Additional criterions are: (a+b), (a+c) and (b+c) are orthogonal to one another,
2147 since the face constructed by a, b, c are diamond shape.
2148 (a+c)(b+c)=a.b+a.c+b.c+c.c=0
2149 (a+b)(a+c)=a.b+a.c+b.c+a.a=0
2150 (a+b)(b+c)=a.b+a.c+b.c+b.b=0
2151 Generally, the lattice vectors are chose so that |a+b|>|a+c|>|c+b|*/
2152 bravais_type = 9;
2153 cell_parameters[0]=sqrt(c*c+b*b+2.0*c*b*cos(alpha));
2154 cell_parameters[1]=sqrt(c*c+a*a+2.0*c*a*cos(beta))/cell_parameters[0];
2155 cell_parameters[2]=sqrt(b*b+a*a+2.0*b*a*cos(gamma))/cell_parameters[0];
2156 }
2157 }else if(fabs(sqrt(b*b+c*c-2.0*b*c*cos(alpha))-a)<smallvalue
2158 && fabs(sqrt(a*a+c*c-2.0*a*c*cos(beta))-b)<smallvalue
2159 && fabs(sqrt(b*b+a*a-2.0*b*a*cos(gamma))-c)<smallvalue
2160 && fabs((ax+bx-cx)*(ax+bx-cx)+(ay+by-cy)*(ay+by-cy)+(az+bz-cz)*(az+bz-cz)-
2161 (ax+cx-bx)*(ax+cx-bx)-(ay+cy-by)*(ay+cy-by)-(az+cz-bz)*(az+cz-bz))>smallvalue
2162 && fabs((ax+cx-bx)*(ax+cx-bx)+(ay+cy-by)*(ay+cy-by)+(az+cz-bz)*(az+cz-bz)-
2163 (bx+cx-ax)*(bx+cx-ax)-(by+cy-ay)*(by+cy-ay)-(bz+cz-az)*(bz+cz-az))>smallvalue
2164 ){/* if |a|=|b-c| and |b|=|a-c| and |c|=|b-a| then oF,
2165 and take the general choice |a+b-c|>|a+c-b|>|b+c-a|
2166 Attention!*/
2167 bravais_type = 10;
2168 cell_parameters[0]=sqrt(a*a+b*b+c*c+2.0*b*c*cos(alpha)-2.0*a*b*cos(gamma)-2.0*a*c*cos(beta));
2169 cell_parameters[1]=sqrt(a*a+b*b+c*c+2.0*a*c*cos(beta)-2.0*b*c*cos(alpha)-2.0*a*b*cos(gamma))/cell_parameters[0];
2170 cell_parameters[2]=sqrt(a*a+b*b+c*c+2.0*a*b*cos(gamma)-2.0*a*c*cos(beta)-2.0*b*c*cos(alpha))/cell_parameters[0];
2171 }else{/*last case, it must be triclinic aP */
2172 /* All angles should be sharp angle and ordered so that cos(gamma)>cos(beta)>cos(alpha)>0
2173 Attention!*/
2174 if(cos(gamma)>cos(beta)&&cos(beta)>cos(alpha)&&cos(alpha)>smallvalue){
2175 bravais_type = 14;
2176 cell_parameters[0]=a;
2177 cell_parameters[1]=b/a;
2178 cell_parameters[2]=c/a;
2179 cell_parameters[3]=alpha;
2180 cell_parameters[4]=beta;
2181 cell_parameters[5]=gamma;
2182 }
2183 }
2184 }
2185 lattice_vector[0][0]=ax;
2186 lattice_vector[0][1]=ay;
2187 lattice_vector[0][2]=az;
2188 lattice_vector[1][0]=bx;
2189 lattice_vector[1][1]=by;
2190 lattice_vector[1][2]=bz;
2191 lattice_vector[2][0]=cx;
2192 lattice_vector[2][1]=cy;
2193 lattice_vector[2][2]=cz;
2194
2195 return bravais_type;
2196 }
2197
Finding_Bravais_Lattice_Type(double ** lattice_vector,double * cell_parameters)2198 int Finding_Bravais_Lattice_Type(double **lattice_vector, double *cell_parameters){
2199
2200 int bravais_type1st, bravais_type; /* Bravais lattice type */
2201 int i,j,k,pcell_brav;
2202 int L11,L12,L13,L21,L22,L23,L31,L32,L33,ID1,ID2,ID3,ID4,ID5;
2203 double pcell_parameters[6]; /* a, b, c and alpha, beta, gamma */
2204 double con_cell[6], cos1, cos2, cos3;
2205 double **latt1st, **rlatt, **platt, **newlatt;
2206
2207 rlatt=(double**)malloc(sizeof(double*)*3);
2208 platt=(double**)malloc(sizeof(double*)*3);
2209 newlatt=(double**)malloc(sizeof(double*)*3);
2210 latt1st=(double**)malloc(sizeof(double*)*3);
2211 for(i=0;i<3;i++){
2212 platt[i]=(double*)malloc(sizeof(double)*3);
2213 rlatt[i]=(double*)malloc(sizeof(double)*3);
2214 newlatt[i]=(double*)malloc(sizeof(double)*3);
2215 latt1st[i]=(double*)malloc(sizeof(double)*3);
2216 }
2217 for(i=0;i<3;i++){/*saving the original lattice vector*/
2218 for(j=0;j<3;j++){
2219 rlatt[i][j]=lattice_vector[i][j];
2220 latt1st[i][j]=lattice_vector[i][j];
2221 platt[i][j]=lattice_vector[i][j];
2222 newlatt[i][j]=lattice_vector[i][j];
2223 }
2224 }
2225 if(debug3==1){
2226 printf("Original lattice vectors are:\n");
2227 for(i=0;i<3;i++){
2228 printf("A%1d (%5.2f, %5.2f, %5.2f)\n",i+1,lattice_vector[i][0],lattice_vector[i][1],lattice_vector[i][2]);
2229 }
2230 }
2231 bravais_type1st=Bravais_Type(latt1st,cell_parameters);
2232 if(debug3==1){
2233 if(0<bravais_type1st && bravais_type1st<15){
2234 printf("In subroutine Bravais_Type, it is found the Lattice is %d\n",bravais_type1st);
2235 printf("Cell parameters are\n");
2236 for(i=0;i<6;i++){
2237 if(cell_parameters[i]!=0.0){
2238 if(i==0){
2239 printf("Lattice parameter %d is %10.5f\n",i,cell_parameters[i]);
2240 }else if(i==1||i==2){
2241 printf("Lattice parameter %d is %10.5f\n",i,cell_parameters[i]*cell_parameters[0]);
2242 }else{
2243 printf("Angle %d information is %10.5f, cosin is %10.5f\n",i,cell_parameters[i]/pi*180.0,cos(cell_parameters[i]));
2244 }
2245 }
2246 }
2247 }
2248 }
2249 for(i=0;i<6;i++){
2250 con_cell[i]=cell_parameters[i];
2251 }
2252 /* Find the shortest lattice vectors. The volume could be kept.*/
2253 Chk_Shorter_Lattice_Vector(rlatt);
2254 if(debug3==1){
2255 printf("The possible shortest lattice vectors are:\n");
2256 for(i=0;i<3;i++){
2257 printf("A%1d (%5.2f, %5.2f, %5.2f)\n",i+1,rlatt[i][0],rlatt[i][1],rlatt[i][2]);
2258 }
2259 }
2260 /*Do several combinations of these lattice vectors
2261 A=L11*a+L12*b+L13*c;
2262 B=L21*a+L22*b+L23*c;
2263 C=L31*a+L32*b+L33*c;
2264 a,b,c are the vectors found from Chk_Shorter_Lattice_Vector;
2265 A,B,C are the obtained vectors after linear combination of a, b, c with integer L11,L12,L13, ...
2266 The idea is to find the highest symmetrical bravais lattice from vectors
2267 with possible combinations which conserving the volume surrounded by them.
2268 */
2269 bravais_type=bravais_type1st;
2270 cos1=1.0;cos2=1.0;cos3=1.0;
2271 for(L33=-2;L33<3;L33++){/*N9*/
2272 for(L32=-2;L32<3;L32++){/*N8*/
2273 for(L31=-2;L31<3;L31++){/*N7*/
2274 for(L23=-2;L23<3;L23++){/*N6*/
2275 for(L22=-2;L22<3;L22++){/*N5*/
2276 ID1=L22*L33-L23*L32;
2277 for(L21=-2;L21<3;L21++){/*N4*/
2278 ID2=L23*L31-L21*L33;ID3=L21*L32-L22*L31;
2279 for(L13=-2;L13<3;L13++){/*N3*/
2280 ID4=L13*ID3;
2281 for(L12=-2;L12<3;L12++){/*N2*/
2282 ID5=L12*ID2+ID4;
2283 for(L11=-2;L11<3;L11++){/*N1*/
2284 if(L11*ID1+ID5==1){/*volume conservation condition*/
2285 platt[0][0] = L11*rlatt[0][0]+L12*rlatt[1][0]+L13*rlatt[2][0];
2286 platt[0][1] = L11*rlatt[0][1]+L12*rlatt[1][1]+L13*rlatt[2][1];
2287 platt[0][2] = L11*rlatt[0][2]+L12*rlatt[1][2]+L13*rlatt[2][2];
2288 platt[1][0] = L21*rlatt[0][0]+L22*rlatt[1][0]+L23*rlatt[2][0];
2289 platt[1][1] = L21*rlatt[0][1]+L22*rlatt[1][1]+L23*rlatt[2][1];
2290 platt[1][2] = L21*rlatt[0][2]+L22*rlatt[1][2]+L23*rlatt[2][2];
2291 platt[2][0] = L31*rlatt[0][0]+L32*rlatt[1][0]+L33*rlatt[2][0];
2292 platt[2][1] = L31*rlatt[0][1]+L32*rlatt[1][1]+L33*rlatt[2][1];
2293 platt[2][2] = L31*rlatt[0][2]+L32*rlatt[1][2]+L33*rlatt[2][2];
2294 pcell_brav=Bravais_Type(platt,pcell_parameters);
2295 if((pcell_brav<bravais_type)||(pcell_brav==bravais_type
2296 &&((fabs(cos(pcell_parameters[3]))<(cos1-smallvalue))
2297 && (fabs(cos(pcell_parameters[4]))<(cos2-smallvalue))
2298 && (fabs(cos(pcell_parameters[5]))<(cos3-smallvalue))))){
2299 bravais_type=pcell_brav;
2300 for(i=0;i<3;i++){/*saving the original lattice vector*/
2301 for(j=0;j<3;j++){
2302 newlatt[i][j]=platt[i][j];
2303 }
2304 }
2305 for(i=0;i<6;i++){
2306 con_cell[i]=pcell_parameters[i];
2307 }
2308 cos1=fabs(cos(pcell_parameters[3]));
2309 cos2=fabs(cos(pcell_parameters[4]));
2310 cos3=fabs(cos(pcell_parameters[5]));
2311 }/*found higher symmetrical lattice*/
2312 }/*keep volume*/
2313 }/*L11*/
2314 }/*L12*/
2315 }/*L13*/
2316 }/*L21*/
2317 }/*L22*/
2318 }/*L23*/
2319 }/*L31*/
2320 }/*L32*/
2321 }/*L33*/
2322 if(bravais_type==bravais_type1st){/* Two types are the same */
2323 ID1=0;
2324 for(i=0;i<6;i++){
2325 if(fabs(cell_parameters[i]-con_cell[i])>smallvalue){
2326 ID1=1;
2327 break;
2328 }
2329 }
2330 if(ID1==0){
2331 for(i=0;i<3;i++){
2332 for(j=0;j<3;j++){
2333 newlatt[i][j]=latt1st[i][j];
2334 }
2335 }
2336 }else{
2337 if(debug3==1){
2338 printf("WARNING!Taking the origianl lattice vectors \nwhile the cell parameters are different from the original ones.\n");
2339 }
2340 }
2341 }
2342
2343 for(i=0;i<6;i++){
2344 cell_parameters[i]=con_cell[i];
2345 }
2346 for(i=0;i<3;i++){
2347 lattice_vector[i][0]=newlatt[i][0];
2348 lattice_vector[i][1]=newlatt[i][1];
2349 lattice_vector[i][2]=newlatt[i][2];
2350 }
2351
2352 for(i=0;i<3;i++){
2353 free(platt[i]);
2354 free(rlatt[i]);
2355 free(newlatt[i]);
2356 free(latt1st[i]);
2357 }
2358 free(rlatt);
2359 free(platt);
2360 free(newlatt);
2361 free(latt1st);
2362
2363 return bravais_type;
2364 }
2365
Matrix_Copy23(int ** source,int n_source,int *** symop,int k_symop)2366 void Matrix_Copy23(int **source,int n_source,int ***symop, int k_symop){
2367 /* copy source to symop*/
2368 int i,j;
2369
2370 for(i=0; i<n_source; i++){
2371 for(j=0; j<n_source; j++){
2372 symop[k_symop][i][j]=source[i][j];
2373 }
2374 }
2375 return;
2376 }
2377
Matrix_Copy32(int ** target,int n_target,int *** symop,int k_symop)2378 void Matrix_Copy32(int **target,int n_target,int ***symop, int k_symop)
2379 {
2380 /* copy from symop to target*/
2381 int i,j;
2382
2383 for(i=0; i<n_target; i++){
2384 for(j=0; j<n_target; j++){
2385 target[i][j] = symop[k_symop][i][j];
2386 }
2387 }
2388 }
2389
Matrix_Copy22(int ** source,int ** target,int dim)2390 void Matrix_Copy22(int **source,int **target, int dim)
2391 {
2392 /* copy from symop to target*/
2393 int i,j;
2394
2395 for(i=0; i<dim; i++){
2396 for(j=0; j<dim; j++){
2397 target[i][j] = source[i][j];
2398 }
2399 }
2400 }
2401
Matrix_Equal(int ** m1,int ** m2,int dim)2402 int Matrix_Equal(int **m1, int **m2, int dim){
2403 int i,j;
2404
2405 for(i=0;i<dim;i++){
2406 for(j=0;j<dim;j++){
2407 if(m1[i][j]!=m2[i][j]){
2408 return 0;
2409 }
2410 }
2411 }
2412 return 1;
2413 }
2414
Matrix_Productor(int dim,int ** m1,int ** m2,int ** pro)2415 void Matrix_Productor(int dim, int **m1, int **m2, int **pro){
2416 int i,j,k,sum;
2417 for(i=0;i<dim;i++){
2418 for(j=0;j<dim;j++){
2419 sum=0;
2420 for(k=0;k<dim;k++){
2421 sum+=m1[i][k]*m2[k][j];
2422 }
2423 pro[i][j]=sum;
2424 }
2425 }
2426 return;
2427 }
2428
Symmtry_Operator_Generation(int *** symgen,int gen_num,int *** symop)2429 int Symmtry_Operator_Generation(int ***symgen,int gen_num,int ***symop){
2430 /* Generating the symmetry operation matrix by using gen_num generators stored in symop */
2431 int op_num,op_i,existing, op_count, op2;
2432 int i,j,k,ii;
2433 int **iden,**genop, **exop, **tmpop, **tmpop1;
2434 int op_order, iorder;
2435 int new1,new2,m,n;
2436
2437 existing=0;
2438
2439 iden=(int**)malloc(sizeof(int*)*3);
2440 genop=(int**)malloc(sizeof(int*)*3);
2441 exop=(int**)malloc(sizeof(int*)*3);
2442 tmpop=(int**)malloc(sizeof(int*)*3);
2443 tmpop1=(int**)malloc(sizeof(int*)*3);
2444 for(i=0;i<3;i++){
2445 iden[i]=(int*)malloc(sizeof(int)*3);
2446 genop[i]=(int*)malloc(sizeof(int)*3);
2447 exop[i]=(int*)malloc(sizeof(int)*3);
2448 tmpop[i]=(int*)malloc(sizeof(int)*3);
2449 tmpop1[i]=(int*)malloc(sizeof(int)*3);
2450 }
2451 for(i=0;i<3;i++){
2452 for(j=0;j<3;j++){
2453 iden[i][j]=0;
2454 genop[i][j]=0;
2455 exop[i][j]=0;
2456 tmpop[i][j]=0;
2457 tmpop1[i][j]=0;
2458 }
2459 }
2460 iden[0][0]=1;iden[1][1]=1;iden[2][2]=1;
2461
2462 Matrix_Copy23(iden,3,symop,0);
2463 op_num=1;
2464
2465 for(k=0;k<gen_num;k++){
2466 existing=0;
2467 Matrix_Copy32(genop,3,symgen,k);/* take out one generator */
2468 if(debug3 == 1){
2469 printf("taking %2d generator\n",k);
2470 for(i=0;i<3;i++){
2471 printf("%3d%3d%3d\n",genop[i][0],genop[i][1],genop[i][2]);
2472 }
2473 }
2474 for(op_i=0;op_i<op_num;op_i++){/* compare this generator with existing operators */
2475 Matrix_Copy32(exop,3,symop,op_i);
2476 if(debug3 == 1){
2477 printf("existing symmetry %2d\n",op_i);
2478 for(i=0;i<3;i++){
2479 printf("%3d%3d%3d\n",exop[i][0],exop[i][1],exop[i][2]);
2480 }
2481 }
2482 if(Matrix_Equal(genop,exop,3)==1){/* whether this generator already exists */
2483 existing=1;
2484 break;
2485 }
2486 }
2487 if(existing==1){/* If already exists, go to the next generator */
2488 continue;
2489 }
2490 Matrix_Productor(3, genop, iden, exop);/*find the order of generator */
2491 if(debug3 == 1){
2492 printf("after productor\n");
2493 for(i=0;i<3;i++){
2494 printf("%3d%3d%3d\n",exop[i][0],exop[i][1],exop[i][2]);
2495 }
2496 }
2497 for(iorder=1;iorder<50;iorder++){
2498 if(Matrix_Equal(exop,iden,3)==1){
2499 op_order=iorder;
2500 if(debug3 == 1){
2501 printf("Found the Order is %d\n",op_order);
2502 }
2503 break;
2504 }
2505 Matrix_Productor(3,genop,exop,tmpop);
2506 Matrix_Copy22(tmpop,exop,3);
2507 }
2508 /* printf("Haha\n Order is %d\n",op_order); */
2509 op_count=op_num;
2510 for(op_i=0;op_i<op_num;op_i++){/* for all existing symmetry operator exop */
2511 Matrix_Copy32(exop,3,symop,op_i);
2512 for(iorder=1;iorder<op_order;iorder++){
2513 Matrix_Productor(3,genop,exop,tmpop);
2514 Matrix_Copy22(tmpop,exop,3); /*exop=genop**Iorder*symop exop == H */
2515 for(i=0;i<op_num;i++){ /* time another existing operator */
2516 Matrix_Copy32(tmpop,3,symop,i);
2517 Matrix_Productor(3,tmpop,exop,tmpop1);/* tmpop1 == HH */
2518 existing=0;
2519 for(j=0;j<op_count;j++){
2520 Matrix_Copy32(tmpop,3,symop,j);
2521 if(Matrix_Equal(tmpop,tmpop1,3)==1){
2522 existing=1;
2523 break;
2524 }
2525 }
2526 if(existing==1){continue;}
2527 /* if not existing, found one new symmetry operator */
2528 Matrix_Copy23(tmpop1,3,symop,op_count);
2529 if(debug3 == 1){
2530 printf("111found one now is %d\n",op_count+1);
2531 for(ii=0;ii<3;ii++){
2532 printf("%3d%3d%3d\n",tmpop1[ii][0],tmpop1[ii][1],tmpop1[ii][2]);
2533 }
2534 }
2535 op_count++;
2536 if(op_count>48){printf("111Error!Over 48\n");return 0;/*error*/}
2537 }
2538 }
2539 if(op_i==0){op2=op_count;}
2540 }
2541 /*Products with more than one sandwiched SIGMA-factor:*/
2542 new1=op_num;
2543 new2=op_count;
2544 for(i=1;i<50;i++){
2545 for(n=op_num;n<op2;n++){
2546 for(m=new1;m<new2;m++){
2547 Matrix_Copy32(tmpop,3,symop,n);
2548 Matrix_Copy32(tmpop1,3,symop,m);
2549 Matrix_Productor(3,tmpop,tmpop1,exop);
2550 existing=0;
2551 for(j=0;j<op_count;j++){
2552 Matrix_Copy32(tmpop,3,symop,j);
2553 if(Matrix_Equal(tmpop,exop,3)==1){
2554 existing=1;
2555 break;
2556 }
2557 }
2558 if(existing!=1){
2559 Matrix_Copy23(exop,3,symop,op_count);
2560 if(debug3 == 1){
2561 printf("222found one now is %d\n",op_count+1);
2562 for(ii=0;ii<3;ii++){
2563 printf("%3d%3d%3d\n",tmpop1[ii][0],tmpop1[ii][1],tmpop1[ii][2]);
2564 }
2565 }
2566 op_count++;
2567 if(op_count>48){printf("222Error!Over 48\n");return 0;}
2568 }
2569 }
2570 }
2571 if(new2==op_count){break;}
2572 new1=new2+1;
2573 new2=op_count;
2574 }
2575 op_num=op_count;
2576 }
2577
2578 for(i=0;i<3;i++){
2579 free(iden[i]);
2580 free(genop[i]);
2581 free(exop[i]);
2582 free(tmpop[i]);
2583 free(tmpop1[i]);
2584 }
2585 free(iden);
2586 free(genop);
2587 free(exop);
2588 free(tmpop);
2589 free(tmpop1);
2590
2591 return op_num;
2592 }
2593
2594
2595
Bravais_Lattice_Symmetry(int bravais_type,int *** symop)2596 int Bravais_Lattice_Symmetry(int bravais_type, int ***symop){
2597 /*Bravais_Lattice_Symmetry generates the symmetry operation of the pure bravais lattice determined above,
2598 without consideration of actual atomic arrangement (lattice basis)
2599 Input
2600 bravais_type
2601 OUTPUT
2602 sym_op symmetry operation matrix
2603 op_num number of symmetry operation
2604 */
2605 int op_num;
2606
2607 int ***symgen;
2608 int **inv, **rot3D, **rot6Z, **rot2hex, **rot2Ybc, **rot2Zbc, **rot2Ybas, **rot2Yfc, **rot2Zfc;
2609 int **rot2Tri, **rot4Zpri, **rot2Ypri, **rot4Zbc, **rot4Zfc, **rot2Zpri;
2610
2611 int i,j,k;
2612
2613 /*initiallize the operation generators */
2614 inv=(int**)malloc(sizeof(int*)*3);
2615 for(i=0;i<3;i++){
2616 inv[i]=(int*)malloc(sizeof(int)*3);
2617 }
2618 for(i=0;i<3;i++){
2619 for(j=0;j<3;j++){
2620 inv[i][j]=0;
2621 }
2622 }
2623 inv[0][0]=-1;inv[1][1]=-1;inv[2][2]=-1;
2624 /*
2625 -1 0 0
2626 0 -1 0
2627 0 0 -1
2628 DATA INV /-1,0,0,0,-1,0,0,0,-1/
2629 */
2630
2631 rot3D=(int**)malloc(sizeof(int*)*3);
2632 for(i=0;i<3;i++){
2633 rot3D[i]=(int*)malloc(sizeof(int)*3);
2634 }
2635 for(i=0;i<3;i++){
2636 for(j=0;j<3;j++){
2637 rot3D[i][j]=0;
2638 }
2639 }
2640 rot3D[0][1]=1;rot3D[1][2]=1;rot3D[2][0]=1;
2641 /*
2642 0 1 0
2643 0 0 1
2644 1 0 0
2645 R3D /0,0,1,1,0,0,0,1,0/
2646 */
2647
2648 rot4Zpri=(int**)malloc(sizeof(int*)*3);
2649 for(i=0;i<3;i++){
2650 rot4Zpri[i]=(int*)malloc(sizeof(int)*3);
2651 }
2652 for(i=0;i<3;i++){
2653 for(j=0;j<3;j++){
2654 rot4Zpri[i][j]=0;
2655 }
2656 }
2657 rot4Zpri[0][1]=1;rot4Zpri[1][0]=-1;rot4Zpri[2][2]=1;
2658 /*
2659 0 1 0
2660 -1 0 0
2661 0 0 1
2662 R4ZP /0,-1,0,1,0,0,0,0,1/
2663 */
2664
2665 rot2hex=(int**)malloc(sizeof(int*)*3);
2666 for(i=0;i<3;i++){
2667 rot2hex[i]=(int*)malloc(sizeof(int)*3);
2668 }
2669 for(i=0;i<3;i++){
2670 for(j=0;j<3;j++){
2671 rot2hex[i][j]=0;
2672 }
2673 }
2674 rot2hex[0][0]=1;rot2hex[1][0]=-1;rot2hex[1][1]=-1;rot2hex[2][2]=-1;
2675 /*
2676 1 0 0
2677 -1 -1 0
2678 0 0 -1
2679 R2HEX /1,-1,0,0,-1,0,0,0,-1/
2680 */
2681
2682 rot6Z=(int**)malloc(sizeof(int*)*3);
2683 for(i=0;i<3;i++){
2684 rot6Z[i]=(int*)malloc(sizeof(int)*3);
2685 }
2686
2687 for(i=0;i<3;i++){
2688 for(j=0;j<3;j++){
2689 rot6Z[i][j]=0;
2690 }
2691 }
2692 rot6Z[0][0]=1;rot6Z[0][1]=1;rot6Z[1][0]=-1;rot6Z[2][2]=1;
2693 /*
2694 1 1 0
2695 -1 0 0
2696 0 0 1
2697 DATA R6Z /1,-1,0,1,0,0,0,0,1/
2698 */
2699
2700 rot2Tri=(int**)malloc(sizeof(int*)*3);
2701 for(i=0;i<3;i++){
2702 rot2Tri[i]=(int*)malloc(sizeof(int)*3);
2703 }
2704 for(i=0;i<3;i++){
2705 for(j=0;j<3;j++){
2706 rot2Tri[i][j]=0;
2707 }
2708 }
2709 rot2Tri[0][0]=-1;rot2Tri[1][2]=-1;rot2Tri[2][1]=-1;
2710 /*
2711 -1 0 0
2712 0 0 -1
2713 0 -1 0
2714 DATA R2TRI /-1,0,0,0,0,-1,0,-1,0/
2715 */
2716
2717
2718
2719 rot2Ypri=(int**)malloc(sizeof(int*)*3);
2720 for(i=0;i<3;i++){
2721 rot2Ypri[i]=(int*)malloc(sizeof(int)*3);
2722 }
2723 for(i=0;i<3;i++){
2724 for(j=0;j<3;j++){
2725 rot2Ypri[i][j]=0;
2726 }
2727 }
2728 rot2Ypri[0][0]=-1;rot2Ypri[1][1]=1;rot2Ypri[2][2]=-1;
2729 /*
2730 -1 0 0
2731 0 1 0
2732 0 0 -1
2733 DATA R2YP /-1,0,0,0,1,0,0,0,-1/
2734 */
2735
2736 rot4Zbc=(int**)malloc(sizeof(int*)*3);
2737 for(i=0;i<3;i++){
2738 rot4Zbc[i]=(int*)malloc(sizeof(int)*3);
2739 }
2740 for(i=0;i<3;i++){
2741 for(j=0;j<3;j++){
2742 rot4Zbc[i][j]=0;
2743 }
2744 }
2745 rot4Zbc[0][2]=-1;rot4Zbc[1][0]=1;rot4Zbc[1][1]=1;rot4Zbc[1][2]=1;rot4Zbc[2][1]=-1;
2746 /*
2747 0 0 -1
2748 1 1 1
2749 0 -1 0
2750 R4ZBC /0,1,0,0,1,-1,-1,1,0/
2751 */
2752
2753 rot4Zfc=(int**)malloc(sizeof(int*)*3);
2754 for(i=0;i<3;i++){
2755 rot4Zfc[i]=(int*)malloc(sizeof(int)*3);
2756 }
2757 for(i=0;i<3;i++){
2758 for(j=0;j<3;j++){
2759 rot4Zfc[i][j]=0;
2760 }
2761 }
2762 rot4Zfc[0][0]=1;rot4Zfc[0][2]=-1;rot4Zfc[1][0]=1;rot4Zfc[2][0]=1;rot4Zfc[2][1]=-1;
2763 /*
2764 1 0 -1
2765 1 0 0
2766 1 -1 0
2767 DATA R4ZFC /1,1,1,0,0,-1,-1,0,0/
2768 */
2769
2770 rot2Zpri=(int**)malloc(sizeof(int*)*3);
2771 for(i=0;i<3;i++){
2772 rot2Zpri[i]=(int*)malloc(sizeof(int)*3);
2773 }
2774 for(i=0;i<3;i++){
2775 for(j=0;j<3;j++){
2776 rot2Zpri[i][j]=0;
2777 }
2778 }
2779 rot2Zpri[0][0]=-1;rot2Zpri[1][1]=-1;rot2Zpri[2][2]=1;
2780 /*
2781 -1 0 0
2782 0 -1 0
2783 0 0 1
2784 R2ZP /-1,0,0,0,-1,0,0,0,1/
2785 */
2786
2787 rot2Ybc=(int**)malloc(sizeof(int*)*3);
2788 for(i=0;i<3;i++){
2789 rot2Ybc[i]=(int*)malloc(sizeof(int)*3);
2790 }
2791 for(i=0;i<3;i++){
2792 for(j=0;j<3;j++){
2793 rot2Ybc[i][j]=0;
2794 }
2795 }
2796 rot2Ybc[0][2]=1;rot2Ybc[1][0]=-1;rot2Ybc[1][1]=-1;rot2Ybc[1][2]=-1;rot2Ybc[2][0]=1;
2797 /*
2798 0 0 1
2799 -1 -1 -1
2800 1 0 0
2801 DATA R2YBC /0,-1,1,0,-1,0,1,-1,0/
2802 */
2803
2804 rot2Zbc=(int**)malloc(sizeof(int*)*3);
2805 for(i=0;i<3;i++){
2806 rot2Zbc[i]=(int*)malloc(sizeof(int)*3);
2807 }
2808 for(i=0;i<3;i++){
2809 for(j=0;j<3;j++){
2810 rot2Zbc[i][j]=0;
2811 }
2812 }
2813 rot2Zbc[0][1]=1;rot2Zbc[1][0]=1;rot2Zbc[2][0]=-1;rot2Zbc[2][1]=-1;rot2Zbc[2][2]=-1;
2814 /*
2815 0 1 0
2816 1 0 0
2817 -1 -1 -1
2818 R2ZBC /0,1,-1,1,0,-1,0,0,-1/
2819 */
2820
2821 rot2Ybas=(int**)malloc(sizeof(int*)*3);
2822 for(i=0;i<3;i++){
2823 rot2Ybas[i]=(int*)malloc(sizeof(int)*3);
2824 }
2825 for(i=0;i<3;i++){
2826 for(j=0;j<3;j++){
2827 rot2Ybas[i][j]=0;
2828 }
2829 }
2830 rot2Ybas[0][1]=-1;rot2Ybas[1][0]=-1;rot2Ybas[2][2]=-1;
2831 /*
2832 0 -1 0
2833 -1 0 0
2834 0 0 -1
2835 DATA R2YBAS /0,-1,0,-1,0,0,0,0,-1/
2836 */
2837
2838 rot2Yfc=(int**)malloc(sizeof(int*)*3);
2839 for(i=0;i<3;i++){
2840 rot2Yfc[i]=(int*)malloc(sizeof(int)*3);
2841 }
2842 for(i=0;i<3;i++){
2843 for(j=0;j<3;j++){
2844 rot2Yfc[i][j]=0;
2845 }
2846 }
2847 rot2Yfc[0][1]=-1;rot2Yfc[0][2]=1;rot2Yfc[1][1]=-1;rot2Yfc[2][0]=1;rot2Yfc[2][1]=-1;
2848 /*
2849 0 -1 1
2850 0 -1 0
2851 1 -1 0
2852 R2YFC /0,0,1,-1,-1,-1,1,0,0/
2853 */
2854
2855 rot2Zfc=(int**)malloc(sizeof(int*)*3);
2856 for(i=0;i<3;i++){
2857 rot2Zfc[i]=(int*)malloc(sizeof(int)*3);
2858 }
2859 for(i=0;i<3;i++){
2860 for(j=0;j<3;j++){
2861 rot2Zfc[i][j]=0;
2862 }
2863 }
2864 rot2Zfc[0][1]=1;rot2Zfc[0][2]=-1;rot2Zfc[1][0]=1;rot2Zfc[1][2]=-1;rot2Zfc[2][2]=-1;
2865 /*
2866 0 1 -1
2867 1 0 -1
2868 0 0 -1
2869 DATA R2ZFC /0,1,0,1,0,0,-1,-1,-1/
2870 */
2871
2872
2873 symgen=(int***)malloc(sizeof(int**)*48);
2874 for(k=0; k<48; k++){
2875 symgen[k] = (int**)malloc(sizeof(int*)*3);
2876 for(i=0;i<3;i++){
2877 symgen[k][i] = (int*)malloc(sizeof(int)*3);
2878 }
2879 }
2880
2881 for (k=0; k<48; k++){
2882 for (i=0;i<3;i++){
2883 for (j=0;j<3;j++){
2884 symgen[k][i][j]=0;
2885 symop[k][i][j]=0;
2886 }
2887 }
2888 }
2889 /* debug printf("in Bravais_lattice_Symmetry lattice is %d\n",bravais_type); */
2890 Matrix_Copy23(inv,3,symgen,0);
2891
2892 switch(bravais_type){
2893 case 1: /* Primitive cubic cP */
2894 Matrix_Copy23(rot3D,3,symgen,1);
2895 Matrix_Copy23(rot4Zpri,3,symgen,2);
2896 if(debug3 == 1){
2897 printf("3 generator\n");
2898 for(k=0;k<3;k++){
2899 printf("%3d\n",k);
2900 for(i=0;i<3;i++){
2901 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
2902 }
2903 }
2904 }
2905 op_num=Symmtry_Operator_Generation(symgen,3,symop);
2906 break;
2907
2908 case 2: /* Body-centered cubic (cI)*/
2909 Matrix_Copy23(rot3D,3,symgen,1);
2910 Matrix_Copy23(rot4Zbc,3,symgen,2);
2911 if(debug3 == 1){
2912 printf("3 generator\n");
2913 for(k=0;k<3;k++){
2914 printf("%3d\n",k);
2915 for(i=0;i<3;i++){
2916 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
2917 }
2918 }
2919 }
2920 op_num=Symmtry_Operator_Generation(symgen,3,symop);
2921 break;
2922
2923 case 3: /* Face-centered cubic (cF)*/
2924 Matrix_Copy23(rot3D,3,symgen,1);
2925 Matrix_Copy23(rot4Zfc,3,symgen,2);
2926 if(debug3 == 1){
2927 printf("3 generator\n");
2928 for(k=0;k<3;k++){
2929 printf("%3d\n",k);
2930 for(i=0;i<3;i++){
2931 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
2932 }
2933 }
2934 }
2935 op_num=Symmtry_Operator_Generation(symgen,3,symop);
2936 break;
2937
2938 case 4: /* Primitive hexagonal (hP) */
2939 Matrix_Copy23(rot6Z,3,symgen,1);
2940 Matrix_Copy23(rot2hex,3,symgen,2);
2941 if(debug3 == 1){
2942 printf("3 generator\n");
2943 for(k=0;k<3;k++){
2944 printf("%3d\n",k);
2945 for(i=0;i<3;i++){
2946 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
2947 }
2948 }
2949 }
2950 op_num=Symmtry_Operator_Generation(symgen,3,symop);
2951 break;
2952
2953 case 5: /* Primitive tetragonal (tP)*/
2954 Matrix_Copy23(rot4Zpri,3,symgen,1);
2955 Matrix_Copy23(rot2Ypri,3,symgen,2);
2956 if(debug3 == 1){
2957 printf("3 generator\n");
2958 for(k=0;k<3;k++){
2959 printf("%3d\n",k);
2960 for(i=0;i<3;i++){
2961 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
2962 }
2963 }
2964 }
2965 op_num=Symmtry_Operator_Generation(symgen,3,symop);
2966 break;
2967
2968 case 6: /* Body-centred tetragonal (tI) */
2969 Matrix_Copy23(rot4Zbc,3,symgen,1);
2970 Matrix_Copy23(rot2Ybc,3,symgen,2);
2971 if(debug3 == 1){
2972 printf("3 generator\n");
2973 for(k=0;k<3;k++){
2974 printf("%3d\n",k);
2975 for(i=0;i<3;i++){
2976 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
2977 }
2978 }
2979 }
2980 op_num=Symmtry_Operator_Generation(symgen,3,symop);
2981 break;
2982
2983 case 7: /*Rhombohedral (hR) */
2984 Matrix_Copy23(rot2Tri,3,symgen,1);
2985 Matrix_Copy23(rot3D,3,symgen,2);
2986 if(debug3 == 1){
2987 printf("3 generator\n");
2988 for(k=0;k<3;k++){
2989 printf("%3d\n",k);
2990 for(i=0;i<3;i++){
2991 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
2992 }
2993 }
2994 }
2995 op_num=Symmtry_Operator_Generation(symgen,3,symop);
2996 break;
2997
2998 case 8: /* Primitive Orthorhombic (oP)*/
2999 Matrix_Copy23(rot2Zpri,3,symgen,1);
3000 Matrix_Copy23(rot2Ypri,3,symgen,2);
3001 if(debug3 == 1){
3002 printf("3 generator\n");
3003 for(k=0;k<3;k++){
3004 printf("%3d\n",k);
3005 for(i=0;i<3;i++){
3006 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
3007 }
3008 }
3009 }
3010 op_num=Symmtry_Operator_Generation(symgen,3,symop);
3011 break;
3012
3013 case 9: /* Body-centred Orthorhombic (oI) */
3014 Matrix_Copy23(rot2Zbc,3,symgen,1);
3015 Matrix_Copy23(rot2Ybc,3,symgen,2);
3016 if(debug3 == 1){
3017 printf("3 generator\n");
3018 for(k=0;k<3;k++){
3019 printf("%3d\n",k);
3020 for(i=0;i<3;i++){
3021 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
3022 }
3023 }
3024 }
3025 op_num=Symmtry_Operator_Generation(symgen,3,symop);
3026 break;
3027
3028 case 10: /* Face-centred Orthorhombic (oF) */
3029 Matrix_Copy23(rot2Zfc,3,symgen,1);
3030 Matrix_Copy23(rot2Yfc,3,symgen,2);
3031 if(debug3 == 1){
3032 printf("3 generator\n");
3033 for(k=0;k<3;k++){
3034 printf("%3d\n",k);
3035 for(i=0;i<3;i++){
3036 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
3037 }
3038 }
3039 }
3040 op_num=Symmtry_Operator_Generation(symgen,3,symop);
3041 break;
3042
3043 case 11: /* Base-centred Orthorhombic (oC) */
3044 Matrix_Copy23(rot2Zpri,3,symgen,1);
3045 Matrix_Copy23(rot2Ybas,3,symgen,2);
3046 if(debug3 == 1){
3047 printf("3 generator\n");
3048 for(k=0;k<3;k++){
3049 printf("%3d\n",k);
3050 for(i=0;i<3;i++){
3051 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
3052 }
3053 }
3054 }
3055 op_num=Symmtry_Operator_Generation(symgen,3,symop);
3056 break;
3057
3058 case 12: /* Primitive monoclinic (mP) */
3059 Matrix_Copy23(rot2Ypri,3,symgen,1);
3060 if(debug3 == 1){
3061 printf("2 generator\n");
3062 for(k=0;k<2;k++){
3063 printf("%3d\n",k);
3064 for(i=0;i<3;i++){
3065 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
3066 }
3067 }
3068 }
3069 op_num=Symmtry_Operator_Generation(symgen,2,symop);
3070 break;
3071
3072 case 13:/* Base-centred monoclinic (mB) */
3073 Matrix_Copy23(rot2Ybas,3,symgen,1);
3074 if(debug3 == 1){
3075 printf("2 generator\n");
3076 for(k=0;k<2;k++){
3077 printf("%3d\n",k);
3078 for(i=0;i<3;i++){
3079 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
3080 }
3081 }
3082 }
3083 op_num=Symmtry_Operator_Generation(symgen,2,symop);
3084 break;
3085
3086 case 14:/* Primitive triclinic (aP) */
3087 if(debug3 == 1){
3088 printf("1 generator\n");
3089 for(k=0;k<1;k++){
3090 printf("%3d\n",k);
3091 for(i=0;i<3;i++){
3092 printf("%3d%3d%3d\n",symgen[k][i][0],symgen[k][i][1],symgen[k][i][2]);
3093 }
3094 }
3095 }
3096 op_num=Symmtry_Operator_Generation(symgen,1,symop);
3097 break;
3098 default:
3099 printf("Eorr in lattice type!\n");
3100 return 0;
3101 break;
3102 }
3103
3104 for(i=0; i<3; i++){
3105 free(inv[i]);
3106 free(rot3D[i]);
3107 free(rot6Z[i]);
3108 free(rot2hex[i]);
3109 free(rot2Ybc[i]);
3110 free(rot2Zbc[i]);
3111 free(rot2Ybas[i]);
3112 free(rot2Yfc[i]);
3113 free(rot2Zfc[i]);
3114 free(rot2Tri[i]);
3115 free(rot4Zpri[i]);
3116 free(rot2Ypri[i]);
3117 free(rot4Zbc[i]);
3118 free(rot4Zfc[i]);
3119 free(rot2Zpri[i]);
3120 }
3121 free(inv);
3122 free(rot3D);
3123 free(rot6Z);
3124 free(rot2hex);
3125 free(rot2Ybc);
3126 free(rot2Zbc);
3127 free(rot2Ybas);
3128 free(rot2Yfc);
3129 free(rot2Zfc);
3130 free(rot2Tri);
3131 free(rot4Zpri);
3132 free(rot2Ypri);
3133 free(rot4Zbc);
3134 free(rot4Zfc);
3135 free(rot2Zpri);
3136
3137 for(k=0; k<48; k++){
3138 for(i=0; i<3; i++){
3139 free(symgen[k][i]);
3140 }
3141 free(symgen[k]);
3142 }
3143 free(symgen);
3144
3145 return op_num;
3146 }
3147
Ascend_Ordering(double * xyz_value,int * ordering,int tot_atom)3148 void Ascend_Ordering(double *xyz_value, int *ordering, int tot_atom){
3149 int i,j,k, tmp_order;
3150 double tmp_xyz;
3151
3152 for(i=1;i<tot_atom; i++){/* taking one value */
3153 for(j=i;j>0;j--){ /* compare with all the other lower index value */
3154 if(xyz_value[j]<xyz_value[j-1]){/* if it is smaller than lower index value, exchange */
3155 tmp_xyz=xyz_value[j];
3156 xyz_value[j]=xyz_value[j-1];
3157 xyz_value[j-1]=tmp_xyz;
3158 tmp_order = ordering[j];
3159 ordering[j]=ordering[j-1];
3160 ordering[j-1]=tmp_order;
3161 }
3162 }
3163 }
3164 return;
3165 }
3166
Ordering_Atomic_Position(double ** atomic_position,int start_atom_indx,int end_atom_indx)3167 void Ordering_Atomic_Position(double **atomic_position, int start_atom_indx, int end_atom_indx){
3168 int atom_indx, tot_atom;
3169 int i,j,k, num_x, num_y, start_i;
3170 double **ordered_atom_pos;
3171 double *xyz_value;
3172 double tmp_value;
3173
3174 int *ordering;/* memorizing the atom_indx in the ascending order */
3175
3176 tot_atom=end_atom_indx-start_atom_indx;
3177 if(debug2==1){
3178 printf("To be ordered atomic position is:\n");
3179 for(i=0;i<tot_atom;i++){
3180 atom_indx=i+start_atom_indx;
3181 printf("atom %2d %12.8f %12.8f %12.8f\n",atom_indx,atomic_position[atom_indx][0],atomic_position[atom_indx][1],atomic_position[atom_indx][2]);
3182 }
3183 }
3184
3185 ordered_atom_pos=(double**)malloc(sizeof(double*)*tot_atom);
3186 xyz_value=(double*)malloc(sizeof(double)*tot_atom);
3187 ordering=(int*)malloc(sizeof(int*)*tot_atom);
3188 for(k=0;k<tot_atom;k++){
3189 ordered_atom_pos[k]=(double*)malloc(sizeof(double)*3);
3190 xyz_value[k]=0.0;
3191 ordering[k]=0;
3192 }
3193
3194 /* Firstly, arrange x-coordinates in ascending order */
3195 for(i=0;i<tot_atom;i++){
3196 atom_indx=i+start_atom_indx;
3197 xyz_value[i]=atomic_position[atom_indx][0];
3198 ordering[i]=atom_indx;
3199 }
3200 Ascend_Ordering(xyz_value, ordering, tot_atom);
3201
3202 for(k=0;k<tot_atom;k++){
3203 ordered_atom_pos[k][0]=atomic_position[ordering[k]][0];
3204 ordered_atom_pos[k][1]=atomic_position[ordering[k]][1];
3205 ordered_atom_pos[k][2]=atomic_position[ordering[k]][2];
3206 }
3207 for(k=0;k<tot_atom;k++){
3208 atomic_position[k+start_atom_indx][0]=ordered_atom_pos[k][0];
3209 atomic_position[k+start_atom_indx][1]=ordered_atom_pos[k][1];
3210 atomic_position[k+start_atom_indx][2]=ordered_atom_pos[k][2];
3211 }
3212 if(debug2==1){
3213 printf("after ordering x-value:\n");
3214 for(i=0;i<tot_atom;i++){
3215 atom_indx=i+start_atom_indx;
3216 printf("atom %2d %12.8f %12.8f %12.8f\n",atom_indx,atomic_position[atom_indx][0],atomic_position[atom_indx][1],atomic_position[atom_indx][2]);
3217 }
3218 }
3219 /* Secondly, arrange y-coordinats those have same x-coordinates in ascending order */
3220 tmp_value=atomic_position[start_atom_indx][0];
3221 num_x=1;
3222 start_i=0;
3223 xyz_value[num_x-1]=atomic_position[start_atom_indx][1];
3224 ordering[num_x-1]=start_atom_indx;
3225
3226 for(i=1;i<tot_atom;i++){
3227 atom_indx=i+start_atom_indx;
3228 if(tmp_value==atomic_position[atom_indx][0]){
3229 num_x++;
3230 xyz_value[num_x-1]=atomic_position[atom_indx][1];
3231 ordering[num_x-1]=atom_indx;
3232 if(i==tot_atom-1){
3233 Ascend_Ordering(xyz_value, ordering, num_x);
3234 for(k=0;k<num_x;k++){
3235 ordered_atom_pos[k][0]=atomic_position[ordering[k]][0];
3236 ordered_atom_pos[k][1]=atomic_position[ordering[k]][1];
3237 ordered_atom_pos[k][2]=atomic_position[ordering[k]][2];
3238 }
3239 for(k=0;k<num_x;k++){
3240 atomic_position[start_i+k+start_atom_indx][0]=ordered_atom_pos[k][0];
3241 atomic_position[start_i+k+start_atom_indx][1]=ordered_atom_pos[k][1];
3242 atomic_position[start_i+k+start_atom_indx][2]=ordered_atom_pos[k][2];
3243 }
3244 }
3245 }else{
3246 Ascend_Ordering(xyz_value, ordering, num_x);
3247 for(k=0;k<num_x;k++){
3248 ordered_atom_pos[k][0]=atomic_position[ordering[k]][0];
3249 ordered_atom_pos[k][1]=atomic_position[ordering[k]][1];
3250 ordered_atom_pos[k][2]=atomic_position[ordering[k]][2];
3251 }
3252 for(k=0;k<num_x;k++){
3253 atomic_position[start_i+k+start_atom_indx][0]=ordered_atom_pos[k][0];
3254 atomic_position[start_i+k+start_atom_indx][1]=ordered_atom_pos[k][1];
3255 atomic_position[start_i+k+start_atom_indx][2]=ordered_atom_pos[k][2];
3256 }
3257 start_i=i;
3258 num_x=1;
3259 tmp_value=atomic_position[atom_indx][0];
3260 xyz_value[num_x-1]=atomic_position[atom_indx][1];
3261 ordering[num_x-1]=atom_indx;
3262 }
3263 }
3264 if(debug2==1){
3265 printf("after ordering x,y-value:\n");
3266 for(i=0;i<tot_atom;i++){
3267 atom_indx=i+start_atom_indx;
3268 printf("atom %2d %12.8f %12.8f %12.8f\n",atom_indx,atomic_position[atom_indx][0],atomic_position[atom_indx][1],atomic_position[atom_indx][2]);
3269 }
3270 }
3271 /* At last, arrange z-coordinats those have same y-coordinates in ascending order
3272 Now just looking at the y values, x values are not necessarily monitored.*/
3273 tmp_value=atomic_position[start_atom_indx][1];
3274 num_x=1;
3275 start_i=0;
3276 xyz_value[num_x-1]=atomic_position[start_atom_indx][2];
3277 ordering[num_x-1]=start_atom_indx;
3278 for(i=1;i<tot_atom;i++){
3279 atom_indx=i+start_atom_indx;
3280 if(tmp_value==atomic_position[atom_indx][1]){
3281 num_x++;
3282 xyz_value[num_x-1]=atomic_position[atom_indx][2];
3283 ordering[num_x-1]=atom_indx;
3284 if(i==tot_atom-1){
3285 Ascend_Ordering(xyz_value, ordering, num_x);
3286 for(k=0;k<num_x;k++){
3287 ordered_atom_pos[k][0]=atomic_position[ordering[k]][0];
3288 ordered_atom_pos[k][1]=atomic_position[ordering[k]][1];
3289 ordered_atom_pos[k][2]=atomic_position[ordering[k]][2];
3290 }
3291 for(k=0;k<num_x;k++){
3292 atomic_position[start_i+k+start_atom_indx][0]=ordered_atom_pos[k][0];
3293 atomic_position[start_i+k+start_atom_indx][1]=ordered_atom_pos[k][1];
3294 atomic_position[start_i+k+start_atom_indx][2]=ordered_atom_pos[k][2];
3295 }
3296 }
3297 }else{
3298 Ascend_Ordering(xyz_value, ordering, num_x);
3299 for(k=0;k<num_x;k++){
3300 ordered_atom_pos[k][0]=atomic_position[ordering[k]][0];
3301 ordered_atom_pos[k][1]=atomic_position[ordering[k]][1];
3302 ordered_atom_pos[k][2]=atomic_position[ordering[k]][2];
3303 }
3304 for(k=0;k<num_x;k++){
3305 atomic_position[start_i+k+start_atom_indx][0]=ordered_atom_pos[k][0];
3306 atomic_position[start_i+k+start_atom_indx][1]=ordered_atom_pos[k][1];
3307 atomic_position[start_i+k+start_atom_indx][2]=ordered_atom_pos[k][2];
3308 }
3309 start_i=i;
3310 num_x=1;
3311 tmp_value=atomic_position[atom_indx][1];
3312 xyz_value[num_x-1]=atomic_position[atom_indx][2];
3313 ordering[num_x-1]=atom_indx;
3314 }
3315 }
3316 /* OK, now all the ordering work done */
3317 if(debug2==1){
3318 printf("after ordering x,y,z-value:\n");
3319 for(i=0;i<tot_atom;i++){
3320 atom_indx=i+start_atom_indx;
3321 printf("atom %2d %12.8f %12.8f %12.8f\n",atom_indx,atomic_position[atom_indx][0],atomic_position[atom_indx][1],atomic_position[atom_indx][2]);
3322 }
3323 }
3324
3325 for(k=0;k<tot_atom;k++){
3326 free(ordered_atom_pos[k]);
3327 }
3328 free(ordered_atom_pos);
3329 free(xyz_value);
3330 free(ordering);
3331
3332 return;
3333 }
3334
Chk_Pure_Point_Group_Op(int ** exop,double ** atomic_position,int * atom_species,int atom_num,int atom_type,double * trans_vec)3335 int Chk_Pure_Point_Group_Op(int **exop, double **atomic_position, int *atom_species,
3336 int atom_num, int atom_type, double *trans_vec){
3337 /*
3338 check whether this operation (exop) is pure point group operation or not, if not, find the
3339 connected translation vector (tmp_vec)
3340 INPUT
3341 exop one symmetry operation
3342 atomic_position[atom_indx][atom_type_indx][3] lattice basis (atomic arrangement)
3343 atom_num total number of atoms in the lattice
3344 atom_type number of atoms' species
3345 atom_species
3346 OUTPUT
3347 pure_point Whether the given operation is pure point group operation or not
3348 tmp_vec the translation vector for non pure point group operation
3349 pure_point = Chk_Pure_Point_Group_Op(exop,atomic_position,atom_species,atom_num,atom_type,tmp_vec);
3350 */
3351
3352 int atom_indx, atom_type_indx, start_atom_indx, end_atom_indx,atom_indx2;
3353 int pure_point,foundone;
3354 int i,j,k;
3355 double **roted_xyz;
3356 double *markone, *tmp_vec, *diff_vec;
3357 char c;
3358 int smallest_species;
3359
3360 foundone=0;
3361 roted_xyz=(double**)malloc(sizeof(double*)*atom_num);
3362 markone=(double*)malloc(sizeof(double)*3);
3363 tmp_vec=(double*)malloc(sizeof(double)*3);
3364 diff_vec=(double*)malloc(sizeof(double)*3);
3365 for(k=0; k<atom_num; k++){
3366 roted_xyz[k] = (double*)malloc(sizeof(double)*3);
3367 for(i=0; i<3; i++){
3368 roted_xyz[k][i] = 0.0;
3369 tmp_vec[i]=3.0;
3370 }
3371 }
3372 /*to be consistent wit VASP, finding the species having smallest number of atom*/
3373 j=atom_species[0];
3374 smallest_species=0;
3375 for(i=1;i<atom_type;i++){
3376 if((atom_species[i]-atom_species[i-1])<j){
3377 j=atom_species[i]-atom_species[i-1];
3378 smallest_species=i;
3379 }
3380 }
3381 if(debug3==1){
3382 printf("smallest number of species is %2d\n",smallest_species);
3383 }
3384 for(atom_type_indx=0;atom_type_indx<atom_type;atom_type_indx++){
3385 if(atom_type_indx==0){
3386 start_atom_indx=0;/* The atoms of first species are stored from 0 index */
3387 }else{
3388 start_atom_indx=atom_species[atom_type_indx-1]; /*Other species atoms are stored from atom_species[atom_type_indx-1] */
3389 }
3390 end_atom_indx=atom_species[atom_type_indx];
3391
3392 for(atom_indx=start_atom_indx;atom_indx<end_atom_indx;atom_indx++){
3393 /* 1. Precess the atomic coordinates, make them be [-0.5, 0.5)
3394 (Applying periodic boundary condition)
3395 */
3396 if(debug3==1){
3397 printf("atom %3d ",atom_indx);
3398 }
3399 for(i=0;i<3;i++){
3400 /* make it positive and less than +1.0 */
3401 if(debug3==1){
3402 printf("%12.8f-->",atomic_position[atom_indx][i]);
3403 }
3404 atomic_position[atom_indx][i]=atomic_position[atom_indx][i]-floor(atomic_position[atom_indx][i]);
3405 atomic_position[atom_indx][i]=fmod(atomic_position[atom_indx][i]+1000.5,1.0)-0.5;
3406 if(debug3==1){
3407 printf("%10.8f",atomic_position[atom_indx][i]);
3408 }
3409 }
3410 if(debug3==1){
3411 printf("\n");
3412 }
3413 }
3414 /* 2. Ordering the atomic coordinates of same species with index from start to end.
3415 firstly x- then y-, z- last. */
3416 Ordering_Atomic_Position(atomic_position, start_atom_indx, end_atom_indx);
3417 /* 3. Applying symmetry operation to each atom's coordinates */
3418 if(debug3==1){
3419 printf("NOW applying Symmetry Operation:\n");
3420 }
3421 for(atom_indx=start_atom_indx;atom_indx<end_atom_indx;atom_indx++){
3422 /*
3423 roted_xyz[atom_indx][0]=exop[0][0]*atomic_position[atom_indx][0]+exop[0][1]*atomic_position[atom_indx][1]+exop[0][2]*atomic_position[atom_indx][2];
3424 roted_xyz[atom_indx][1]=exop[1][0]*atomic_position[atom_indx][0]+exop[1][1]*atomic_position[atom_indx][1]+exop[1][2]*atomic_position[atom_indx][2];
3425 roted_xyz[atom_indx][2]=exop[2][0]*atomic_position[atom_indx][0]+exop[2][1]*atomic_position[atom_indx][1]+exop[2][2]*atomic_position[atom_indx][2];
3426 */
3427 roted_xyz[atom_indx][0]=exop[0][0]*atomic_position[atom_indx][0]+exop[1][0]*atomic_position[atom_indx][1]+exop[2][0]*atomic_position[atom_indx][2];
3428 roted_xyz[atom_indx][1]=exop[0][1]*atomic_position[atom_indx][0]+exop[1][1]*atomic_position[atom_indx][1]+exop[2][1]*atomic_position[atom_indx][2];
3429 roted_xyz[atom_indx][2]=exop[0][2]*atomic_position[atom_indx][0]+exop[1][2]*atomic_position[atom_indx][1]+exop[2][2]*atomic_position[atom_indx][2];
3430
3431 /* Similarly, applying periodic boundary condition*/
3432 if(debug3==1){
3433 printf("atom %3d ",atom_indx);
3434 }
3435 for(i=0;i<3;i++){
3436 /* make it positive and less than +1.0 */
3437 if(debug3==1){
3438 printf("%12.8f-->",atomic_position[atom_indx][i]);
3439 }
3440 roted_xyz[atom_indx][i]=roted_xyz[atom_indx][i]-floor(roted_xyz[atom_indx][i]);
3441 roted_xyz[atom_indx][i]=fmod(roted_xyz[atom_indx][i]+1000.5,1.0)-0.5;
3442 if(debug3==1){
3443 printf("%10.8f",roted_xyz[atom_indx][i]);
3444 }
3445 }
3446 if(debug3==1){
3447 printf("\n");
3448 }
3449 }
3450 Ordering_Atomic_Position(roted_xyz, start_atom_indx, end_atom_indx);
3451 }
3452 /* Comparing the original and rotated atomic positions to check the symmetry operation
3453 or to find the translation vector connecting rotated and original coordinates*/
3454
3455 if(smallest_species==0){
3456 start_atom_indx=0;
3457 }else{
3458 start_atom_indx=atom_species[smallest_species-1];
3459 }
3460 markone[0]=roted_xyz[start_atom_indx][0];
3461 markone[1]=roted_xyz[start_atom_indx][1];
3462 markone[2]=roted_xyz[start_atom_indx][2];
3463 if(debug3==1){
3464 printf("MARKED atom is %12.8f%12.8f%12.8f\n",markone[0],markone[1],markone[2]);
3465 }
3466 for(atom_indx=start_atom_indx;atom_indx<atom_species[smallest_species];atom_indx++){
3467 trans_vec[0]=atomic_position[atom_indx][0]-markone[0];
3468 trans_vec[1]=atomic_position[atom_indx][1]-markone[1];
3469 trans_vec[2]=atomic_position[atom_indx][2]-markone[2];
3470
3471 trans_vec[0]=fmod(trans_vec[0]+1000.0,1.0);
3472 trans_vec[1]=fmod(trans_vec[1]+1000.0,1.0);
3473 trans_vec[2]=fmod(trans_vec[2]+1000.0,1.0);
3474 if(fabs(trans_vec[0]-1.0)<smallvalue){trans_vec[0]=0.0;}
3475 if(fabs(trans_vec[1]-1.0)<smallvalue){trans_vec[1]=0.0;}
3476 if(fabs(trans_vec[2]-1.0)<smallvalue){trans_vec[2]=0.0;}
3477 if(debug3==1){
3478 printf("atom %2d and ",atom_indx);
3479 printf("TRANS_VEC %12.8f%12.8f%12.8f\n",trans_vec[0],trans_vec[1],trans_vec[2]);
3480 printf("tmp_vec %12.8f%12.8f%12.8f\n",tmp_vec[0],tmp_vec[1],tmp_vec[2]);
3481 /* c=getchar(); */
3482 }
3483
3484 if(trans_vec[0]>(smallvalue+tmp_vec[0])
3485 ||trans_vec[1]>(smallvalue+tmp_vec[1])
3486 ||trans_vec[2]>(smallvalue+tmp_vec[2])){
3487 if(debug3==1){
3488 printf("Ignore too large vector\n");
3489 }
3490 }else{
3491 /* translate the rotated coordinates with trans_vec and compare with original ones*/
3492 if(debug3==1){
3493 printf("applying TRANSLATION vectors:\n");
3494 }
3495 for(atom_type_indx=0;atom_type_indx<atom_type;atom_type_indx++){
3496 if(atom_type_indx==0){
3497 start_atom_indx=0;/* The atoms of first species are stored from 0 index */
3498 }else{
3499 start_atom_indx=atom_species[atom_type_indx-1]; /*Other species atoms are stored from atom_species[atom_type_indx-1] */
3500 }
3501 end_atom_indx=atom_species[atom_type_indx];
3502
3503 for(atom_indx2=start_atom_indx;atom_indx2<end_atom_indx;atom_indx2++){
3504 /* Applying periodic boundary condition */
3505 if(debug3==1){
3506 printf("atom %3d ",atom_indx2);
3507 }
3508 for(i=0;i<3;i++){
3509 /* make it positive and less than +1.0 */
3510 if(debug3==1){
3511 printf("%12.8f-->",roted_xyz[atom_indx2][i]);
3512 }
3513 roted_xyz[atom_indx2][i]=roted_xyz[atom_indx2][i]+trans_vec[i];
3514 roted_xyz[atom_indx2][i]=roted_xyz[atom_indx2][i]-floor(roted_xyz[atom_indx2][i]);
3515 roted_xyz[atom_indx2][i]=fmod(roted_xyz[atom_indx2][i]+1000.5,1.0)-0.5;
3516 if(debug3==1){
3517 printf("%10.8f",roted_xyz[atom_indx2][i]);
3518 }
3519 }
3520 if(debug3==1){
3521 printf("\n");
3522 }
3523 }
3524 /* Ordering the atomic coordinates of same species with index from start to end.
3525 firstly x- then y-, z- last. */
3526 Ordering_Atomic_Position(roted_xyz, start_atom_indx, end_atom_indx);
3527 }/*applying translation */
3528 /* after translation, now comparing */
3529 pure_point=0;
3530 for(atom_type_indx=0;atom_type_indx<atom_type;atom_type_indx++){
3531 if(atom_type_indx==0){
3532 start_atom_indx=0;/* The atoms of first species are stored from 0 index */
3533 }else{
3534 start_atom_indx=atom_species[atom_type_indx-1]; /*Other species atoms are stored from atom_species[atom_type_indx-1] */
3535 }
3536 end_atom_indx=atom_species[atom_type_indx];
3537 for(atom_indx2=start_atom_indx;atom_indx2<end_atom_indx;atom_indx2++){
3538 diff_vec[0]=atomic_position[atom_indx2][0]-roted_xyz[atom_indx2][0];
3539 diff_vec[1]=atomic_position[atom_indx2][1]-roted_xyz[atom_indx2][1];
3540 diff_vec[2]=atomic_position[atom_indx2][2]-roted_xyz[atom_indx2][2];
3541
3542 diff_vec[0]=fmod(diff_vec[0]+1000.0,1.0);
3543 diff_vec[1]=fmod(diff_vec[1]+1000.0,1.0);
3544 diff_vec[2]=fmod(diff_vec[2]+1000.0,1.0);
3545 if(fabs(diff_vec[0]-1.0)<smallvalue){diff_vec[0]=0.0;}
3546 if(fabs(diff_vec[1]-1.0)<smallvalue){diff_vec[1]=0.0;}
3547 if(fabs(diff_vec[2]-1.0)<smallvalue){diff_vec[2]=0.0;}
3548 if(fabs(diff_vec[0])<smallvalue
3549 &&fabs(diff_vec[1])<smallvalue
3550 &&fabs(diff_vec[2])<smallvalue){
3551 pure_point=1;
3552 }else{
3553 pure_point=0;
3554 if(debug3==1){
3555 printf("NOT TRANSLATED!!!!!\n");
3556 }
3557 break;
3558 }
3559 }
3560 if(pure_point==0){break;}
3561 }/*comparing */
3562 if(pure_point==1){
3563 /*translation vector can reproduce all the atomic position, mark it */
3564 tmp_vec[0]=trans_vec[0];
3565 tmp_vec[1]=trans_vec[1];
3566 tmp_vec[2]=trans_vec[2];
3567 /* printf("Haha!!!!!!!!!!!!!!!!!!!!!! FOUND ONE\n"); */
3568 /* printf("tmp_vec %12.8f%12.8f%12.8f\n",tmp_vec[0],tmp_vec[1],tmp_vec[2]); */
3569 foundone=1;
3570 }
3571 for(atom_type_indx=0;atom_type_indx<atom_type;atom_type_indx++){
3572 if(atom_type_indx==0){
3573 start_atom_indx=0;/* The atoms of first species are stored from 0 index */
3574 }else{
3575 start_atom_indx=atom_species[atom_type_indx-1]; /*Other species atoms are stored from atom_species[atom_type_indx-1] */
3576 }
3577 end_atom_indx=atom_species[atom_type_indx];
3578
3579 for(atom_indx2=start_atom_indx;atom_indx2<end_atom_indx;atom_indx2++){
3580 for(i=0;i<3;i++){
3581 roted_xyz[atom_indx2][i]=roted_xyz[atom_indx2][i]-trans_vec[i];
3582 roted_xyz[atom_indx2][i]=roted_xyz[atom_indx2][i]-floor(roted_xyz[atom_indx2][i]);
3583 roted_xyz[atom_indx2][i]=fmod(roted_xyz[atom_indx2][i]+1000.5,1.0)-0.5;
3584 }
3585 }
3586 }
3587 }/*find a translation vector */
3588 }
3589 if(foundone==1){
3590 trans_vec[0]=tmp_vec[0];
3591 trans_vec[1]=tmp_vec[1];
3592 trans_vec[2]=tmp_vec[2];
3593 }
3594
3595 for(k=0; k<atom_num; k++){
3596 free(roted_xyz[k]);
3597 }
3598 free(roted_xyz);
3599 free(markone);
3600 free(tmp_vec);
3601 free(diff_vec);
3602
3603 return foundone;
3604 }
3605
Get_Symmetry_Operation(int *** symop,int * opnum,double ** atomic_position,int * atom_species,int atom_num,int atom_type,int * num_pnt_op,double ** trans_op_vec)3606 void Get_Symmetry_Operation(int ***symop, int *opnum, double **atomic_position, int *atom_species,
3607 int atom_num, int atom_type, int *num_pnt_op, double **trans_op_vec){
3608 /* Find the possible symmetry operations according to the atomic arrangement
3609 (lattic basis, atomic_position) from the pool of symmetry operations
3610 (sym_op[op_num][3][3]) found from pure bravais lattice. sym_op matix is changed
3611 after Get_Symmetry_Operation. Totally it returns op_num operations while the first
3612 num_pure_pnt_op is the pure point symmetry operation. The left are those connected
3613 with translation vectors, which are stored in trans_op[op_num-num_pure_pnt_op][3].
3614 */
3615 int i,j,k,pure_point;
3616 int **exop;
3617 int ***spg_op; /* temp array for store founded space group (non pure point group) operation */
3618 double **trans_vec;
3619 double *tmp_vec;
3620 char c;
3621 int op_num,sizeof_matrix;
3622 int num_pure_pnt_op,num_spg_op;
3623
3624
3625 num_pure_pnt_op=0;
3626 num_spg_op=0;
3627 pure_point = 0;
3628
3629 op_num=*opnum;
3630 sizeof_matrix=op_num;
3631
3632 spg_op = (int***)malloc(sizeof(int**)*op_num);
3633 for (k=0; k<op_num; k++){
3634 spg_op[k] = (int**)malloc(sizeof(int*)*3);
3635 for (i=0; i<3; i++){
3636 spg_op[k][i] = (int*)malloc(sizeof(int)*3);
3637 for (j=0; j<3; j++) spg_op[k][i][j] = 0;
3638 }
3639 }
3640
3641 trans_vec = (double**)malloc(sizeof(double*)*op_num);
3642 for (k=0; k<op_num; k++){
3643 trans_vec[k]=(double*)malloc(sizeof(double)*3);
3644 for (i=0; i<3; i++) trans_vec[k][i] = 0.0;
3645 }
3646
3647 exop=(int**)malloc(sizeof(int*)*3);
3648 tmp_vec=(double*)malloc(sizeof(double)*3);
3649 for(i=0;i<3;i++){
3650 exop[i]=(int*)malloc(sizeof(int)*3);
3651 tmp_vec[i]=0.0;
3652 }
3653 for(i=0;i<3;i++){
3654 for(j=0;j<3;j++){
3655 exop[i][j]=0;
3656 }
3657 }
3658
3659 for(k=0;k<op_num;k++){ /* for each operation */
3660
3661 Matrix_Copy32(exop,3,symop,k);
3662 if(debug2 ==1 ){
3663 printf("operation %2d:\n",k);
3664 for(i=0;i<3;i++){
3665 printf("%4d%4d%4d\n",exop[i][0],exop[i][1],exop[i][2]);
3666 }
3667 }
3668 /*
3669 check whether this operation (exop) is pure point group operation or not, if not,
3670 find the connected translation vector (tmp_vec)
3671 INPUT
3672 exop one symmetry operation
3673 atomic_position[atom_indx][atom_type_indx][3] lattice basis (atomic arrangement)
3674 atom_num total number of atoms in the lattice
3675 atom_type number of atoms' species
3676 */
3677 pure_point = Chk_Pure_Point_Group_Op(exop,atomic_position,atom_species,atom_num,atom_type,tmp_vec);
3678 if(pure_point==1){/* if it is an allowed symmetry */
3679 if(debug2 ==1 ){
3680 printf("********************This is an allowed symmetry. Number %2d\n",k);
3681 }
3682 if(fabs(tmp_vec[0])<smallvalue
3683 &&fabs(tmp_vec[1])<smallvalue
3684 &&fabs(tmp_vec[2])<smallvalue){
3685 /* pure point group symmetry */
3686 Matrix_Copy23(exop,3,symop,num_pure_pnt_op);
3687 trans_op_vec[num_pure_pnt_op][0]=0.0;
3688 trans_op_vec[num_pure_pnt_op][1]=0.0;
3689 trans_op_vec[num_pure_pnt_op][2]=0.0;
3690 num_pure_pnt_op++;
3691 }else{
3692 /* space group symmetry */
3693
3694 Matrix_Copy23(exop,3,spg_op,num_spg_op);
3695 trans_vec[num_spg_op][0]=tmp_vec[0];
3696 trans_vec[num_spg_op][1]=tmp_vec[1];
3697 trans_vec[num_spg_op][2]=tmp_vec[2];
3698 if(debug2 ==1 ){
3699 printf("********************But with translation vector%8.5f%8.5f%8.5f\n",tmp_vec[0],tmp_vec[1],tmp_vec[2]);
3700 }
3701 num_spg_op++;
3702 }
3703 }else{
3704 if(debug2 ==1 ){
3705 printf("!!!NOT allowed symmetry. Number %2d\n",k);
3706 }
3707 }
3708 }
3709
3710 for(i=0;i<num_spg_op;i++){/* put space group operations and corresponding translation vector*/
3711 Matrix_Copy32(exop,3,spg_op,i);
3712 Matrix_Copy23(exop,3,symop,i+num_pure_pnt_op);
3713 trans_op_vec[i+num_pure_pnt_op][0]=trans_vec[i][0];
3714 trans_op_vec[i+num_pure_pnt_op][1]=trans_vec[i][1];
3715 trans_op_vec[i+num_pure_pnt_op][2]=trans_vec[i][2];
3716 }
3717
3718 op_num=num_pure_pnt_op+num_spg_op;
3719 for(i=0;i<3;i++){
3720 for(j=0;j<3;j++){
3721 exop[i][j]=0;
3722 }
3723 }
3724 for(i=op_num;i<*opnum;i++){
3725 Matrix_Copy23(exop,3,symop,i);
3726 trans_op_vec[i][0]=0.0;
3727 trans_op_vec[i][1]=0.0;
3728 trans_op_vec[i][2]=0.0;
3729 }
3730 *opnum=op_num;
3731 *num_pnt_op=num_pure_pnt_op;
3732 /* printf("the allowed symmetry number is %2d and there are %2d space group operation\n",*opnum, *num_pnt_op); */
3733
3734 for (k=0; k<sizeof_matrix; k++){
3735 free(trans_vec[k]);
3736 }
3737 free(trans_vec);
3738
3739 for (k=0; k<sizeof_matrix; k++){
3740 for (i=0; i<3; i++){
3741 free(spg_op[k][i]);
3742 }
3743 free(spg_op[k]);
3744 }
3745 free(spg_op);
3746
3747 for(i=0;i<3;i++){
3748 free(exop[i]);
3749 }
3750 free(tmp_vec);
3751 free(exop);
3752 }
3753
Chk_Primitive_Cell(int bravais_type,double * cell_parameters,double ** lattice_vector,double ** atomic_position,int * atom_species,int atom_num,int atom_type,double ** platt,double ** ptran_vec,double * pcell_parameters,int * npcell)3754 int Chk_Primitive_Cell(int bravais_type, double *cell_parameters, double **lattice_vector,
3755 double **atomic_position, int *atom_species,int atom_num, int atom_type,
3756 double **platt, double **ptran_vec, double *pcell_parameters,int *npcell){
3757 /* Check whether the inputed unit cell is a primitive cell or not
3758 INPUT
3759 bravais_type Bravais lattice type
3760 cell_parameters a, b, c length and angles between vectors
3761 lattice_vector the original lattice vectors
3762 atomic_position the atomic positions transformed from OpenMX
3763 atom_species the indicator of atomic index of each species in atomic_position
3764 atom_num number of atoms in atomic_position array
3765 atom_type number of species in array atom_species
3766
3767 OUTPUT
3768 platt the primitive lattice vectors founded
3769 ptran_vec array to store the translation vectors for each atom
3770 pcell_parameters the cell parameters for primitive cell
3771 npcell number of primitive cell in cell defined by lattice_vector
3772 pcell_brav return the bravais type of primitive lattice
3773 */
3774 int atom_indx, atom_type_indx, start_atom_indx, end_atom_indx,atom_indx2;
3775 int i,j,k,ip,jp,kp;
3776 double **roted_xyz;
3777 double *markone, *tmp_vec, *diff_vec, *trans_vec;
3778 char c;
3779 int smallest_species, pure_point, ptrans_num, pcell_brav;
3780 double cellvol,pcellvol;
3781
3782
3783 roted_xyz=(double**)malloc(sizeof(double*)*atom_num);
3784 markone=(double*)malloc(sizeof(double)*3);
3785 tmp_vec=(double*)malloc(sizeof(double)*3);
3786 diff_vec=(double*)malloc(sizeof(double)*3);
3787 trans_vec=(double*)malloc(sizeof(double)*3);
3788 for(k=0; k<atom_num; k++){
3789 roted_xyz[k] = (double*)malloc(sizeof(double)*3);
3790 for(i=0; i<3; i++){
3791 roted_xyz[k][i] = 0.0;
3792 ptran_vec[k][i] = 0.0;
3793 tmp_vec[i]=3.0;
3794 trans_vec[i]=0.0;
3795 }
3796 }
3797 for(i=0;i<3;i++){
3798 ptran_vec[atom_num][i]=0.0;
3799 ptran_vec[atom_num+1][i]=0.0;
3800 }
3801 /*to be consistent wit VASP, finding the species having smallest number of atom*/
3802 j=atom_species[0];
3803 smallest_species=0;
3804 for(i=1;i<atom_type;i++){
3805 if((atom_species[i]-atom_species[i-1])<j){
3806 j=atom_species[i]-atom_species[i-1];
3807 smallest_species=i;
3808 }
3809 }
3810 if(debug3==1){
3811 printf("smallest number of species is %2d\n",smallest_species);
3812 }
3813 if(smallest_species==0){
3814 start_atom_indx=0;
3815 }else{
3816 start_atom_indx=atom_species[smallest_species-1];
3817 }
3818 if((atom_species[smallest_species]-start_atom_indx)==1){
3819 printf("Original cell was already a primitive cell.\n");
3820 *npcell=1;
3821
3822 for(i=0;i<3;i++){
3823 for(j=0;j<3;j++){
3824 platt[i][j]=lattice_vector[i][j];
3825 }
3826 }
3827
3828 for(i=0;i<6;i++){
3829 pcell_parameters[i]=cell_parameters[i];
3830 }
3831
3832 for(k=0; k<atom_num; k++){
3833 free(roted_xyz[k]);
3834 }
3835 free(roted_xyz);
3836 free(markone);
3837 free(tmp_vec);
3838 free(diff_vec);
3839 free(trans_vec);
3840
3841 return bravais_type;
3842 }
3843
3844 for(atom_type_indx=0;atom_type_indx<atom_type;atom_type_indx++){
3845 if(atom_type_indx==0){
3846 start_atom_indx=0;/* The atoms of first species are stored from 0 index */
3847 }else{
3848 start_atom_indx=atom_species[atom_type_indx-1]; /*Other species atoms are stored from atom_species[atom_type_indx-1] */
3849 }
3850 end_atom_indx=atom_species[atom_type_indx];
3851
3852 for(atom_indx=start_atom_indx;atom_indx<end_atom_indx;atom_indx++){
3853 /* 1. Precess the atomic coordinates, make them be [-0.5, 0.5)
3854 (Applying periodic boundary condition)
3855 */
3856 if(debug3==1){
3857 printf("atom %3d ",atom_indx);
3858 }
3859 for(i=0;i<3;i++){
3860 /* make it positive and less than +1.0 */
3861 if(debug3==1){
3862 printf("%12.8f-->",atomic_position[atom_indx][i]);
3863 }
3864 atomic_position[atom_indx][i]=atomic_position[atom_indx][i]-floor(atomic_position[atom_indx][i]);
3865 atomic_position[atom_indx][i]=fmod(atomic_position[atom_indx][i]+1000.5,1.0)-0.5;
3866 if(debug3==1){
3867 printf("%10.8f",atomic_position[atom_indx][i]);
3868 }
3869 }
3870 if(debug3==1){
3871 printf("\n");
3872 }
3873 }
3874 /* 2. Ordering the atomic coordinates of same species with index from start to end.
3875 firstly x- then y-, z- last. */
3876 Ordering_Atomic_Position(atomic_position, start_atom_indx, end_atom_indx);
3877 }
3878
3879 /* mark the first atom */
3880 if(smallest_species==0){
3881 start_atom_indx=0;
3882 }else{
3883 start_atom_indx=atom_species[smallest_species-1];
3884 }
3885 markone[0]=atomic_position[start_atom_indx][0];
3886 markone[1]=atomic_position[start_atom_indx][1];
3887 markone[2]=atomic_position[start_atom_indx][2];
3888 ptrans_num=3;
3889 for(i=0;i<3;i++){
3890 ptran_vec[i][i]=1.0;
3891 }
3892 if(debug3==1){
3893 printf("MARKED atom is %12.8f%12.8f%12.8f\n",markone[0],markone[1],markone[2]);
3894 }
3895 for(atom_indx=start_atom_indx+1;atom_indx<atom_species[smallest_species];atom_indx++){
3896 trans_vec[0]=atomic_position[atom_indx][0]-markone[0];
3897 trans_vec[1]=atomic_position[atom_indx][1]-markone[1];
3898 trans_vec[2]=atomic_position[atom_indx][2]-markone[2];
3899
3900 trans_vec[0]=fmod(trans_vec[0]+1000.0,1.0);
3901 trans_vec[1]=fmod(trans_vec[1]+1000.0,1.0);
3902 trans_vec[2]=fmod(trans_vec[2]+1000.0,1.0);
3903 if(debug3==1){
3904 printf("atom %2d and ",atom_indx);
3905 printf("TRANS_VEC %12.8f%12.8f%12.8f\n",trans_vec[0],trans_vec[1],trans_vec[2]);
3906 }
3907 /* c=getchar(); */
3908 if(fabs(trans_vec[0]-1.0)<smallvalue){trans_vec[0]=0.0;}
3909 if(fabs(trans_vec[0]-1.0)<smallvalue){trans_vec[0]=0.0;}
3910 if(fabs(trans_vec[0]-1.0)<smallvalue){trans_vec[0]=0.0;}
3911 /* translate the rotated coordinates with trans_vec and compare with original ones*/
3912 if(debug3==1){
3913 printf("applying TRANSLATION vectors:\n");
3914 }
3915 for(atom_type_indx=0;atom_type_indx<atom_type;atom_type_indx++){
3916 if(atom_type_indx==0){
3917 start_atom_indx=0;/* The atoms of first species are stored from 0 index */
3918 }else{
3919 start_atom_indx=atom_species[atom_type_indx-1]; /*Other species atoms are stored from atom_species[atom_type_indx-1] */
3920 }
3921 end_atom_indx=atom_species[atom_type_indx];
3922
3923 for(atom_indx2=start_atom_indx;atom_indx2<end_atom_indx;atom_indx2++){
3924 /* Applying periodic boundary condition */
3925 if(debug3==1){
3926 printf("atom %3d ",atom_indx2);
3927 }
3928 for(i=0;i<3;i++){
3929 /* make it positive and less than +1.0 */
3930 if(debug3==1){
3931 printf("%12.8f-->",atomic_position[atom_indx2][i]);
3932 }
3933 roted_xyz[atom_indx2][i]=atomic_position[atom_indx2][i]+trans_vec[i];
3934 roted_xyz[atom_indx2][i]=roted_xyz[atom_indx2][i]-floor(roted_xyz[atom_indx2][i]);
3935 roted_xyz[atom_indx2][i]=fmod(roted_xyz[atom_indx2][i]+1000.5,1.0)-0.5;
3936 if(debug3==1){
3937 printf("%10.8f",roted_xyz[atom_indx2][i]);
3938 }
3939 }
3940 if(debug3==1){
3941 printf("\n");
3942 }
3943 }
3944 /* Ordering the atomic coordinates of same species with index from start to end.
3945 firstly x- then y-, z- last. */
3946 Ordering_Atomic_Position(roted_xyz, start_atom_indx, end_atom_indx);
3947 }/*applying translation */
3948 /* after translation, now comparing */
3949 pure_point=0;
3950 for(atom_type_indx=0;atom_type_indx<atom_type;atom_type_indx++){
3951 if(atom_type_indx==0){
3952 start_atom_indx=0;/* The atoms of first species are stored from 0 index */
3953 }else{
3954 start_atom_indx=atom_species[atom_type_indx-1]; /*Other species atoms are stored from atom_species[atom_type_indx-1] */
3955 }
3956 end_atom_indx=atom_species[atom_type_indx];
3957 for(atom_indx2=start_atom_indx;atom_indx2<end_atom_indx;atom_indx2++){
3958 diff_vec[0]=atomic_position[atom_indx2][0]-roted_xyz[atom_indx2][0];
3959 diff_vec[1]=atomic_position[atom_indx2][1]-roted_xyz[atom_indx2][1];
3960 diff_vec[2]=atomic_position[atom_indx2][2]-roted_xyz[atom_indx2][2];
3961
3962 diff_vec[0]=fmod(diff_vec[0]+1000.0,1.0);
3963 diff_vec[1]=fmod(diff_vec[1]+1000.0,1.0);
3964 diff_vec[2]=fmod(diff_vec[2]+1000.0,1.0);
3965 if(fabs(diff_vec[0]-1.0)<smallvalue){diff_vec[0]=0.0;}
3966 if(fabs(diff_vec[1]-1.0)<smallvalue){diff_vec[1]=0.0;}
3967 if(fabs(diff_vec[2]-1.0)<smallvalue){diff_vec[2]=0.0;}
3968 if(fabs(diff_vec[0])<smallvalue
3969 &&fabs(diff_vec[1])<smallvalue
3970 &&fabs(diff_vec[2])<smallvalue){
3971 pure_point=1;
3972 }else{
3973 pure_point=0;
3974 if(debug3==1){
3975 printf("NOT TRANSLATED!!!!!\n");
3976 }
3977 break;
3978 }
3979 }
3980 if(pure_point==0){break;}
3981 }/*comparing */
3982 if(pure_point==1){
3983 /*translation vector can reproduce all the atomic position, mark it */
3984 if(debug3==1){
3985 printf("OK find one! ptrans_num=%2d\n",ptrans_num);
3986 }
3987 ptran_vec[ptrans_num][0]=trans_vec[0];
3988 ptran_vec[ptrans_num][1]=trans_vec[1];
3989 ptran_vec[ptrans_num][2]=trans_vec[2];
3990 ptrans_num++;
3991 }
3992 }
3993 /* c=getchar(); */
3994 if(ptrans_num==3){/*no translation vectors are founded */
3995 printf("Original cell was already a primitive cell.\n");
3996 *npcell=1;
3997 for(i=0;i<3;i++){
3998 for(j=0;j<3;j++){
3999 platt[i][j]=lattice_vector[i][j];
4000 }
4001 }
4002 for(i=0;i<6;i++){
4003 pcell_parameters[i]=cell_parameters[i];
4004 }
4005 for(k=0; k<atom_num; k++){
4006 free(roted_xyz[k]);
4007 }
4008 free(roted_xyz);
4009 free(markone);
4010 free(tmp_vec);
4011 free(diff_vec);
4012 free(trans_vec);
4013 return bravais_type;
4014 }
4015 if(debug3==1){
4016 printf("before ordering, ptrans_num=%2d\n",ptrans_num);
4017 }
4018 Ordering_Atomic_Position(ptran_vec, 0, ptrans_num);
4019 /* y-z plane
4020 *markone, *tmp_vec, *diff_vec will be used.*/
4021 for(i=1;i<ptrans_num;i++){
4022 if(fabs(ptran_vec[i][0]-ptran_vec[0][0])>smallvalue){
4023 ip=i-1;
4024 jp=i;
4025 if(debug3==1){
4026 printf("ip=%d,jp=%d\n",ip,jp);
4027 }
4028 break;
4029 }
4030 }
4031 markone[0]=ptran_vec[jp][0];
4032 markone[1]=ptran_vec[jp][1];
4033 markone[2]=ptran_vec[jp][2];
4034 for(i=1;i<(ip+1);i++){
4035 if(fabs(ptran_vec[i][1]-ptran_vec[0][1])>smallvalue){
4036 kp=i;
4037 if(debug3==1){
4038 printf("kp=%d\n",kp);
4039 }
4040 break;
4041 }
4042 }
4043 tmp_vec[0]=ptran_vec[kp][0];
4044 tmp_vec[1]=ptran_vec[kp][1];
4045 tmp_vec[2]=ptran_vec[kp][2];
4046 diff_vec[0]=ptran_vec[0][0];
4047 diff_vec[1]=ptran_vec[0][1];
4048 diff_vec[2]=ptran_vec[0][2];
4049 platt[0][0]=markone[0]*lattice_vector[0][0]+markone[1]*lattice_vector[1][0]+markone[2]*lattice_vector[2][0];
4050 platt[0][1]=markone[0]*lattice_vector[0][1]+markone[1]*lattice_vector[1][1]+markone[2]*lattice_vector[2][1];
4051 platt[0][2]=markone[0]*lattice_vector[0][2]+markone[1]*lattice_vector[1][2]+markone[2]*lattice_vector[2][2];
4052
4053 platt[1][0]=tmp_vec[0]*lattice_vector[0][0]+tmp_vec[1]*lattice_vector[1][0]+tmp_vec[2]*lattice_vector[2][0];
4054 platt[1][1]=tmp_vec[0]*lattice_vector[0][1]+tmp_vec[1]*lattice_vector[1][1]+tmp_vec[2]*lattice_vector[2][1];
4055 platt[1][2]=tmp_vec[0]*lattice_vector[0][2]+tmp_vec[1]*lattice_vector[1][2]+tmp_vec[2]*lattice_vector[2][2];
4056
4057 platt[2][0]=diff_vec[0]*lattice_vector[0][0]+diff_vec[1]*lattice_vector[1][0]+diff_vec[2]*lattice_vector[2][0];
4058 platt[2][1]=diff_vec[0]*lattice_vector[0][1]+diff_vec[1]*lattice_vector[1][1]+diff_vec[2]*lattice_vector[2][1];
4059 platt[2][2]=diff_vec[0]*lattice_vector[0][2]+diff_vec[1]*lattice_vector[1][2]+diff_vec[2]*lattice_vector[2][2];
4060
4061 pcell_brav=Finding_Bravais_Lattice_Type(platt,pcell_parameters);
4062 cellvol=Cal_Cell_Volume(lattice_vector);
4063 pcellvol=Cal_Cell_Volume(platt);
4064 if(debug3==1){
4065 printf("Original cell's volume=%10.5f. Primitive cell 's volume=%10.5f\n",cellvol,pcellvol);
4066 }
4067 cellvol=cellvol/pcellvol;
4068 if((cellvol-(int)cellvol)<smallvalue){
4069 *npcell=(int)cellvol;
4070 }else{
4071 *npcell=(int)cellvol+1;
4072 }
4073
4074 for(k=0; k<atom_num; k++){
4075 free(roted_xyz[k]);
4076 }
4077 free(roted_xyz);
4078 free(markone);
4079 free(tmp_vec);
4080 free(diff_vec);
4081 free(trans_vec);
4082
4083 return pcell_brav;
4084 }
4085
4086
4087
Generate_MP_Special_Kpt(int knum_i,int knum_j,int knum_k,int *** sym_op,int op_num,int *** pureGsym,int pureG_num,double * shift,double * KGrids1,double * KGrids2,double * KGrids3,int * T_k_op)4088 int Generate_MP_Special_Kpt(int knum_i, int knum_j, int knum_k, int ***sym_op, int op_num,
4089 int ***pureGsym, int pureG_num, double *shift,
4090 double *KGrids1, double *KGrids2, double *KGrids3, int *T_k_op)
4091 /*
4092 kpt_num=Generate_MP_Special_Kpt(knum_i, knum_j, knum_k, ksym_op,ksym_num,
4093 pureGsym, pureG_num, shift, tmpK1, tmpK2, tmpK3, tmpWeight);
4094 INPUT
4095 knum_i, knum_j, knum_k sampling grids knum_i*knum_j*knum_k
4096 sym_op Symmetry operations of the given crystal
4097 op_num The first op_num operator in sym_op is pure point group operation
4098
4099 OUTPUT
4100 return the total number of non-equivalent k points
4101 T_KGrids1, T_KGrids2, T_KGrids3 k point coordinates kx,ky,kz
4102 T_k_op weight of the k point
4103 return the total non-equivlent k point number.
4104 */
4105 {
4106 int kpt_num, ktest; /* total number of non-equivalent k points */
4107
4108 double ktmp[48][3],kx,ky,kz;
4109 int i,j,k,r,p,s, itst,ksym;
4110 int whetherNonEquiv;
4111 double *tmpWeight;
4112 char c;
4113 kpt_num = 0;
4114
4115 tmpWeight=(double*)malloc(sizeof(double)*(8*knum_i*knum_j*knum_k));
4116 for(i=0;i<(8*knum_i*knum_j*knum_k);i++){
4117 tmpWeight[i]=0.0;
4118 }
4119 if(debug4==1){
4120 printf("pureG number is %2d, and op_num=%2d\n",pureG_num,op_num);
4121 }
4122 for(p=0;p<knum_k;p++){
4123 for(r=0;r<knum_j;r++){
4124 for(s=0;s<knum_i;s++){
4125 /*generate one k point */
4126 ktmp[0][0]=((double)s+shift[0])/(double)knum_i;
4127 ktmp[0][1]=((double)r+shift[1])/(double)knum_j;
4128 ktmp[0][2]=((double)p+shift[2])/(double)knum_k;
4129 if(debug4==1){
4130 printf("%10.5f%10.5f%10.5f\n",ktmp[0][0],ktmp[0][1],ktmp[0][2]);
4131 }
4132 ktest=0;
4133 for(k=0;k<pureG_num;k++){
4134 kx=ktmp[0][0]*(double)pureGsym[k][0][0]+ktmp[0][1]*(double)pureGsym[k][1][0]+ktmp[0][2]*(double)pureGsym[k][2][0];
4135 ky=ktmp[0][0]*(double)pureGsym[k][0][1]+ktmp[0][1]*(double)pureGsym[k][1][1]+ktmp[0][2]*(double)pureGsym[k][2][1];
4136 kz=ktmp[0][0]*(double)pureGsym[k][0][2]+ktmp[0][1]*(double)pureGsym[k][1][2]+ktmp[0][2]*(double)pureGsym[k][2][2];
4137 kx=kx-floor(kx);
4138 kx=fmod(kx+1000.5-0.5*smallvalue,1.0)-0.5+0.5*smallvalue;
4139
4140 ky=ky-floor(ky);
4141 ky=fmod(ky+1000.5-0.5*smallvalue,1.0)-0.5+0.5*smallvalue;
4142
4143 kz=kz-floor(kz);
4144 kz=fmod(kz+1000.5-0.5*smallvalue,1.0)-0.5+0.5*smallvalue;
4145
4146 whetherNonEquiv=1;
4147 for(itst=0;itst<ktest;itst++){
4148 if( fabs(kx-ktmp[itst][0])<smallvalue
4149 && fabs(ky-ktmp[itst][1])<smallvalue
4150 && fabs(kz-ktmp[itst][2])<smallvalue) {
4151 whetherNonEquiv=0;
4152 if(debug4==1){
4153 printf("k=%2d,existing with itst=%2d and ktest=%2d\n",k,itst,ktest);
4154 }
4155 }
4156 }
4157 if(whetherNonEquiv==1){
4158 ktmp[ktest][0]=kx;
4159 ktmp[ktest][1]=ky;
4160 ktmp[ktest][2]=kz;
4161 ktest++;
4162 if(debug4==1){
4163 printf("k=%2d,Find one! ktest=%5d\n",k,ktest);
4164 }
4165 }
4166 }/* End of pure G symmetry operation */
4167 /* printf("ktest=%5d",ktest); */
4168 /* c=getchar(); */
4169 for(itst=0;itst<ktest;itst++){
4170 whetherNonEquiv=1;
4171 for(ksym=0;ksym<op_num;ksym++){
4172 /* Symmtry operating this k point*/
4173 kx=sym_op[ksym][0][0]*ktmp[itst][0]+sym_op[ksym][1][0]*ktmp[itst][1]+sym_op[ksym][2][0]*ktmp[itst][2];
4174 ky=sym_op[ksym][0][1]*ktmp[itst][0]+sym_op[ksym][1][1]*ktmp[itst][1]+sym_op[ksym][2][1]*ktmp[itst][2];
4175 kz=sym_op[ksym][0][2]*ktmp[itst][0]+sym_op[ksym][1][2]*ktmp[itst][1]+sym_op[ksym][2][2]*ktmp[itst][2];
4176 /* Applying periodic boundary condition*/
4177 kx=kx-floor(kx);
4178 kx=fmod(kx+1000.5-0.5*smallvalue,1.0)-0.5+0.5*smallvalue;
4179
4180 ky=ky-floor(ky);
4181 ky=fmod(ky+1000.5-0.5*smallvalue,1.0)-0.5+0.5*smallvalue;
4182
4183 kz=kz-floor(kz);
4184 kz=fmod(kz+1000.5-0.5*smallvalue,1.0)-0.5+0.5*smallvalue;
4185 for(i=0;i<kpt_num;i++){
4186 if( fabs(kx-KGrids1[i])<smallvalue
4187 && fabs(ky-KGrids2[i])<smallvalue
4188 && fabs(kz-KGrids3[i])<smallvalue) {
4189 whetherNonEquiv=0;
4190 tmpWeight[i]+=(double)(pureG_num/ktest);
4191 break;
4192 }
4193 }
4194 if(whetherNonEquiv==0){
4195 break;
4196 }
4197 }
4198 if(whetherNonEquiv==1){
4199 if(kpt_num>=(8*knum_i*knum_j*knum_k)){
4200 printf("!***************!\n");
4201 printf("!Something Error!\n");
4202 printf("!***************!\n");
4203 return 0;
4204 }
4205 KGrids1[kpt_num]=ktmp[itst][0];
4206 KGrids2[kpt_num]=ktmp[itst][1];
4207 KGrids3[kpt_num]=ktmp[itst][2];
4208 tmpWeight[kpt_num]=(double)(pureG_num/ktest);
4209 kpt_num++;
4210 if(debug4==1){
4211 printf("kpt_num=%2d",kpt_num);
4212 } /* c=getchar(); */
4213 }
4214 }
4215 }
4216 }
4217 }
4218 /* printf("kpt_num=%2d\n",kpt_num); */
4219
4220 for(j=0;j<kpt_num;j++){
4221 T_k_op[j]=(int)tmpWeight[j];
4222 /*printf("%20.14f%20.14f%20.14f%14d\n",KGrids1[j],KGrids2[j],KGrids3[j],T_k_op[j]);*/
4223 }
4224 free(tmpWeight);
4225 return kpt_num;
4226 }
4227