예제 #1
0
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 */
예제 #2
0
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 */
예제 #3
0
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 */
예제 #4
0
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 */
예제 #5
0
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 */
예제 #6
0
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 */
예제 #7
0
파일: dft.c 프로젝트: wadejong/NWChem-Json
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;
   }
}
예제 #8
0
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 */
예제 #9
0
파일: rpsp.c 프로젝트: toperkin/nw
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 */
예제 #10
0
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 */
예제 #11
0
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 */
예제 #12
0
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 */
예제 #13
0
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);
}
예제 #14
0
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;
}
예제 #15
0
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 */
예제 #16
0
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 */