/**************************************** 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_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]; }
/**************************************** 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_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_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 */ }