Пример #1
0
/*double btaunu_(double *deltam)
*/
double btaunu_(void)
{
	double rtau,mBu,mHp,xHp;
	struct read_param_tag param;
	double eps_b=0, eps_bp=0, eps_tps=0;
	
	if(read_prm(&param))
	{
		puts("btaunu: can not read parameters.");
		return 0.0;
	}
	
/*	dump_prm(&param);
*/
       
         mHp=param.Mhc;
	 mBu=5.279;
	 xHp=mBu*mBu/mHp/mHp;
	     

/*Large tan beta */
/* Calculates the eps_b eps_b' ..*/	
	calc_eps(&param, &eps_b, &eps_bp, &eps_tps);
		
         rtau=(1-xHp*param.tb*param.tb/(1+eps_b*param.tb))*(1-xHp*param.tb*param.tb/(1+eps_b*param.tb));
      	
	return rtau;
}
static void do_dip(t_topology *top,int ePBC,real volume,
                   const char *fn,
                   const char *out_mtot,const char *out_eps,
                   const char *out_aver, const char *dipdist,
                   const char *cosaver, const char *fndip3d,
                   const char *fnadip,  gmx_bool bPairs,
                   const char *corrtype,const char *corf,
                   gmx_bool bGkr,     const char *gkrfn,
                   gmx_bool bPhi,     int  *nlevels,  int ndegrees,
                   int  ncos,
                   const char *cmap,    real rcmax,
                   gmx_bool bQuad,    const char *quadfn,
                   gmx_bool bMU,      const char *mufn,
                   int  *gnx,     int  *molindex[],
                   real mu_max,   real mu_aver,
                   real epsilonRF,real temp,
                   int  *gkatom,  int skip,
                   gmx_bool bSlab,    int nslices,
                   const char *axtitle, const char *slabfn,
                   const output_env_t oenv)
{
    const char *leg_mtot[] = { 
        "M\\sx \\N", 
        "M\\sy \\N",
        "M\\sz \\N",
        "|M\\stot \\N|"
    };
#define NLEGMTOT asize(leg_mtot)
    const char *leg_eps[] = { 
        "epsilon",
        "G\\sk",
        "g\\sk"
    };
#define NLEGEPS asize(leg_eps)
    const char *leg_aver[] = { 
        "< |M|\\S2\\N >", 
        "< |M| >\\S2\\N",
        "< |M|\\S2\\N > - < |M| >\\S2\\N",
        "< |M| >\\S2\\N / < |M|\\S2\\N >"
    };
#define NLEGAVER asize(leg_aver)
    const char *leg_cosaver[] = {
        "\\f{4}<|cos\\f{12}q\\f{4}\\sij\\N|>",
        "RMSD cos",
        "\\f{4}<|cos\\f{12}q\\f{4}\\siX\\N|>",
        "\\f{4}<|cos\\f{12}q\\f{4}\\siY\\N|>",
        "\\f{4}<|cos\\f{12}q\\f{4}\\siZ\\N|>"
    };
#define NLEGCOSAVER asize(leg_cosaver)
    const char *leg_adip[] = {
        "<mu>",
        "Std. Dev.",
        "Error"
    };
#define NLEGADIP asize(leg_adip)

    FILE       *outdd,*outmtot,*outaver,*outeps,*caver=NULL;
    FILE       *dip3d=NULL,*adip=NULL;
    rvec       *x,*dipole=NULL,mu_t,quad,*dipsp=NULL;
    t_gkrbin   *gkrbin = NULL;
    gmx_enxnm_t *enm=NULL;
    t_enxframe *fr;
    int        nframes=1000,nre,timecheck=0,ncolour=0;
    ener_file_t fmu=NULL;
    int        i,j,k,n,m,natom=0,nmol,gnx_tot,teller,tel3;
    t_trxstatus *status;
    int        *dipole_bin,ndipbin,ibin,iVol,step,idim=-1;
    unsigned long mode;
    char       buf[STRLEN];
    real       rcut=0,t,t0,t1,dt,lambda,dd,rms_cos;
    rvec       dipaxis;
    matrix     box;
    gmx_bool   bCorr,bTotal,bCont;
    double     M_diff=0,epsilon,invtel,vol_aver;
    double     mu_ave,mu_mol,M2_ave=0,M_ave2=0,M_av[DIM],M_av2[DIM];
    double     M[3],M2[3],M4[3],Gk=0,g_k=0;
    gmx_stats_t Mx,My,Mz,Msq,Vol,*Qlsq,mulsq,muframelsq=NULL;
    ivec       iMu;
    real       **muall=NULL;
    rvec       *slab_dipoles=NULL;
    t_atom     *atom=NULL;
    t_block    *mols=NULL;
    gmx_rmpbc_t gpbc=NULL;

    gnx_tot = gnx[0];
    if (ncos > 1) {
        gnx_tot += gnx[1];
    }

    vol_aver = 0.0;
      
    iVol=-1;
    if (bMU) 
    {
        fmu = open_enx(mufn,"r");
        do_enxnms(fmu,&nre,&enm);

        /* Determine the indexes of the energy grps we need */
        for (i=0; (i<nre); i++) {
            if (strstr(enm[i].name,"Volume"))
                iVol=i;
            else if (strstr(enm[i].name,"Mu-X"))
                iMu[XX]=i;
            else if (strstr(enm[i].name,"Mu-Y"))
                iMu[YY]=i;
            else if (strstr(enm[i].name,"Mu-Z"))
                iMu[ZZ]=i;
        }
    }
    else 
    {
        atom = top->atoms.atom;
        mols = &(top->mols);
    }
  
    if ((iVol == -1) && bMU)
        printf("Using Volume from topology: %g nm^3\n",volume);

    /* Correlation stuff */ 
    bCorr  = (corrtype[0] != 'n');
    bTotal = (corrtype[0] == 't');
    if (bCorr) 
    {
        if (bTotal) 
        {
            snew(muall,1);
            snew(muall[0],nframes*DIM);
        }
        else 
        {
            snew(muall,gnx[0]);
            for(i=0; (i<gnx[0]); i++)
                snew(muall[i],nframes*DIM);
        }
    }

    /* Allocate array which contains for every molecule in a frame the
     * dipole moment.
     */
    if (!bMU)
        snew(dipole,gnx_tot);

    /* Statistics */
    snew(Qlsq,DIM);
    for(i=0; (i<DIM); i++) 
        Qlsq[i] = gmx_stats_init();
    mulsq = gmx_stats_init();
  
    /* Open all the files */
    outmtot = xvgropen(out_mtot,
                       "Total dipole moment of the simulation box vs. time",
                       "Time (ps)","Total Dipole Moment (Debye)",oenv);
    outeps  = xvgropen(out_eps,"Epsilon and Kirkwood factors",
                       "Time (ps)","",oenv);
    outaver = xvgropen(out_aver,"Total dipole moment",
                       "Time (ps)","D",oenv);
    if (bSlab) 
    {
        idim = axtitle[0] - 'X';
        if ((idim < 0) || (idim >= DIM))
            idim = axtitle[0] - 'x';
        if ((idim < 0) || (idim >= DIM))
            bSlab = FALSE;
        if (nslices < 2)
            bSlab = FALSE;
        fprintf(stderr,"axtitle = %s, nslices = %d, idim = %d\n",
                axtitle,nslices,idim);
        if (bSlab) 
        {
            snew(slab_dipoles,nslices);
            fprintf(stderr,"Doing slab analysis\n");
        }
    }
  
    if (fnadip) 
    {
        adip = xvgropen(fnadip, "Average molecular dipole","Dipole (D)","",oenv);
        xvgr_legend(adip,NLEGADIP,leg_adip, oenv);
  
    }
    if (cosaver) 
    {
        caver = xvgropen(cosaver,bPairs ? "Average pair orientation" :
                         "Average absolute dipole orientation","Time (ps)","",oenv);
        xvgr_legend(caver,NLEGCOSAVER,bPairs ? leg_cosaver : &(leg_cosaver[1]),
                    oenv);
    }
    
    if (fndip3d) 
    {
        snew(dipsp,gnx_tot);
  
        /* we need a dummy file for gnuplot */
        dip3d = (FILE *)ffopen("dummy.dat","w");
        fprintf(dip3d,"%f %f %f", 0.0,0.0,0.0);
        ffclose(dip3d);

        dip3d = (FILE *)ffopen(fndip3d,"w");
        fprintf(dip3d,"# This file was created by %s\n",Program());
        fprintf(dip3d,"# which is part of G R O M A C S:\n");
        fprintf(dip3d,"#\n");
    }
  
    /* Write legends to all the files */
    xvgr_legend(outmtot,NLEGMTOT,leg_mtot,oenv);
    xvgr_legend(outaver,NLEGAVER,leg_aver,oenv);
  
    if (bMU && (mu_aver == -1))
        xvgr_legend(outeps,NLEGEPS-2,leg_eps,oenv);
    else
        xvgr_legend(outeps,NLEGEPS,leg_eps,oenv);
    
    snew(fr,1);
    clear_rvec(mu_t);
    teller = 0;
    /* Read the first frame from energy or traj file */
    if (bMU)
        do 
        {
            bCont = read_mu_from_enx(fmu,iVol,iMu,mu_t,&volume,&t,nre,fr);
            if (bCont) 
            {  
                timecheck=check_times(t);
                if (timecheck < 0)
                    teller++;
                if ((teller % 10) == 0)
                    fprintf(stderr,"\r Skipping Frame %6d, time: %8.3f", teller, t);
            }
            else 
            {
                printf("End of %s reached\n",mufn);
                break;
            }
        } while (bCont && (timecheck < 0));
    else
        natom  = read_first_x(oenv,&status,fn,&t,&x,box);
  
    /* Calculate spacing for dipole bin (simple histogram) */
    ndipbin = 1+(mu_max/0.01);
    snew(dipole_bin, ndipbin);
    epsilon    = 0.0;
    mu_ave     = 0.0;
    for(m=0; (m<DIM); m++) 
    {
        M[m] = M2[m] = M4[m] = 0.0;
    }
  
    if (bGkr) 
    {
        /* Use 0.7 iso 0.5 to account for pressure scaling */
        /*  rcut   = 0.7*sqrt(max_cutoff2(box)); */
        rcut   = 0.7*sqrt(sqr(box[XX][XX])+sqr(box[YY][YY])+sqr(box[ZZ][ZZ]));

        gkrbin = mk_gkrbin(rcut,rcmax,bPhi,ndegrees); 
    }
    gpbc = gmx_rmpbc_init(&top->idef,ePBC,natom,box);

    /* Start while loop over frames */
    t1 = t0 = t;
    teller = 0;
    do 
    {
        if (bCorr && (teller >= nframes)) 
        {
            nframes += 1000;
            if (bTotal) 
            {
                srenew(muall[0],nframes*DIM);
            }
            else 
            {
                for(i=0; (i<gnx_tot); i++)
                    srenew(muall[i],nframes*DIM);
            }
        }
        t1 = t;

        muframelsq = gmx_stats_init();
    
        /* Initialise */
        for(m=0; (m<DIM); m++) 
            M_av2[m] = 0;
            
        if (bMU) 
        {
            /* Copy rvec into double precision local variable */
            for(m=0; (m<DIM); m++)
                M_av[m]  = mu_t[m];
        }
        else 
        {
            /* Initialise */
            for(m=0; (m<DIM); m++) 
                M_av[m] = 0;
                
            gmx_rmpbc(gpbc,natom,box,x);
      
            /* Begin loop of all molecules in frame */
            for(n=0; (n<ncos); n++) 
            {
                for(i=0; (i<gnx[n]); i++) 
                {
                    int gi,ind0,ind1;
	  
                    ind0  = mols->index[molindex[n][i]];
                    ind1  = mols->index[molindex[n][i]+1];
	  
                    mol_dip(ind0,ind1,x,atom,dipole[i]);
                    gmx_stats_add_point(mulsq,0,norm(dipole[i]),0,0);
                    gmx_stats_add_point(muframelsq,0,norm(dipole[i]),0,0);
                    if (bSlab) 
                        update_slab_dipoles(ind0,ind1,x,
                                            dipole[i],idim,nslices,slab_dipoles,box);
                    if (bQuad) 
                    {
                        mol_quad(ind0,ind1,x,atom,quad);
                        for(m=0; (m<DIM); m++)
                            gmx_stats_add_point(Qlsq[m],0,quad[m],0,0);
                    }
                    if (bCorr && !bTotal) 
                    {
                        tel3=DIM*teller;
                        muall[i][tel3+XX] = dipole[i][XX];
                        muall[i][tel3+YY] = dipole[i][YY];
                        muall[i][tel3+ZZ] = dipole[i][ZZ];
                    }
                    mu_mol = 0.0;
                    for(m=0; (m<DIM); m++) 
                    {
                        M_av[m]  += dipole[i][m];               /* M per frame */
                        mu_mol   += dipole[i][m]*dipole[i][m];  /* calc. mu for distribution */
                    }
                    mu_mol = sqrt(mu_mol);
	  
                    mu_ave += mu_mol;                         /* calc. the average mu */
	  
                    /* Update the dipole distribution */
                    ibin = (int)(ndipbin*mu_mol/mu_max + 0.5);
                    if (ibin < ndipbin)
                        dipole_bin[ibin]++;
	  
                    if (fndip3d) 
                    {
                        rvec2sprvec(dipole[i],dipsp[i]);
	    
                        if (dipsp[i][YY] > -M_PI && dipsp[i][YY] < -0.5*M_PI) {
                            if (dipsp[i][ZZ] < 0.5 * M_PI) 
                            {
                                ncolour = 1;
                            } 
                            else 
                            {
                                ncolour = 2;
                            }
                        }
                        else if (dipsp[i][YY] > -0.5*M_PI && dipsp[i][YY] < 0.0*M_PI) 
                        {
                            if (dipsp[i][ZZ] < 0.5 * M_PI) 
                            {
                                ncolour = 3;
                            } 
                            else 
                            {
                                ncolour = 4;
                            }       
                        }else if (dipsp[i][YY] > 0.0 && dipsp[i][YY] < 0.5*M_PI) {
                            if (dipsp[i][ZZ] < 0.5 * M_PI) {
                                ncolour = 5;
                            } else {
                                ncolour = 6;
                            }      
                        }
                        else if (dipsp[i][YY] > 0.5*M_PI && dipsp[i][YY] < M_PI) 
                        {
                            if (dipsp[i][ZZ] < 0.5 * M_PI) 
                            {
                                ncolour = 7;
                            } 
                            else 
                            {
                                ncolour = 8;
                            }
                        }
                        if (dip3d)
                            fprintf(dip3d,"set arrow %d from %f, %f, %f to %f, %f, %f lt %d  # %d %d\n", 
                                    i+1,
                                    x[ind0][XX],
                                    x[ind0][YY],
                                    x[ind0][ZZ],
                                    x[ind0][XX]+dipole[i][XX]/25, 
                                    x[ind0][YY]+dipole[i][YY]/25, 
                                    x[ind0][ZZ]+dipole[i][ZZ]/25, 
                                    ncolour, ind0, i);
                    }
                } /* End loop of all molecules in frame */
	
                if (dip3d) 
                {
                    fprintf(dip3d,"set title \"t = %4.3f\"\n",t);
                    fprintf(dip3d,"set xrange [0.0:%4.2f]\n",box[XX][XX]);
                    fprintf(dip3d,"set yrange [0.0:%4.2f]\n",box[YY][YY]);
                    fprintf(dip3d,"set zrange [0.0:%4.2f]\n\n",box[ZZ][ZZ]);
                    fprintf(dip3d,"splot 'dummy.dat' using 1:2:3 w vec\n");
                    fprintf(dip3d,"pause -1 'Hit return to continue'\n");
                }
            }
        }
        /* Compute square of total dipole */
        for(m=0; (m<DIM); m++)
            M_av2[m] = M_av[m]*M_av[m];
    
        if (cosaver) 
        {
            compute_avercos(gnx_tot,dipole,&dd,dipaxis,bPairs);
            rms_cos = sqrt(sqr(dipaxis[XX]-0.5)+
                           sqr(dipaxis[YY]-0.5)+
                           sqr(dipaxis[ZZ]-0.5));
            if (bPairs) 
                fprintf(caver,"%10.3e  %10.3e  %10.3e  %10.3e  %10.3e  %10.3e\n",
                        t,dd,rms_cos,dipaxis[XX],dipaxis[YY],dipaxis[ZZ]);
            else
                fprintf(caver,"%10.3e  %10.3e  %10.3e  %10.3e  %10.3e\n",
                        t,rms_cos,dipaxis[XX],dipaxis[YY],dipaxis[ZZ]);
        }
    
        if (bGkr) 
        {
            do_gkr(gkrbin,ncos,gnx,molindex,mols->index,x,dipole,ePBC,box,
                   atom,gkatom);
        }
    
        if (bTotal) 
        {
            tel3 = DIM*teller;
            muall[0][tel3+XX] = M_av[XX];
            muall[0][tel3+YY] = M_av[YY];
            muall[0][tel3+ZZ] = M_av[ZZ];
        }

        /* Write to file the total dipole moment of the box, and its components 
         * for this frame.
         */
        if ((skip == 0) || ((teller % skip) == 0))
            fprintf(outmtot,"%10g  %12.8e %12.8e %12.8e %12.8e\n",
                    t,M_av[XX],M_av[YY],M_av[ZZ],
                    sqrt(M_av2[XX]+M_av2[YY]+M_av2[ZZ]));

        for(m=0; (m<DIM); m++) 
        {
            M[m]  += M_av[m];
            M2[m] += M_av2[m];
            M4[m] += sqr(M_av2[m]);
        }
        /* Increment loop counter */
        teller++;
    
        /* Calculate for output the running averages */
        invtel  = 1.0/teller;
        M2_ave  = (M2[XX]+M2[YY]+M2[ZZ])*invtel;
        M_ave2  = invtel*(invtel*(M[XX]*M[XX] + M[YY]*M[YY] + M[ZZ]*M[ZZ]));
        M_diff  = M2_ave - M_ave2;

        /* Compute volume from box in traj, else we use the one from above */
        if (!bMU)
            volume  = det(box);
        vol_aver += volume;
    
        epsilon = calc_eps(M_diff,(vol_aver/teller),epsilonRF,temp);

        /* Calculate running average for dipole */
        if (mu_ave != 0) 
            mu_aver = (mu_ave/gnx_tot)*invtel;
    
        if ((skip == 0) || ((teller % skip) == 0)) 
        {
            /* Write to file < |M|^2 >, |< M >|^2. And the difference between 
             * the two. Here M is sum mu_i. Further write the finite system
             * Kirkwood G factor and epsilon.
             */
            fprintf(outaver,"%10g  %10.3e %10.3e %10.3e %10.3e\n",
                    t,M2_ave,M_ave2,M_diff,M_ave2/M2_ave);
      
            if (fnadip) 
            {
                real aver;
                gmx_stats_get_average(muframelsq,&aver);
                fprintf(adip, "%10g %f \n", t,aver);
            }
            /*if (dipole)
              printf("%f %f\n", norm(dipole[0]), norm(dipole[1]));
            */      
            if (!bMU || (mu_aver != -1)) 
            {
                /* Finite system Kirkwood G-factor */
                Gk = M_diff/(gnx_tot*mu_aver*mu_aver);
                /* Infinite system Kirkwood G-factor */
                if (epsilonRF == 0.0) 
                    g_k = ((2*epsilon+1)*Gk/(3*epsilon));
                else 
                    g_k = ((2*epsilonRF+epsilon)*(2*epsilon+1)*
                           Gk/(3*epsilon*(2*epsilonRF+1)));
	
                fprintf(outeps,"%10g  %10.3e %10.3e %10.3e\n",t,epsilon,Gk,g_k);

            }
            else 
                fprintf(outeps,"%10g  %12.8e\n",t,epsilon);
        }
        gmx_stats_done(muframelsq);
    
        if (bMU)
            bCont = read_mu_from_enx(fmu,iVol,iMu,mu_t,&volume,&t,nre,fr); 
        else
            bCont = read_next_x(oenv,status,&t,natom,x,box);
        timecheck=check_times(t);
    } while (bCont && (timecheck == 0) );
  
    gmx_rmpbc_done(gpbc);

    if (!bMU)
        close_trj(status);
    
    ffclose(outmtot);
    ffclose(outaver);
    ffclose(outeps);

    if (fnadip)
        ffclose(adip);

    if (cosaver)
        ffclose(caver);

    if (dip3d) {
        fprintf(dip3d,"set xrange [0.0:%4.2f]\n",box[XX][XX]);
        fprintf(dip3d,"set yrange [0.0:%4.2f]\n",box[YY][YY]);
        fprintf(dip3d,"set zrange [0.0:%4.2f]\n\n",box[ZZ][ZZ]);
        fprintf(dip3d,"splot 'dummy.dat' using 1:2:3 w vec\n");
        fprintf(dip3d,"pause -1 'Hit return to continue'\n");
        ffclose(dip3d);
    }

    if (bSlab) {
        dump_slab_dipoles(slabfn,idim,nslices,slab_dipoles,box,teller,oenv);
        sfree(slab_dipoles);
    }
  
    vol_aver /= teller;
    printf("Average volume over run is %g\n",vol_aver);
    if (bGkr) {
        print_gkrbin(gkrfn,gkrbin,gnx[0],teller,vol_aver,oenv);
        print_cmap(cmap,gkrbin,nlevels);
    }
    /* Autocorrelation function */  
    if (bCorr) {
        if (teller < 2) {
            printf("Not enough frames for autocorrelation\n");
        }
        else {
            dt=(t1 - t0)/(teller-1);
            printf("t0 %g, t %g, teller %d\n", t0,t,teller);
      
            mode = eacVector;

            if (bTotal)
                do_autocorr(corf,oenv,"Autocorrelation Function of Total Dipole",
                            teller,1,muall,dt,mode,TRUE);
            else
                do_autocorr(corf,oenv,"Dipole Autocorrelation Function",
                            teller,gnx_tot,muall,dt,
                            mode,strcmp(corrtype,"molsep"));
        }
    }
    if (!bMU) {
        real aver,sigma,error,lsq;

        gmx_stats_get_ase(mulsq,&aver,&sigma,&error);
        printf("\nDipole moment (Debye)\n");
        printf("---------------------\n");
        printf("Average  = %8.4f  Std. Dev. = %8.4f  Error = %8.4f\n",
               aver,sigma,error);
        if (bQuad) {
            rvec a,s,e;
            int mm;
            for(m=0; (m<DIM); m++)
                gmx_stats_get_ase(mulsq,&(a[m]),&(s[m]),&(e[m]));
    
            printf("\nQuadrupole moment (Debye-Ang)\n");
            printf("-----------------------------\n");
            printf("Averages  = %8.4f  %8.4f  %8.4f\n",a[XX],a[YY],a[ZZ]);
            printf("Std. Dev. = %8.4f  %8.4f  %8.4f\n",s[XX],s[YY],s[ZZ]);
            printf("Error     = %8.4f  %8.4f  %8.4f\n",e[XX],e[YY],e[ZZ]);
        }
        printf("\n");
    }
    printf("The following averages for the complete trajectory have been calculated:\n\n");
    printf(" Total < M_x > = %g Debye\n", M[XX]/teller);
    printf(" Total < M_y > = %g Debye\n", M[YY]/teller);
    printf(" Total < M_z > = %g Debye\n\n", M[ZZ]/teller);

    printf(" Total < M_x^2 > = %g Debye^2\n", M2[XX]/teller);
    printf(" Total < M_y^2 > = %g Debye^2\n", M2[YY]/teller);
    printf(" Total < M_z^2 > = %g Debye^2\n\n", M2[ZZ]/teller);

    printf(" Total < |M|^2 > = %g Debye^2\n", M2_ave);
    printf(" Total |< M >|^2 = %g Debye^2\n\n", M_ave2);

    printf(" < |M|^2 > - |< M >|^2 = %g Debye^2\n\n", M_diff);
  
    if (!bMU || (mu_aver != -1)) {
        printf("Finite system Kirkwood g factor G_k = %g\n", Gk);
        printf("Infinite system Kirkwood g factor g_k = %g\n\n", g_k);
    }
    printf("Epsilon = %g\n", epsilon);

    if (!bMU) {
        /* Write to file the dipole moment distibution during the simulation.
         */
        outdd=xvgropen(dipdist,"Dipole Moment Distribution","mu (Debye)","",oenv);
        for(i=0; (i<ndipbin); i++)
            fprintf(outdd,"%10g  %10f\n",
                    (i*mu_max)/ndipbin,dipole_bin[i]/(double)teller);
        ffclose(outdd);
        sfree(dipole_bin);
    }
    if (bGkr) 
        done_gkrbin(&gkrbin);
}