/**************************************** 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); }
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; } } }
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())); }