void dp_xpansion(double dp[]) { int i; double r1,r2,r3,r5,r7,r9,r11; double *r; r = r_LogGrid(); /* generate (d/dr)p(r) */ for (i=0; i<=match; ++i) { r1 = r[i]; r2 = r1*r1; r3 = r1*r2; r5 = r3*r2; r7 = r5*r2; r9 = r7*r2; r11 = r9*r2; dp[i] = 2.0 *c[1]*r1 + 4.0 *c[2]*r3 + 6.0 *c[3]*r5 + 8.0 *c[4]*r7 + 10.0*c[5]*r9 + 12.0*c[6]*r11; } } /* dp_xpansion */
void ddp_xpansion(double ddp[]) { int i; double r1,r2,r4,r6,r8,r10; double *r; r = r_LogGrid(); /* generate (d/dr)(d/dr) p(r) */ for (i=0; i<=match; ++i) { r1 = r[i]; r2 = r1*r1; r4 = r2*r2; r6 = r4*r2; r8 = r6*r2; r10 = r8*r2; ddp[i] = 2.0 *c[1] + 12.0 *c[2]*r2 + 30.0 *c[3]*r4 + 56.0 *c[4]*r6 + 90.0 *c[5]*r8 + 132.0*c[6]*r10; } } /* ddp_xpansion */
void p_xpansion(double p[]) { int i; double r1,r2,r4,r6,r8,r10,r12; double *r; r = r_LogGrid(); /* generate p(r) */ for (i=0; i<=match; ++i) { r1 = r[i]; r2 = r1*r1; r4 = r2*r2; r6 = r4*r2; r8 = r6*r2; r10 = r8*r2; r12 = r10*r2; p[i] = c[0] + c[1]*r2 + c[2]*r4 + c[3]*r6 + c[4]*r8 + c[5]*r10 + c[6]*r12; } } /* p_xpansion */
void psp_xpansion() { int i,Ngrid; double *r,*dp,*ddp; Ngrid = N_LogGrid(); r = r_LogGrid(); dp = alloc_LogGrid(); ddp = alloc_LogGrid(); dp_xpansion(dp); ddp_xpansion(ddp); for (i=0; i<=match; ++i) { Vl[i] = el + dp[i]*(l+1.0)/r[i] + 0.5*ddp[i] + 0.5*dp[i]*dp[i]; } for (i=(match+1); i<Ngrid; ++i) Vl[i] = Vall[i]; dealloc_LogGrid(dp); dealloc_LogGrid(ddp); } /* psp_xpansion */
void dpsi_xpansion() { int i,Ngrid; double al; double *r,*p,*dp; Ngrid = N_LogGrid(); r = r_LogGrid(); al = log_amesh_LogGrid(); p = alloc_LogGrid(); dp = alloc_LogGrid(); p_xpansion(p); dp_xpansion(dp); /* wl_prime = (d/di)wl */ for (i=0; i<=match; ++i) wl_prime[i] = (al*r[i])*( (l+1.0) + r[i]*dp[i] )*pow(r[i],l)*exp(p[i]); for (i=(match+1); i<Ngrid; ++i) wl_prime[i] = ul_prime[i]; dealloc_LogGrid(p); dealloc_LogGrid(dp); } /* dpsi_xpansion */
void chi_xpansion2() { int i,Ngrid; double *r,*dp,*ddp; Ngrid = N_LogGrid(); r = r_LogGrid(); dp = alloc_LogGrid(); ddp = alloc_LogGrid(); dp_xpansion2(dp); ddp_xpansion2(ddp); for (i=0; i<=match; ++i) { Vl[i] = el + dp[i]*(l+1.0)/r[i] + 0.5*ddp[i] + 0.5*dp[i]*dp[i]; } for (i=(match+1); i<Ngrid; ++i) Vl[i] = Vall[i]; /* make it a projector rather than a potential */ for (i=0; i<Ngrid; ++i) Vl[i] = Vl[i]*wl[i]; dealloc_LogGrid(dp); dealloc_LogGrid(ddp); } /* chi_xpansion2 */
void R_Screening_Cut(double * Vx) { int k,NN,n0,n1=0; double r0,r1=0.0,v0,v1=0.0,m,b; double *r; if (screening_cut>0.0) { r = r_LogGrid(); NN = index_r_LogGrid(screening_cut) + 5; for (k=0; k<NN; ++k) if (r[k] < screening_cut) { n0=n1; r0=r1; v0=v1; n1=k; r1=r[k]; v1=Vx[k]; } m = (v1-v0)/(r1-r0); b = v1 - m*r1; for (k=0; k<n1; ++k) Vx[k] = m*r[k] + b; } }
void psi_xpansion() { int i,Ngrid; double *r,*p; Ngrid = N_LogGrid(); r = r_LogGrid(); p = alloc_LogGrid(); p_xpansion(p); for (i=0; i<=match; ++i) wl[i] = pow(r[i],l+1.0)*exp(p[i]); for (i=(match+1); i<Ngrid; ++i) wl[i] = ul[i]; dealloc_LogGrid(p); } /* psi_xpansion */
void solve_RelPsp () { int p, k, Ngrid; double *rgrid; /* get loggrid variables */ Ngrid = N_LogGrid (); rgrid = r_LogGrid (); if (Solver_Type==Troullier) { solve_RelTroullier(Nvalence, n, l, spin, eigenvalue, fill, rcut, r_psi, r_psi_prime, rho, rho_semicore, V_psp, &Total_E, &E_Hartree, &P_Hartree, &E_exchange, &P_exchange, &E_correlation, &P_correlation); }else{ solve_RelHamann(Nvalence, n, l, spin, eigenvalue, fill, rcut, r_psi, r_psi_prime, rho, rho_semicore, V_psp, &Total_E, &E_Hartree, &P_Hartree, &E_exchange, &P_exchange, &E_correlation, &P_correlation); } /******************************************************/ /* find the outermost peak of the pseudowavefunctions */ /******************************************************/ for (p = 0; p < Nvalence; ++p) { if (fill[p] != 0.0) { k = Ngrid - 2; while ((r_psi_prime[p][k] * r_psi_prime[p][k + 1] >= 0.0) && (k >= 0)) --k; peak[p] = rgrid[k]; } else peak[p] = rgrid[Ngrid - 1]; } } /* solve_RelPsp */
void ddddp_xpansion2(double ddddp[]) { int i; double r1,r2,r4,r6,r8; double *r; r = r_LogGrid(); /* generate (d/dr)**4 p(r) */ for (i=0; i<=match; ++i) { r1 = r[i]; r2 = r1*r1; r4 = r2*r2; r6 = r4*r2; r8 = r6*r2; ddddp[i] = 24.0 *c[2] + 360.0 *c[3]*r2 + 1680.0 *c[4]*r4 + 5040.0 *c[5]*r6; } } /* ddddp_xpansion2 */
void dddp_xpansion2(double dddp[]) { int i; double r1,r2,r3,r5,r7,r9; double *r; r = r_LogGrid(); /* generate (d/dr)**3 p(r) */ for (i=0; i<=match; ++i) { r1 = r[i]; r2 = r1*r1; r3 = r1*r2; r5 = r3*r2; r7 = r5*r2; r9 = r7*r2; dddp[i] = 24.0 *c[2]*r1 + 120.0 *c[3]*r3 + 336.0 *c[4]*r5 + 720.0 *c[5]*r7; } } /* dddp_xpansion2 */
void solve_RelTroullier (int num_psp, int *n_psp, int *l_psp, int *s_psp, double *e_psp, double *fill_psp, double *rcut_psp, double **r_psi_psp, double **r_psi_prime_psp, double *rho_psp, double *rho_semicore, double **V_psp, double *eall_psp, double *eh_psp, double *ph_psp, double *ex_psp, double *px_psp, double *ec_psp, double *pc_psp) { int istate, i, l, k, p, s2, match, mch, Ngrid; double al, amesh, rmax, Zion; double gamma, gpr, nu0; double ldpsi_match; double el, eeig=0.0; double ph, px, pc, eh, ex, ec; double *ul, *ul_prime; double *wl, *wl_prime; double *r, *Vh, *Vx, *Vc, *rho_total, *Vall, *Vl; /* Allocate Grids */ Vall = Vall_Atom (); r = r_LogGrid (); Ngrid = N_LogGrid (); al = log_amesh_LogGrid (); amesh = amesh_LogGrid (); Zion = 0.0; for (k = 0; k < Ngrid; ++k) rho_psp[k] = 0.0; if (debug_print ()) { printf ("\n\nRelTroullier pseudopotential check\n\n"); printf ("l\trcore rmatch E in E psp norm test slope test\n"); } for (p = 0; p < (num_psp); ++p) { l = l_psp[p]; s2 = s_psp[p]; wl = r_psi_psp[p]; wl_prime = r_psi_prime_psp[p]; Vl = V_psp[p]; /*******************************************/ /* Solve for scattering state if necessary */ /*******************************************/ if (fill_psp[p] < 1.e-15) { rmax = 10.0; solve_Scattering_State_Atom (n_psp[p], l_psp[p], e_psp[p], rmax); /* scattering state saved at the end of the atom list */ istate = Nvalence_Atom () + Ncore_Atom (); if (s2 < 0) istate += 1; mch = (int) rint (log (rmax / r[0]) / al); ul = r_psi_Atom (istate); ul_prime = r_psi_prime_Atom (istate); nu0 = Norm_LogGrid (mch, (l + 1.0), ul); nu0 = 1.0 / sqrt (nu0); for (i = 0; i < Ngrid; ++i) { ul[i] = ul[i] * nu0; ul_prime[i] = ul_prime[i] * nu0; } } /*******************************************/ /* find state of all-electron wavefunction */ /*******************************************/ else istate = state_RelAtom (n_psp[p], l_psp[p], s_psp[p]); /*************************************/ /* get the all-electron wavefunction */ /*************************************/ ul = r_psi_Atom (istate); ul_prime = r_psi_prime_Atom (istate); el = e_psp[p]; /*****************************/ /* find matching point stuff */ /*****************************/ match = (int) rint (log (rcut_psp[p] / r[0]) / al); ldpsi_match = ul_prime[match] / ul[match]; /* make sure that wavefunctions are non-negative at the matching point */ if (ul[match] < 0.0) { nu0 = -1.0; for (i = 0; i < Ngrid; ++i) { ul[i] = ul[i] * nu0; ul_prime[i] = ul_prime[i] * nu0; } } /**************************************/ /* generate troullier pseudopotential */ /**************************************/ init_xpansion (l, match, fill_psp[p], el, Vall, ul, ul_prime, Vl, wl, wl_prime); psi_xpansion (); dpsi_xpansion (); psp_xpansion (); /******************/ /* verify psp Vl */ /******************/ /*******************/ /* psp bound state */ /*******************/ if (fill_psp[p] > 1.e-14) { R_Schrodinger (l_psp[p] + 1, l_psp[p], Vl, &mch, &el, wl, wl_prime); } /* scattering state */ else { R_Schrodinger_Fixed_Logderiv (l_psp[p] + 1, l_psp[p], Vl, match, ldpsi_match, &el, wl, wl_prime); R_Schrodinger_Fixed_E (l_psp[p] + 1, l_psp[p], Vl, Ngrid - 1, el, wl, wl_prime); /* normalize the scattering state to mch = 10.0 a.u. */ rmax = 10.0; mch = rint (log (rmax / r[0]) / al); nu0 = Norm_LogGrid (mch, (l + 1.0), wl); nu0 = 1.0 / sqrt (nu0); for (i = 0; i < Ngrid; ++i) { wl[i] = wl[i] * nu0; wl_prime[i] = wl_prime[i] * nu0; } } gamma = fabs (ul[match] / wl[match]); gpr = fabs (ul_prime[match] / wl_prime[match]); if (debug_print ()) { /*printf("ul[match] wl[match]: %lf %lf\n",ul[match],wl[match]); */ printf ("%d\t%lf %lf %lf %lf %lf %lf\n", l_psp[p], rcut_psp[p], r[match], e_psp[p], el, gamma, gpr); } /* Use the analytic form of pseudopotential */ el = e_psp[p]; psi_xpansion (); dpsi_xpansion (); psp_xpansion (); if (fill_psp[p] > 1.e-14) { eeig += fill_psp[p] * el; /* accumulate charges */ Zion += fill_psp[p]; for (k = 0; k < Ngrid; ++k) rho_psp[k] += fill_psp[p] * pow (wl[k] / r[k], 2.0); } } /* for p */ /***************************************/ /* get the hartree potential an energy */ /* get the exchange potential and energy */ /* get the correlation potential and energy */ /***************************************/ Vh = alloc_LogGrid (); Vx = alloc_LogGrid (); Vc = alloc_LogGrid (); ph = R_Hartree_DFT (rho_psp, Zion, Vh); eh = 0.5 * ph; rho_total = alloc_LogGrid (); for (k = 0; k < Ngrid; ++k) rho_total[k] = rho_psp[k] + rho_semicore[k]; R_Exchange_DFT (rho_total, Vx, &ex, &px); R_Correlation_DFT (rho_total, Vc, &ec, &pc); /* recalculate px and pc */ for (k = 0; k < Ngrid; ++k) rho_total[k] = (rho_psp[k]) * Vx[k]; px = Integrate_LogGrid (rho_total); for (k = 0; k < Ngrid; ++k) rho_total[k] = (rho_psp[k]) * Vc[k]; pc = Integrate_LogGrid (rho_total); *eall_psp = eeig + eh + ex + ec - ph - px - pc; *eh_psp = eh; *ph_psp = ph; *ex_psp = ex; *px_psp = px; *ec_psp = ec; *pc_psp = pc; for (p = 0; p < num_psp; ++p) for (k = 0; k < Ngrid; ++k) V_psp[p][k] = V_psp[p][k] - Vh[k] - Vx[k] - Vc[k]; /* deallocate memory */ dealloc_LogGrid (Vh); dealloc_LogGrid (Vx); dealloc_LogGrid (Vc); dealloc_LogGrid (rho_total); } /* solve_Troullier */
void init_Atom (char *filename) { int i, Ngrid, nx, lx, ncvh; double *rgrid, fillx; char *w; FILE *fp; /* set the solver type first */ fp = fopen (filename, "r+"); w = get_word (fp); while ((w != NIL) && (strcmp ("<solver>", w) != 0)) w = get_word (fp); if (w != NIL) { w = get_word (fp); if (strcmp ("schrodinger", w) == 0) Solver_Type = Schrodinger; if (strcmp ("pauli", w) == 0) Solver_Type = Pauli; if (strcmp ("dirac", w) == 0) Solver_Type = Dirac; if (strcmp ("zora", w) == 0) Solver_Type = ZORA; } fclose (fp); /* open data file */ fp = fopen (filename, "r+"); /* move to <atom> section of data file */ w = get_word (fp); while ((w != NIL) && (strcmp ("<atom>", w) != 0)) w = get_word (fp); /* Error occured */ if (w == NIL) { printf ("Error: <atom> section not found\n"); fclose (fp); exit (99); } /* set the name of the atom */ fscanf (fp, "%s", atom_name); /* read in atom info. from the stream */ fscanf (fp, "%le", &Zion); fscanf (fp, "%le", &amass); fscanf (fp, "%d %d", &Ncore, &Nvalence); if (Solver_Type != Dirac && Solver_Type!=ZORA) { Ncv = Ncore + Nvalence; /* allocate the necessary memory for eigenvalues */ n = (int *) malloc ((Ncv + 1) * sizeof (int)); l = (int *) malloc ((Ncv + 1) * sizeof (int)); s2 = (int *) malloc ((Ncv + 1) * sizeof (int)); fill = (double *) malloc ((Ncv + 1) * sizeof (double)); /* allocate memory for outer peak and turning_point positions */ turning_point = (int *) malloc ((Ncv + 1) * sizeof (int)); peak = (double *) malloc ((Ncv + 1) * sizeof (double)); /* set eigenvalue arrays */ lmax = 0; for (i = 0; i < Ncv; ++i) { fscanf (fp, "%d %d %le", &n[i], &l[i], &fill[i]); if (l[i] > lmax) lmax = l[i]; } /* set up logarithmic grid */ init_LogGrid (Zion); Ngrid = N_LogGrid (); rgrid = r_LogGrid (); /* allocate the necessary memory */ eigenvalue = (double *) malloc ((Ncv + 1) * sizeof (double)); r_psi = (double **) malloc ((Ncv + 1) * sizeof (double *)); r_psi_prime = (double **) malloc ((Ncv + 1) * sizeof (double *)); for (i = 0; i < (Ncv + 1); ++i) { r_psi[i] = alloc_LogGrid (); r_psi_prime[i] = alloc_LogGrid (); } } else { Ncore = 2 * Ncore; Nvalence = 2 * Nvalence; Ncv = Ncore + Nvalence; /* allocate the necessary memory for eigenvalues */ n = (int *) malloc ((Ncv + 2) * sizeof (int)); l = (int *) malloc ((Ncv + 2) * sizeof (int)); s2 = (int *) malloc ((Ncv + 2) * sizeof (int)); fill = (double *) malloc ((Ncv + 2) * sizeof (double)); /* allocate memory for outer peak and turning_point positions */ turning_point = (int *) malloc ((Ncv + 2) * sizeof (int)); peak = (double *) malloc ((Ncv + 2) * sizeof (double)); /* set eigenvalue arrays */ lmax = 0; ncvh = Ncv / 2; for (i = 0; i < ncvh; ++i) { fscanf (fp, "%d %d %le", &nx, &lx, &fillx); lmax=(lmax>lx)?lmax:lx; n[2 * i] = nx; n[2 * i + 1] = nx; l[2 * i] = lx; l[2 * i + 1] = lx; s2[2 * i] = -1; s2[2 * i + 1] = 1; /**************************************************************** * fill in the j=l+0.5 and j=l-0.5 states with the proper * occupancy. A simple divide will give the wrong occupancies. ****************************************************************/ if (!lx) { fill[2 * i] = fillx * 0.5; fill[2 * i + 1] = fillx * 0.5; } else { fill[2 * i] = (2.0 * lx) * (fillx * 0.5 / (2. * lx + 1.)); fill[2 * i + 1] = (2.0 * lx+ 2.0) * (fillx * 0.5 / (2. * lx + 1.)); } } /* set up logarithmic grid */ init_LogGrid (Zion); Ngrid = N_LogGrid (); rgrid = r_LogGrid (); /* allocate the necessary memory */ eigenvalue = (double *) malloc ((Ncv + 2) * sizeof (double)); r_psi = (double **) malloc ((Ncv + 2) * sizeof (double *)); r_psi_prime = (double **) malloc ((Ncv + 2) * sizeof (double *)); for (i = 0; i < (Ncv + 2); ++i) { r_psi[i] = alloc_LogGrid (); r_psi_prime[i] = alloc_LogGrid (); } } rho = alloc_LogGrid (); rho_core = alloc_LogGrid (); rho_valence = alloc_LogGrid (); Vion = alloc_LogGrid (); Vall = alloc_LogGrid (); /* set Vion */ for (i = 0; i < Ngrid; ++i) Vion[i] = -Zion / rgrid[i]; fclose (fp); /* initialize DFT stuff */ init_DFT (filename); }
void FATR rpspsolve_ #if defined(USE_FCD) (Integer * print_ptr, Integer * debug_ptr, Integer * lmax_ptr, Integer * locp_ptr, double *rlocal_ptr, const _fcd fcd_sdir_name, Integer * n9, const _fcd fcd_dir_name, Integer * n0, const _fcd fcd_in_filename, Integer * n1, const _fcd fcd_out_filename, Integer * n2) { char *sdir_name = _fcdtocp (fcd_sdir_name); char *dir_name = _fcdtocp (fcd_dir_name); char *in_filename = _fcdtocp (fcd_in_filename); char *out_filename = _fcdtocp (fcd_out_filename); #else (print_ptr, debug_ptr, lmax_ptr, locp_ptr, rlocal_ptr, sdir_name, n9, dir_name, n0, in_filename, n1, out_filename, n2) Integer *print_ptr; Integer *debug_ptr; Integer *lmax_ptr; Integer *locp_ptr; double *rlocal_ptr; char sdir_name[]; Integer *n9; char dir_name[]; Integer *n0; char in_filename[]; Integer *n1; char out_filename[]; Integer *n2; { #endif int i, j, k, l, p, Nlinear, Nvalence; int debug, print; double *rl, *rhol, **psil, **pspl; double over_fourpi, c, x, y; int Ngrid; double *vall, *rgrid; char name[255]; int lmax_out, locp_out, nvh; double rlocal_out, vx; FILE *fp; int m9 = ((int) (*n9)); int m0 = ((int) (*n0)); int m1 = ((int) (*n1)); int m2 = ((int) (*n2)); char *infile = (char *) malloc (m9 + m1 + 5); char *outfile = (char *) malloc (m0 + m2 + 5); char *soutfile = (char *) malloc (m0 + m2 + 9); char *full_filename = (char *) malloc (m9 + 25 + 5); print = *print_ptr; debug = *debug_ptr; lmax_out = *lmax_ptr; locp_out = *locp_ptr; rlocal_out = *rlocal_ptr; (void) strncpy (infile, sdir_name, m9); infile[m9] = '\0'; strcat (infile, "/"); infile[m9 + 1] = '\0'; strncat (infile, in_filename, m1); infile[m9 + m1 + 1] = '\0'; (void) strncpy (outfile, dir_name, m0); outfile[m0] = '\0'; strcat (outfile, "/"); outfile[m0 + 1] = '\0'; strncat (outfile, out_filename, m2); outfile[m0 + m2 + 1] = '\0'; over_fourpi = 0.25/M_PI; /******************** * we have already solved for the Relativsitic AE wavefunctions using atom * in the call to pspsolve *******************/ set_debug_print (debug); init_RelPsp (infile); solve_RelPsp (); if (debug) print_RelPsp (stdout); init_Linear (infile); /* allocate linear meshes */ Nvalence = Nvalence_RelPsp (); Nlinear = nrl_Linear (); psil = (double **) malloc (Nvalence * sizeof (double *)); pspl = (double **) malloc (Nvalence * sizeof (double *)); for (p = 0; p < Nvalence; ++p) { psil[p] = (double *) malloc (Nlinear * sizeof (double)); pspl[p] = (double *) malloc (Nlinear * sizeof (double)); } rl = (double *) malloc (Nlinear * sizeof (double)); rhol = (double *) malloc (Nlinear * sizeof (double)); /* Norm-conserving output */ for (p = 0; p < Nvalence; ++p) { Log_to_Linear (r_psi_RelPsp (p), rl, psil[p]); Log_to_Linear_zero (V_RelPsp (p), rl, pspl[p]); /* normalize scattering state */ if (fill_RelPsp (p) == 0.0) { normalize_Linear (psil[p]); } } Log_to_Linear (rho_RelPsp (), rl, rhol); if (debug) { /* output pseudowavefunctions argv[1].psw */ strcpy (name, name_Atom ()); strcat (name, ".psw.plt"); full_filename[0] = '\0'; strncpy (full_filename, sdir_name, m9); full_filename[m9] = '\0'; strcat (full_filename, "/"); full_filename[m9 + 1] = '\0'; strcat (full_filename, name); printf ("Outputing pseudowavefunctions: %s\n", full_filename); fp = fopen (full_filename, "w+"); for (k = 0; k < Nlinear; ++k) { fprintf (fp, "%12.8lf", rl[k]); for (p = 0; p < Nvalence; ++p) fprintf (fp, " %12.8lf", psil[p][k]); fprintf (fp, "\n"); } fclose (fp); /* output pseudopotentials argv[1].psp.plt */ strcpy (name, name_Atom ()); strcat (name, ".psp.plt"); full_filename[0] = '\0'; strncpy (full_filename, sdir_name, m9); full_filename[m9] = '\0'; strcat (full_filename, "/"); full_filename[m9 + 1] = '\0'; strcat (full_filename, name); printf ("Outputing pseudopotentials: %s\n", full_filename); fp = fopen (full_filename, "w+"); for (k = 0; k < Nlinear; ++k) { fprintf (fp, "%12.8lf", rl[k]); for (p = 0; p < Nvalence; ++p) fprintf (fp, " %12.8lf", pspl[p][k]); fprintf (fp, "\n"); } fclose (fp); /* output pseudodensity infile.psd.plt */ strcpy (name, name_Atom ()); strcat (name, ".psd.plt"); full_filename[0] = '\0'; strncpy (full_filename, sdir_name, m9); full_filename[m9] = '\0'; strcat (full_filename, "/"); full_filename[m9 + 1] = '\0'; strcat (full_filename, name); fp = fopen (full_filename, "w+"); for (k = 0; k < Nlinear; ++k) fprintf (fp, "%12.8lf %12.8lf\n", rl[k], rhol[k]); fclose (fp); } /* output datafile to be used for Kleinman-Bylander input, argv[1].psp */ if (print) { printf (" Creating datafile for Kleinman-Bylander input: %s\n", outfile); } fp = fopen (outfile, "w+"); fprintf (fp, "7 %s\n", name_Atom ()); fprintf (fp, "%lf %lf %d %d %d %lf\n", Zion_RelPsp (), Amass_Atom (), lmax_RelPsp (), lmax_out, locp_out, rlocal_out); for (p = 0; p <= lmax_RelPsp (); ++p) fprintf (fp, "%lf ", rcut_RelPsp (p)); fprintf (fp, "\n"); fprintf (fp, "%d %lf\n", nrl_Linear (), drl_Linear ()); fprintf (fp, "%s\n", comment_RelPsp ()); if (print) { printf (" + Appending pseudopotentials: %s thru %s\n", spd_Name (0), spd_Name (lmax_RelPsp ())); } nvh=Nvalence/2; for (k = 0; k < Nlinear; ++k) { fprintf (fp, "%12.8lf", rl[k]); for (p = 0; p < nvh; ++p) { /************************************************************** * Here we output the v average * v_avg(l,r)=((l*v(l-1/2) + (l+1)*v(l+1/2))/(2*l+1) *************************************************************/ vx = ((p) * pspl[2 * p][k] + (p+1) * pspl[2 * p + 1][k])/(p+p+1); fprintf (fp, " %12.8lf", vx); } fprintf (fp, "\n"); } if (print) { printf (" + Appending pseudowavefunctions: %s thru %s\n", spd_Name (0), spd_Name (lmax_RelPsp ())); } for (k = 0; k < Nlinear; ++k) { fprintf (fp, "%12.8lf ", rl[k]); for (p = 0; p < Nvalence; ++p) fprintf (fp, " %12.8lf", psil[p][k]); fprintf (fp, "\n"); } /* output spin-orbit datafile to be used for Kleinman-Bylander input, argv[1].dat */ if (print) { printf (" Creating spin-orbit datafile for Kleinman-Bylander input: %s\n", outfile); } if (print) { printf (" + Appending Spin-Orbit pseudopotentials: %s thru %s\n", spd_Name (0), spd_Name (lmax_RelPsp ())); } for (k = 0; k < Nlinear; ++k) { fprintf (fp, "%12.8lf", rl[k]); /************************************************************** * Here we output the v spin orbit * v_spin_orbit(l,r)=2*(v(l+1/2) - v(l-1/2))/(2*l+1) * * so that V_spin_orbit|Psi>= -1/2(1+kappa)*v_spin_orbit|Psi> * its confusing because L*S -> - (1+kappa)/2 *************************************************************/ for (p = 1; p < nvh;++p) { vx = (pspl[2*p+1][k] - pspl[2*p][k]); vx *= 2. / (2. * p + 1.); fprintf (fp, " %15.8lf", vx); } fprintf (fp, "\n"); } /* append semicore corrections */ if (r_semicore_RelPsp () != 0.0) { if (print) { printf (" + Appending semicore density\n"); } Log_to_Linear (rho_semicore_RelPsp (), rl, rhol); fprintf (fp, "%lf\n", r_semicore_RelPsp ()); for (k = 0; k < Nlinear; ++k) fprintf (fp, "%12.8lf %12.8lf\n", rl[k], fabs (rhol[k] * over_fourpi)); if (print) { printf (" + Appending semicore density gradient\n"); } Log_to_Linear (drho_semicore_RelPsp (), rl, rhol); for (k = 0; k < Nlinear; ++k) fprintf (fp, "%12.8lf %12.8lf\n", rl[k], (rhol[k] * over_fourpi)); } fclose (fp); /******************************************************************/ /******************* output AE information ************************/ /******************************************************************/ if (debug) { /* output all-electron wavefunctions */ printf ("Outputing all-electron wavefunctions:"); Ngrid = N_LogGrid (); rgrid = r_LogGrid (); for (p = 0; p < (Ncore_Atom () + Nvalence_Atom ()); ++p) { sprintf (name, "%s.%1d%s%s", name_Atom (), n_Atom (p), spd_Name (l_Atom (p)), spin_Name (p)); full_filename[0] = '\0'; strncpy (full_filename, sdir_name, m9); full_filename[m9] = '\0'; strcat (full_filename, "/"); full_filename[m9 + 1] = '\0'; strcat (full_filename, name); printf (" %s", full_filename); fp = fopen (full_filename, "w+"); for (k = 0; k < Ngrid; ++k) fprintf (fp, "%12.8lf %12.8lf\n", rgrid[k], r_psi_Atom (p)[k]); fclose (fp); } printf ("\n"); /* output density argv[1].dns */ Ngrid = N_LogGrid (); rgrid = r_LogGrid (); strcpy (name, name_Atom ()); strcat (name, ".dns.plt"); full_filename[0] = '\0'; strncpy (full_filename, sdir_name, m9); full_filename[m9] = '\0'; strcat (full_filename, "/"); full_filename[m9 + 1] = '\0'; strcat (full_filename, name); printf ("Outputing atom density: %s\n", full_filename); fp = fopen (full_filename, "w+"); for (k = 0; k < Ngrid; ++k) fprintf (fp, "%12.8lf %12.8lf\n", rgrid[k], rho_Atom ()[k]); fclose (fp); /* output core density argv[1].cdns */ Ngrid = N_LogGrid (); rgrid = r_LogGrid (); strcpy (name, name_Atom ()); strcat (name, ".cdns.plt"); full_filename[0] = '\0'; strncpy (full_filename, sdir_name, m9); full_filename[m9] = '\0'; strcat (full_filename, "/"); full_filename[m9 + 1] = '\0'; strcat (full_filename, name); printf ("Outputing core density: %s\n", full_filename); fp = fopen (full_filename, "w+"); for (k = 0; k < Ngrid; ++k) fprintf (fp, "%12.8lf %12.8lf\n", rgrid[k], rho_core_Atom ()[k]); fclose (fp); /* output core density gradient argv[1].cddns */ vall = alloc_LogGrid (); Derivative_LogGrid (rho_core_Atom (), vall); Ngrid = N_LogGrid (); rgrid = r_LogGrid (); strcpy (name, name_Atom ()); strcat (name, ".cddns.plt"); full_filename[0] = '\0'; strncpy (full_filename, sdir_name, m9); full_filename[m9] = '\0'; strcat (full_filename, "/"); full_filename[m9 + 1] = '\0'; strcat (full_filename, name); printf ("Outputing core density gradient: %s\n", full_filename); fp = fopen (full_filename, "w+"); for (k = 0; k < Ngrid; ++k) fprintf (fp, "%12.8lf %12.8lf\n", rgrid[k], vall[k]); fclose (fp); dealloc_LogGrid (vall); /* output semicore density infile.sdns */ Ngrid = N_LogGrid (); rgrid = r_LogGrid (); strcpy (name, name_Atom ()); strcat (name, ".sdns.plt"); full_filename[0] = '\0'; strncpy (full_filename, sdir_name, m9); full_filename[m9] = '\0'; strcat (full_filename, "/"); full_filename[m9 + 1] = '\0'; strcat (full_filename, name); printf ("Outputing semicore density: %s\n", full_filename); fp = fopen (full_filename, "w+"); for (k = 0; k < Ngrid; ++k) fprintf (fp, "%12.8lf %12.8lf\n", rgrid[k], rho_semicore_RelPsp ()[k]); fclose (fp); /* output semicore density gradient infile.sddns */ Ngrid = N_LogGrid (); rgrid = r_LogGrid (); strcpy (name, name_Atom ()); strcat (name, ".sddns.plt"); full_filename[0] = '\0'; strncpy (full_filename, sdir_name, m9); full_filename[m9] = '\0'; strcat (full_filename, "/"); full_filename[m9 + 1] = '\0'; strcat (full_filename, name); printf ("Outputing semicore density gradient: %s\n", full_filename); fp = fopen (full_filename, "w+"); for (k = 0; k < Ngrid; ++k) { vx=drho_semicore_RelPsp()[k]; fprintf (fp, "%12.8lf %12.8lf\n", rgrid[k], vx); } fclose (fp); /* output all-electron potential infile.pot */ vall = Vall_Atom (); Ngrid = N_LogGrid (); rgrid = r_LogGrid (); strcpy (name, name_Atom ()); strcat (name, ".pot.plt"); full_filename[0] = '\0'; strncpy (full_filename, sdir_name, m9); full_filename[m9] = '\0'; strcat (full_filename, "/"); full_filename[m9 + 1] = '\0'; strcat (full_filename, name); printf ("Outputing all-electron potential(non-screened): %s\n", full_filename); fp = fopen (full_filename, "w+"); c = 0.0; for (k = 0; k < Ngrid; ++k) { x = rgrid[k] / rcut_RelPsp (0); x = pow (x, 3.5); x = exp (-x); y = 1.0 - x; fprintf (fp, "%12.8lf %12.8lf %12.8lf\n", rgrid[k], vall[k], y * vall[k] + c * x); } fclose (fp); } /* free malloc memory */ free (infile); free (outfile); free (full_filename); for (p = 0; p < Nvalence; ++p) { free (psil[p]); free (pspl[p]); } free (psil); free (pspl); free (rl); free (rhol); end_Linear (); fflush (stdout); return; }
void init_xpansion(int l_in, int match_in, double occupation_in, double el_in, double *Vall_in, double *ul_in, double *ul_prime_in, double *Vl_in, double *wl_in, double *wl_prime_in) { int i,iteration; double gamma,gamma_mid,dgamma; double constraint1,constraint2,constraint_mid; double gamma1,gamma2; double Vall_match, dVall_match,ddVall_match; double al; double *r; r = r_LogGrid(); al = log_amesh_LogGrid(); l = l_in; match = match_in; occupation = occupation_in; el = el_in; Vall = Vall_in; ul = ul_in; ul_prime = ul_prime_in; Vl = Vl_in; wl = wl_in; wl_prime = wl_prime_in; /* fix ul_prime = (d/dr)ul, rather then (d/di)ul */ ldpsi = ul_prime[match]/(al*r[match]*ul[match]); Vall_match = Vall[match]; dVall_match = (1.0/(al*r[match]))*Derivative7_4(match,Vall); ddVall_match = (-1.0/(r[match]*r[match]*al)) *Derivative7_4(match,Vall) + (+1.0/(r[match]*r[match]*al*al))*Laplacian7_4(match,Vall); rc[0] = 1.0; rc[1] = r[match]; for (i=2; i<13; ++i) rc[i] = rc[1]*rc[i-1]; /******************************************/ /* Calculate the all-electron core charge */ /******************************************/ ae_core_charge = Norm_LogGrid(match,(l+1.0),ul); /**************************************************************/ /* define p(rcl), p'(rcl), p''(rcl), p'''(rcl) and p''''(rcl) */ /**************************************************************/ poly[0] = log(ul[match]/pow(rc[1],(l+1.0))); poly[1] = ldpsi - (l+1.0)/rc[1]; poly[2] = 2.0*Vall_match - 2.0*el - (2.0*(l+1.0)/rc[1])*poly[1] - poly[1]*poly[1]; poly[3] = 2.0*dVall_match + (2.0*(l+1.0)/rc[2])*poly[1] - (2.0*(l+1.0)/rc[1])*poly[2] - 2.0*poly[1]*poly[2]; poly[4] = 2.0*ddVall_match - (4.0*(l+1.0)/rc[3])*poly[1] + (4.0*(l+1.0)/rc[2])*poly[2] - (2.0*(l+1.0)/rc[1])*poly[3] - 2.0*poly[2]*poly[2] - 2.0*poly[1]*poly[3]; /* get initial guess for gamma */ get_c0_c10(); /* Bracket gamma, so that constraint==0 can be found */ gamma1 = c[1]; gamma2 = -c[1]; constraint1 = get_c0_c12(gamma1); constraint2 = get_c0_c12(gamma2); iteration = 0; while ((constraint1*constraint2 > 0.0) && (iteration <=50)) { ++iteration; if (fabs(constraint1) < fabs(constraint2)) { gamma1 = gamma1 + 1.6*(gamma1-gamma2); constraint1 = get_c0_c12(gamma1); } else { gamma2 = gamma2 + 1.6*(gamma2-gamma1); constraint2 = get_c0_c12(gamma2); } } /* perform bisection of gamma1 and gamma2 until constraint==0 */ constraint1 = get_c0_c12(gamma1); constraint2 = get_c0_c12(gamma2); if (constraint1 < 0.0) { gamma = gamma1; dgamma = (gamma2-gamma1); } else { gamma = gamma2; dgamma = (gamma1-gamma2); } iteration = 0; constraint_mid = 1.0; while ((fabs(dgamma) > SMALL) && (constraint_mid != 0.0) && (iteration<=80)) { ++iteration; dgamma = 0.5*dgamma; gamma_mid = gamma+dgamma; constraint_mid = get_c0_c12(gamma_mid); if (constraint_mid < 0.0) gamma = gamma_mid; } } /*init_xpansion */
int init_xpansion2(int l_in, int match_in, double el_in, double *Vall_in, double *ul_in, double *ul_prime_in, double *Vl_in, double *wl_in, double *wl_prime_in) { int i; double Vall_match, dVall_match,ddVall_match; double al; double *r; r = r_LogGrid(); al = log_amesh_LogGrid(); l = l_in; match = match_in; el = el_in; Vall = Vall_in; ul = ul_in; ul_prime = ul_prime_in; Vl = Vl_in; wl = wl_in; wl_prime = wl_prime_in; /* fix ul_prime = (d/dr)ul, rather then (d/di)ul */ ldpsi = ul_prime[match]/(al*r[match]*ul[match]); Vall_match = Vall[match]; dVall_match = (1.0/(al*r[match]))*Derivative7_4(match,Vall); ddVall_match = (-1.0/(r[match]*r[match]*al)) *Derivative7_4(match,Vall) + (+1.0/(r[match]*r[match]*al*al))*Laplacian7_4(match,Vall); rc[0] = 1.0; rc[1] = r[match]; for (i=2; i<13; ++i) rc[i] = rc[1]*rc[i-1]; /**************************************************************/ /* define p(rcl), p'(rcl), p''(rcl), p'''(rcl) and p''''(rcl) */ /**************************************************************/ poly[0] = log(ul[match]/pow(rc[1],(l+1.0))); poly[1] = ldpsi - (l+1.0)/rc[1]; poly[2] = 2.0*Vall_match - 2.0*el - (2.0*(l+1.0)/rc[1])*poly[1] - poly[1]*poly[1]; poly[3] = 2.0*dVall_match + (2.0*(l+1.0)/rc[2])*poly[1] - (2.0*(l+1.0)/rc[1])*poly[2] - 2.0*poly[1]*poly[2]; poly[4] = 2.0*ddVall_match - (4.0*(l+1.0)/rc[3])*poly[1] + (4.0*(l+1.0)/rc[2])*poly[2] - (2.0*(l+1.0)/rc[1])*poly[3] - 2.0*poly[2]*poly[2] - 2.0*poly[1]*poly[3]; /* generate trouulier-Martin expansion, if possible */ return get_c0_c10_xpansion2(); } /*init_xpansion2 */