Exemplo n.º 1
0
int get_ixyz(double lat[3][3], double cutoff)
{
    int i, j, ixyz;
    int n = 3, lda = 3, info, lwork;
    double* work;
    double wkopt, w[3], a[9], lat2[3][3];

    lwork = -1;

    for (i=0; i < 3; i++)
        for (j=0; j < 3; j++)
            lat2[i][j] = lat[i][0]*lat[j][0] + lat[i][1]*lat[j][1] + lat[i][2]*lat[j][2];

    for (i = 0; i < 3; i++)
        for (j = 0; j < 3; j++)
            a[i*3+j] = lat2[j][i];

    dsyev("V", "U", &n, a, &lda, w, &wkopt, &lwork, &info);
    lwork = (int)wkopt;
    work = (double*) malloc(lwork*sizeof(double));
    dsyev("V", "U", &n, a, &lda, w, work, &lwork, &info);
    if (info > 0 ) {
        fprintf(stderr, "Error: DSYEV ixyz");
        exit(1);
    }

    ixyz = (int)(sqrt(1.0/w[0])*cutoff + 1);

    free(work);

    return ixyz;
}
Exemplo n.º 2
0
void get_fp(int flag, int nat, int ntyp, int ixyz, int nx, int lseg, int l, double lat[3][3],
        double rxyz[][3], int types[], double rcov[], double cutoff, double **lfp, double **sfp)
{
    int iat, jat, ix, iy, iz, il, i, j;
    int n_sphere, ityp_sphere, nid, nids = l*(ntyp+1);
    int n_sphere_min = 1000000;
    int n_sphere_max = 0;
    int ind[nx*lseg];
    double xi, yi, zi, xj, yj, zj, d2;
    double cutoff2 = cutoff*cutoff;
    double rxyz_sphere[nx][3];
    double rcov_sphere[nx];
    double amp[nx];
    double fc, wc;

    double **om, *pvec;
    double omx[nids][nids], omy[nids][nids];

    int lda, info, lwork;
    double wkopt;
    double *work, *w, *a;


    wc = cutoff / sqrt(2.0 * NC);
    fc = 1.0 / (2.0 * NC * wc * wc);

    for (iat = 0; iat < nat; iat++) {
        xi = rxyz[iat][0];
        yi = rxyz[iat][1];
        zi = rxyz[iat][2];
        n_sphere = 0;
        for (jat = 0; jat < nat; jat++) {
            for (ix = -ixyz; ix <= ixyz; ix++) {
                for (iy = -ixyz; iy <= ixyz; iy++) {
                    for (iz = -ixyz; iz <= ixyz; iz++) {
                        xj = rxyz[jat][0] + ix*lat[0][0] + iy*lat[1][0] + iz*lat[2][0];
                        yj = rxyz[jat][1] + ix*lat[0][1] + iy*lat[1][1] + iz*lat[2][1];
                        zj = rxyz[jat][2] + ix*lat[0][2] + iy*lat[1][2] + iz*lat[2][2];
                        d2 = (xj-xi)*(xj-xi) + (yj-yi)*(yj-yi) + (zj-zi)*(zj-zi);
                        if (d2 <= cutoff2) {
                            n_sphere++;
                            if (n_sphere > nx) {
                                fprintf(stderr, "Error: cutoff is too large.");
                                exit(1);
                            }
                            amp[n_sphere-1] = pow((1.0 - d2*fc), NC);
                            rxyz_sphere[n_sphere-1][0] = xj;
                            rxyz_sphere[n_sphere-1][1] = yj;
                            rxyz_sphere[n_sphere-1][2] = zj;
                            rcov_sphere[n_sphere-1] = rcov[jat];
                            if (jat == iat && ix == 0 && iy == 0 && iz == 0) {
                                ityp_sphere = 0;
                            } else {
                                ityp_sphere = types[jat];
                            }

                            for (il = 0; il < lseg; il++) {
                                if (il == 0){
                                    ind[il+lseg*(n_sphere-1)] = ityp_sphere * l + 0;
                                } else {
                                    ind[il+lseg*(n_sphere-1)] = ityp_sphere * l + 1;
                                }
                            }

                        }
                    }
                }
            }
        }
        n_sphere_min = MIN(n_sphere_min, n_sphere);
        n_sphere_max = MAX(n_sphere_max, n_sphere);


        // big overlap matrix

        nid = lseg * n_sphere;

        if ( (om = (double **) malloc(sizeof(double)*nid)) == NULL) {
            fprintf(stderr, "Memory could not be allocated.");
            exit(1);
        }
        for (i = 0; i < nid; i++){
            if ( (om[i] = (double *) malloc(sizeof(double)*nid)) == NULL) {
                fprintf(stderr, "Memory could not be allocated.");
                exit(1);
            }
        }

        if ( (pvec = (double *) malloc(sizeof(double)*nid)) == NULL ){
            fprintf(stderr, "Memory could not be allocated.");
            exit(1);}


        creat_om( lseg, n_sphere, rxyz_sphere, rcov_sphere, amp, om );


        if ( (a = (double *) malloc(sizeof(double)*nid*nid)) == NULL) {
            fprintf(stderr, "Memory could not be allocated.");
            exit(1);}

        if ( (w = (double *) malloc(sizeof(double)*nid)) == NULL) {
            fprintf(stderr, "Memory could not be allocated.");
            exit(1);}

        for (i = 0; i < nid; i++)
            for (j = 0; j< nid; j++)
                a[i*nid + j] = om[j][i];



        lda = nid;
        lwork = -1;

        /// for (i = 0; i< nid*nid; i++)
        ///     printf("a[%d]= %g\n", i, a[i]);

        dsyev("V", "U", &nid, a, &lda, w, &wkopt, &lwork, &info);
        lwork = (int)wkopt;
        work = (double*) malloc(lwork*sizeof(double));
        dsyev("V", "U", &nid, a, &lda, w, work, &lwork, &info);
        if (info > 0 ) {
            fprintf(stderr, "Error: DSYEV 1");
            exit(1); }
        if (w[0] < -1E-12) {
            printf("w[0] = %g\n", w[0]);
            fprintf(stderr, "Error: Negative w");
            exit(1); }

        for (i = 0; i < nid; i++)
            pvec[i] = a[i + (nid-1)*nid];

        if (flag <= 0 ) {
            for (i = 0; i < nid; i++)
                lfp[iat][i] = w[nid-1-i];
            for (i = nid; i < nx; i++)
                lfp[iat][i] = 0.0;
        }

        free(w);
        free(a);
        free(work);


        if (flag >= 0 ){
            /* contract */
            nids = l*(ntyp+1);

            for (i = 0; i < nids; i++) {
                for (j = 0; j < nids; j++) {
                    omx[i][j] = 0.0;
                    omy[i][j] = 0.0;
                }
            }

            for (i = 0; i < nid; i++)
                for (j = 0; j < nid; j++)
                    omx[ind[i]][ind[j]] = omx[ind[i]][ind[j]] + pvec[i] * om[i][j] * pvec[j];


            if ( (a = (double *) malloc(sizeof(double)*nids*nids)) == NULL) {
                fprintf(stderr, "Memory could not be allocated.");
                exit(1);}

            if ( (w = (double *) malloc(sizeof(double)*nids)) == NULL) {
                fprintf(stderr, "Memory could not be allocated.");
                exit(1);} 

            for (i = 0; i < nids; i++){
                for (j = 0; j< nids; j++){
                    a[i*nids + j] = omx[j][i];
                }
            }

            
            lda = nids;
            lwork = -1;
            dsyev("V", "U", &nids, a, &lda, w, &wkopt, &lwork, &info);
            lwork = (int)wkopt;
            work = (double*) malloc(lwork*sizeof(double));
            dsyev("V", "U", &nids, a, &lda, w, work, &lwork, &info);
            

            for (i = 0; i < nids; i++)
                sfp[iat][i] = w[nids-1-i];

            /*
               printf("iat = %d\n", iat);
               for (i = 0; i < nids; i++)
               printf(" %e ", sfp[iat][i]);
               printf("\n");
               */

            free(a);
            free(w);
        }

        free(work);
        for (i = 0; i < n_sphere; i++)
            free(om[i]);
        free(om);
        free(pvec);


    }
    printf("min  %d, max  %d\n", n_sphere_min, n_sphere_max);
}
Exemplo n.º 3
0
void toast::lapack::syev ( char * JOBZ, char * UPLO, int * N, double * A, int * LDA, double * W, double * WORK, int * LWORK, int * INFO ) {
  dsyev ( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO );
  return;
}