/src/TRAN_Set_IntegPath.c
C | 1133 lines | 581 code | 295 blank | 257 comment | 70 complexity | 31cde782fd8630865e7abff1f42abb64 MD5 | raw file
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #ifdef nompi
- #include "mimic_mpi.h"
- #else
- #include <mpi.h>
- #endif
- #include "tran_prototypes.h"
- #include "tran_variables.h"
- #include "lapack_prototypes.h"
- #define PI 3.1415926535897932384626
- typedef struct {
- double a,b;
- } dlists;
- /* Taisuke Ozaki Copyright (C) */
- static void Eigen_DGGEVX( int n, double **a, double **s, double *eval,
- double *resr, double *resi );
- /* Taisuke Ozaki Copyright (C) */
- static void zero_cfrac( int n, dcomplex *zp, dcomplex *Rp );
- /* Taisuke Ozaki Copyright (C) */
- static int dlists_cmp(const dlists *x, const dlists *y);
- /* Taisuke Ozaki Copyright (C) */
- static void dqsort(long n, double *a, double *b);
- /*
- * (0,3) -> (1,3)
- * A |
- * | V
- * (0,2) (1,2) ->(1+|VR-VL|,2)
- */
- void TRAN_Set_IntegPath_Square(void)
- {
- static int method=1; /* log or linear for the (1,3)->(1,2) path */
- int i,itotal;
- double x;
- double fac;
- dcomplex dx;
- tran_omega_n_scf=0;
- for (i=0;i<=3;i++) {
- tran_omega_n_scf += tran_square_path_div[i];
- }
- if (tran_bias_apply) {
- tran_omega_n_scf += tran_square_path_bias_div;
- }
-
- /* allocation */
- tran_omega_scf = (dcomplex*)malloc(sizeof(dcomplex)*tran_omega_n_scf);
- tran_omega_weight_scf=(dcomplex*)malloc(sizeof(dcomplex)*tran_omega_n_scf);
- tran_integ_method_scf=(int*)malloc(sizeof(int)*tran_omega_n_scf);
- /* calculate freq */
- /* spec = -1/PI Im G^R(w) */
- fac = 1.0/PI;
- itotal=0;
- /* (0,2)->(0,3) divided by div[0] */
- dx.r = 0.0;
- dx.i = ( tran_square_path_ene[3]- tran_square_path_ene[2] ) / tran_square_path_div[0];
-
- for (i=0;i<tran_square_path_div[0];i++) {
- x = (double)i+0.5;
- tran_omega_scf[itotal].r = tran_square_path_ene[0] + dx.r*x;
- tran_omega_scf[itotal].i = tran_square_path_ene[2] + dx.i*x;
- tran_omega_weight_scf[itotal].r = -dx.r*fac;
- tran_omega_weight_scf[itotal].i = -dx.i*fac;
- tran_integ_method_scf[itotal] = 1; /* equiv */
- itotal++;
- }
- /* (0,3) -> (1,3) by div[1] */
- dx.r = ( tran_square_path_ene[1]- tran_square_path_ene[0] ) / tran_square_path_div[1];
- dx.i = 0.0;
- for (i=0;i<tran_square_path_div[1];i++) {
- x=(double)i+0.5;
- tran_omega_scf[itotal].r = tran_square_path_ene[0] + dx.r*x;
- tran_omega_scf[itotal].i = tran_square_path_ene[3] + dx.i*x;
- tran_omega_weight_scf[itotal].r = -dx.r*fac;
- tran_omega_weight_scf[itotal].i = -dx.i*fac;
- tran_integ_method_scf[itotal] = 1; /* equiv */
- itotal++;
- }
- /* (1,3) -> (1,2) by div[2] */
- if (method==1) { /* linear */
- dx.r = 0.0;
- dx.i = ( tran_square_path_ene[2]- tran_square_path_ene[3] ) / tran_square_path_div[2];
- for (i=0;i<tran_square_path_div[2];i++) {
- x=i+0.5;
- tran_omega_scf[itotal].r = tran_square_path_ene[1] + dx.r*x;
- tran_omega_scf[itotal].i = tran_square_path_ene[3] + dx.i*x;
- tran_omega_weight_scf[itotal].r = -dx.r*fac;
- tran_omega_weight_scf[itotal].i = -dx.i*fac;
- tran_integ_method_scf[itotal] = 1; /* equiv */
- itotal++;
- }
- }
- else if (method==2) { /* log */
- /*
- c assuming
- c theta(1/2+i) = exp(th1+delta(1/2+i))
- c boundary condition
- c theta(0) = exp(th1) = exp( log(w4) ) = w4
- c theta(N3)= exp(th1+delta*N3)) = exp(th1+(th2-th1)/N3*N3) = exp(th2)= w3
- c delta = (th2-th1)/N3
- c integral weight
- c int d theta = int exp(th1+delta x) delta dx
- c => weight = exp(th1+delta(1/2+i))delta for ith
- c
- */
- double th1, th2,delta;
- th1 = log( tran_square_path_ene[3] );
- th2 = log (tran_square_path_ene[2] );
- delta = (th2-th1)/tran_square_path_div[2];
- for (i=0;i<tran_square_path_div[2];i++) {
- x = 0.5+i;
- tran_omega_scf[itotal].r = tran_square_path_ene[1] ;
- tran_omega_scf[itotal].i = exp(th1+delta*x);
- tran_omega_weight_scf[itotal].r = 0.0;
- tran_omega_weight_scf[itotal].i = -delta*exp(th1+delta*x)*fac;
- tran_integ_method_scf[itotal] = 1; /* equiv */
- itotal++;
- }
- } /* method */
- if ( tran_bias_apply ) {
- /* bias case, (NEGF) */
- /* path (1,2)-> (| V_L - V_R | + biasV ,2) */
- dx.r = ( fabs(tran_biasvoltage_e[0]-tran_biasvoltage_e[1]) +
- tran_square_path_bias_expandenergy ) / tran_square_path_bias_div;
- dx.i = 0;
- for (i=0;i<tran_square_path_bias_div;i++) {
- x=(double)i+0.5;
- tran_omega_scf[itotal].r = tran_square_path_ene[1] + dx.r*x;
- tran_omega_scf[itotal].i = tran_square_path_ene[2] + dx.i*x;
- /* -i/pi int A dw
- * -i dw = (dw.r+ i dw.i)*(-i) = ( dw.i -i dw.r )
- */
- tran_omega_weight_scf[itotal].r = dx.i*fac;
- tran_omega_weight_scf[itotal].i = -dx.r*fac;
- tran_integ_method_scf[itotal] = 2; /* non-equiv. */
- itotal++;
- }
- }
- /*debug*/
- printf("integral path\n");
- printf("id freq weight\n");
- for (i=0;i<tran_omega_n_scf;i++) {
- printf("%d %lf %lf %lf %lf\n",i, tran_omega_scf[i].r, tran_omega_scf[i].i,
- tran_omega_weight_scf[i].r, tran_omega_weight_scf[i].i);
- }
- printf("\n");
- /*end debug*/
-
- }
- /*****************************************************************************************
- *****************************************************************************************
- *****************************************************************************************/
- /*
- spectra = -1/pi Im G^R(w)
- */
- /*
- ----------
- / \ (1-gamma,3)
- / -------------(1,3)
- | x
- | x
- | x
- ---+------------------------------>
- (0,2)
- n = int_C A(x) nF(x) dx
- (0,2) -> (1-gamma,3) divided by n0
- (1-gamma,3)->(1,3) divided by n1
- if (applied_bias) additional points
- use
- double tran_thermalarc_path_ene[5];
- int tran_thermalarc_path_ene_fix[5];
- int tran_thermalarc_path_div[2];
- double tran_thermalarc_path_bias_expandenergy; for NEGF
- int tran_thermalarc_path_bias_div; for NEGF
- */
- void TRAN_Set_IntegPath_ThermalArc(void)
- {
- double f,factor,beta;
- double chem;
- int n_max;
- int i, itotal;
- double gamma, w1,w2,w3,w4;
- double a,b;
- double th1,th2,dth;
-
- /* find chem=chemical potential */
- chem = ( ChemP_e[0] < ChemP_e[1] )? ChemP_e[0] : ChemP_e[1] ;
- if ( tran_bias_apply ) {
- chem -= tran_thermalarc_path_bias_expandenergy;
- }
- n_max=100;
- f= PI*(2*n_max+1)*tran_temperature;
- if ( f< tran_thermalarc_path_ene[3] ) {
- printf("PI*(2*n_max+1)*tran_temperature (%lf) < tran_thermalarc_path_ene[3] (%lf)\n",
- f,tran_thermalarc_path_ene[3]);
- exit(0);
- }
- /* count max thermal freq */
- for (i=0;i<=n_max;i++) {
- f = (2.0*(double)i+1.0)*PI*tran_temperature;
- if (f> tran_thermalarc_path_ene[3]) {
- break;
- }
- }
- n_max = i;
- /* storage size */
- tran_omega_n_scf=0;
- for (i=0;i<=3;i++) {
- tran_omega_n_scf += tran_square_path_div[i];
- }
-
- tran_omega_n_scf += n_max; /* contribution of thermal freq */
-
- if (tran_bias_apply) {
- tran_omega_n_scf += tran_square_path_bias_div;
- }
-
- /* allocation */
- tran_omega_scf = (dcomplex*)malloc(sizeof(dcomplex)*tran_omega_n_scf);
- tran_omega_weight_scf=(dcomplex*)malloc(sizeof(dcomplex)*tran_omega_n_scf);
- tran_integ_method_scf=(int*)malloc(sizeof(int)*tran_omega_n_scf);
- /* calculate freq */
- /* spec = -1/PI Im G^R(w) */
- factor = 1.0/PI;
- itotal=0;
- /************
- 1st contribution
- calculate arc
- -----------
- / \
- / \(2,4)-(gamma,0)
- |
- |
- ---------+---------------------------
- (1,3) (b,0)
- radius = a
- center = (b,0)
- a^2 = (w1-b)^2+w3^2
- a^2 = (w2-gamma-b)^2+w4^2
- 0 = w1^2 -2 w1 b + w3^2
- - ( (w2-gamma)^2 - 2(w2-gamma) b + w4^2 )
- b = ( w1^2 + w3^2 - (w2-gamma)^2 - w4^2 ) / ( w1- (w2-gamma) )/2.0
-
- ******************/
- w1 = tran_thermalarc_path_ene[0];
- w2 = tran_thermalarc_path_ene[1];
- w3 = tran_thermalarc_path_ene[2];
- w4 = tran_thermalarc_path_ene[3];
- gamma = tran_thermalarc_path_ene[4];
- b = ( sqr( w1 ) +sqr(w3) - sqr( w2-gamma ) - sqr( w4 ) )/
- ( w1- w2+ gamma )*0.5;
- a = sqrt( sqr(w1-b) + sqr(w3) );
- /* comment
- (1,0) is 0 degree
- (sqrt(2)/2,sqrt(2)/2) is 45 degree
- (-1,0) is 180 degree */
- th1 = acos( (w1-b)/a );
- th2 = asin( w4/a );
- dth = (th2-th1)/tran_thermalarc_path_div[0];
- /* int_C a(x) nF(x) dx
- = int_C a(x(t)) (nF(x(t)) dx/dt) dt ,
- here calculate (nF(x(t)) dx/dt) */
- for (i=0;i<tran_thermalarc_path_div[0] ;i++) {
- double x,th,d;
- dcomplex z,z2,z1,fermi,dxdth;
- x=0.5+i;
- th = th1 + dth*x;
- z.r = a*cos(th)+b;
- z.i = a*sin(th);
- tran_omega_scf[itotal].r = z.r;
- tran_omega_scf[itotal].i = z.i;
- z2.r = beta*(z.r-chem); z2.i = beta*(z.i);
- z_exp_inline(z2,z1);
- z1.r += 1.0; /* z1 = exp(beta(z-chem))+1 */
- d = sqr(z1.r)+ sqr(z1.i);
- fermi.r = z1.r/d; fermi.i = -z1.i/d; /* fermi = 1/ (nf(beta(z-chem))+1 ) */
- dxdth.r= -a *sin(th)* dth; dxdth.i = a* cos(th)* dth;
- z_mul_inline(fermi, dxdth, z1);
-
- tran_omega_weight_scf[itotal].r = z1.r*factor;
- tran_omega_weight_scf[itotal].i = z1.i*factor;
- tran_integ_method_scf[itotal]=1;
- itotal++;
- }
- /*
- (2,4)-(gamma,0) -> (2,4)
- */
- {
- dcomplex w_int;
-
- w_int.r = gamma/w2; w_int.i =0.0;
- for (i=0;i<tran_thermalarc_path_div[1];i++) {
- double x,d;
- dcomplex z,z1,z2,fermi;
-
- x=0.5+i;
- z.r = w2-gamma+w_int.r*x; z.i = w4;
- tran_omega_scf[itotal].r = z.r;
- tran_omega_scf[itotal].i = z.i;
- z2.r = beta*(z.r-chem); z2.i = beta*(z.i);
- z_exp_inline(z2,z1); /* exp(beta(z-chem)) */
- z1.r += 1.0; /* z1 = exp(beta(z-chem))+1 */
- d = sqr(z1.r)+ sqr(z1.i);
- fermi.r = z1.r/d; fermi.i = -z1.i/d;
- z_mul_inline( w_int, fermi, z2);
-
- tran_omega_weight_scf[itotal].r = -z2.r*factor;
- tran_omega_weight_scf[itotal].i = -z2.i*factor;
- tran_integ_method_scf[itotal]=1;
-
- itotal++;
- }
- }
- /* contour integral */
- for (i=0;i<n_max;i++) {
- double th;
- th = (2.0*(double)i+1.0)*PI*tran_temperature;
- tran_omega_scf[itotal].r = chem;
- tran_omega_scf[itotal].i= th;
- tran_omega_weight_scf[itotal].r=0;
- tran_omega_weight_scf[itotal].i=-factor*2.0*PI*tran_temperature;
- tran_integ_method_scf[itotal]=1;
- itotal++;
- }
- /* applied bias */
- if (tran_bias_apply) {
- dcomplex w_int;
- factor = 1.0/(2.0*PI);
- w_int.r = (fabs(ChemP_e[0]-ChemP_e[1])+ tran_thermalarc_path_bias_expandenergy )/ tran_thermalarc_path_bias_div;
- w_int.i=0;
- for (i=0;i<tran_thermalarc_path_bias_div;i++) {
- double x;
- x=0.5+i;
- tran_omega_scf[itotal].r = chem+ w_int.r*x;
- tran_omega_scf[itotal].i = w2;
- tran_omega_weight_scf[itotal].r= w_int.i*factor;
- tran_omega_weight_scf[itotal].i= -w_int.r*factor;
-
- tran_integ_method_scf[itotal]=2;
- itotal++;
-
- }
- }
- }
- /* Taisuke Ozaki Copyright (C) */
- void TRAN_Set_IntegPath_GaussHG( double kBvalue, double Electronic_Temperature )
- {
- int p;
- double beta,R;
- R = 1.0e+12;
- if ( tran_bias_apply ){
- if (TRAN_Kspace_grid2==1 && TRAN_Kspace_grid3==1)
- tran_omega_n_scf = 2*(tran_num_poles + 1);
- else
- tran_omega_n_scf = 4*(tran_num_poles + 1);
- }
- else{
- if (TRAN_Kspace_grid2==1 && TRAN_Kspace_grid3==1)
- tran_omega_n_scf = tran_num_poles + 1;
- else
- tran_omega_n_scf = 2*(tran_num_poles + 1);
- }
- /* allocation */
- tran_omega_scf = (dcomplex*)malloc(sizeof(dcomplex)*tran_omega_n_scf);
- tran_omega_weight_scf=(dcomplex*)malloc(sizeof(dcomplex)*tran_omega_n_scf);
- tran_integ_method_scf=(int*)malloc(sizeof(int)*tran_omega_n_scf);
- zero_cfrac( tran_num_poles, tran_omega_scf, tran_omega_weight_scf );
- beta = 1.0/kBvalue/Electronic_Temperature;
- /*
- for (p=0; p<tran_num_poles; p++){
- printf("p=%3d zp.r=%15.12f zp.i=%15.12f Rp.r=%15.12f Rp.i=%15.12f\n",
- p, tran_zp[p].r, tran_zp[p].i, tran_Rp[p].r, tran_Rp[p].i );
- }
- */
- /* bias case */
- if ( tran_bias_apply ){
- /*************************************
- (1) finite bias and only Gamma point
- p=0,tran_num_poles-1
- poles for mu_L
- p=tran_num_poles
- iR for mu_L
- p=tran_num_poles+1,2*tran_num_poles
- poles for mu_R
-
- p=2*tran_num_poles+1
- iR for mu_R
- *************************************/
- if (TRAN_Kspace_grid2==1 && TRAN_Kspace_grid3==1){
- /* contribution of poles */
- for (p=0; p<tran_num_poles; p++){
- tran_omega_scf[p].r = ChemP_e[0];
- tran_omega_scf[p].i = tran_omega_scf[p].i/beta;
- tran_omega_weight_scf[p].r = -2.0*tran_omega_weight_scf[p].r/beta;
- tran_omega_weight_scf[p].i = 0.0;
- tran_integ_method_scf[p] = 3;
- tran_omega_scf[tran_num_poles+p+1].r = ChemP_e[1];
- tran_omega_scf[tran_num_poles+p+1].i = tran_omega_scf[p].i;
- tran_omega_weight_scf[tran_num_poles+p+1].r = tran_omega_weight_scf[p].r;
- tran_omega_weight_scf[tran_num_poles+p+1].i = 0.0;
- tran_integ_method_scf[tran_num_poles+p+1] = 4;
- }
- /* contribution of the half circle contour integral */
-
- tran_omega_scf[tran_num_poles].r = 0.0;
- tran_omega_scf[tran_num_poles].i = R;
- tran_omega_weight_scf[tran_num_poles].r = 0.0;
- tran_omega_weight_scf[tran_num_poles].i = 0.5*R;
- tran_integ_method_scf[tran_num_poles] = 3;
- tran_omega_scf[2*tran_num_poles+1].r = 0.0;
- tran_omega_scf[2*tran_num_poles+1].i = R;
- tran_omega_weight_scf[2*tran_num_poles+1].r = 0.0;
- tran_omega_weight_scf[2*tran_num_poles+1].i = 0.5*R;
- tran_integ_method_scf[2*tran_num_poles+1] = 4;
- }
- /*************************************
- (2) finite bias and lots of k-points
- p=0,tran_num_poles-1
- poles for retarded with mu_L
- p=tran_num_poles
- iR for retarded with mu_L
- p=tran_num_poles+1,2*tran_num_poles
- poles for advanced with mu_L
-
- p=2*tran_num_poles+1
- iR for advanced with mu_L
- p=2*tran_num_poles+2,3*tran_num_poles+1
- poles for retarded with mu_R
- p=3*tran_num_poles + 2
- iR for retarded with mu_L
- p=3*tran_num_poles+3,4*tran_num_poles+2
- poles for advanced with mu_L
-
- p=4*tran_num_poles+3
- iR for advanced with mu_L
- *************************************/
- else{
- /* contribution of poles */
- for (p=0; p<tran_num_poles; p++){
- /* retarded with mu_L */
- tran_omega_scf[p].r = ChemP_e[0];
- tran_omega_scf[p].i = tran_omega_scf[p].i/beta;
- tran_omega_weight_scf[p].r = -tran_omega_weight_scf[p].r/beta;
- tran_omega_weight_scf[p].i = 0.0;
- tran_integ_method_scf[p] = 3;
- /* advanced with mu_L */
- tran_omega_scf[tran_num_poles+p+1].r = ChemP_e[0];
- tran_omega_scf[tran_num_poles+p+1].i = -tran_omega_scf[p].i;
- tran_omega_weight_scf[tran_num_poles+p+1].r = tran_omega_weight_scf[p].r;
- tran_omega_weight_scf[tran_num_poles+p+1].i = 0.0;
- tran_integ_method_scf[tran_num_poles+p+1] = 3;
- /* retarded with mu_R */
- tran_omega_scf[2*tran_num_poles+p+2].r = ChemP_e[1];
- tran_omega_scf[2*tran_num_poles+p+2].i = tran_omega_scf[p].i;
- tran_omega_weight_scf[2*tran_num_poles+p+2].r = tran_omega_weight_scf[p].r;
- tran_omega_weight_scf[2*tran_num_poles+p+2].i = 0.0;
- tran_integ_method_scf[2*tran_num_poles+p+2] = 4;
- /* advanced with mu_R */
- tran_omega_scf[3*tran_num_poles+p+3].r = ChemP_e[1];
- tran_omega_scf[3*tran_num_poles+p+3].i = -tran_omega_scf[p].i;
- tran_omega_weight_scf[3*tran_num_poles+p+3].r = tran_omega_weight_scf[p].r;
- tran_omega_weight_scf[3*tran_num_poles+p+3].i = 0.0;
- tran_integ_method_scf[3*tran_num_poles+p+3] = 4;
- }
- /* contribution of the half circle contour integral */
-
- tran_omega_scf[tran_num_poles].r = 0.0;
- tran_omega_scf[tran_num_poles].i = R;
- tran_omega_weight_scf[tran_num_poles].r = 0.0;
- tran_omega_weight_scf[tran_num_poles].i = 0.25*R;
- tran_integ_method_scf[tran_num_poles] = 3;
- tran_omega_scf[2*tran_num_poles+1].r = 0.0;
- tran_omega_scf[2*tran_num_poles+1].i = R;
- tran_omega_weight_scf[2*tran_num_poles+1].r = 0.0;
- tran_omega_weight_scf[2*tran_num_poles+1].i = 0.25*R;
- tran_integ_method_scf[2*tran_num_poles+1] = 3;
- tran_omega_scf[3*tran_num_poles+2].r = 0.0;
- tran_omega_scf[3*tran_num_poles+2].i = R;
- tran_omega_weight_scf[3*tran_num_poles+2].r = 0.0;
- tran_omega_weight_scf[3*tran_num_poles+2].i = 0.25*R;
- tran_integ_method_scf[3*tran_num_poles+2] = 4;
- tran_omega_scf[4*tran_num_poles+3].r = 0.0;
- tran_omega_scf[4*tran_num_poles+3].i = R;
- tran_omega_weight_scf[4*tran_num_poles+3].r = 0.0;
- tran_omega_weight_scf[4*tran_num_poles+3].i = 0.25*R;
- tran_integ_method_scf[4*tran_num_poles+3] = 4;
- }
- }
- /* zero-bias case */
- else {
- /*************************************
- (3) zero-bias and only Gamma point
- *************************************/
- if (TRAN_Kspace_grid2==1 && TRAN_Kspace_grid3==1){
- /* contribution of poles */
- for (p=0; p<tran_num_poles; p++){
- tran_omega_scf[p].r = ChemP_e[0];
- tran_omega_scf[p].i = tran_omega_scf[p].i/beta;
- tran_omega_weight_scf[p].r = -2.0*tran_omega_weight_scf[p].r/beta;
- tran_omega_weight_scf[p].i = 0.0;
- }
- /* contribution of the half circle contour integral */
- tran_omega_scf[tran_num_poles].r = 0.0;
- tran_omega_scf[tran_num_poles].i = R;
- tran_omega_weight_scf[tran_num_poles].r = 0.0;
- tran_omega_weight_scf[tran_num_poles].i = 0.5*R;
- /* set the integral method in 1 */
- for (p=0; p<=tran_num_poles; p++){
- tran_integ_method_scf[p] = 1;
- }
- }
- /*************************************
- (4) zero-bias and lots of k-points
- p=0,tran_num_poles-1
- poles for retarded
- p=tran_num_poles
- iR for retarded
- p=tran_num_poles+1,2*tran_num_poles
- poles for advanced
-
- p=2*tran_num_poles+1
- iR for advanced
- *************************************/
- else{
-
- /* contribution of poles */
- for (p=0; p<tran_num_poles; p++){
- tran_omega_scf[p].r = ChemP_e[0];
- tran_omega_scf[p].i = tran_omega_scf[p].i/beta;
- tran_omega_weight_scf[p].r = -tran_omega_weight_scf[p].r/beta;
- tran_omega_weight_scf[p].i = 0.0;
- tran_integ_method_scf[p] = 1;
- tran_omega_scf[tran_num_poles+p+1].r = ChemP_e[0];
- tran_omega_scf[tran_num_poles+p+1].i =-tran_omega_scf[p].i;
- tran_omega_weight_scf[tran_num_poles+p+1].r = tran_omega_weight_scf[p].r;
- tran_omega_weight_scf[tran_num_poles+p+1].i = 0.0;
- tran_integ_method_scf[tran_num_poles+p+1] = 1;
- }
- /* contribution of the half circle contour integral */
- tran_omega_scf[tran_num_poles].r = 0.0;
- tran_omega_scf[tran_num_poles].i = R;
- tran_omega_weight_scf[tran_num_poles].r = 0.0;
- tran_omega_weight_scf[tran_num_poles].i = 0.25*R;
- tran_integ_method_scf[tran_num_poles] = 1;
- tran_omega_scf[2*tran_num_poles+1].r = 0.0;
- tran_omega_scf[2*tran_num_poles+1].i = R;
- tran_omega_weight_scf[2*tran_num_poles+1].r = 0.0;
- tran_omega_weight_scf[2*tran_num_poles+1].i = 0.25*R;
- tran_integ_method_scf[2*tran_num_poles+1] = 1;
- }
- }
- /*
- printf("ChemP_e[0]=%15.12f\n",ChemP_e[0]);
- printf("ChemP_e[1]=%15.12f\n",ChemP_e[1]);
- */
- }
- /* Taisuke Ozaki Copyright (C) */
- void zero_cfrac( int n, dcomplex *zp, dcomplex *Rp )
- {
- static int i,j,N;
- static double **a,**s,*eval,*resr,*resi;
- /* check input parameters */
- if (n<=0){
- printf("\ncould not find the number of zeros\n\n");
- MPI_Finalize();
- exit(0);
- }
- /* the total number of zeros including minus value */
- N = 2*n + 1;
- /* allocation of arrays */
- a = (double**)malloc(sizeof(double*)*(N+2));
- for (i=0; i<(N+2); i++){
- a[i] = (double*)malloc(sizeof(double)*(N+2));
- }
- s = (double**)malloc(sizeof(double*)*(N+2));
- for (i=0; i<(N+2); i++){
- s[i] = (double*)malloc(sizeof(double)*(N+2));
- }
- eval = (double*)malloc(sizeof(double)*(n+3));
- resr = (double*)malloc(sizeof(double)*(n+3));
- resi = (double*)malloc(sizeof(double)*(n+3));
- /* initialize arrays */
- for (i=0; i<(N+2); i++){
- for (j=0; j<(N+2); j++){
- a[i][j] = 0.0;
- s[i][j] = 0.0;
- }
- }
- /* set matrix elements */
- s[2][1] = 1.0;
- s[2][2] = -0.5;
- for (i=3; i<=N; i++){
- s[i][i-1] = -0.5;
- s[i-1][i] = 0.5;
- }
- a[1][1] = -2.0;
- a[1][2] = 1.0;
- a[2][2] = -1.0;
- for (i=3; i<=N; i++){
- a[i][i] = -(2.0*(double)i - 3.0);
- }
- /* diagonalization */
- Eigen_DGGEVX( N, a, s, eval, resr, resi );
- for (i=0; i<n; i++){
- zp[i].r = 0.0;
- zp[i].i = eval[i+1];
- Rp[i].r = resr[i+1];
- Rp[i].i = 0.0;
- }
- /* print result */
- /*
- for (i=1; i<=n; i++){
- printf("i=%4d eval=%18.14f resr=%18.15f resi=%18.15f\n",i,eval[i],resr[i],resi[i]);
- }
- */
- /*
- for (i=1; i<=n; i++){
- printf("%4d 0.0 %18.14f\n",i,eval[i]);
- }
- MPI_Finalize();
- exit(0);
- */
- /* free of arrays */
- for (i=0; i<(N+2); i++){
- free(a[i]);
- }
- free(a);
- for (i=0; i<(N+2); i++){
- free(s[i]);
- }
- free(s);
- free(eval);
- free(resr);
- free(resi);
- }
- /* Taisuke Ozaki Copyright (C) */
- void dqsort(long n, double *a, double *b)
- {
- int i;
- dlists *AB;
- AB = (dlists*)malloc(sizeof(dlists)*n);
- for (i=0; i<n; i++){
- AB[i].a = a[i+1];
- AB[i].b = b[i+1];
- }
- qsort(AB, n, sizeof(dlists), (int(*)(const void*, const void*))dlists_cmp);
- for (i=0; i<n; i++){
- a[i+1] = AB[i].a;
- b[i+1] = AB[i].b;
- }
- free(AB);
- }
- /* Taisuke Ozaki Copyright (C) */
- int dlists_cmp(const dlists *x, const dlists *y)
- {
- return (x->a < y->a ? -1 :
- y->a < x->a ? 1 : 0);
- }
- /* Taisuke Ozaki Copyright (C) */
- void Eigen_DGGEVX( int n, double **a, double **s, double *eval, double *resr, double *resi )
- {
- static int i,j,k,l,num;
- static char balanc = 'N';
- static char jobvl = 'V';
- static char jobvr = 'V';
- static char sense = 'B';
- static double *A;
- static double *b;
- static double *alphar;
- static double *alphai;
- static double *beta;
- static double *vl;
- static double *vr;
- static double *lscale;
- static double *rscale;
- static double abnrm;
- static double bbnrm;
- static double *rconde;
- static double *rcondv;
- static double *work;
- static double *tmpvecr,*tmpveci;
- static INTEGER *iwork;
- static INTEGER lda,ldb,ldvl,ldvr,ilo,ihi;
- static INTEGER lwork,info;
- static logical *bwork;
- static double sumr,sumi,tmpr,tmpi;
- static double *sortnum;
- lda = n;
- ldb = n;
- ldvl = n;
- ldvr = n;
- A = (double*)malloc(sizeof(double)*n*n);
- b = (double*)malloc(sizeof(double)*n*n);
- alphar = (double*)malloc(sizeof(double)*n);
- alphai = (double*)malloc(sizeof(double)*n);
- beta = (double*)malloc(sizeof(double)*n);
- vl = (double*)malloc(sizeof(double)*n*n);
- vr = (double*)malloc(sizeof(double)*n*n);
- lscale = (double*)malloc(sizeof(double)*n);
- rscale = (double*)malloc(sizeof(double)*n);
- rconde = (double*)malloc(sizeof(double)*n);
- rcondv = (double*)malloc(sizeof(double)*n);
- lwork = 2*n*n + 12*n + 16;
- work = (double*)malloc(sizeof(double)*lwork);
- iwork = (INTEGER*)malloc(sizeof(INTEGER)*(n+6));
- bwork = (logical*)malloc(sizeof(logical)*n);
- tmpvecr = (double*)malloc(sizeof(double)*(n+2));
- tmpveci = (double*)malloc(sizeof(double)*(n+2));
- sortnum = (double*)malloc(sizeof(double)*(n+2));
- /* convert two dimensional arrays to one-dimensional arrays */
- for (i=0; i<n; i++) {
- for (j=0; j<n; j++) {
- A[j*n+i]= a[i+1][j+1];
- b[j*n+i]= s[i+1][j+1];
- }
- }
- /* call dggevx_() */
- F77_NAME(dggevx,DGGEVX)(
- &balanc, &jobvl, & jobvr, &sense, &n, A, &lda, b, &ldb,
- alphar, alphai, beta, vl, &ldvl, vr, &ldvr, &ilo, &ihi,
- lscale, rscale, &abnrm, &bbnrm, rconde, rcondv, work,
- &lwork, iwork, bwork, &info );
- if (info!=0){
- printf("Errors in dggevx_() info=%2d\n",info);
- }
- /*
- for (i=0; i<n; i++){
- printf("i=%4d %18.13f %18.13f %18.13f\n",i,alphar[i],alphai[i],beta[i]);
- }
- printf("\n");
- */
- num = 0;
- for (i=0; i<n; i++){
- if ( 1.0e-13<fabs(beta[i]) && 0.0<alphai[i]/beta[i] ){
- /* normalize the eigenvector */
- for (j=0; j<n; j++) {
- sumr = 0.0;
- sumi = 0.0;
- for (k=0; k<n; k++) {
- sumr += s[j+1][k+1]*vr[i*n +k];
- sumi += s[j+1][k+1]*vr[(i+1)*n+k];
- }
-
- tmpvecr[j] = sumr;
- tmpveci[j] = sumi;
- }
- sumr = 0.0;
- sumi = 0.0;
- for (k=0; k<n; k++) {
- sumr += vl[i*n+k]*tmpvecr[k] + vl[(i+1)*n+k]*tmpveci[k];
- sumi += vl[i*n+k]*tmpveci[k] - vl[(i+1)*n+k]*tmpvecr[k];
- }
- /* calculate zero point and residue */
- eval[num+1] = alphai[i]/beta[i];
- tmpr = vr[i*n]*vl[i*n] + vr[(i+1)*n]*vl[(i+1)*n];
- tmpi = -vr[i*n]*vl[(i+1)*n] + vr[(i+1)*n]*vl[i*n];
- resr[num+1] = tmpi/sumi;
- resi[num+1] = -tmpr/sumi;
- num++;
- }
- else{
- /*
- printf("i=%4d %18.13f %18.13f %18.13f\n",i+1,alphar[i],alphai[i],beta[i]);
- */
- }
- }
- /* check round-off error */
- for (i=1; i<=num; i++){
- if (1.0e-8<fabs(resi[i])){
- printf("Could not calculate zero points and residues due to round-off error\n");
- MPI_Finalize();
- exit(0);
- }
- }
- /* sorting */
- dqsort(num,eval,resr);
- /* free arraies */
- free(A);
- free(b);
- free(alphar);
- free(alphai);
- free(beta);
- free(vl);
- free(vr);
- free(lscale);
- free(rscale);
- free(rconde);
- free(rcondv);
- free(work);
- free(iwork);
- free(bwork);
- free(tmpvecr);
- free(tmpveci);
- free(sortnum);
- }
- void TRAN_Set_IntegPath( double kBvalue, double Electronic_Temperature )
- {
- if ( tran_integ_pathtype==1 ) {
- TRAN_Set_IntegPath_Square();
- }
- else if ( tran_integ_pathtype==10 ) {
- TRAN_Set_IntegPath_ThermalArc();
- }
- /* Taisuke Ozaki Copyright (C) */
- else if ( tran_integ_pathtype==3 ) {
- TRAN_Set_IntegPath_GaussHG( kBvalue, Electronic_Temperature );
- }
- else {
- printf("abort tran_integ_pathtype=%d, not supported\n",tran_integ_pathtype);
- exit(10);
- }
- }