/**************************************** Function name : paw_bound_state_test Description : Return type : int Argument : int n Argument : int l Argument : double *v Author : Marat Valiev Date & Time : 3/31/99 3:02:14 PM ****************************************/ int paw_bound_state_test(int l, double *v) { int i; int Ngrid; double L2,r2; double Emin; double *r; Ngrid = paw_N_LogGrid(); r = (double *) paw_r_LogGrid(); L2 = ((double) (l*(l+1))); Emin = 0; for (i=0; i<Ngrid; ++i) { r2 = r[i]; r2 = r2*r2; Emin = Min(Emin, (v[i] + 0.5*L2/r2)); } if (Emin>=0) { return 0; } else { return 1; } }
/**************************************** Function name : paw_print_loggrid_information Description : Return type : void Argument : FILE *fp Author : Marat Valiev Date & Time : 3/31/99 3:00:49 PM ****************************************/ void paw_print_loggrid_information(FILE *fp) { fprintf(fp,"\n"); fprintf(fp," Logarithmic grid information ( r(i)=r0*pow(a,i) ):\n"); fprintf(fp,"\n"); fprintf(fp," a = %le\n", paw_amesh_LogGrid()); fprintf(fp," N = %d\n", paw_N_LogGrid()); fprintf(fp," r0 = %le\n",paw_r0_LogGrid()); fprintf(fp," rmax = %le\n",paw_r_LogGrid()[paw_N_LogGrid()-1]); fprintf(fp,"\n"); }
/**************************************** Function name : paw_solve_pseudo_orbitals Description : Return type : void Author : Marat Valiev Date & Time : 5/15/00 ****************************************/ void paw_solve_pseudo_orbitals() { int i; int k; int i_end_point; int Ngrid; double scale; double *rgrid; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); for (i=0;i<= nbasis-1;i++) { i_end_point = paw_get_grid_index(1.2*r_orbital[i]); paw_solve_paw_scattering(orb_l[i], 3*r_orbital[i], e_ps[i], psi_ps[i],psi_ps_prime[i]); if (paw_debug()) printf("%d%s log derivative %le %le \n",prin_n[i],paw_spd_Name(orb_l[i]), psi_ps_prime[i][i_end_point]/(psi_ps[i][i_end_point]*rgrid[i_end_point]*paw_log_amesh_LogGrid()), phi0_prime[i][i_end_point]/(phi0[i][i_end_point]*rgrid[i_end_point]*paw_log_amesh_LogGrid())); /*rescale the orbitals*/ scale = phi_ps0[i][i_r_orbital[i]]/psi_ps[i][i_r_orbital[i]]; for (k=0;k<=i_end_point;++k) { psi_ps[i][k] = psi_ps[i][k]*scale; psi_ps_prime[i][k] = psi_ps_prime[i][k]*scale; } for (k=i_end_point+1;k<=Ngrid-1;++k) { psi_ps[i][k] = phi_ps0[i][k]; psi_ps_prime[i][k] = phi_ps0_prime[i][k]; } } }
/**************************************** Function name : paw_init_ion(double Z) Description : ****************************************/ void paw_init_ion(double Z) { int i; int Ngrid; double *rgrid; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); Zion = Z; Vion = paw_alloc_LogGrid(); for (i=0; i<Ngrid; ++i) Vion[i] = -Z/rgrid[i]; }
/**************************************** Function name : paw_get_core_density Description : Return type : void Argument : double** rho Author : Marat Valiev Date & Time : 3/31/99 3:35:46 PM ****************************************/ void paw_generate_density(double* rho) { int i; int k; int Ngrid; double* rgrid; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); paw_Zero_LogGrid(rho); for (i=0; i<=Nvalence-1; ++i) { for (k=0; k<Ngrid; ++k) rho[k] += fill[i]*pow((psi[i][k]/rgrid[k]),2.0); } }
void paw_generate_projectors_vanderbilt() { int i; int j; int k; int Ngrid; double norm; double max_prj; double max_phi; double max_phi_ps; double tmp_prj; double *V_ref; double *V; double *rgrid; double **b; double **prj_ps0; char output[300]; FILE *fp; /*make sure the pseudo orbitalas were found*/ if (! pseudo_orbitals_done) { printf("cannot calculate projectors\n"); printf("pseudo basis is not ready\n"); exit(1); } Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); b = paw_alloc_2d_array(nbasis,nbasis); prj_ps0 = paw_alloc_2d_array(nbasis,Ngrid); /*obtain the ref potential*/ V_ref = paw_get_ref_pot(); /*form initial guess for projectors as in Blochl*/ for (i = 0; i < nbasis; ++i) { V = paw_get_paw_potential(i); for (k = 0; k < Ngrid; ++k) prj_ps[i][k] = (V_ref[k] - V[k])*phi_ps[i][k]; if (paw_debug()) { sprintf(output, "%s%s_%d%d", paw_sdir(),"p",prin_n[i],orb_l[i]); fp = fopen(output, "w+"); for (k = 0; k < Ngrid; ++k) { fprintf(fp, "%le\t %le\t %le \n", rgrid[k], prj_ps[i][k],(V_ref[k] - V[k])); } fclose(fp); } } /*check for accidental null projectors*/ for (i = 0; i < nbasis; ++i) { max_prj = 0.0; for (k = 0; k < Ngrid; ++k) { tmp_prj = fabs(prj_ps[i][k]); if (tmp_prj > max_prj) max_prj = tmp_prj; } if (max_prj <0.000001) { printf("found null projectors, aborting the program ... \n"); exit(1); } } for (i=0;i<=nbasis-1;i++) { for (j=0;j<=nbasis-1;j++) { if (orb_l[i] == orb_l[j] ) { b[i][j] = paw_dot_product(phi_ps[j],prj_ps[i]); } else { b[i][j] = 0.0; } } } paw_get_inverse(b,nbasis); for (i=0;i<=nbasis-1;i++) { for (k = 0; k <= Ngrid-1; k++) prj_ps0[i][k] = prj_ps[i][k]; } for (i=0;i<=nbasis-1;i++) { paw_Zero_LogGrid(prj_ps[i]); } for (i=0;i<=nbasis-1;i++) { for (j=0;j<=nbasis-1;j++) { for (k = 0; k <= Ngrid-1; k++) prj_ps[i][k] = prj_ps[i][k] + b[i][j]*prj_ps0[j][k]; } } for (i=0;i<=nbasis-1;i++) { norm = paw_dot_product(prj_ps[i],phi_ps[i]); if (fabs(norm) < SMALL) { printf("division by zero while normalizing prj_pss"); exit(99); } if (paw_debug()) printf("prj_ps norm=%le\n",norm); for (k = 0; k < Ngrid; ++k) prj_ps[i][k] = prj_ps[i][k]/norm; } /*rescale basis*/ for (i = 0; i <= nbasis-1; i++) { max_prj = 0.0; max_phi = 0.0; max_phi_ps = 0.0; for (k = 0; k < i_r_orbital[i]; k++) { if (max_prj < fabs(prj_ps[i][k])) max_prj = fabs(prj_ps[i][k]); if (max_phi_ps < fabs(phi_ps[i][k])) max_phi_ps = fabs(phi_ps[i][k]); } if (max_prj == 0.0 || max_phi_ps == 0.0) { printf("division by zero while rescaling basis\n"); exit(99); } norm = 0.75*sqrt(max_phi_ps/max_prj); max_prj = 0.0; max_phi = 0.0; max_phi_ps = 0.0; for (k = 0; k < Ngrid; ++k) { prj_ps[i][k] = prj_ps[i][k]*norm; phi[i][k] = phi[i][k]/norm; phi_ps[i][k] = phi_ps[i][k]/norm; phi_prime[i][k] = phi_prime[i][k]/norm; phi_ps_prime[i][k] = phi_ps_prime[i][k]/norm; } } }
/**************************************** Function name : solve_pseudo_orbitals Description : Return type : void Author : Marat Valiev Date & Time : 4/7/99 2:31:16 PM ****************************************/ void paw_generate_pseudo_orbitals() { int i; int k; int Ngrid; int max_iter; int converged; int iteration; int match; int status; double log_amesh; double f1,f2; double *V; double *rgrid; double *f; double norm; char output[300]; FILE *fp; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); log_amesh = paw_log_amesh_LogGrid(); /*set maximum number of iterations*/ max_iter = 600; for (i = 0; i <= nbasis-1; i++) { iteration = 0; converged = False; status = False; match = i_r_orbital[i]; /*Start the selfconsistent loop over given ps state */ while ((iteration <= max_iter) && (!converged)) { ++iteration; /* get pseudopotential*/ V = paw_get_paw_potential(i); /* if(orb_type[i]==bound || orb_type[i]==virt) { status = paw_R_Schrodinger(prin_n_ps[i], orb_l[i], V, &e_ps[i], phi_ps[i], phi_ps_prime[i]); } else if(orb_type[i]==scattering) { status = paw_R_Schrodinger_Fixed_Logderiv(prin_n_ps[i], orb_l[i], V, match, log_deriv[i], &e_ps[i], phi_ps[i], phi_ps_prime[i]); } else { printf("unknown orbital type\n"); exit(1); } */ status = paw_R_Schrodinger_Fixed_Logderiv(prin_n_ps[i], orb_l[i], V, match, log_deriv[i], &e_ps[i], phi_ps[i], phi_ps_prime[i]); /*Update pseudopotential potential*/ paw_update_paw_potential(&converged, i, e[i], e_ps[i],phi_ps[i]); } /*report on convergence status*/ if (converged && (status)) { if (paw_debug()) printf("\n%d%d pseudo orbital with the eigenvalue=%f has been found\n", prin_n[i], orb_l[i], e_ps[i]); } else { if (paw_debug()) printf("Unable to find %d%d orbital\n ", prin_n[i], orb_l[i]); } norm = phi[i][match]/phi_ps[i][match]; /*scale ps orbital */ for (k=0;k<=match;k++) { phi_ps[i][k]=phi_ps[i][k]*norm; phi_ps_prime[i][k]=phi_ps_prime[i][k]*norm; } for (k=match+1;k<=Ngrid-1;k++) { phi_ps[i][k]=phi[i][k]; phi_ps_prime[i][k]=phi_prime[i][k]; } } if (paw_debug()) { for (i = 0; i <= nbasis-1; ++i) { sprintf(output, "%s%s%d%d", paw_sdir(),"test",prin_n[i],orb_l[i]); fp = fopen(output, "w+"); for (k = 0; k < Ngrid; k++) { fprintf(fp, "%f\t%f\t%f\n", rgrid[k], phi[i][k],phi_ps[i][k]); } fclose(fp); } } pseudo_orbitals_done = True; /* save original basis functions */ for (i=0;i<=nbasis-1;i++) { for (k = 0; k <= Ngrid-1; k++) { phi0[i][k] = phi[i][k]; phi0_prime[i][k] = phi_prime[i][k]; phi_ps0[i][k] = phi_ps[i][k]; phi_ps0_prime[i][k] = phi_ps_prime[i][k]; } } /* calculate densities */ paw_Zero_LogGrid(rho); paw_Zero_LogGrid(rho_ps); for (i = 0; i <= nbasis-1; i++) { for (k = 0; k <= Ngrid-1; k++) { rho[k] += fill[i]*pow((phi0[i][k]/rgrid[k]),2.0); rho_ps[k] += fill[i]*pow((phi_ps0[i][k]/rgrid[k]),2.0); } } /*calculate kinetic energy*/ ekin = paw_get_kinetic_energy(nbasis, orb_l, fill, phi, phi_prime); f = paw_alloc_LogGrid(); for (i = 0; i <= nbasis-1; i++) { for (k=0; k<=Ngrid-1; k++) { f[k] = 0.5*phi_prime[i][k]/(rgrid[k]*log_amesh)* phi_prime[i][k]/(rgrid[k]*log_amesh) - 0.5*phi_ps_prime[i][k]/(rgrid[k]*log_amesh)* phi_ps_prime[i][k]/(rgrid[k]*log_amesh); } f1 = paw_Def_Integr(0.0,f,0.0,Ngrid-1); for (k=0; k<=Ngrid-1; k++) { f[k] = 0.5*phi_prime[i][k]/(rgrid[k]*log_amesh)* phi_prime[i][k]/(rgrid[k]*log_amesh); } f2 = paw_Def_Integr(0.0,f,0.0,Ngrid-1); delta_ekin[i] = (int)(100*f1/f2); if (paw_debug()) printf("kinetic energy of the %d%s orbital was reduced by %d%s\n", prin_n[i],paw_spd_Name(orb_l[i]),delta_ekin[i],"%"); } paw_dealloc_LogGrid(f); }
/**************************************** Function name : paw_solve_pseudo_orbitals Description : Return type : void Author : Marat Valiev Date & Time : 5/15/00 ****************************************/ void paw_scattering_test(double e1,double e2,int number_points ,int l, double r ) { int i; int k; int i_end_point; int Ngrid; double *rgrid; FILE *fp; double *V_ks; double *psi1; double *psi1_prime; double *psi; double *psi_prime; double *log_grid_ae; double *log_grid_paw; double de; double* e3; double e_test; double log_amesh; /*char output[30];*/ char data_filename[300]; char script_filename[300]; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); log_amesh = paw_log_amesh_LogGrid(); psi1 = paw_alloc_LogGrid(); psi1_prime = paw_alloc_LogGrid(); psi = paw_alloc_LogGrid(); psi_prime = paw_alloc_LogGrid(); log_grid_ae = paw_alloc_1d_array(number_points); log_grid_paw = paw_alloc_1d_array(number_points); e3 = paw_alloc_1d_array(number_points); de = (e2-e1)/number_points; V_ks = paw_get_kohn_sham_potential(); i_end_point = paw_get_grid_index(r); for (i=0;i<= number_points-1;i++) { e_test = e1+de*i; e3[i] = e_test; paw_solve_paw_scattering(l, r, e_test, psi,psi_prime); paw_R_Schrodinger_Fixed_E( l, V_ks, i_end_point, e_test, psi1, psi1_prime ); log_grid_ae[i] = psi1_prime[i_end_point-1]/(psi1[i_end_point-1]*rgrid[i_end_point-1]*log_amesh); log_grid_paw[i] = psi_prime[i_end_point-1]/(psi[i_end_point-1]*rgrid[i_end_point-1]*log_amesh); } if (paw_debug()) { sprintf(data_filename,"%s%s_%s_scat_test.dat", paw_sdir(),paw_get_atom_name(),paw_spd_Name(l)); fp = fopen(data_filename,"w+"); for (k=0; k<=number_points-1; k++) { fprintf(fp,"%le\t%le\t%le\n", e3[k],log_grid_ae[k],log_grid_paw[k]); } fclose(fp); sprintf(script_filename,"%s%s_%s_scat_test.plt", paw_sdir(),paw_get_atom_name(),paw_spd_Name(l)); printf("script_filename: %s\n",script_filename); fp = fopen(script_filename,"w+"); fprintf(fp,"set style data lines \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set autoscale \n"); fprintf(fp,"set xr[%f:%f] \n",e1,e2); fprintf(fp,"set grid \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set xlabel \"e (Hartree)\" \n"); fprintf(fp,"set ylabel \"logarithmic derivative at r=%f\" \n",r); fprintf(fp,"set title \" %s %s channel scattering test\n",paw_get_atom_name(),paw_spd_Name(l)); fprintf(fp,"plot \"%s\" using 1:2 title \"all electron\",",data_filename); fprintf(fp,"\"\" using 1:3 title \"paw\" \n"); fprintf(fp,"\n"); fprintf(fp,"pause -1\n"); fclose(fp); } }
/**************************************** Function name : paw_print_basis_to_file Description : Return type : void Author : Marat Valiev Date & Time : 3/31/99 3:01:57 PM ****************************************/ void paw_print_basis_test_to_file(char* atom_name) { int i; int j; int k; int Ngrid; double *rgrid; char data_filename[300]; char script_filename[300]; char nl_name[20]; char title[20]; FILE *fp; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); if (paw_debug()) { sprintf(data_filename,"%s%s_test.dat",paw_sdir(),atom_name); printf("data_filename: %s\n",data_filename); fp = fopen(data_filename,"w+"); for (k=0; k<=Ngrid-1; k++) { fprintf(fp,"%le", rgrid[k]); for (i=0; i<=nbasis-1; i++) fprintf(fp,"\t%le \t%le",phi_ps0[i][k],psi_ps[i][k]); fprintf(fp,"\n"); } fclose(fp); /*gnu script file */ for (i=0,j=2; i<=nbasis-1; i++,j=j+2) { sprintf(nl_name,"%d%s",prin_n[i],paw_spd_Name(orb_l[i])); sprintf(script_filename,"%s%s_%s_test.plt",paw_sdir(),atom_name,nl_name); printf("script_filename: %s \n",script_filename); fp = fopen(script_filename,"w+"); fprintf(fp,"set style data lines \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set autoscale \n"); fprintf(fp,"set xr[0:%f] \n",1.5*r_orbital[i]); fprintf(fp,"set grid \n"); fprintf(fp,"set key \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set xlabel \"r (a0)\" \n"); fprintf(fp,"set title \" %s paw_basis test for %s\\n (e=%f Hartree)\" \n", nl_name,atom_name,e_ps[i]); sprintf(title,"%s (%f)",nl_name,e_ps[i]); fprintf(fp,"plot \"%s\" using 1:%d title \" original pseudo orbital \" , ",data_filename,j); fprintf(fp,"\"%s\" using 1:%d title \" solution of PAW Hamiltonian \" with points\n",data_filename,j+1); fprintf(fp,"\n"); fprintf(fp,"pause -1\n"); fclose(fp); } } }
/**************************************** Function name : paw_print_basis_to_file Description : Return type : void Author : Marat Valiev Date & Time : 3/31/99 3:01:57 PM ****************************************/ void paw_print_basis_to_file(char* atom_name) { int i; int j; int k; int Ngrid; double *rgrid; char data_filename[300]; char script_filename[300]; char nl_name[20]; char title[20]; FILE *fp; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); if (paw_debug()) { sprintf(data_filename,"%s%s_paw.dat",paw_sdir(),atom_name); fp = fopen(data_filename,"w+"); for (k=0; k<=Ngrid-1; k++) { fprintf(fp,"%le", rgrid[k]); for (i=0; i<=nbasis-1; i++) fprintf(fp,"\t%le \t%le \t%le ",phi[i][k],phi_ps[i][k],prj_ps[i][k]); fprintf(fp,"\n"); } fclose(fp); /* individual orbitals gnu script file */ for (i=0,j=2; i<=nbasis-1; i++,j=j+3) { sprintf(nl_name,"%d%s",prin_n[i],paw_spd_Name(orb_l[i])); sprintf(script_filename,"%s%s_%s_paw.plt",paw_sdir(),atom_name,nl_name); fp = fopen(script_filename,"w+"); fprintf(fp,"set style data lines \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set autoscale \n"); fprintf(fp,"set xr[0:%f] \n",1.5*r_orbital[i]); fprintf(fp,"set grid \n"); fprintf(fp,"set key \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set xlabel \"r (a0)\" \n"); fprintf(fp,"set title \" %s paw_basis for %s\\n (e=%f Hartree)\" \n", nl_name,atom_name,e_ps[i]); sprintf(title,"%s (%f)",nl_name,e_ps[i]); fprintf(fp,"plot \"%s\" using 1:%d title \" all-electron orbital \" , ",data_filename,j); fprintf(fp,"\"%s\" using 1:%d title \" pseudo orbital \" , ",data_filename,j+1); fprintf(fp,"\"%s\" using 1:%d title \" projector \" \n",data_filename,j+2); fprintf(fp,"\n"); fprintf(fp,"pause -1\n"); fclose(fp); } } }
/**************************************** 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); }
/**************************************** 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); }
void paw_generate_basis_file(char *outfile) { char* atom_name; FILE *fp; int i; int k; double tmp; double *Vpseudo; double *rho_core; double *rho_core_ps; int nbasis; int Ngrid; double *rgrid; int* prin_n; int* prin_n_ps; int *l; double* e; double** psi; double** psi_ps0; double** psi_prime; double** psi_ps; double** psi_ps_prime; double** prj_ps; double** prj_ps0; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); atom_name = paw_get_atom_name(); nbasis = paw_get_nbasis(); prin_n = paw_get_pointer_paw_n_array(); prin_n_ps = paw_get_pointer_paw_n_ps_array(); l = paw_get_pointer_paw_l_array(); e = paw_get_pointer_paw_e_array(); psi = paw_get_pointer_paw_psi_array(); psi_ps = paw_get_pointer_paw_psi_ps_array(); psi_prime = paw_get_pointer_paw_psi_prime_array(); psi_ps_prime = paw_get_pointer_paw_psi_ps_prime_array(); prj_ps = paw_get_pointer_paw_prj_ps_array(); prj_ps0 = paw_get_pointer_paw_prj_ps0_array(); rho_core = paw_get_pointer_core_density(); rho_core_ps = paw_get_pointer_ps_core_density(); Vpseudo = paw_get_pointer_pseudopotential(); psi_ps0 = paw_get_pointer_paw_psi_ps_unscr_array(); /* output the basis file */ /*sprintf(output, "%s_basis", atom_name);*/ if (paw_debug()) printf("paw basis file generated: %s\n",outfile); fp = fopen(outfile, "w+"); fprintf(fp,"4\n"); /*dummy tag*/ /* new*/ fprintf(fp,"%s\n",atom_name); /* new*/ fprintf(fp,"%lf\n",paw_get_Zvalence()); /* new*/ fprintf(fp,"%15.11e\n",rgrid[0]); fprintf(fp,"%15.11e\n",rgrid[Ngrid-1]); fprintf(fp,"%d\n",Ngrid); fprintf(fp,"%d\n",nbasis); /* printout cutoff radii */ /* new*/ for (i=0; i<nbasis; ++i) fprintf(fp,"%le ",paw_get_r_orbital(i)); /* new*/ fprintf(fp,"\n"); /* new*/ fprintf(fp,"%d\n",paw_get_max_i_r_orbital()); fprintf(fp,"%s\n",paw_get_comment()); /* new*/ fprintf(fp,"%15.11e\n",paw_get_core_kinetic_energy()); for ( i = 0; i < nbasis; ++i) fprintf(fp, "%d\t %15.11e\t %d\t %d\n",prin_n[i],e[i],prin_n_ps[i],l[i]); for ( i = 0; i <= nbasis-1; i++) { for (k = 0; k <= Ngrid-1; k++) fprintf(fp, "%15.11e \n",psi[i][k]); } for ( i = 0; i <= nbasis-1; i++) { for (k = 0; k <= Ngrid-1; k++) { tmp = psi_prime[i][k]/(rgrid[k]*paw_log_amesh_LogGrid()); fprintf(fp, "%15.11e \n",psi_prime[i][k]/(rgrid[k]*paw_log_amesh_LogGrid())); } } for ( i = 0; i <= nbasis-1; i++) { for (k = 0; k <= Ngrid-1; k++) fprintf(fp, "%15.11e \n",psi_ps[i][k]); } for ( i = 0; i <= nbasis-1; i++) { for (k = 0; k <= Ngrid-1; k++) { tmp = psi_ps_prime[i][k]/(rgrid[k]*paw_log_amesh_LogGrid()); fprintf(fp, "%15.11e \n",psi_ps_prime[i][k]/(rgrid[k]*paw_log_amesh_LogGrid())); } } for ( i = 0; i <= nbasis-1; i++) { for (k = 0; k <= Ngrid-1; k++) fprintf(fp, "%15.11e \n",prj_ps[i][k]); } for (k = 0; k <= Ngrid-1; k++) { fprintf(fp, "%15.11e \n",rho_core[k]/(4.0*PI)); } for (k = 0; k <= Ngrid-1; k++) { fprintf(fp, "%15.11e \n",rho_core_ps[k]/(4.0*PI)); } for (k = 0; k <= Ngrid-1; k++) { fprintf(fp, "%15.11e \n",Vpseudo[k]); } fprintf(fp,"%15.11e\n",paw_get_sigma_comp()); fprintf(fp,"%15.11e\n",paw_get_ion_charge()); for ( i = 0; i <= nbasis-1; i++) { for (k = 0; k <= Ngrid-1; k++) fprintf(fp, "%15.11e \n",prj_ps0[i][k]); } fclose(fp); }
/**************************************** Function name : paw_save_orbitals_to_file Description : Return type : void Author : Marat Valiev Date & Time : 3/31/99 3:01:57 PM ****************************************/ void paw_print_orbitals_to_file(char* atom_name) { int i; int k; int Ngrid; double *rgrid; char data_filename[300]; char script_filename[300]; char nl_name[20]; char title[20]; FILE *fp; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); if (paw_debug()) { sprintf(data_filename,"%s%s_orb.dat",paw_sdir(),atom_name); fp = fopen(data_filename,"w+"); for (k=0; k<=Ngrid-1; k++) { fprintf(fp,"%le", rgrid[k]); for (i=0; i<=Ntotal-1; i++) { fprintf(fp,"\t%le",psi[i][k]); } fprintf(fp,"\n"); } fclose(fp); /* all orbitals gnu script file */ sprintf(script_filename,"%s%s_all_orb.plt",paw_sdir(),atom_name); fp = fopen(script_filename,"w+"); fprintf(fp, "set title \" Kohn-Sham bound states for %s \" \n", atom_name); fprintf(fp,"set nolabel \n"); fprintf(fp,"set key right top box\n"); fprintf(fp,"set grid \n"); fprintf(fp,"set xlabel \"r (a0)\" \n"); fprintf(fp,"set style data lines \n"); fprintf(fp,"set autoscale \n"); fprintf(fp,"set xr[0:5] \n"); i=0; sprintf(nl_name,"%d%s",n[i],paw_spd_Name(l[i])); sprintf(title,"%s (%f)",nl_name,eigenvalue[i]); fprintf(fp,"plot \"%s\" using 1:2 title \"%s\" ",data_filename,title); for (i=1; i<=Nbound-1; i++) { sprintf(nl_name,"%d%s",n[i],paw_spd_Name(l[i])); sprintf(title,"%s (%f)",nl_name,eigenvalue[i]); fprintf(fp,",\"\" using 1:%d title \"%s\" ",i+2,title); } fprintf(fp,"\n"); fprintf(fp,"pause -1\n"); fclose(fp); /* individual orbitals gnu script file */ for (i=0; i<=Ntotal-1; i++) { sprintf(nl_name,"%d%s",n[i],paw_spd_Name(l[i])); sprintf(script_filename,"%s%s_%s_orb.plt",paw_sdir(),atom_name,nl_name); fp = fopen(script_filename,"w+"); fprintf(fp,"set style data lines \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set autoscale \n"); fprintf(fp,"set xr[0:%d] \n",n[i]+l[i]); fprintf(fp,"set xlabel \"r (a0)\" \n"); fprintf(fp,"set grid \n"); fprintf(fp,"set nokey \n"); fprintf(fp,"set title \" %s orbital for %s\\n (e=%f Hartree)\" \n", nl_name,atom_name,eigenvalue[i]); sprintf(title,"%s (%f)",nl_name,eigenvalue[i]); fprintf(fp,"plot \"%s\" using 1:%d title \"%s\" ",data_filename,i+2,title); fprintf(fp,"\n"); fprintf(fp,"pause -1\n"); fclose(fp); } } }
int paw_R_Schrodinger_Fixed_Logderiv1( int n, int l, double *v, int match, double u_logderiv, double *Eig, double *u, double *uprime ) { int i; int j; int iteration; int Ngrid; double sum; double E; double de; double Emax; double Emin; double log_amesh; double log_amesh2; double gamma; double L2; double r2; double uout; double upout; double upin; double *r; double *f_upp; double *upp; /* define eigenvalues */ E = *Eig; /* define power of the orbital near 0 */ gamma = ((double) (l+1)); /* define square of the angular momentum */ L2 = ((double) (l*(l+1))); /* define log grid parameters */ Ngrid = paw_N_LogGrid(); log_amesh = paw_log_amesh_LogGrid(); log_amesh2 = log_amesh*log_amesh; /* get pointer rgrid, and extra memory */ r = (double *) paw_r_LogGrid(); f_upp = (double *) paw_alloc_LogGrid(); upp = (double *) paw_alloc_LogGrid(); /* set up bounds for eigenvalue */ Emax = E + 10.0; Emin = E - 10.0; iteration = 0; while (iteration < Max_Iterations) { ++iteration; /* define f_upp */ for (i=0; i<Ngrid; ++i) { r2 = r[i]*r[i]; f_upp[i] = log_amesh2*(L2 + 2.0*(v[i] - E)*r2); } /* set the boundry condition near zero */ for (i=0; i<4; ++i) { u[i] = pow(r[i],gamma); uprime[i] = log_amesh*gamma*u[i]; upp[i] = log_amesh*uprime[i] + f_upp[i]*u[i]; } /* integrate from 0 to match */ for (i=3; i<match; ++i) { /* predictors */ u[i+1] = paw_Predictor_Out(i,u,uprime); uprime[i+1] = paw_Predictor_Out(i,uprime,upp); /* correctors */ for (j=0; j<Corrector_Iterations; ++j) { upp[i+1] = log_amesh*uprime[i+1] + f_upp[i+1]*u[i+1]; uprime[i+1] = paw_Corrector_Out(i,uprime,upp); u[i+1] = paw_Corrector_Out(i,u,uprime); } } uout = u[match]; upout = uprime[match]; upin = u_logderiv*uout; /* Find Integral(u^2) */ sum = paw_Norm_LogGrid(match,gamma,u); sum = 1.0/sqrt(sum); uout = sum*uout; upout = sum*upout; upin = sum*upin; for (i=0; i<=match; ++i) { u[i] = sum*u[i]; uprime[i] = sum*uprime[i]; } for (i=match+1; i<Ngrid; ++i) { u[i] = 0.0; uprime[i] = 0.0; } /* figure out new eigenvalue */ de = 0.5*uout*(upout-upin)/(log_amesh*r[match]); /* eigenvalue is converged, exit */ if (fabs(de) < (Max(fabs(E),0.2)*tolerance)) { *Eig = E; /* dealloc memory */ paw_dealloc_LogGrid(upp); paw_dealloc_LogGrid(f_upp); return True; } if (de > 0.0) Emin = E; else Emax = E; E = E + de; if ( (E > Emax) || (E < Emin)) E = 0.5*(Emin+Emax); } /* while */ printf("paw_Error R_Schrodinger_Fixed_Logderiv: More than %d iterations\n", Max_Iterations); *Eig = E; /* dealloc memory */ paw_dealloc_LogGrid(upp); paw_dealloc_LogGrid(f_upp); return False; } /* paw_R_Schrodinger_Fixed_LogDeriv */
/**************************************** Function name : paw_solve_scattering_orbitals Description : Return type : void Author : Marat Valiev Date & Time : 4/10/99 4:58:27 PM ****************************************/ void paw_solve_scattering_orbitals() { int i; int j; int k; int i_match; int Ngrid; double sum; double *V; double *rgrid; double r_sphere; double Zion; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); Zion = paw_get_ion_charge(); /*normalization sphere radius*/ r_sphere = 2.0; /*check if the occupied orbitals are done*/ if (!(occupied_orbitals_done)) { printf("cannot calculate scattering orbitals\n"); printf("calculate occupied states first\n"); } /*get Kohn-Sham potential*/ V = paw_get_kohn_sham_potential(); for (i=Nbound;i<Ntotal;i++) { /*set the end point*/ i_match = Ngrid-1; if (Solver_Type==Schrodinger) { paw_R_Schrodinger_Fixed_E(l[i],V,i_match,eigenvalue[i],psi[i],psi_prime[i]); } else { paw_R_Pauli_Fixed_E(n[i],l[i],Zion,V,i_match,eigenvalue[i],psi[i],psi_prime[i]); } 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*/ sum = paw_dot_product1(paw_get_grid_index(r_sphere),psi[i],psi[i]); sum = 1.0/sqrt(sum); for (k=0;k<Ngrid;++k) { psi[i][k] = psi[i][k]*sum; psi_prime[i][k] = psi_prime[i][k]*sum; } } /*debug printf("orthogonality\n"); for(i=0;i<=Ntotal-1;i++) { for(j=0;j<=Ntotal-1;j++) { if(l[i]==l[j]) { printf("%d\t %d\t %f\n",i,j, paw_dot_product(psi[i],psi[j])); } } } exit(1); end debug */ }
/**************************************** 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); } }
void paw_generate_projectors_blochl() { int i; int j; int k; int Ngrid; double norm; double max_prj; double max_phi; double max_phi_ps; double tmp_prj; double *V_ref; double *V; double *rgrid; double **b; double **L; double **U; double **L_inv; double **U_inv; double **test_matrix; char output[300]; FILE *fp; /*make sure the pseudo orbitalas were found*/ if (! pseudo_orbitals_done) { printf("cannot calculate projectors\n"); printf("pseudo basis is not ready\n"); exit(1); } Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); b = paw_alloc_2d_array(nbasis,nbasis); L = paw_alloc_2d_array(nbasis,nbasis); L_inv = paw_alloc_2d_array(nbasis,nbasis); U = paw_alloc_2d_array(nbasis,nbasis); U_inv = paw_alloc_2d_array(nbasis,nbasis); test_matrix = paw_alloc_2d_array(nbasis,nbasis); /*obtain the ref potential*/ V_ref = paw_get_ref_pot(); /*form initial guess for projectors as in Blochl*/ for (i = 0; i < nbasis; ++i) { V = paw_get_paw_potential(i); for (k = 0; k < Ngrid; ++k) prj_ps[i][k] = (V_ref[k] - V[k])*phi_ps[i][k]; if (paw_debug()) { sprintf(output, "%s%s_%d%d", paw_sdir(),"p",prin_n[i],orb_l[i]); fp = fopen(output, "w+"); for (k = 0; k < Ngrid; ++k) { fprintf(fp, "%le\t %le\t %le \n", rgrid[k], prj_ps[i][k],(V_ref[k] - V[k])); } fclose(fp); } } /*check for accidental null projectors*/ for (i = 0; i < nbasis; ++i) { max_prj = 0.0; for (k = 0; k < Ngrid; ++k) { tmp_prj = fabs(prj_ps[i][k]); if (tmp_prj > max_prj) max_prj = tmp_prj; } if (max_prj <0.000001) { printf("found null projectors, aborting the program ... \n"); exit(1); } } for (i=0;i<=nbasis-1;i++) { for (j=0;j<=nbasis-1;j++) { if (orb_l[i] == orb_l[j] ) { b[i][j] = paw_dot_product(phi_ps[j],prj_ps[i]); } else { b[i][j] = 0.0; } } } paw_lu_decompose(nbasis, b, L, U); paw_triang_matrix_inverse("l",nbasis,L,L_inv); paw_triang_matrix_inverse("u",nbasis,U,U_inv); for (i=0;i<=nbasis-1;i++) { for (k = 0; k <= Ngrid-1; k++) prj_ps0[i][k] = prj_ps[i][k]; } for (i=0;i<=nbasis-1;i++) { paw_Zero_LogGrid(prj_ps[i]); paw_Zero_LogGrid(phi[i]); paw_Zero_LogGrid(phi_ps[i]); paw_Zero_LogGrid(phi_prime[i]); paw_Zero_LogGrid(phi_ps_prime[i]); } for (i=0;i<=nbasis-1;i++) { for (j=0;j<=i;j++) { for (k = 0; k <= Ngrid-1; k++) { prj_ps[i][k] = prj_ps[i][k] + L_inv[i][j]*prj_ps0[j][k]; phi[i][k] = phi[i][k] + U_inv[j][i]*phi0[j][k]; phi_ps[i][k] = phi_ps[i][k] + U_inv[j][i]*phi_ps0[j][k]; phi_prime[i][k] = phi_prime[i][k] + U_inv[j][i]*phi0_prime[j][k]; phi_ps_prime[i][k] = phi_ps_prime[i][k] + U_inv[j][i]*phi_ps0_prime[j][k]; } } } for (i=0;i<=nbasis-1;i++) paw_Zero_LogGrid(prj_ps0[i]); for (i=0;i<=nbasis-1;i++) { for (j=0;j<=nbasis-1;j++) { for (k = 0; k <= Ngrid-1; k++) { prj_ps0[i][k] = prj_ps0[i][k] + U_inv[i][j]*prj_ps[j][k]; } } } /*rescale basis*/ for (i = 0; i <= nbasis-1; i++) { max_prj = 0.0; max_phi = 0.0; max_phi_ps = 0.0; for (k = 0; k < i_r_orbital[i]; k++) { if (max_prj < fabs(prj_ps[i][k])) max_prj = fabs(prj_ps[i][k]); if (max_phi_ps < fabs(phi_ps[i][k])) max_phi_ps = fabs(phi_ps[i][k]); } if (max_prj == 0.0 || max_phi_ps == 0.0) { printf("division by zero while rescaling basis\n"); exit(99); } norm = 0.75*sqrt(max_phi_ps/max_prj); max_prj = 0.0; max_phi = 0.0; max_phi_ps = 0.0; scaling_factor[i] = norm; for (k = 0; k < Ngrid; ++k) { prj_ps[i][k] = prj_ps[i][k]*norm; phi[i][k] = phi[i][k]/norm; phi_ps[i][k] = phi_ps[i][k]/norm; phi_prime[i][k] = phi_prime[i][k]/norm; phi_ps_prime[i][k] = phi_ps_prime[i][k]/norm; } } for (i = 0; i <= nbasis-1; i++) { for (j = 0; j <= nbasis-1; j++) { tr_matrix[i][j] = U_inv[i][j]; } } if (paw_debug()) printf("derivative=%f\n",phi_ps_prime[0][0]/(rgrid[0]*paw_log_amesh_LogGrid())); }
/**************************************** Function name : paw_init_paw_orbitals Description : Return type : void Argument : int a_nbasis Argument : double *a_rc_orb Argument : int *a_n Argument : int *a_n_ps Argument : int *a_l Argument : int *a_s_z Argument : double *a_e Argument : double *a_fill Author : Marat Valiev Date & Time : 4/4/99 5:11:29 PM ****************************************/ void paw_init_paw_basis( char* a_nodal_constraint, char* a_projector_method, int a_nbasis, int *a_n, int *a_l, double *r_match ) { int i; int k; int i_match; int Ngrid; int index; double *rgrid; double *psi; double *psi_prime; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); strcpy(nodal_constraint,a_nodal_constraint); strcpy(projector_method,a_projector_method); nbasis = a_nbasis; /* prin_n = a_n; */ /* orb_l = a_l; */ /* r_orbital = r_match; */ /*maximum angular momentum in the basis*/ max_orb_l = 0; for (i=0;i<=nbasis-1;i++) { if (max_orb_l < a_l[i]) max_orb_l = a_l[i]; } delta_ekin = (int *) malloc( nbasis* sizeof(int)); orb_type = (int *) malloc( nbasis* sizeof(int)); prin_n_ps = (int *) malloc( nbasis* sizeof(int)); prin_n = (int *) malloc( nbasis* sizeof(int)); orb_l = (int *) malloc( nbasis* sizeof(int)); l_counter = (int *) malloc((max_orb_l+1)*sizeof(int)); i_r_orbital = (int *) malloc( nbasis* sizeof(int)); r_orbital = (double *) malloc( nbasis* sizeof(double)); fill = (double *) malloc( nbasis* sizeof(double)); e = (double *) malloc( nbasis* sizeof(double)); e_ps = (double *) malloc( nbasis* sizeof(double)); log_deriv = (double *) malloc( nbasis* sizeof(double)); rho = paw_alloc_LogGrid(); rho_ps = paw_alloc_LogGrid(); phi = (double **) malloc(nbasis * sizeof(double *)); phi0 = (double **) malloc(nbasis * sizeof(double *)); phi_prime = (double **) malloc(nbasis * sizeof(double *)); phi_ps0 = (double **) malloc(nbasis * sizeof(double *)); phi_ps0_prime= (double **) malloc(nbasis * sizeof(double *)); phi0_prime = (double **) malloc(nbasis * sizeof(double *)); phi_ps = (double **) malloc(nbasis * sizeof(double *)); phi_ps_prime = (double **) malloc(nbasis * sizeof(double *)); prj_ps = (double **) malloc(nbasis * sizeof(double *)); prj_ps0 = (double **) malloc(nbasis * sizeof(double *)); psi_ps = (double **) malloc(nbasis * sizeof(double *)); psi_ps_prime = (double **) malloc(nbasis * sizeof(double *)); for (i = 0; i < nbasis; ++i) { prin_n[i] = a_n[i]; orb_l[i] = a_l[i]; phi0[i] = paw_alloc_LogGrid(); phi[i] = paw_alloc_LogGrid(); phi_prime[i] = paw_alloc_LogGrid(); phi_ps0[i] = paw_alloc_LogGrid(); phi_ps[i] = paw_alloc_LogGrid(); phi_ps_prime[i] = paw_alloc_LogGrid(); phi_ps0_prime[i] = paw_alloc_LogGrid(); phi0_prime[i] = paw_alloc_LogGrid(); prj_ps[i] = paw_alloc_LogGrid(); prj_ps0[i] = paw_alloc_LogGrid(); psi_ps[i] = paw_alloc_LogGrid(); psi_ps_prime[i] = paw_alloc_LogGrid(); } Zvalence = 0.0; for (i=0;i<=nbasis-1;i++) { index = paw_get_orbital_index(prin_n[i],orb_l[i]); fill[i] = paw_get_fill(index); Zvalence += fill[i]; e[i] = paw_get_e(index); e_ps[i] = e[i]; orb_type[i] = paw_get_orb_type(index); psi = paw_get_psi(index); for (k=0;k<=Ngrid-1;k++) phi[i][k] = psi[k]; psi_prime = paw_get_psi_prime(index); for (k=0;k<=Ngrid-1;k++) phi_prime[i][k] = psi_prime[k]; } /* set matching point for pseudoorbitals*/ for (i=0;i<=nbasis-1;i++) { i_r_orbital[i] = paw_get_grid_index(r_match[i]); /*r_orbital[i] = rgrid[i_r_orbital[i]]; */ r_orbital[i] = r_match[i]; } /*largest sphere in the basis*/ max_i_r_orbital = 0; for (i=0;i<=nbasis-1;i++) { if (max_i_r_orbital < i_r_orbital[i]) max_i_r_orbital = i_r_orbital[i]; } /*check if prin_n array is monotonically increasing*/ for (i=0;i<=nbasis-2;i++) { if (prin_n[i]>prin_n[i+1]) printf("please order your states according to increasing n"); } /* counter for number of orbitals per angular momentum*/ for (i=0;i<(max_orb_l+1);++i) l_counter[i] = 0; if (strcmp(nodal_constraint,"off")==0) { for (i=0;i<nbasis;++i) { prin_n_ps[i] = orb_l[i] + 1; } } else if (strcmp(nodal_constraint,"on")==0) { for (i=0;i<nbasis;++i) { prin_n_ps[i] = orb_l[i] + 1 + l_counter[orb_l[i]]; l_counter[orb_l[i]] = l_counter[orb_l[i]]+1; } } else { printf("unknown value for the nodal_constraint\n"); exit(1); } for (i = 0; i < nbasis; ++i) { i_match = i_r_orbital[i]; if (fabs(phi[i][i_match]) < SMALL) { printf("error, your orbital matching sphere is to close to the node of %d%d orbital \n", prin_n[i],orb_l[i]); exit(1); } else { log_deriv[i] = phi_prime[i][i_match]/phi[i][i_match]; } } /*set all paw orbitals to scattering ***/ for (i = 0; i < nbasis; ++i) { orb_type[i]=scattering; } scaling_factor = paw_alloc_1d_array(nbasis); tr_matrix = paw_alloc_2d_array(nbasis,nbasis); }
/**************************************** Function name : paw_init_paw_potential Description : Return type : void Argument : int a_nbasis Argument : double a_r_sphere Author : Marat Valiev Date & Time : 4/11/99 4:11:34 PM ****************************************/ void paw_init_paw_potential(int a_nbasis, double c0, double a_r_ref, double* a_r_potential, double* V_ks) { int i; int k; int Ngrid; int ic; double rc; double a,d,b; double V_prime; double *rgrid; Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); nbasis = a_nbasis; r_ref = a_r_ref; rc_ref = paw_find_rc_pot(r_ref); i_r_potential = (int *) malloc(nbasis * sizeof(int)); r_potential = (double *) malloc(nbasis * sizeof(double)); rc_pot = (double *) malloc(nbasis * sizeof(double)); c = (double *) malloc(nbasis * sizeof(double)); fcut = (double **) malloc(nbasis * sizeof(double *)); V_pseudo = paw_alloc_LogGrid(); V_ref = paw_alloc_LogGrid(); V_paw = (double **) malloc(nbasis * sizeof(double *)); for (i = 0; i <= nbasis-1; ++i) { V_paw[i] = paw_alloc_LogGrid(); fcut[i] = paw_alloc_LogGrid(); } for (i=0; i <= nbasis-1;i++) { i_r_potential[i] = paw_get_grid_index(a_r_potential[i]); /*r_potential[i] = rgrid[i_r_potential[i]];*/ r_potential[i] = a_r_potential[i]; rc_pot[i] = paw_find_rc_pot(r_potential[i]); } /* set ref potential for (k = 0; k <= Ngrid-1; ++k) V_ref[k] = V_ks[k]*(1 - exp(-pow((rgrid[k]/rc_ref),lambda)))+ c0*exp(-pow((rgrid[k]/rc_ref),lambda)); */ ic = paw_get_grid_index(a_r_ref); rc = rgrid[ic]; V_prime = 0.5*(V_ks[ic+1] - V_ks[ic-1])/(rc*paw_log_amesh_LogGrid()); a = c0; d = (0.5*V_prime*rc + a - V_ks[ic])/(rc*rc*rc*rc); b = (0.5*V_prime*rc - 2.0*d*rc*rc*rc*rc)/(rc*rc); for (k=0;k<ic;++k) V_ref[k] = a + b*rgrid[k]*rgrid[k] + d*rgrid[k]*rgrid[k]*rgrid[k]*rgrid[k]; for (k=ic;k<Ngrid;++k) V_ref[k] = V_ks[k]; /* Form cutoff function for PS potential*/ for (i = 0; i <= nbasis-1; i++) for (k = 0; k <= Ngrid-1; k++) fcut[i][k] = exp(-pow((rgrid[k]/rc_pot[i]),lambda)); /*Initialize coefficients for the construction of PS potential*/ for (i=0; i<nbasis; ++i) c[i] = V_ks[i_r_potential[i]]; /* for (i = 0; i < nbasis; ++i) c[i] = V_ks[paw_get_grid_index(r_potential[i])]; */ /* set initial paw potential*/ for (i = 0; i < nbasis; ++i) for (k = 0; k <= Ngrid-1; k++) V_paw[i][k] = V_ref[k] + c[i] * fcut[i][k]; }
int paw_R_Schrodinger(int n, int l, double* v, double *Eig, double* u, double* uprime) { int i,j, iteration, node, match, Ninf, Ngrid; double E, de, Emax, Emin, log_amesh, log_amesh2, gamma, L2, sum, a, scale, m1scale, uout,upout,upin, *r, *f_upp, *r2, *upp; /* define eigenvalues */ E = *Eig; gamma = ((double) (l+1)); L2 = ((double) (l*(l+1))); /* define log grid parameters */ Ngrid = paw_N_LogGrid(); log_amesh = paw_log_amesh_LogGrid(); log_amesh2 = log_amesh*log_amesh; /* get pointer rgrid, and extra memory */ r = paw_r_LogGrid(); r2 = paw_r2_LogGrid(); f_upp = paw_alloc_LogGrid(); upp = paw_alloc_LogGrid(); /* set up bounds for eigenvalue */ Emin = 0.0; Emax = v[Ngrid-1] + 0.5*L2/(r[Ngrid-1]*r[Ngrid-1]); for (i=0; i <= Ngrid-1; i++) Emin = Min(Emin, (v[i] + 0.5*L2/r2[i])); if (E > Emax) E = 1.25*Emax; if (E < Emin) E = 0.75*Emin; if (E > Emax) E = 0.5*(Emax+Emin); iteration = 0; while (iteration < Max_Iterations) { ++iteration; /* define f_upp */ for (i=0; i<Ngrid; ++i) f_upp[i] = log_amesh2*(L2 + 2.0*(v[i] - E)*r2[i]); /* classical turning point is used for matching */ match = Ngrid-1; while (f_upp[match-1]*f_upp[match] > 0.0) { match = match - 1; if (match < 2) { printf("Error in paw_R_Schrodinger: no turning point\n"); return False; } } /* set the boundry condition near zero */ m1scale = 1.0; for (i=0; i<(n-l-1); ++i) m1scale *= -1.0; for (i=0; i<=3; i++) { u[i] = m1scale*pow(r[i],gamma); uprime[i] = log_amesh*gamma*u[i]; upp[i] = log_amesh*uprime[i] + f_upp[i]*u[i]; } /* integrate from 0 to match */ node = 0; for (i=3; i <= match-1; i++) { /* predictors */ u[i+1] = paw_Predictor_Out(i,u,uprime); uprime[i+1] = paw_Predictor_Out(i,uprime,upp); /* correctors */ for (j=0; j<= Corrector_Iterations-1; j++) { upp[i+1] = log_amesh*uprime[i+1] + f_upp[i+1]*u[i+1]; uprime[i+1] = paw_Corrector_Out(i,uprime,upp); u[i+1] = paw_Corrector_Out(i,u,uprime); } /* finding nodes */ if (u[i+1]*u[i] <= 0) node = node + 1; } uout = u[match]; upout = uprime[match]; /* not enough nodes in u */ if ((node-n+l+1) < 0) { Emin = E; E = 0.5*(Emin+Emax); } /* too many nodes in u */ else if ((node-n+l+1) > 0) { Emax = E; E = 0.5*(Emin+Emax); } /* number of nodes ok, start integration inward */ else { /* find infinity */ /* find infinity */ Ninf = match + floor(2.3/log_amesh); if ((Ninf+5) > Ngrid) Ninf = Ngrid - 5; /* define boundry near infinity */ a = sqrt( L2/(r[Ninf]*r[Ninf]) + 2.0*(v[Ninf]-E) ); for (i=Ninf; i<=(Ninf+4); i++) { u[i] = exp(-a*(r[i]-r[Ninf])); uprime[i] = -r[i]*log_amesh*a*u[i]; upp[i] = log_amesh*uprime[i] + f_upp[i]*u[i]; } /* integrate from infinity to match */ for (i=Ninf; i>=(match+1); --i) { /* predictors */ u[i-1] = paw_Predictor_In(i,u,uprime); uprime[i-1] = paw_Predictor_In(i,uprime,upp); /* Correctors */ for (j=0; j<Corrector_Iterations; ++j) { upp[i-1] = log_amesh*uprime[i-1] + f_upp[i-1]*u[i-1]; uprime[i-1] = paw_Corrector_In(i,uprime,upp); u[i-1] = paw_Corrector_In(i,u,uprime); } } /* make the outside u, match the inside u */ scale = uout/u[match]; for (i=match; i<= Ninf; i++) { u[i] = scale*u[i]; uprime[i] = scale*uprime[i]; } upin = uprime[match]; /* Find Integral(u^2) */ sum = paw_Norm_LogGrid(Ninf,gamma,u); sum = 1.0/sqrt(sum); uout = sum*uout; upout = sum*upout; upin = sum*upin; for (i=0; i<=Ninf; i++) { u[i] = sum*u[i]; uprime[i] = sum*uprime[i]; } /* figure out new eigenvalue */ de = 0.5*uout*(upout-upin)/(log_amesh*r[match]); /* eigenvalue is converged, exit */ if (fabs(de) < (Max(fabs(E),0.2)*tolerance)) { *Eig = E; for (i=Ninf+1; i<Ngrid; ++i) { u[i] = u[Ninf]*exp(-a*(r[i]-r[Ninf])); uprime[i] = -r[i]*log_amesh*a*u[i]; } /* dealloc memory */ paw_dealloc_LogGrid(upp); paw_dealloc_LogGrid(f_upp); return True; } if (de > 0.0) Emin = E; else Emax = E; E = E + de; if (Emax<=Emin) { /* dealloc memory */ paw_dealloc_LogGrid(upp); paw_dealloc_LogGrid(f_upp); *Eig = E; return False; } if ( (E > Emax) || (E < Emin)) E = 0.5*(Emin+Emax); } /* nodes ok */ } /* while */ printf("Error paw_R_Schrodinger: More than %d iterations\n",Max_Iterations); *Eig = E; /* dealloc memory */ paw_dealloc_LogGrid(upp); paw_dealloc_LogGrid(f_upp); return False; } /* paw_R_Schrodinger */
void paw_print_paw_potential_to_file(char* atom_name) { int i; int j; int k; int Ngrid; int *prin_n; int * orb_l; double *rgrid; char data_filename[300]; char script_filename[300]; char nl_name[20]; FILE *fp; if (paw_debug()) { Ngrid = paw_N_LogGrid(); rgrid = paw_r_LogGrid(); prin_n = paw_get_pointer_paw_n_array(); orb_l = paw_get_pointer_paw_l_array(); sprintf(data_filename,"%s%s_pot.dat",paw_sdir(),atom_name); fp = fopen(data_filename,"w+"); for (k=0; k<=Ngrid-1; k++) { fprintf(fp,"%le\t%le\t%le", rgrid[k], V_ref[k], V_pseudo[k]); for (i=0; i<=nbasis-1; i++) fprintf(fp,"\t%le ",V_paw[i][k]); fprintf(fp,"\n"); } fclose(fp); sprintf(script_filename,"%s%s_ref_pot.plt",paw_sdir(),atom_name); fp = fopen(script_filename,"w+"); fprintf(fp,"set data style lines \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set autoscale \n"); fprintf(fp,"set xr[0:%f] \n",2*r_ref); fprintf(fp,"set grid \n"); fprintf(fp,"set nokey \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set xlabel \"r (a0)\" \n"); fprintf(fp,"set title \" %s reference potential\n",atom_name); fprintf(fp,"plot \"%s\" using 1:2 \n",data_filename); fprintf(fp,"\n"); fprintf(fp,"pause -1\n"); fclose(fp); sprintf(script_filename,"%s%s_loc_pot.plt",paw_sdir(),atom_name); fp = fopen(script_filename,"w+"); fprintf(fp,"set data style lines \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set autoscale \n"); fprintf(fp,"set xr[0:%f] \n",2*r_ref); fprintf(fp,"set grid \n"); fprintf(fp,"set nokey \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set xlabel \"r (a0)\" \n"); fprintf(fp,"set title \" %s local potential\n",atom_name); fprintf(fp,"plot \"%s\" using 1:3 \n",data_filename); fprintf(fp,"\n"); fprintf(fp,"pause -1\n"); fclose(fp); /*gnu script file */ for (i=0,j=4; i<=nbasis-1; i++,j=j+1) { sprintf(nl_name,"%d%s",prin_n[i],paw_spd_Name(orb_l[i])); sprintf(script_filename,"%s%s_%s_pot.plt",paw_sdir(),atom_name,nl_name); fp = fopen(script_filename,"w+"); fprintf(fp,"set data style lines \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set autoscale \n"); fprintf(fp,"set xr[0:%f] \n",1.5*r_potential[i]); fprintf(fp,"set grid \n"); fprintf(fp,"set nokey \n"); fprintf(fp,"set nolabel \n"); fprintf(fp,"set xlabel \"r (a0)\" \n"); fprintf(fp,"set title \" %s paw potential for %s orbital\" \n", atom_name,nl_name); fprintf(fp,"plot \"%s\" using 1:%d \n",data_filename,j); fprintf(fp,"\n"); fprintf(fp,"pause -1\n"); fclose(fp); } } }
void paw_R_Schrodinger_Fixed_E1( int l, double *v, double *f, int match, double E, double *u, double *uprime ) { int i,j, Ngrid; double log_amesh, log_amesh2, gamma, L2, r2, *r, *f_upp, *upp; double max_u; /*set maximum allowed value for u*/ max_u = 10000000; /* define power of the orbital near 0 */ gamma = ((double) (l+1)); /* define square of the angular momentum */ L2 = ((double) (l*(l+1))); /* define log grid parameters */ Ngrid = paw_N_LogGrid(); log_amesh = paw_log_amesh_LogGrid(); log_amesh2 = log_amesh*log_amesh; if (match > Ngrid-1) { printf("match point is outside the allowed region\n"); printf("abborting the program\n"); exit(1); } /* get pointer rgrid, and extra memory */ r = (double *) paw_r_LogGrid(); f_upp = (double *) paw_alloc_LogGrid(); upp = (double *) paw_alloc_LogGrid(); for (i=0; i<=match; i++) { u[i] = 0.0; uprime[i] = 0.0; } /* define f_upp */ for (i=0; i<match+1; ++i) { r2 = r[i]*r[i]; f_upp[i] = log_amesh2*(L2 + 2.0*(v[i] - E)*r2); } for (i=0; i<4; ++i) { u[i] = pow(r[i],gamma); uprime[i] = log_amesh*gamma*u[i]; upp[i] = log_amesh*uprime[i] + f_upp[i]*u[i]; } /* integrate from 0 to match */ i=3; while (i<match && fabs(u[i])<max_u) { /* predictors */ u[i+1] = paw_Predictor_Out(i,u,uprime); uprime[i+1] = paw_Predictor_Out(i,uprime,upp); /* correctors */ for (j=0; j<Corrector_Iterations; ++j) { upp[i+1] = log_amesh*uprime[i+1] + f_upp[i+1]*u[i+1]- 2.0*log_amesh2*r[i+1]*r[i+1]*f[i+1]; uprime[i+1] = paw_Corrector_Out(i,uprime,upp); u[i+1] = paw_Corrector_Out(i,u,uprime); } i = i+1; } /* dealloc memory */ paw_dealloc_LogGrid(upp); paw_dealloc_LogGrid(f_upp); return; } /* paw_R_Schrodinger */