Ejemplo n.º 1
0
/****************************************
 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);

}
Ejemplo n.º 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;

        }

    }



}
Ejemplo n.º 3
0
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()));

}