/* fortran interface */ void tran_calc_surfgreen_direct( dcomplex *w, int *n, dcomplex *h00, dcomplex *h01, dcomplex *s00, dcomplex *s01, int *iteration_max, double *eps, dcomplex *gr /* output */ ) { TRAN_Calc_SurfGreen_direct(*w, *n, h00,h01,s00,s01, *iteration_max, *eps, gr); }
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 **DM2, double **H1, double **H2, 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,spinsize; int *MP; int iw,iw_method; dcomplex w, w_weight; dcomplex *GC_Ad; dcomplex *GC,*GRL,*GRR; dcomplex *SigmaL, *SigmaR; dcomplex *SigmaL_Ad, *SigmaR_Ad; dcomplex *work1,*work2,*Gless; dcomplex **v2,*v20; double dum; double TStime,TEtime; int MA_AN, GA_AN, wanA, tnoA, Anum; int LB_AN, GB_AN, wanB, tnoB, Bnum; int NUM_c0; static int ID; int Miw,iw0; double time_a0, time_a1, time_a2; /* setup MP */ /* TRAN_Set_MP(0, atomnum, WhatSpecies, Spe_Total_CNO, &NUM_c, &i); */ MP = (int*)malloc(sizeof(int)*(atomnum+1)); TRAN_Set_MP(1, atomnum, WhatSpecies, Spe_Total_CNO, &NUM_c, MP); NUM_c0=NUM_c; NUM_c=2*NUM_c; /* initialize */ TRAN_Set_Value_double(SCC_nc,NUM_c*NUM_c, 0.0,0.0); TRAN_Set_Value_double(SCL_nc,NUM_c*NUM_e[0], 0.0,0.0); TRAN_Set_Value_double(SCR_nc,NUM_c*NUM_e[1], 0.0,0.0); TRAN_Set_Value_double(HCC_nc,NUM_c*NUM_c, 0.0,0.0); TRAN_Set_Value_double(HCL_nc,NUM_c*NUM_e[0], 0.0,0.0); TRAN_Set_Value_double(HCR_nc,NUM_c*NUM_e[1], 0.0,0.0); /* set Hamiltonian and overlap matrices of left and right leads */ TRAN_Set_SurfOverlap_NC(comm1,"left", k2, k3); TRAN_Set_SurfOverlap_NC(comm1,"right",k2, k3); /* set CC, CL and CR */ TRAN_Set_CentOverlap_NC( comm1, 3, SpinP_switch, k2, k3, order_GA, H1, H2, 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_c0*NUM_c0); TRAN_Set_Value_double( v2[k], NUM_c0*NUM_c0, 0.0, 0.0); } /* added by Y. Xiao */ v20 = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c* NUM_c); TRAN_Set_Value_double( v20, NUM_c*NUM_c, 0.0, 0.0); GC = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c* NUM_c); GC_Ad = (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); SigmaL_Ad = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c* NUM_c); SigmaR_Ad = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c* NUM_c); work1 = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c* NUM_c); work2 = (dcomplex*)malloc(sizeof(dcomplex)*NUM_c* NUM_c); Gless = (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); } if (SpinP_switch==0) spinsize = 1; else if (SpinP_switch==1) spinsize = 2; else if (SpinP_switch==3) spinsize = 1; /* The three below lines are not used for NC cal. */ /************************************************************** calculation of Green functions at k and iw **************************************************************/ for ( Miw=myid; Miw<tran_omega_n_scf; Miw+=numprocs ) { /* for ( Miw=myid; Miw<tran_omega_n_scf*spinsize; Miw+=numprocs ) { */ /* k = Miw/tran_omega_n_scf; */ /* iw = Miw - k*tran_omega_n_scf; */ iw = Miw; w = tran_omega_scf[iw]; w_weight = tran_omega_weight_scf[iw]; iw_method = tran_integ_method_scf[iw]; /* printf("Miw=%3d iw=%d of %d w=%le %le weight=%le %le method=%d\n", Miw,iw,tran_omega_n_scf, w.r,w.i, w_weight.r, w_weight.i, iw_method); */ /* calculation of surface Green's function and self energy from the LEFT lead */ iside = 0; TRAN_Calc_SurfGreen_direct(w, NUM_e[iside], H00_nc_e[iside], H01_nc_e[iside], S00_nc_e[iside], S01_nc_e[iside], tran_surfgreen_iteration_max, tran_surfgreen_eps, GRL); TRAN_Calc_SelfEnergy(w, NUM_e[iside], GRL, NUM_c, HCL_nc, SCL_nc, SigmaL); /* calculation of surface Green's function and self energy from the RIGHT lead */ iside = 1; TRAN_Calc_SurfGreen_direct(w, NUM_e[iside], H00_nc_e[iside], H01_nc_e[iside], S00_nc_e[iside], S01_nc_e[iside], tran_surfgreen_iteration_max, tran_surfgreen_eps, GRR); TRAN_Calc_SelfEnergy(w, NUM_e[iside], GRR, NUM_c, HCR_nc, SCR_nc, SigmaR); /* calculation of central retarded Green's function */ TRAN_Calc_CentGreen(w, NUM_c, SigmaL, SigmaR, HCC_nc, SCC_nc, GC); /*********************************************** The non-equilibrium part is calculated by using the lesser Green's function. ***********************************************/ /* calculation of central advanced Green's function */ if (iw_method==2){ /* conjugate complex */ w.i = -w.i; /* calculation of surface Green's function and self energy from the LEFT lead */ iside = 0; TRAN_Calc_SurfGreen_direct(w, NUM_e[iside], H00_nc_e[iside], H01_nc_e[iside], S00_nc_e[iside], S01_nc_e[iside], tran_surfgreen_iteration_max, tran_surfgreen_eps, GRL); TRAN_Calc_SelfEnergy(w, NUM_e[iside], GRL, NUM_c, HCL_nc, SCL_nc, SigmaL_Ad); /* calculation of surface Green's function and self energy from the RIGHT lead */ iside = 1; TRAN_Calc_SurfGreen_direct(w, NUM_e[iside], H00_nc_e[iside], H01_nc_e[iside], S00_nc_e[iside], S01_nc_e[iside], tran_surfgreen_iteration_max, tran_surfgreen_eps, GRR); TRAN_Calc_SelfEnergy(w, NUM_e[iside], GRR, NUM_c, HCR_nc, SCR_nc, SigmaR_Ad); /* calculation of central advanced Green's function */ TRAN_Calc_CentGreen(w, NUM_c, SigmaL_Ad, SigmaR_Ad, HCC_nc, SCC_nc, GC_Ad); /* conjugate complex */ w.i = -w.i; /* calculation of central lesser Green's function */ TRAN_Calc_CentGreenLesser( w, ChemP_e, NUM_c, Order_Lead_Side, SigmaL, SigmaL_Ad, SigmaR, SigmaR_Ad, GC, GC_Ad, HCC_nc, SCC_nc, work1, work2, Gless); } /* if (iw_method==2) */ /*********************************************** add it to construct the density matrix ***********************************************/ if (iw_method==1) TRAN_Add_MAT( 1, NUM_c, w_weight, GC, v20); else if (iw_method==2) TRAN_Add_MAT( 1, NUM_c, w_weight, Gless, v20); } /* iw */ if (MEASURE_TIME){ dtime(&time_a1); } /* distribution of spin-spin */ for (i=1; i<=NUM_c0; i++) { for (j=1; j<=NUM_c0; j++) { /* alpha-alpha */ v2[0][(j-1)*NUM_c0+(i)-1].r = v20[(j-1)*NUM_c+(i)-1].r; v2[0][(j-1)*NUM_c0+(i)-1].i = v20[(j-1)*NUM_c+(i)-1].i; /* beta-beta */ v2[1][(j-1)*NUM_c0+(i)-1].r = v20[(j+NUM_c0-1)*NUM_c+(i+NUM_c0)-1].r; v2[1][(j-1)*NUM_c0+(i)-1].i = v20[(j+NUM_c0-1)*NUM_c+(i+NUM_c0)-1].i; /* alpha-beta */ v2[2][(j-1)*NUM_c0+(i)-1].r = v20[(j+NUM_c0-1)*NUM_c+(i)-1].r; v2[2][(j-1)*NUM_c0+(i)-1].i = v20[(j+NUM_c0-1)*NUM_c+(i)-1].i; /* beta-alpha */ v2[3][(j-1)*NUM_c0+(i)-1].r = v20[(j-1)*NUM_c+(i+NUM_c0)-1].r; v2[3][(j-1)*NUM_c0+(i)-1].i = v20[(j-1)*NUM_c+(i+NUM_c0)-1].i; } } /*********************************************** calculation of density matrix ***********************************************/ { int l1,l2,l3,RnB; int size_v3,itot,itot0,size_temp; double kRn,si,co,re,im; double *my_v3; double *v3; dcomplex **DM1_temp; /* find the size of v3 */ size_v3 = 0; size_temp = 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++; size_temp++; } } } } /* allocate arrays */ my_v3 = (double*)malloc(sizeof(double)*size_v3); v3 = (double*)malloc(sizeof(double)*size_v3); /* allocate a temporal array for DM1 */ DM1_temp = (dcomplex**)malloc(sizeof(dcomplex*)*(SpinP_switch+1)); for (k=0; k<=SpinP_switch; k++){ DM1_temp[k] = (dcomplex*)malloc(sizeof(dcomplex)*size_temp); TRAN_Set_Value_double( DM1_temp[k], size_temp, 0.0, 0.0); } /* set up v3 */ #define v_idx(i,j) ( ((j)-1)*NUM_c0 + (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++]; /* divided by numprocs due to the later MPI_Allreduce */ DM1_temp[k][itot0].r += (re*co + im*si)/(double)numprocs; DM1_temp[k][itot0].i += (im*co - re*si)/(double)numprocs; itot0++; } } } } } /* k */ /* transfer the value of DM1_temp to DM1 */ for (i=0; i<size_temp; i++) { DM1[0][i] += DM1_temp[0][i].r; DM1[1][i] += DM1_temp[1][i].r; DM1[2][i] += DM1_temp[2][i].r; DM1[3][i] -= DM1_temp[2][i].i; DM2[0][i] += DM1_temp[0][i].i; DM2[1][i] += DM1_temp[1][i].i; } /* free arrays */ free(my_v3); free(v3); for (i=0; i<=SpinP_switch; i++){ free(DM1_temp[i]); } free(DM1_temp); } if (MEASURE_TIME){ MPI_Barrier(comm1); dtime(&time_a2); printf("TRAN_DFT(%d)> calculaiton (%le)\n",myid, time_a1-time_a0 ); } /* free arrays */ free(Gless); free(work2); free(work1); free(SigmaL_Ad); free(SigmaR_Ad); free(SigmaR); free(SigmaL); free(GRR); free(GRL); free(GC_Ad); free(GC); for (k=0; k<=SpinP_switch; k++) { free(v2[k]); } free(v2); free(v20); free(MP); }
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); }