void TRAN_Calc_CentGreenLesser_old( /* input */ dcomplex w, double ChemP_e[2], int nc, int Order_Lead_Side[2], dcomplex *SigmaL, dcomplex *SigmaL_Ad, dcomplex *SigmaR, dcomplex *SigmaR_Ad, dcomplex *GC, dcomplex *GC_Ad, dcomplex *HCCk, dcomplex *SCC, /* work, nc*nc */ dcomplex *v1, dcomplex *v2, /* output */ dcomplex *Gless ) #define GC_ref(i,j) GC[nc*((j)-1)+(i)-1] #define GC_Ad_ref(i,j) GC_Ad[nc*((j)-1)+(i)-1] #define SigmaL_ref(i,j) SigmaL[nc*((j)-1)+(i)-1] #define SigmaL_Ad_ref(i,j) SigmaL_Ad[nc*((j)-1)+(i)-1] #define SigmaR_ref(i,j) SigmaR[nc*((j)-1)+(i)-1] #define SigmaR_Ad_ref(i,j) SigmaR_Ad[nc*((j)-1)+(i)-1] #define SCC_ref(i,j) SCC[nc*((j)-1)+(i)-1] #define HCCk_ref(i,j) HCCk[nc*((j)-1)+(i)-1] #define v1_ref(i,j) v1[nc*((j)-1)+(i)-1] #define v2_ref(i,j) v2[nc*((j)-1)+(i)-1] #define Gless_ref(i,j) Gless[nc*((j)-1)+(i)-1] { int i,j; int side; dcomplex alpha,beta; dcomplex ctmp; alpha.r = 1.0; alpha.i = 0.0; beta.r = 0.0; beta.i = 0.0; /****************************************************** retarded Green's function of the left or right part ******************************************************/ /* v1 = 1/2z^* S - 1/2H - \sigama_{L or R}(z^*) */ if (Order_Lead_Side[1]==0){ for (i=1; i<=nc; i++) { for (j=1; j<=nc; j++) { v1_ref(i,j).r = 0.0*( 0.5*w.r*SCC_ref(i,j).r + 0.5*w.i*SCC_ref(i,j).i) - 0.5*HCCk_ref(i,j).r - SigmaL_Ad_ref(i,j).r; v1_ref(i,j).i = 0.0*(-0.5*w.i*SCC_ref(i,j).r + 0.5*w.r*SCC_ref(i,j).i) - 0.5*HCCk_ref(i,j).i - SigmaL_Ad_ref(i,j).i; } } } else{ for (i=1; i<=nc; i++) { for (j=1; j<=nc; j++) { v1_ref(i,j).r = 0.0*( 0.5*w.r*SCC_ref(i,j).r + 0.5*w.i*SCC_ref(i,j).i) - 0.5*HCCk_ref(i,j).r - SigmaR_Ad_ref(i,j).r; v1_ref(i,j).i = 0.0*(-0.5*w.i*SCC_ref(i,j).r + 0.5*w.r*SCC_ref(i,j).i) - 0.5*HCCk_ref(i,j).i - SigmaR_Ad_ref(i,j).i; } } } /* v2 = G(z) [1/2z^* S - 1/2 H - \sigama_{L or R}(z^*)] */ F77_NAME(zgemm,ZGEMM)("N","N", &nc, &nc, &nc, &alpha, GC, &nc, v1, &nc, &beta, v2, &nc); /* Gless = G(z) [1/2z^* S - 1/2H - \sigama_{L or R}(z^*)] G(z^*) */ F77_NAME(zgemm,ZGEMM)("N","N", &nc, &nc, &nc, &alpha, v2, &nc, GC_Ad, &nc, &beta, Gless, &nc); /****************************************************** advanced Green's function of the left or right part ******************************************************/ /* v1 = 1/2z S - 1/2 H - \sigama_{L or R}(z) */ if (Order_Lead_Side[1]==0){ for (i=1; i<=nc; i++) { for (j=1; j<=nc; j++) { v1_ref(i,j).r = 0.0*(0.5*w.r*SCC_ref(i,j).r - 0.5*w.i*SCC_ref(i,j).i) - 0.5*HCCk_ref(i,j).r - SigmaL_ref(i,j).r; v1_ref(i,j).i = 0.0*(0.5*w.i*SCC_ref(i,j).r + 0.5*w.r*SCC_ref(i,j).i) - 0.5*HCCk_ref(i,j).i - SigmaL_ref(i,j).i; } } } else{ for (i=1; i<=nc; i++) { for (j=1; j<=nc; j++) { v1_ref(i,j).r = 0.0*(0.5*w.r*SCC_ref(i,j).r - 0.5*w.i*SCC_ref(i,j).i) - 0.5*HCCk_ref(i,j).r - SigmaR_ref(i,j).r; v1_ref(i,j).i = 0.0*(0.5*w.i*SCC_ref(i,j).r + 0.5*w.r*SCC_ref(i,j).i) - 0.5*HCCk_ref(i,j).i - SigmaR_ref(i,j).i; } } } /* v2 = G(z) [1/2z S - 1/2 H - \sigama_{L or R}(z^*)] */ F77_NAME(zgemm,ZGEMM)("N","N", &nc, &nc, &nc, &alpha, GC, &nc, v1, &nc, &beta, v2, &nc); /* v1 = G(z) [1/2z S - 1/2 H - \sigama_{L or R}(z)] G(z^*) */ F77_NAME(zgemm,ZGEMM)("N","N", &nc, &nc, &nc, &alpha, v2, &nc, GC_Ad, &nc, &beta, v1, &nc); /****************************************************** -1/(i 2Pi) times (retarded Green's function minus advanced Green's function of the left or right part) ******************************************************/ for (i=1; i<=nc; i++) { for (j=1; j<=nc; j++) { ctmp.r = (Gless_ref(i,j).r - v1_ref(i,j).r)/(2.0*PI); ctmp.i = (Gless_ref(i,j).i - v1_ref(i,j).i)/(2.0*PI); Gless_ref(i,j).r =-ctmp.i; Gless_ref(i,j).i = ctmp.r; } } }
void TRAN_Calc_CentGreenLesser( /* input */ dcomplex w, double ChemP_e[2], int nc, int Order_Lead_Side[2], dcomplex *SigmaL, dcomplex *SigmaL_Ad, dcomplex *SigmaR, dcomplex *SigmaR_Ad, dcomplex *GC, dcomplex *GC_Ad, dcomplex *HCCk, dcomplex *SCC, /* work, nc*nc */ dcomplex *v1, dcomplex *v2, /* output */ dcomplex *Gless ) #define GC_ref(i,j) GC[nc*((j)-1)+(i)-1] #define GC_Ad_ref(i,j) GC_Ad[nc*((j)-1)+(i)-1] #define SigmaL_ref(i,j) SigmaL[nc*((j)-1)+(i)-1] #define SigmaL_Ad_ref(i,j) SigmaL_Ad[nc*((j)-1)+(i)-1] #define SigmaR_ref(i,j) SigmaR[nc*((j)-1)+(i)-1] #define SigmaR_Ad_ref(i,j) SigmaR_Ad[nc*((j)-1)+(i)-1] #define SCC_ref(i,j) SCC[nc*((j)-1)+(i)-1] #define HCCk_ref(i,j) HCCk[nc*((j)-1)+(i)-1] #define v1_ref(i,j) v1[nc*((j)-1)+(i)-1] #define v2_ref(i,j) v2[nc*((j)-1)+(i)-1] #define Gless_ref(i,j) Gless[nc*((j)-1)+(i)-1] { int i,j; int side; dcomplex alpha,beta; dcomplex ctmp; alpha.r = 1.0; alpha.i = 0.0; beta.r = 0.0; beta.i = 0.0; /****************************************************** lesser Green's function ******************************************************/ /* v1 = -\sigama_{L or R}(z^*) */ if (Order_Lead_Side[1]==0){ for (i=1; i<=nc; i++) { for (j=1; j<=nc; j++) { v1_ref(i,j).r = SigmaL_ref(i,j).r - SigmaL_Ad_ref(i,j).r; v1_ref(i,j).i = SigmaL_ref(i,j).i - SigmaL_Ad_ref(i,j).i; } } } else{ for (i=1; i<=nc; i++) { for (j=1; j<=nc; j++) { v1_ref(i,j).r = SigmaR_ref(i,j).r - SigmaR_Ad_ref(i,j).r; v1_ref(i,j).i = SigmaR_ref(i,j).i - SigmaR_Ad_ref(i,j).i; } } } /* v2 = G(z) * v1 */ F77_NAME(zgemm,ZGEMM)("N","N", &nc, &nc, &nc, &alpha, GC, &nc, v1, &nc, &beta, v2, &nc); /* Gless = G(z) * v1 * G(z^*) */ F77_NAME(zgemm,ZGEMM)("N","N", &nc, &nc, &nc, &alpha, v2, &nc, GC_Ad, &nc, &beta, Gless, &nc); /****************************************************** -1/(i 2Pi) * Gless ******************************************************/ for (i=1; i<=nc; i++) { for (j=1; j<=nc; j++) { ctmp.r = Gless_ref(i,j).r/(2.0*PI); ctmp.i = Gless_ref(i,j).i/(2.0*PI); Gless_ref(i,j).r =-ctmp.i; Gless_ref(i,j).i = ctmp.r; } } }
static void TRAN_DFT_Kdependent( /* input */ MPI_Comm comm1, int parallel_mode, int numprocs, int myid, int level_stdout, int iter, int SpinP_switch, double k2, double k3, int k_op, int *order_GA, double **DM1, double **H1, double *S1, double *****nh, /* H */ double *****ImNL, /* not used, SO-coupling */ double ****CntOLP, int atomnum, int Matomnum, int *WhatSpecies, int *Spe_Total_CNO, int *FNAN, int **natn, int **ncn, int *M2G, int *G2ID, int **atv_ijk, int *List_YOUSO, /* output */ double *****CDM, /* output, charge density */ double *****EDM, /* not used */ double Eele0[2], double Eele1[2]) /* not used */ #define GC_ref(i,j) GC[ NUM_c*((j)-1) + (i)-1 ] #define Gless_ref(i,j) Gless[ NUM_c*((j)-1) + (i)-1 ] { int i,j,k,iside; int *MP; int iw,iw_method; dcomplex w, w_weight; dcomplex *GC,*GRL,*GRR,*SigmaL, *SigmaR; dcomplex *v1,*Gless,*GCLorR; dcomplex **v2; double dum; double TStime,TEtime; int MA_AN, GA_AN, wanA, tnoA, Anum; int LB_AN, GB_AN, wanB, tnoB, Bnum; /* debug */ double **Density; double density_sum; /* end debug*/ static int ID; int **iwIdx, Miwmax, Miw,iw0; double time_a0, time_a1, time_a2; /* parallel setup */ iwIdx=(int**)malloc(sizeof(int*)*numprocs); Miwmax = (tran_omega_n_scf)/numprocs+1; for (i=0; i<numprocs; i++) { iwIdx[i]=(int*)malloc(sizeof(int)*Miwmax); } TRAN_Distribute_Node_Idx(0, tran_omega_n_scf-1, numprocs, Miwmax, iwIdx); /* output */ /* setup MP */ TRAN_Set_MP(0, atomnum, WhatSpecies, Spe_Total_CNO, &NUM_c, MP); MP = (int*)malloc(sizeof(int)*(NUM_c+1)); TRAN_Set_MP(1, atomnum, WhatSpecies, Spe_Total_CNO, &NUM_c, MP); /*debug */ if (WRITE_DENSITY){ Density = (double**)malloc(sizeof(double*)*(SpinP_switch+1)); for (k=0;k<=SpinP_switch;k++) { Density[k] = (double*)malloc(sizeof(double)*NUM_c); for (i=0;i<NUM_c;i++) { Density[k][i]=0.0; } } } /*end debug */ /* initialize */ TRAN_Set_Value_double(SCC,NUM_c*NUM_c, 0.0,0.0); TRAN_Set_Value_double(SCL,NUM_c*NUM_e[0], 0.0,0.0); TRAN_Set_Value_double(SCR,NUM_c*NUM_e[1], 0.0,0.0); for (k=0; k<=SpinP_switch; k++) { TRAN_Set_Value_double(HCC[k],NUM_c*NUM_c, 0.0,0.0); TRAN_Set_Value_double(HCL[k],NUM_c*NUM_e[0], 0.0,0.0); TRAN_Set_Value_double(HCR[k],NUM_c*NUM_e[1], 0.0,0.0); } /* set Hamiltonian and overlap matrices of left and right leads */ TRAN_Set_SurfOverlap(comm1,"left", k2, k3); TRAN_Set_SurfOverlap(comm1,"right",k2, k3); /* set CC, CL and CR */ TRAN_Set_CentOverlap( comm1, 3, SpinP_switch, k2, k3, order_GA, H1, S1, nh, /* input */ CntOLP, /* input */ atomnum, Matomnum, M2G, G2ID, WhatSpecies, Spe_Total_CNO, FNAN, natn, ncn, atv_ijk); if (MEASURE_TIME){ dtime(&time_a0); } /* allocate */ v2 = (dcomplex**)malloc(sizeof(dcomplex*)*(SpinP_switch+1)); for (k=0; k<=SpinP_switch; k++) { v2[k] = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c*NUM_c); TRAN_Set_Value_double( v2[k], NUM_c*NUM_c, 0.0, 0.0); } GC = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c* NUM_c); GRL = (dcomplex*)malloc(sizeof(dcomplex)*NUM_e[0]* NUM_e[0]); GRR = (dcomplex*)malloc(sizeof(dcomplex)*NUM_e[1]* NUM_e[1]); SigmaL = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c* NUM_c); SigmaR = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c* NUM_c); v1 = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c* NUM_c); Gless = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c* NUM_c); GCLorR = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c* NUM_c); if (2<=level_stdout){ printf("NUM_c=%d, NUM_e= %d %d\n",NUM_c, NUM_e[0], NUM_e[1]); printf("# of freq. to calculate G =%d\n",tran_omega_n_scf); } /*parallel global iw 0:tran_omega_n_scf-1 */ /*parallel local Miw 0:Miwmax-1 */ /*parllel variable iw=iwIdx[myid][Miw] */ for (Miw=0; Miw<Miwmax; Miw++) { iw = iwIdx[myid][Miw]; if (iw>=0) { w = tran_omega_scf[iw]; w_weight = tran_omega_weight_scf[iw]; iw_method = tran_integ_method_scf[iw]; } /* printf("Miwmax=%3d Miw=%3d iw=%d of %d w=%le %le weight=%le %le method=%d\n", Miwmax,Miw,iw,tran_omega_n_scf, w.r,w.i, w_weight.r, w_weight.i, iw_method); */ for (k=0; k<=SpinP_switch; k++) { if (iw>=0) { iside=0; TRAN_Calc_SurfGreen_direct(w,NUM_e[iside], H00_e[iside][k],H01_e[iside][k], S00_e[iside], S01_e[iside], tran_surfgreen_iteration_max, tran_surfgreen_eps, GRL); TRAN_Calc_SelfEnergy(w, NUM_e[iside], GRL, NUM_c, HCL[k], SCL, SigmaL); iside=1; TRAN_Calc_SurfGreen_direct(w,NUM_e[iside], H00_e[iside][k],H01_e[iside][k], S00_e[iside], S01_e[iside], tran_surfgreen_iteration_max, tran_surfgreen_eps, GRR); TRAN_Calc_SelfEnergy(w, NUM_e[iside], GRR, NUM_c, HCR[k], SCR, SigmaR); TRAN_Calc_CentGreen(w, NUM_c, SigmaL,SigmaR, HCC[k], SCC, GC); /*********************************************** G_{C} ***********************************************/ if (iw_method==1) { /* start debug */ if (WRITE_DENSITY){ for (i=0;i<NUM_c;i++) { /* imag( GC * weight ) */ Density[k][i] += GC_ref(i+1,i+1).r*w_weight.i + GC_ref(i+1,i+1).i*w_weight.r; } } /* end debug */ } /* iw_method */ /*********************************************** based on the lesser Green's function ***********************************************/ else if (iw_method==2) { if (2<=level_stdout){ printf("G_Lesser, iw=%d (of %d) w=%le %le\n",iw,tran_omega_n_scf,w.r, w.i); } TRAN_Calc_CentGreenLesser(w, ChemP_e, NUM_c, SigmaL,SigmaR,GC,v1, Gless); #ifdef DEBUG TRAN_Print2_dcomplex("Gless",NUM_c,NUM_c,Gless); printf("exit after TRAN_Print2_dcomplex Gless\n"); exit(0); #endif if (WRITE_DENSITY){ /* real( Gless * w_weight ) */ for (i=0;i<NUM_c;i++) { Density[k][i] += Gless_ref(i+1,i+1).r*w_weight.r - Gless_ref(i+1,i+1).i*w_weight.i; } /* printf("iw=%d w=%lf %lf weight=%lf %lf GC=%lf %lf, val=%lf\n", * iw,w.r , w.i, w_weight.r, w_weight.i, Density[k][0]); */ /*end debug */ } } /*********************************************** G_{C_L} in the non-equilibrium case based on the GaussHG method ***********************************************/ else if (iw_method==3){ TRAN_Calc_GC_LorR(iw_method, w, ChemP_e, NUM_c, NUM_e, SigmaL, GC, HCC[k], SCC, v1, GCLorR); } /*********************************************** G_{C_R} in the non-equilibrium case based on the GaussHG method ***********************************************/ else if (iw_method==4){ TRAN_Calc_GC_LorR(iw_method, w, ChemP_e, NUM_c, NUM_e, SigmaR, GC, HCC[k], SCC, v1, GCLorR); } else { printf("error, iw_method=%d",iw_method); exit(10); } /*********************************************** add it to construct the density matrix ***********************************************/ if (iw_method==1) { TRAN_Add_MAT( 1, NUM_c, w_weight, GC, v2[k]); } else if (iw_method==2) { TRAN_Add_MAT( 2, NUM_c, w_weight, Gless, v2[k]); } else if (iw_method==3) { TRAN_Add_MAT( 1, NUM_c, w_weight, GCLorR, v2[k]); } else if (iw_method==4) { TRAN_Add_MAT( 1, NUM_c, w_weight, GCLorR, v2[k]); } } /* iw>=0 */ } /* for k */ } /* iw */ if (MEASURE_TIME){ dtime(&time_a1); } free(GCLorR); free(Gless); free(v1); free(SigmaR); free(SigmaL); free(GRR); free(GRL); free(GC); /*********************************************** calculation of density matrix ***********************************************/ { int l1,l2,l3,RnB; int size_v3,itot,itot0; double kRn,si,co,re,im; double *my_v3; double *v3; /* find the size of v3 */ size_v3 = 0; for (GA_AN=1; GA_AN<=atomnum; GA_AN++) { wanA = WhatSpecies[GA_AN]; tnoA = Spe_Total_CNO[wanA]; Anum = MP[GA_AN]; for (LB_AN=0; LB_AN<=FNAN[GA_AN]; LB_AN++){ GB_AN = natn[GA_AN][LB_AN]; wanB = WhatSpecies[GB_AN]; tnoB = Spe_Total_CNO[wanB]; Bnum = MP[GB_AN]; for (i=0;i<tnoA;i++) { for (j=0;j<tnoB;j++) { size_v3++; size_v3++; } } } } /* allocate arrays */ my_v3 = (double*)malloc(sizeof(double)*size_v3); v3 = (double*)malloc(sizeof(double)*size_v3); /* set up v3 */ #define v_idx(i,j) ( ((j)-1)*NUM_c + (i)-1 ) for (k=0; k<=SpinP_switch; k++) { itot = 0; for (GA_AN=1; GA_AN<=atomnum; GA_AN++) { wanA = WhatSpecies[GA_AN]; tnoA = Spe_Total_CNO[wanA]; Anum = MP[GA_AN]; for (LB_AN=0; LB_AN<=FNAN[GA_AN]; LB_AN++){ GB_AN = natn[GA_AN][LB_AN]; wanB = WhatSpecies[GB_AN]; tnoB = Spe_Total_CNO[wanB]; Bnum = MP[GB_AN]; for (i=0;i<tnoA;i++) { for (j=0;j<tnoB;j++) { my_v3[itot++] = v2[k][ v_idx( Anum+i, Bnum+j) ].r; my_v3[itot++] = v2[k][ v_idx( Anum+i, Bnum+j) ].i; } } } } if (parallel_mode){ MPI_Allreduce( my_v3, v3, itot, MPI_DOUBLE, MPI_SUM, comm1); } else { for (i=0; i<itot; i++) { v3[i] = my_v3[i]; } } /* v3 -> CDM */ itot = 0; itot0 = 0; for (GA_AN=1; GA_AN<=atomnum; GA_AN++) { wanA = WhatSpecies[GA_AN]; tnoA = Spe_Total_CNO[wanA]; Anum = MP[GA_AN]; for (LB_AN=0; LB_AN<=FNAN[GA_AN]; LB_AN++){ GB_AN = natn[GA_AN][LB_AN]; RnB = ncn[GA_AN][LB_AN]; wanB = WhatSpecies[GB_AN]; tnoB = Spe_Total_CNO[wanB]; Bnum = MP[GB_AN]; l1 = atv_ijk[RnB][1]; l2 = atv_ijk[RnB][2]; l3 = atv_ijk[RnB][3]; kRn = k2*(double)l2 + k3*(double)l3; si = (double)k_op*sin(2.0*PI*kRn); co = (double)k_op*cos(2.0*PI*kRn); for (i=0;i<tnoA;i++) { for (j=0;j<tnoB;j++) { re = v3[itot++]; im = v3[itot++]; DM1[k][itot0++] += (re*co + im*si)/(double)numprocs; } } } } } /* k */ /* free arrays */ free(my_v3); free(v3); } if (MEASURE_TIME){ MPI_Barrier(comm1); dtime(&time_a2); printf("TRAN_DFT(%d)> calculaiton (%le)\n",myid, time_a1-time_a0 ); } /* free arrays */ for (k=0; k<=SpinP_switch; k++) { free(v2[k]); } free(v2); if (WRITE_DENSITY){ for (k=SpinP_switch; k>=0; k--) { free(Density[k]); } free(Density); } free(MP); for (i=0;i<numprocs;i++) { free(iwIdx[i]); } free(iwIdx); }