Beispiel #1
0
static void power_fit(int n,int nset,real **val,real *t)
{
  real *x,*y,quality,a,b,r;
  int  s,i;

  snew(x,n);
  snew(y,n);
  
  if (t[0]>0) {
    for(i=0; i<n; i++)
      if (t[0]>0)
	x[i] = log(t[i]);
  } else {
    fprintf(stdout,"First time is not larger than 0, using index number as time for power fit\n");
    for(i=0; i<n; i++)
      x[i] = log(i+1);
  }
  
  for(s=0; s<nset; s++) {
    i=0;
    for(i=0; i<n && val[s][i]>=0; i++)
      y[i] = log(val[s][i]);
    if (i < n)
      fprintf(stdout,"Will power fit up to point %d, since it is not larger than 0\n",i);
    lsq_y_ax_b(i,x,y,&a,&b,&r,&quality);
    fprintf(stdout,"Power fit set %3d:  error %.3f  a %g  b %g\n",
	    s+1,quality,a,exp(b));
  }
  
  sfree(y); 
  sfree(x);
}
Beispiel #2
0
static void regression_analysis(int n,bool bXYdy,real *x,real **val)
{
  real S,chi2,a,b,da,db,r=0;

  printf("Fitting data to a function f(x) = ax + b\n");
  printf("Minimizing residual chi2 = Sum_i w_i [f(x_i) - y_i]2\n");
  printf("Error estimates will be given if w_i (sigma) values are given\n");
  printf("(use option -xydy).\n\n");
  if (bXYdy) 
    lsq_y_ax_b_error(n,x,val[0],val[1],&a,&b,&da,&db,&r,&S);
  else
    lsq_y_ax_b(n,x,val[0],&a,&b,&r,&S);
  chi2 = sqr((n-2)*S);
  printf("Chi2                    = %g\n",chi2);
  printf("S (Sqrt(Chi2/(n-2))     = %g\n",S);
  printf("Correlation coefficient = %.1f%%\n",100*r);
  printf("\n");
  if (bXYdy) {
    printf("a    = %g +/- %g\n",a,da);
    printf("b    = %g +/- %g\n",b,db);
  }
  else {
    printf("a    = %g\n",a);
    printf("b    = %g\n",b);
  }
}
Beispiel #3
0
static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor,
                       FILE *fmjdsp, gmx_bool bNoJump, gmx_bool bACF, gmx_bool bINT,
                       int ePBC, t_topology top, t_trxframe fr, real temp,
                       real bfit, real efit, real bvit, real evit,
                       t_trxstatus *status, int isize, int nmols, int nshift,
                       int *index0, int indexm[], real mass2[],
                       real qmol[], real eps_rf, const gmx_output_env_t *oenv)
{
    int       i, j;
    int       valloc, nalloc, nfr, nvfr;
    int       vshfr;
    real     *xshfr       = NULL;
    int      *vfr         = NULL;
    real      refr        = 0.0;
    real     *cacf        = NULL;
    real     *time        = NULL;
    real     *djc         = NULL;
    real      corint      = 0.0;
    real      prefactorav = 0.0;
    real      prefactor   = 0.0;
    real      volume;
    real      volume_av = 0.0;
    real      dk_s, dk_d, dk_f;
    real      mj    = 0.0;
    real      mj2   = 0.0;
    real      mjd   = 0.0;
    real      mjdav = 0.0;
    real      md2   = 0.0;
    real      mdav2 = 0.0;
    real      sgk;
    rvec      mja_tmp;
    rvec      mjd_tmp;
    rvec      mdvec;
    rvec     *mu    = NULL;
    rvec     *xp    = NULL;
    rvec     *v0    = NULL;
    rvec     *mjdsp = NULL;
    real     *dsp2  = NULL;
    real      t0;
    real      rtmp;

    rvec      tmp;
    rvec     *mtrans = NULL;

    /*
     * Variables for the least-squares fit for Einstein-Helfand and Green-Kubo
     */

    int          bi, ei, ie, ii;
    real         rest  = 0.0;
    real         sigma = 0.0;
    real         malt  = 0.0;
    real         err   = 0.0;
    real        *xfit;
    real        *yfit;
    gmx_rmpbc_t  gpbc = NULL;

    /*
     * indices for EH
     */

    ei = 0;
    bi = 0;

    /*
     * indices for GK
     */

    ii  = 0;
    ie  = 0;
    t0  = 0;
    sgk = 0.0;


    /* This is the main loop over frames */


    nfr = 0;


    nvfr   = 0;
    vshfr  = 0;
    nalloc = 0;
    valloc = 0;

    clear_rvec(mja_tmp);
    clear_rvec(mjd_tmp);
    clear_rvec(mdvec);
    clear_rvec(tmp);
    gpbc = gmx_rmpbc_init(&top.idef, ePBC, fr.natoms);

    do
    {

        refr = (nfr+1);

        if (nfr >= nalloc)
        {
            nalloc += 100;
            srenew(time, nalloc);
            srenew(mu, nalloc);
            srenew(mjdsp, nalloc);
            srenew(dsp2, nalloc);
            srenew(mtrans, nalloc);
            srenew(xshfr, nalloc);

            for (i = nfr; i < nalloc; i++)
            {
                clear_rvec(mjdsp[i]);
                clear_rvec(mu[i]);
                clear_rvec(mtrans[i]);
                dsp2[i]  = 0.0;
                xshfr[i] = 0.0;
            }
        }
        GMX_RELEASE_ASSERT(time != NULL, "Memory not allocated correctly - time array is NULL");

        if (nfr == 0)
        {
            t0 = fr.time;

        }

        time[nfr] = fr.time-t0;

        if (time[nfr] <= bfit)
        {
            bi = nfr;
        }
        if (time[nfr] <= efit)
        {
            ei = nfr;
        }

        if (bNoJump)
        {

            if (xp)
            {
                remove_jump(fr.box, fr.natoms, xp, fr.x);
            }
            else
            {
                snew(xp, fr.natoms);
            }

            for (i = 0; i < fr.natoms; i++)
            {
                copy_rvec(fr.x[i], xp[i]);
            }

        }

        gmx_rmpbc_trxfr(gpbc, &fr);

        calc_mj(top, ePBC, fr.box, bNoJump, nmols, indexm, fr.x, mtrans[nfr], mass2, qmol);

        for (i = 0; i < isize; i++)
        {
            j = index0[i];
            svmul(top.atoms.atom[j].q, fr.x[j], fr.x[j]);
            rvec_inc(mu[nfr], fr.x[j]);
        }

        /*if(mod(nfr,nshift)==0){*/
        if (nfr%nshift == 0)
        {
            for (j = nfr; j >= 0; j--)
            {
                rvec_sub(mtrans[nfr], mtrans[j], tmp);
                dsp2[nfr-j]  += norm2(tmp);
                xshfr[nfr-j] += 1.0;
            }
        }

        if (fr.bV)
        {
            if (nvfr >= valloc)
            {
                valloc += 100;
                srenew(vfr, valloc);
                if (bINT)
                {
                    srenew(djc, valloc);
                }
                srenew(v0, valloc);
                if (bACF)
                {
                    srenew(cacf, valloc);
                }
            }
            if (time[nfr] <= bvit)
            {
                ii = nvfr;
            }
            if (time[nfr] <= evit)
            {
                ie = nvfr;
            }
            vfr[nvfr] = nfr;
            clear_rvec(v0[nvfr]);
            if (bACF)
            {
                cacf[nvfr] = 0.0;
            }
            if (bINT)
            {
                djc[nvfr] = 0.0;
            }
            for (i = 0; i < isize; i++)
            {
                j = index0[i];
                svmul(mass2[j], fr.v[j], fr.v[j]);
                svmul(qmol[j], fr.v[j], fr.v[j]);
                rvec_inc(v0[nvfr], fr.v[j]);
            }

            fprintf(fcur, "%.3f\t%.6f\t%.6f\t%.6f\n", time[nfr], v0[nfr][XX], v0[nfr][YY], v0[nfr][ZZ]);
            if (bACF || bINT)
            {
                /*if(mod(nvfr,nshift)==0){*/
                if (nvfr%nshift == 0)
                {
                    for (j = nvfr; j >= 0; j--)
                    {
                        if (bACF)
                        {
                            cacf[nvfr-j] += iprod(v0[nvfr], v0[j]);
                        }
                        if (bINT)
                        {
                            djc[nvfr-j] += iprod(mu[vfr[j]], v0[nvfr]);
                        }
                    }
                    vshfr++;
                }
            }
            nvfr++;
        }

        volume     = det(fr.box);
        volume_av += volume;

        rvec_inc(mja_tmp, mtrans[nfr]);
        mjd += iprod(mu[nfr], mtrans[nfr]);
        rvec_inc(mdvec, mu[nfr]);

        mj2 += iprod(mtrans[nfr], mtrans[nfr]);
        md2 += iprod(mu[nfr], mu[nfr]);

        fprintf(fmj, "%.3f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\n", time[nfr], mtrans[nfr][XX], mtrans[nfr][YY], mtrans[nfr][ZZ], mj2/refr, norm(mja_tmp)/refr);
        fprintf(fmd, "%.3f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\n",    \
                time[nfr], mu[nfr][XX], mu[nfr][YY], mu[nfr][ZZ], md2/refr, norm(mdvec)/refr);

        nfr++;

    }
    while (read_next_frame(oenv, status, &fr));

    gmx_rmpbc_done(gpbc);

    volume_av /= refr;

    prefactor  = 1.0;
    prefactor /= 3.0*EPSILON0*volume_av*BOLTZ*temp;


    prefactorav  = E_CHARGE*E_CHARGE;
    prefactorav /= volume_av*BOLTZMANN*temp*NANO*6.0;

    fprintf(stderr, "Prefactor fit E-H: 1 / 6.0*V*k_B*T: %g\n", prefactorav);

    calc_mjdsp(fmjdsp, prefactorav, dsp2, time, nfr, xshfr);

    /*
     * Now we can average and calculate the correlation functions
     */


    mj2 /= refr;
    mjd /= refr;
    md2 /= refr;

    svmul(1.0/refr, mdvec, mdvec);
    svmul(1.0/refr, mja_tmp, mja_tmp);

    mdav2 = norm2(mdvec);
    mj    = norm2(mja_tmp);
    mjdav = iprod(mdvec, mja_tmp);


    printf("\n\nAverage translational dipole moment M_J [enm] after %d frames (|M|^2): %f %f %f (%f)\n", nfr, mja_tmp[XX], mja_tmp[YY], mja_tmp[ZZ], mj2);
    printf("\n\nAverage molecular dipole moment M_D [enm] after %d frames (|M|^2): %f %f %f (%f)\n", nfr, mdvec[XX], mdvec[YY], mdvec[ZZ], md2);

    if (v0 != NULL)
    {
        if (bINT)
        {

            printf("\nCalculating M_D - current correlation integral ... \n");
            corint = calc_cacf(mcor, prefactorav/EPSI0, djc, time, nvfr, vfr, ie, nshift);

        }

        if (bACF)
        {

            printf("\nCalculating current autocorrelation ... \n");
            sgk = calc_cacf(outf, prefactorav/PICO, cacf, time, nvfr, vfr, ie, nshift);

            if (ie > ii)
            {

                snew(xfit, ie-ii+1);
                snew(yfit, ie-ii+1);

                for (i = ii; i <= ie; i++)
                {

                    xfit[i-ii] = std::log(time[vfr[i]]);
                    rtmp       = std::abs(cacf[i]);
                    yfit[i-ii] = std::log(rtmp);

                }

                lsq_y_ax_b(ie-ii, xfit, yfit, &sigma, &malt, &err, &rest);

                malt = std::exp(malt);

                sigma += 1.0;

                malt *= prefactorav*2.0e12/sigma;

                sfree(xfit);
                sfree(yfit);

            }
        }
    }


    /* Calculation of the dielectric constant */

    fprintf(stderr, "\n********************************************\n");
    dk_s = calceps(prefactor, md2, mj2, mjd, eps_rf, FALSE);
    fprintf(stderr, "\nAbsolute values:\n epsilon=%f\n", dk_s);
    fprintf(stderr, " <M_D^2> , <M_J^2>, <(M_J*M_D)^2>:  (%f, %f, %f)\n\n", md2, mj2, mjd);
    fprintf(stderr, "********************************************\n");


    dk_f = calceps(prefactor, md2-mdav2, mj2-mj, mjd-mjdav, eps_rf, FALSE);
    fprintf(stderr, "\n\nFluctuations:\n epsilon=%f\n\n", dk_f);
    fprintf(stderr, "\n deltaM_D , deltaM_J, deltaM_JD:  (%f, %f, %f)\n", md2-mdav2, mj2-mj, mjd-mjdav);
    fprintf(stderr, "\n********************************************\n");
    if (bINT)
    {
        dk_d = calceps(prefactor, md2-mdav2, mj2-mj, corint, eps_rf, TRUE);
        fprintf(stderr, "\nStatic dielectric constant using integral and fluctuations: %f\n", dk_d);
        fprintf(stderr, "\n < M_JM_D > via integral:  %.3f\n", -1.0*corint);
    }

    fprintf(stderr, "\n***************************************************");
    fprintf(stderr, "\n\nAverage volume V=%f nm^3 at T=%f K\n", volume_av, temp);
    fprintf(stderr, "and corresponding refactor 1.0 / 3.0*V*k_B*T*EPSILON_0: %f \n", prefactor);



    if (bACF && (ii < nvfr))
    {
        fprintf(stderr, "Integral and integrated fit to the current acf yields at t=%f:\n", time[vfr[ii]]);
        fprintf(stderr, "sigma=%8.3f (pure integral: %.3f)\n", sgk-malt*std::pow(time[vfr[ii]], sigma), sgk);
    }

    if (ei > bi)
    {
        fprintf(stderr, "\nStart fit at %f ps (%f).\n", time[bi], bfit);
        fprintf(stderr, "End fit at %f ps (%f).\n\n", time[ei], efit);

        snew(xfit, ei-bi+1);
        snew(yfit, ei-bi+1);

        for (i = bi; i <= ei; i++)
        {
            xfit[i-bi] = time[i];
            yfit[i-bi] = dsp2[i];
        }

        lsq_y_ax_b(ei-bi, xfit, yfit, &sigma, &malt, &err, &rest);

        sigma *= 1e12;
        dk_d   = calceps(prefactor, md2, 0.5*malt/prefactorav, corint, eps_rf, TRUE);

        fprintf(stderr, "Einstein-Helfand fit to the MSD of the translational dipole moment yields:\n\n");
        fprintf(stderr, "sigma=%.4f\n", sigma);
        fprintf(stderr, "translational fraction of M^2: %.4f\n", 0.5*malt/prefactorav);
        fprintf(stderr, "Dielectric constant using EH: %.4f\n", dk_d);

        sfree(xfit);
        sfree(yfit);
    }
    else
    {
        fprintf(stderr, "Too few points for a fit.\n");
    }


    if (v0 != NULL)
    {
        sfree(v0);
    }
    if (bACF)
    {
        sfree(cacf);
    }
    if (bINT)
    {
        sfree(djc);
    }

    sfree(time);


    sfree(mjdsp);
    sfree(mu);
}
Beispiel #4
0
static void regression_analysis(int n, gmx_bool bXYdy,
                                real *x, int nset, real **val)
{
    real S, chi2, a, b, da, db, r = 0;
    int  ok;

    if (bXYdy || (nset == 1))
    {
        printf("Fitting data to a function f(x) = ax + b\n");
        printf("Minimizing residual chi2 = Sum_i w_i [f(x_i) - y_i]2\n");
        printf("Error estimates will be given if w_i (sigma) values are given\n");
        printf("(use option -xydy).\n\n");
        if (bXYdy)
        {
            if ((ok = lsq_y_ax_b_error(n, x, val[0], val[1], &a, &b, &da, &db, &r, &S)) != estatsOK)
            {
                gmx_fatal(FARGS, "Error fitting the data: %s",
                          gmx_stats_message(ok));
            }
        }
        else
        {
            if ((ok = lsq_y_ax_b(n, x, val[0], &a, &b, &r, &S)) != estatsOK)
            {
                gmx_fatal(FARGS, "Error fitting the data: %s",
                          gmx_stats_message(ok));
            }
        }
        chi2 = sqr((n-2)*S);
        printf("Chi2                    = %g\n", chi2);
        printf("S (Sqrt(Chi2/(n-2))     = %g\n", S);
        printf("Correlation coefficient = %.1f%%\n", 100*r);
        printf("\n");
        if (bXYdy)
        {
            printf("a    = %g +/- %g\n", a, da);
            printf("b    = %g +/- %g\n", b, db);
        }
        else
        {
            printf("a    = %g\n", a);
            printf("b    = %g\n", b);
        }
    }
    else
    {
        double chi2, *a, **xx, *y;
        int    i, j;

        snew(y, n);
        snew(xx, nset-1);
        for (j = 0; (j < nset-1); j++)
        {
            snew(xx[j], n);
        }
        for (i = 0; (i < n); i++)
        {
            y[i] = val[0][i];
            for (j = 1; (j < nset); j++)
            {
                xx[j-1][i] = val[j][i];
            }
        }
        snew(a, nset-1);
        chi2 = multi_regression(NULL, n, y, nset-1, xx, a);
        printf("Fitting %d data points in %d sets\n", n, nset-1);
        printf("chi2 = %g\n", chi2);
        printf("A =");
        for (i = 0; (i < nset-1); i++)
        {
            printf("  %g", a[i]);
            sfree(xx[i]);
        }
        printf("\n");
        sfree(xx);
        sfree(y);
        sfree(a);
    }
}
Beispiel #5
0
void do_corr(const char *trx_file, const char *ndx_file, const char *msd_file,
             const char *mol_file, const char *pdb_file, real t_pdb,
             int nrgrp, t_topology *top, int ePBC,
             gmx_bool bTen, gmx_bool bMW, gmx_bool bRmCOMM,
             int type, real dim_factor, int axis,
             real dt, real beginfit, real endfit, const output_env_t oenv)
{
    t_corr        *msd;
    int           *gnx;   /* the selected groups' sizes */
    atom_id      **index; /* selected groups' indices */
    char         **grpname;
    int            i, i0, i1, j, N, nat_trx;
    real          *DD, *SigmaD, a, a2, b, r, chi2;
    rvec          *x;
    matrix         box;
    int           *gnx_com     = NULL; /* the COM removal group size  */
    atom_id      **index_com   = NULL; /* the COM removal group atom indices */
    char         **grpname_com = NULL; /* the COM removal group name */

    snew(gnx, nrgrp);
    snew(index, nrgrp);
    snew(grpname, nrgrp);

    fprintf(stderr, "\nSelect a group to calculate mean squared displacement for:\n");
    get_index(&top->atoms, ndx_file, nrgrp, gnx, index, grpname);

    if (bRmCOMM)
    {
        snew(gnx_com, 1);
        snew(index_com, 1);
        snew(grpname_com, 1);

        fprintf(stderr, "\nNow select a group for center of mass removal:\n");
        get_index(&top->atoms, ndx_file, 1, gnx_com, index_com, grpname_com);
    }

    if (mol_file)
    {
        index_atom2mol(&gnx[0], index[0], &top->mols);
    }

    msd = init_corr(nrgrp, type, axis, dim_factor,
                    mol_file == NULL ? 0 : gnx[0], bTen, bMW, dt, top,
                    beginfit, endfit);

    nat_trx =
        corr_loop(msd, trx_file, top, ePBC, mol_file ? gnx[0] : 0, gnx, index,
                  (mol_file != NULL) ? calc1_mol : (bMW ? calc1_mw : calc1_norm),
                  bTen, gnx_com, index_com, dt, t_pdb,
                  pdb_file ? &x : NULL, box, oenv);

    /* Correct for the number of points */
    for (j = 0; (j < msd->ngrp); j++)
    {
        for (i = 0; (i < msd->nframes); i++)
        {
            msd->data[j][i] /= msd->ndata[j][i];
            if (bTen)
            {
                msmul(msd->datam[j][i], 1.0/msd->ndata[j][i], msd->datam[j][i]);
            }
        }
    }

    if (mol_file)
    {
        if (pdb_file && x == NULL)
        {
            fprintf(stderr, "\nNo frame found need time tpdb = %g ps\n"
                    "Can not write %s\n\n", t_pdb, pdb_file);
        }
        i             = top->atoms.nr;
        top->atoms.nr = nat_trx;
        printmol(msd, mol_file, pdb_file, index[0], top, x, ePBC, box, oenv);
        top->atoms.nr = i;
    }

    DD     = NULL;
    SigmaD = NULL;

    if (beginfit == -1)
    {
        i0       = static_cast<int>(0.1*(msd->nframes - 1) + 0.5);
        beginfit = msd->time[i0];
    }
    else
    {
        for (i0 = 0; i0 < msd->nframes && msd->time[i0] < beginfit; i0++)
        {
            ;
        }
    }

    if (endfit == -1)
    {
        i1     = static_cast<int>(0.9*(msd->nframes - 1) + 0.5) + 1;
        endfit = msd->time[i1-1];
    }
    else
    {
        for (i1 = i0; i1 < msd->nframes && msd->time[i1] <= endfit; i1++)
        {
            ;
        }
    }
    fprintf(stdout, "Fitting from %g to %g %s\n\n", beginfit, endfit,
            output_env_get_time_unit(oenv));

    N = i1-i0;
    if (N <= 2)
    {
        fprintf(stdout, "Not enough points for fitting (%d).\n"
                "Can not determine the diffusion constant.\n", N);
    }
    else
    {
        snew(DD, msd->ngrp);
        snew(SigmaD, msd->ngrp);
        for (j = 0; j < msd->ngrp; j++)
        {
            if (N >= 4)
            {
                lsq_y_ax_b(N/2, &(msd->time[i0]), &(msd->data[j][i0]), &a, &b, &r, &chi2);
                lsq_y_ax_b(N/2, &(msd->time[i0+N/2]), &(msd->data[j][i0+N/2]), &a2, &b, &r, &chi2);
                SigmaD[j] = std::abs(a-a2);
            }
            else
            {
                SigmaD[j] = 0;
            }
            lsq_y_ax_b(N, &(msd->time[i0]), &(msd->data[j][i0]), &(DD[j]), &b, &r, &chi2);
            DD[j]     *= FACTOR/msd->dim_factor;
            SigmaD[j] *= FACTOR/msd->dim_factor;
            if (DD[j] > 0.01 && DD[j] < 1e4)
            {
                fprintf(stdout, "D[%10s] %.4f (+/- %.4f) 1e-5 cm^2/s\n",
                        grpname[j], DD[j], SigmaD[j]);
            }
            else
            {
                fprintf(stdout, "D[%10s] %.4g (+/- %.4g) 1e-5 cm^2/s\n",
                        grpname[j], DD[j], SigmaD[j]);
            }
        }
    }
    /* Print mean square displacement */
    corr_print(msd, bTen, msd_file,
               "Mean Square Displacement",
               "MSD (nm\\S2\\N)",
               msd->time[msd->nframes-1], beginfit, endfit, DD, SigmaD, grpname, oenv);
}