1 /**********************************************************************
2   TRAN_Output_HKS.c:
3 
4   TRAN_Output_HKS.c is a subroutine to save and load data on leads
5 
6   Log of TRAN_Output_HKS.c:
7 
8      11/Dec/2005   Released by H. Kino
9 
10 ***********************************************************************/
11 /* revised by Y. Xiao for Noncollinear NEGF calculations */
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include "openmx_common.h"
17 #include <mpi.h>
18 #include "tran_variables.h"
19 #include "tran_prototypes.h"
20 
21 
22 /****************************************************************
23    purpose: save and load data to restart without input file
24 
25    from RestartFileDFT.c
26 ------------------------------------------
27 
28 "read" mode allocates
29 
30 int *WhatSpecies_l;
31 int *Spe_Total_CNO_l;
32 int *Spe_Total_NO_l;
33 int *FNAN_l;
34 int **natn_l;
35 int **ncn_l;
36 int **atv_ijk_l;
37 
38 double *****OLP_l;
39 double *****H_l;
40 double ******DM_l;
41 
42 or
43 
44 int *WhatSpecies_r;
45 int *Spe_Total_CNO_r;
46 int *Spe_Total_NO_r;
47 int *FNAN_r;
48 int **natn_r;
49 int **ncn_r;
50 int **atv_ijk_r;
51 
52 double *****OLP_r;
53 double *****H_r;
54 double ******DM_r;
55 
56 
57 *****************************************************************/
58 
59 /*
60   e.g. Overlap_Band, which gives hints of data to be saved
61   for (MA_AN=1; MA_AN<=Matomnum; MA_AN++){
62   GA_AN = M2G[MA_AN];
63   wanA = WhatSpecies[GA_AN]; int* WhatSpecies[atomnum+1]
64   tnoA = Spe_Total_CNO[wanA]; int* Spe_Total_CNO[SpeciesNum]
65   Anum = MP[GA_AN];   int *MP, neglect!
66 
67   for (LB_AN=0; LB_AN<=FNAN[GA_AN]; LB_AN++){
68   GB_AN = natn[GA_AN][LB_AN]; int** natn[atomnum+1][Max_FSNAN*ScaleSize+1]
69   Rn = ncn[GA_AN][LB_AN];  int** ncn[atomnum+1][Max_FSNAN*ScaleSize+1]
70   wanB = WhatSpecies[GB_AN];
71   tnoB = Spe_Total_CNO[wanB];
72 
73   l1 = atv_ijk[Rn][1];  int** atv_ijk[TCpyCell+1][4];
74   l2 = atv_ijk[Rn][2];
75   l3 = atv_ijk[Rn][3];
76   kRn = k1*(double)l1 + k2*(double)l2 + k3*(double)l3;
77 
78   si = sin(2.0*PI*kRn);
79   co = cos(2.0*PI*kRn);
80   Bnum = MP[GB_AN];
81   for (i=0; i<tnoA; i++){
82   for (j=0; j<tnoB; j++){
83   s = OLP[MA_AN][LB_AN][i][j]; double****
84   size: OLP[4]
85   [Matomnum+MatomnumF+MatomnumS+1]
86   [FNAN[Gc_AN]+1]
87   [Spe_Total_NO[Cwan]]
88   [Spe_Total_NO[Hwan]]
89 
90   int *Spe_Total_NO  Spe_Total_NO[SpeciesNum]
91 */
92 
93 
94 /***************************************************************************/
95 
TRAN_Output_HKS(char * fileHKS)96 int TRAN_Output_HKS(char *fileHKS)
97 {
98   FILE *fp;
99   int i_vec[100],i2_vec[2];
100   double *d_vec;
101   int i,id,j;
102   int size1,size,vsize;
103   int *ia_vec;
104   int Gc_AN,Mc_AN, tno0, Cwan, h_AN, tno1, Gh_AN, Hwan,k,m,N;
105 
106   int myid,numprocs;
107   int tag=99;
108   double *v;
109 
110   MPI_Status status;
111   MPI_Request request;
112 
113   MPI_Comm_rank(mpi_comm_level1, &myid);
114   MPI_Comm_size(mpi_comm_level1, &numprocs);
115 
116   if (myid==Host_ID) {
117 
118     d_vec = (double*)malloc(sizeof(double)*(3*(atomnum+1)+100));
119 
120     /* make a filename */
121     if ( (fp=fopen(fileHKS,"w"))==NULL) {
122       printf("can not open %s\n",fileHKS);
123       exit(0);
124     }
125 
126     /* save data to the file (*fp) */
127 
128     /* parameter to allocate memory */
129     i=0;
130     i_vec[i++]=1; /* major version */
131     i_vec[i++]=0; /* minor version*/
132 
133     fwrite(i_vec,sizeof(int),i,fp);
134 
135     i=0;
136     i_vec[i++]= SpinP_switch;
137     i_vec[i++]= atomnum;
138     i_vec[i++]= SpeciesNum;
139     i_vec[i++]= Max_FSNAN;
140     i_vec[i++]= TCpyCell;
141     i_vec[i++]= Matomnum;
142     i_vec[i++]= MatomnumF;
143     i_vec[i++]= MatomnumS;
144     i_vec[i++]= Ngrid1;
145     i_vec[i++]= Ngrid2;
146     i_vec[i++]= Ngrid3;
147     i_vec[i++]= Num_Cells0;
148 
149     fwrite(i_vec,sizeof(int),i,fp);
150 
151     id=0;
152     d_vec[id++]= ScaleSize;
153     for(j=1;j<=3;j++) {
154       for (k=1;k<=3;k++) {
155 	d_vec[id++]= tv[j][k];
156       }
157     }
158     for(j=1;j<=3;j++) {
159       for (k=1;k<=3;k++) {
160 	d_vec[id++]= gtv[j][k];
161       }
162     }
163     for (i=1;i<=3;i++) {
164       d_vec[id++] = Grid_Origin[i];
165     }
166 
167     for (i=1; i<=atomnum; i++) {
168       for (j=1; j<=3; j++) {
169         d_vec[id++] = Gxyz[i][j];
170       }
171     }
172 
173     d_vec[id++] = ChemP;
174 
175     fwrite(d_vec,sizeof(double),id,fp);
176 
177     /*  data in arrays */
178     fwrite(WhatSpecies, sizeof(int), atomnum+1, fp);
179     fwrite(Spe_Total_CNO, sizeof(int), SpeciesNum, fp);
180     fwrite(Spe_Total_NO,sizeof(int),SpeciesNum,fp);
181 
182     fwrite(FNAN,sizeof(int),atomnum+1,fp);
183 
184     size1=(int)Max_FSNAN*ScaleSize+1;
185     for (i=0;i<= atomnum; i++) {
186       fwrite(natn[i],sizeof(int),size1,fp);
187     }
188     for (i=0;i<= atomnum; i++) {
189       fwrite(ncn[i],sizeof(int),size1,fp);
190     }
191 
192     /*  printf("atv_ijk\n"); */
193 
194     size1=(TCpyCell+1)*4;
195     ia_vec=(int*)malloc(sizeof(int)*size1);
196     id=0;
197     for (i=0;i<TCpyCell+1;i++) {
198       for (j=0;j<=3;j++) {
199 	ia_vec[id++]=atv_ijk[i][j];
200       }
201     }
202     fwrite(ia_vec,sizeof(int),size1,fp);
203     free(ia_vec);
204 
205     /* freeing of d_vec */
206 
207     free(d_vec);
208 
209   }  /* if (myid==Host_ID) */
210 
211   /* allocate v */
212 
213   v = (double*)malloc(sizeof(double)*List_YOUSO[8]*List_YOUSO[7]*List_YOUSO[7]);
214 
215   /* OLP,  this is complex */
216 
217   for (k=0;k<4;k++) {
218 
219     int m,ID;
220 
221     /*global  Gc_AN  1:atomnum */
222     /*variable ID = G2ID[Gc_AN] */
223     /*variable Mc_AN = G2M[Gc_AN] */
224 
225     for (Gc_AN=1; Gc_AN<=atomnum; Gc_AN++){
226 
227       Mc_AN = F_G2M[Gc_AN];
228       ID = G2ID[Gc_AN];
229       Cwan = WhatSpecies[Gc_AN];
230       tno0 = Spe_Total_NO[Cwan];
231 
232       /* OLP into v */
233 
234       if (myid==ID) {
235 
236 	vsize = 0;
237 
238 	for (h_AN=0; h_AN<=FNAN[Gc_AN]; h_AN++){
239 
240 	  if (Mc_AN==0){
241 	    tno1 = 1;
242 	  }
243 	  else{
244 	    Gh_AN = natn[Gc_AN][h_AN];
245 	    Hwan = WhatSpecies[Gh_AN];
246 	    tno1 = Spe_Total_NO[Hwan];
247 	  }
248 
249 	  for (i=0; i<tno0; i++){
250 	    for (j=0;j<tno1;j++) {
251 	      v[vsize] =  OLP[k][Mc_AN][h_AN][i][j];
252 	      vsize++;
253 	    }
254 	  }
255 	}
256 
257         /* Isend */
258 
259         if (myid!=Host_ID){
260           MPI_Isend(&vsize, 1, MPI_INT, Host_ID, tag, mpi_comm_level1, &request);
261           MPI_Wait(&request,&status);
262           MPI_Isend(&v[0], vsize, MPI_DOUBLE, Host_ID, tag, mpi_comm_level1, &request);
263           MPI_Wait(&request,&status);
264 	}
265         else{
266           fwrite(v, sizeof(double), vsize, fp);
267         }
268       }
269 
270       /* Recv */
271 
272       else if (ID!=myid && myid==Host_ID){
273         MPI_Recv(&vsize, 1, MPI_INT, ID, tag, mpi_comm_level1, &status);
274         MPI_Recv(&v[0], vsize, MPI_DOUBLE, ID, tag, mpi_comm_level1, &status);
275         fwrite(v, sizeof(double), vsize, fp);
276       }
277 
278     } /* Gc_AN */
279   } /* k */
280 
281 
282   /* H */
283   for (k=0; k<=SpinP_switch; k++){
284 
285     int ID;
286 
287     /*global  Gc_AN  1:atomnum */
288     /*variable ID = G2ID[Gc_AN] */
289     /*variable Mc_AN = G2M[Gc_AN] */
290 
291     for (Gc_AN=1; Gc_AN<=atomnum; Gc_AN++){
292 
293       ID    = G2ID[Gc_AN];
294       Mc_AN = F_G2M[Gc_AN];
295       Cwan = WhatSpecies[Gc_AN];
296       tno0 = Spe_Total_NO[Cwan];
297 
298       /* H into v */
299 
300       if (myid==ID) {
301 
302 	vsize = 0;
303 
304 	for (h_AN=0; h_AN<=FNAN[Gc_AN]; h_AN++){
305 
306 	  if (Mc_AN==0){
307 	    tno1 = 1;
308 	  }
309 	  else{
310 	    Gh_AN = natn[Gc_AN][h_AN];
311 	    Hwan = WhatSpecies[Gh_AN];
312 	    tno1 = Spe_Total_NO[Hwan];
313 	  }
314 
315           for (i=0; i<tno0; i++){
316 	    for (j=0;j<tno1; j++) {
317 	      v[vsize] = H[k][Mc_AN][h_AN][i][j];
318 	      vsize++;
319 	    }
320 	  }
321 	}
322 
323         /* Isend */
324 
325         if (myid!=Host_ID){
326           MPI_Isend(&vsize, 1, MPI_INT, Host_ID, tag, mpi_comm_level1, &request);
327           MPI_Wait(&request,&status);
328           MPI_Isend(&v[0], vsize, MPI_DOUBLE, Host_ID, tag, mpi_comm_level1, &request);
329           MPI_Wait(&request,&status);
330 	}
331         else{
332           fwrite(v, sizeof(double), vsize, fp);
333         }
334       }
335 
336       /* Recv */
337 
338       else if (ID!=myid && myid==Host_ID){
339         MPI_Recv(&vsize, 1, MPI_INT, ID, tag, mpi_comm_level1, &status);
340         MPI_Recv(&v[0], vsize, MPI_DOUBLE, ID, tag, mpi_comm_level1, &status);
341         fwrite(v, sizeof(double), vsize, fp);
342       }
343 
344     }
345   } /* k */
346 
347 /* revised by Y. Xiao for Noncollinear NEGF calculations */
348   /* iHNL */
349 if(SpinP_switch==3) {
350 
351   for (k=0; k<=2; k++){
352 
353     int ID;
354 
355     /*global  Gc_AN  1:atomnum */
356     /*variable ID = G2ID[Gc_AN] */
357     /*variable Mc_AN = G2M[Gc_AN] */
358 
359     for (Gc_AN=1; Gc_AN<=atomnum; Gc_AN++){
360 
361       ID    = G2ID[Gc_AN];
362       Mc_AN = F_G2M[Gc_AN];
363       Cwan = WhatSpecies[Gc_AN];
364       tno0 = Spe_Total_NO[Cwan];
365 
366       /* H into v */
367 
368       if (myid==ID) {
369 
370         vsize = 0;
371 
372         for (h_AN=0; h_AN<=FNAN[Gc_AN]; h_AN++){
373 
374           if (Mc_AN==0){
375             tno1 = 1;
376           }
377           else{
378             Gh_AN = natn[Gc_AN][h_AN];
379             Hwan = WhatSpecies[Gh_AN];
380             tno1 = Spe_Total_NO[Hwan];
381           }
382 
383           for (i=0; i<tno0; i++){
384             for (j=0;j<tno1; j++) {
385               v[vsize] = iHNL[k][Mc_AN][h_AN][i][j];
386               vsize++;
387             }
388           }
389         }
390 
391         /* Isend */
392 
393         if (myid!=Host_ID){
394           MPI_Isend(&vsize, 1, MPI_INT, Host_ID, tag, mpi_comm_level1, &request);
395           MPI_Wait(&request,&status);
396           MPI_Isend(&v[0], vsize, MPI_DOUBLE, Host_ID, tag, mpi_comm_level1, &request);
397           MPI_Wait(&request,&status);
398         }
399         else{
400           fwrite(v, sizeof(double), vsize, fp);
401         }
402       }
403 
404       /* Recv */
405 
406       else if (ID!=myid && myid==Host_ID){
407         MPI_Recv(&vsize, 1, MPI_INT, ID, tag, mpi_comm_level1, &status);
408         MPI_Recv(&v[0], vsize, MPI_DOUBLE, ID, tag, mpi_comm_level1, &status);
409         fwrite(v, sizeof(double), vsize, fp);
410       }
411 
412     }
413   } /* k */
414  } /* if (SpinP_switch==3)  */
415 /* until here by Y. Xiao for Noncollinear NEGF calculations */
416 
417   /* DM */
418 
419   for (m=0; m<1; m++){
420 
421     int ID;
422 
423     for (k=0; k<=SpinP_switch; k++){
424 
425       /*global  Gc_AN  1:atomnum */
426       /*variable ID = G2ID[Gc_AN] */
427       /*variable Mc_AN = G2M[Gc_AN] */
428 
429       for (Gc_AN=1; Gc_AN<=atomnum; Gc_AN++){
430 
431         ID = G2ID[ Gc_AN];
432 	Mc_AN = F_G2M[Gc_AN];
433 	Cwan = WhatSpecies[Gc_AN];
434 	tno0 = Spe_Total_NO[Cwan];
435 
436         /* DM into v */
437 
438         if (myid==ID) {
439 
440     	  vsize = 0;
441 
442 	  for (h_AN=0; h_AN<=FNAN[Gc_AN]; h_AN++){
443 
444 	    if (Mc_AN==0){
445 	      tno1 = 1;
446 	    }
447 	    else{
448 	      Gh_AN = natn[Gc_AN][h_AN];
449 	      Hwan = WhatSpecies[Gh_AN];
450 	      tno1 = Spe_Total_NO[Hwan];
451 	    }
452 
453 	    for (i=0; i<tno0; i++){
454 	      for (j=0;j<tno1;j++) {
455 		v[vsize] = DM[m][k][Mc_AN][h_AN][i][j] ;
456   	        vsize++;
457 	      }
458 	    }
459 	  }
460 
461           /* Isend */
462 
463 	  if (myid!=Host_ID){
464 	    MPI_Isend(&vsize, 1, MPI_INT, Host_ID, tag, mpi_comm_level1, &request);
465 	    MPI_Wait(&request,&status);
466 	    MPI_Isend(&v[0], vsize, MPI_DOUBLE, Host_ID, tag, mpi_comm_level1, &request);
467 	    MPI_Wait(&request,&status);
468 	  }
469 	  else{
470 	    fwrite(v, sizeof(double), vsize, fp);
471 	  }
472 	}
473 
474         /* Recv */
475 
476         else if (ID!=myid && myid==Host_ID){
477           MPI_Recv(&vsize, 1, MPI_INT, ID, tag, mpi_comm_level1, &status);
478           MPI_Recv(&v[0], vsize, MPI_DOUBLE, ID, tag, mpi_comm_level1, &status);
479           fwrite(v, sizeof(double), vsize, fp);
480         }
481 
482       } /* Gc_AN */
483     } /* k */
484   } /* m */
485 
486 
487   /* free v */
488 
489   free(v);
490 
491   /* Density_Grid[0] + Density_Grid[1] - 2.0*ADensity_Grid */
492 
493   TRAN_Output_HKS_Write_Grid(mpi_comm_level1,
494                              1,
495  	                     Ngrid1,Ngrid2,Ngrid3,
496 			     Density_Grid_B[0],Density_Grid_B[1],ADensity_Grid_B,fp);
497   /* Vpot_Grid */
498 
499   TRAN_Output_HKS_Write_Grid(mpi_comm_level1,
500                              0,
501 			     Ngrid1,Ngrid2,Ngrid3,
502 			     dVHart_Grid_B,NULL,NULL,fp);
503 
504   if (myid==Host_ID) fclose(fp);
505 
506   return 1;
507 
508 }
509 
510 
511 
512 
513 
514