/**************************************** Function name : paw_get_correlation_energy_LDA(double *rho) ****************************************/ double paw_get_correlation_energy_LDA(double *rho) { int i; double rs,n; double x,xxp; double ec_p; double Ec; double *tmp; /* loggrid variables */ int Ngrid; /* access the loggrid variables */ Ngrid = paw_N_LogGrid(); tmp = paw_scratch_LogGrid(); /* allocate temporary memory */ tmp = paw_alloc_LogGrid(); ec_functional = paw_alloc_LogGrid(); for (i=0; i<= Ngrid-1; i++) { n = rho[i]/(4.0*PI); rs = rs_scale/pow(n,onethird); x = sqrt(rs); xxp = rs + bp*x + cp; ec_p = cp1*log(rs/xxp) + cp2*log( (x+cp3)*(x+cp3)/xxp) + cp4*atan(cp5/(x+cp6)); ec_functional[i] = ec_p; } /*for i*/ for (i=0; i<= Ngrid-1; i++) tmp[i] = rho[i]*ec_functional[i]; Ec = paw_Integrate_LogGrid(tmp); return Ec; }
/**************************************** Function name : paw_get_ion_energy Description : Return type : double Argument : double *dn Author : Marat Valiev Date & Time : 3/31/99 2:12:25 PM ****************************************/ double paw_get_ion_energy(double *dn) { int k; int Ngrid; double *tmp; Ngrid = paw_N_LogGrid(); tmp = paw_scratch_LogGrid(); for (k=0; k<Ngrid; ++k) { tmp[k] = Vion[k]*dn[k]; } Eion = paw_Integrate_LogGrid(tmp); return Eion; }
/**************************************** Function name : paw_get_exchange_energy_LDA(double *rho) Description : ****************************************/ double paw_get_exchange_energy_LDA(double *rho) { int i; double n; double n_onethird; double ex_p; double Ex; double *tmp; /* loggrid variables */ int Ngrid; /* access the loggrid variables */ Ngrid = paw_N_LogGrid(); tmp = paw_scratch_LogGrid(); for (i=0; i<Ngrid; ++i) { n = rho[i]/(4.0*PI); n_onethird = pow((3.0*n/PI),onethird); ex_p = -(9.0/8.0)*alpha*n_onethird; ex_functional[i] = ex_p; } /*for i*/ for (i=0; i<Ngrid; ++i) tmp[i] = rho[i]*ex_functional[i]; Ex = paw_Integrate_LogGrid(tmp); return Ex; }
/**************************************** Function name : paw_generate_pseudopot Description : Return type : void Author : Marat Valiev Date & Time : 4/10/99 7:40:00 PM ****************************************/ void paw_generate_pseudopot() { int k; int Ngrid; double charge; double ps_charge; double Z; double *Vh; double *Vx; double *Vc; double *rho; double *rho_ps; double *rho_core; double *rho_core_ps; double *full_density; double *full_ps_density; double* V_comp; double *rgrid; FILE *fp; char data_filename[300]; if ( !(paw_projectors_are_done()) ) { printf("error, pseudopotential cannot be generated "); printf(" because projectors have not been yet \n"); exit(1); } Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); Vh = paw_alloc_LogGrid(); Vx = paw_alloc_LogGrid(); Vc = paw_alloc_LogGrid(); full_density = paw_alloc_LogGrid(); full_ps_density = paw_alloc_LogGrid(); Z = paw_get_ion_charge(); paw_set_core(); /*get densities*/ rho = paw_get_pointer_paw_density(); rho_ps = paw_get_pointer_paw_ps_density(); rho_core = paw_get_pointer_core_density(); rho_core_ps = paw_get_pointer_ps_core_density(); paw_Zero_LogGrid(full_density); paw_Zero_LogGrid(full_ps_density); for (k=0;k<=Ngrid-1;k++) { full_density[k] = rho[k] + rho_core[k]; full_ps_density[k] = rho_ps[k] + rho_core_ps[k]; } charge = paw_Integrate_LogGrid(full_density); ps_charge = paw_Integrate_LogGrid(full_ps_density); V_comp = paw_find_comp_charge_potential(Z,charge,ps_charge); paw_generate_hartree_pot(full_ps_density); Vh = paw_get_hartree_pot(); paw_generate_exchange_pot_LDA(full_ps_density); Vx = paw_get_exchange_potential(); paw_generate_corr_pot_LDA(full_ps_density); Vc = paw_get_corr_pot_LDA(); /*form pseudopotential*/ for (k=0;k<=Ngrid-1;k++) { V_pseudo[k] = V_ref[k] - Vh[k]- V_comp[k]- Vc[k] - Vx[k]; } if (paw_debug()) { sprintf(data_filename,"%sdensity",paw_sdir()); fp = fopen(data_filename,"w"); for (k=0;k<Ngrid;++k) fprintf(fp,"%f %f %f\n",rgrid[k],rho[k] - rho_ps[k],V_pseudo[k]); fclose(fp); } paw_dealloc_LogGrid(full_density); paw_dealloc_LogGrid(full_ps_density); }
/**************************************** Function name : paw_solve_unoccupied_orbitals Description : Return type : void Author : Marat Valiev Date & Time : 4/10/99 6:13:39 PM ****************************************/ void paw_solve_unoccupied_orbitals() { int i; int j; int k; int state; int Ngrid; int status; double sum; double *V; double *rgrid; double Zion; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); Zion = paw_get_ion_charge(); /*check if the occupied orbitals are done*/ if (!(occupied_orbitals_done)) { printf("cannot calculate unoccupied states\n"); printf("calculate occupied states first\n"); } /*get Kohn-Sham potential*/ V = paw_get_kohn_sham_potential(); for (i=Nvalence; i<= Nbound-1; i++) { state=paw_bound_state_test(l[i],V); if (state==0) { printf("This potential has no bound states with n=%d l=%d\n",n[i],l[i]); printf("please change your input file\n"); exit(1); } else { if (Solver_Type==Schrodinger) { status = paw_R_Schrodinger(n[i],l[i],V, &eigenvalue[i],psi[i],psi_prime[i]); } else { status = paw_R_Pauli(n[i],l[i],Zion,V, &eigenvalue[i],psi[i],psi_prime[i]); } } if (!(status)) { printf("This potential has no bound states with n=%d l=%d\n",n[i],l[i]); printf("please change your input file\n"); exit(1); } /*orthogonalize to lower orbitals*/ for (j=0;j<=i-1;j++) { if (l[i]==l[j]) { sum = paw_dot_product(psi[i],psi[j]); for (k=0;k<=Ngrid-1;k++) psi[i][k] = psi[i][k] - sum*psi[j][k]; } } for (k=0;k<=Ngrid-1;k++) psi_tmp[k] = pow((psi[i][k]/rgrid[k]),2.0); sum = paw_Integrate_LogGrid(psi_tmp); for (k=0;k<=Ngrid-1;k++) psi[i][k]=psi[i][k]/pow(sum,0.5); } }
/**************************************** Function name : paw_solve_occupied_orbitals Description : Return type : void Author : Marat Valiev Date & Time : 4/10/99 6:13:22 PM ****************************************/ void paw_solve_occupied_orbitals() { int i; int j; int k; int it; int converged; int Ngrid; int max_iter; double sum; double Etmp; double thl; double sn; double sd; double dr; double rl0; double rl1; double vn; double Zion; double *Vo; double *Vo1; double *Vi1; double *Vi; double *rgrid; max_iter = 100; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); /* allocate temporary grids */ Vi = paw_alloc_LogGrid(); Vo1 = paw_alloc_LogGrid(); Vi1 = paw_alloc_LogGrid(); /* set initial guess for KS potential as Thomas-Fermi*/ Zion = paw_get_ion_charge(); paw_Thomas_Fermi(Zion,Vi); /*initial guess for the eigenvalues*/ paw_guess_eigenvalues(Zion,Vi); it = 0; converged = False; while ((!converged) && (it < max_iter)) { it = it + 1; converged = True; /* solve for each of the eigenstates */ for (i=0; i<= Nvalence-1; i++) { Etmp = eigenvalue[i]; if (Solver_Type==Schrodinger) { paw_R_Schrodinger(n[i],l[i],Vi, &Etmp,psi[i],psi_prime[i]); } else { paw_R_Pauli(n[i],l[i],Zion,Vi, &Etmp,psi[i],psi_prime[i]); } if (fabs(eigenvalue[i] - Etmp) >1.0e-10) converged = False; eigenvalue[i]=Etmp; /*orthogonalize to lower orbitals*/ for (j=0;j<=i-1;j++) { if (l[i]==l[j]) { sum = paw_dot_product(psi[i],psi[j]); for (k=0;k<Ngrid;++k) psi[i][k] = psi[i][k] - sum*psi[j][k]; } } /*normalize the orbital*/ for (k=0; k<=Ngrid-1; k++) psi_tmp[k] = pow((psi[i][k]/rgrid[k]),2.0); sum = paw_Integrate_LogGrid(psi_tmp); for (k=0; k<=Ngrid-1; k++) psi[i][k]=psi[i][k]/pow(sum,0.5); } /*get new density*/ paw_generate_density(rho); /*get new potential*/ paw_set_kohn_sham_potential(rho); Vo = paw_get_kohn_sham_potential(); /*****************************************/ /* Generate the next iteration potential */ /* using D.G. Anderson method */ /*****************************************/ thl = 0.0; if (it > 1) { sn = 0.0; sd = 0.0; for (k=0; k<Ngrid; ++k) { rl0 = Vo[k] - Vi[k]; rl1 = Vo1[k] - Vi1[k]; dr = rl0 - rl1; sn = sn + rl0*dr*(rgrid[k]*rgrid[k]); sd = sd + dr*dr*(rgrid[k]*rgrid[k]); } thl = sn/sd; } for (k=0; k<=Ngrid-1; k++) { vn = (1.0-0.5)*( (1.0-thl)*Vi[k] + thl*Vi1[k] ) + 0.5 *( (1.0-thl)*Vo[k] + thl*Vo1[k] ); Vi1[k] = Vi[k]; Vo1[k] = Vo[k]; Vi[k] = vn; } } /* end while */ if (!converged) { printf("Not Converged\n"); exit(1); } occupied_orbitals_done = True; paw_generate_density(rho); paw_set_kohn_sham_potential(rho); /* free up temporary memory */ paw_dealloc_LogGrid(Vi); paw_dealloc_LogGrid(Vo1); paw_dealloc_LogGrid(Vi1); }