static void init_proj_matrix(settleparam_t *p, real invmO, real invmH, real dOH, real dHH) { real imOn, imHn; matrix mat; p->imO = invmO; p->imH = invmH; /* We normalize the inverse masses with imO for the matrix inversion. * so we can keep using masses of almost zero for frozen particles, * without running out of the float range in m_inv. */ imOn = 1; imHn = p->imH/p->imO; /* Construct the constraint coupling matrix */ mat[0][0] = imOn + imHn; mat[0][1] = imOn*(1 - 0.5*dHH*dHH/(dOH*dOH)); mat[0][2] = imHn*0.5*dHH/dOH; mat[1][1] = mat[0][0]; mat[1][2] = mat[0][2]; mat[2][2] = imHn + imHn; mat[1][0] = mat[0][1]; mat[2][0] = mat[0][2]; mat[2][1] = mat[1][2]; m_inv(mat, p->invmat); msmul(p->invmat, 1/p->imO, p->invmat); p->invdOH = 1/dOH; p->invdHH = 1/dHH; }
/* the non-mass-weighted mean-squared displacement calcuation */ static real calc1_norm(t_corr *curr, int nx, atom_id index[], int nx0, rvec xc[], rvec dcom, gmx_bool bTen, matrix mat) { int i, ix, m, m2; real g, r, r2; rvec rv; g = 0.0; clear_mat(mat); for (i = 0; (i < nx); i++) { ix = index[i]; r2 = 0.0; switch (curr->type) { case NORMAL: for (m = 0; (m < DIM); m++) { rv[m] = xc[ix][m] - curr->x0[nx0][ix][m] - dcom[m]; r2 += rv[m]*rv[m]; if (bTen) { for (m2 = 0; m2 <= m; m2++) { mat[m][m2] += rv[m]*rv[m2]; } } } break; case X: case Y: case Z: r = xc[ix][curr->type-X] - curr->x0[nx0][ix][curr->type-X] - dcom[curr->type-X]; r2 += r*r; break; case LATERAL: for (m = 0; (m < DIM); m++) { if (m != curr->axis) { r = xc[ix][m] - curr->x0[nx0][ix][m] - dcom[m]; r2 += r*r; } } break; default: gmx_fatal(FARGS, "Error: did not expect option value %d", curr->type); } g += r2; } g /= nx; msmul(mat, 1.0/nx, mat); return g; }
static void boxv_trotter(t_inputrec *ir, real *veta, real dt, tensor box, gmx_ekindata_t *ekind, tensor vir, real pcorr, real ecorr, t_extmass *MassQ) { real pscal; double alpha; int i,j,d,n,nwall; real T,GW,vol; tensor Winvm,ekinmod,localpres; /* The heat bath is coupled to a separate barostat, the last temperature group. In the 2006 Tuckerman et al paper., the order is iL_{T_baro} iL {T_part} */ if (ir->epct==epctSEMIISOTROPIC) { nwall = 2; } else { nwall = 3; } /* eta is in pure units. veta is in units of ps^-1. GW is in units of ps^-2. However, eta has a reference of 1 nm^3, so care must be taken to use only RATIOS of eta in updating the volume. */ /* we take the partial pressure tensors, modify the kinetic energy tensor, and recovert to pressure */ if (ir->opts.nrdf[0]==0) { gmx_fatal(FARGS,"Barostat is coupled to a T-group with no degrees of freedom\n"); } /* alpha factor for phase space volume, then multiply by the ekin scaling factor. */ alpha = 1.0 + DIM/((double)ir->opts.nrdf[0]); alpha *= ekind->tcstat[0].ekinscalef_nhc; msmul(ekind->ekin,alpha,ekinmod); /* for now, we use Elr = 0, because if you want to get it right, you really should be using PME. Maybe print a warning? */ pscal = calc_pres(ir->ePBC,nwall,box,ekinmod,vir,localpres,0.0) + pcorr; vol = det(box); GW = (vol*(MassQ->Winv/PRESFAC))*(DIM*pscal - trace(ir->ref_p)); /* W is in ps^2 * bar * nm^3 */ *veta += 0.5*dt*GW; }
/* the normal, mass-weighted mean-squared displacement calcuation */ static real calc1_mw(t_corr *curr,int nx,atom_id index[],int nx0,rvec xc[], rvec dcom,gmx_bool bTen,matrix mat,const output_env_t oenv) { int i; real g,tm; g=tm=0.0; clear_mat(mat); for(i=0; (i<nx); i++) g += calc_one_mw(curr,index[i],nx0,xc,&tm,dcom,bTen,mat); g/=tm; if (bTen) msmul(mat,1/tm,mat); return g; }
static real calc1_mol(t_corr *curr,int nx,atom_id index[],int nx0,rvec xc[], rvec dcom,gmx_bool bTen,matrix mat, const output_env_t oenv) { int i; real g,tm,gtot,tt; tt = curr->time[in_data(curr,nx0)]; gtot = 0; tm = 0; clear_mat(mat); for(i=0; (i<nx); i++) { g = calc_one_mw(curr,i,nx0,xc,&tm,dcom,bTen,mat); /* We don't need to normalize as the mass was set to 1 */ gtot += g; if (tt >= curr->beginfit && (curr->endfit < 0 || tt <= curr->endfit)) gmx_stats_add_point(curr->lsq[nx0][i],tt,g,0,0); } msmul(mat,1.0/nx,mat); return gtot/nx; }
/* the normal, mass-weighted mean-squared displacement calcuation */ static real calc1_mw(t_corr *curr, int nx, int index[], int nx0, rvec xc[], rvec dcom, gmx_bool bTen, matrix mat) { int i; real g, tm; g = tm = 0.0; clear_mat(mat); for (i = 0; (i < nx); i++) { g += calc_one_mw(curr, index[i], nx0, xc, &tm, dcom, bTen, mat); } g /= tm; if (bTen) { msmul(mat, 1/tm, mat); } return g; }
real sum_ekin(t_grpopts *opts, gmx_ekindata_t *ekind, real *dekindlambda, gmx_bool bEkinAveVel, gmx_bool bSaveEkinOld, gmx_bool bScaleEkin) { int i, j, m, ngtc; real T, ek; t_grp_tcstat *tcstat; real nrdf, nd, *ndf; ngtc = opts->ngtc; ndf = opts->nrdf; T = 0; nrdf = 0; clear_mat(ekind->ekin); for (i = 0; (i < ngtc); i++) { nd = ndf[i]; tcstat = &ekind->tcstat[i]; /* Sometimes a group does not have degrees of freedom, e.g. * when it consists of shells and virtual sites, then we just * set the temperatue to 0 and also neglect the kinetic * energy, which should be zero anyway. */ if (nd > 0) { if (bEkinAveVel) { if (!bScaleEkin) { /* in this case, kinetic energy is from the current velocities already */ msmul(tcstat->ekinf, tcstat->ekinscalef_nhc, tcstat->ekinf); } } else { /* Calculate the full step Ekin as the average of the half steps */ for (j = 0; (j < DIM); j++) { for (m = 0; (m < DIM); m++) { tcstat->ekinf[j][m] = 0.5*(tcstat->ekinh[j][m]*tcstat->ekinscaleh_nhc + tcstat->ekinh_old[j][m]); } } } m_add(tcstat->ekinf, ekind->ekin, ekind->ekin); tcstat->Th = calc_temp(trace(tcstat->ekinh), nd); tcstat->T = calc_temp(trace(tcstat->ekinf), nd); /* after the scaling factors have been multiplied in, we can remove them */ if (bEkinAveVel) { tcstat->ekinscalef_nhc = 1.0; } else { tcstat->ekinscaleh_nhc = 1.0; } } else { tcstat->T = 0; tcstat->Th = 0; } T += nd*tcstat->T; nrdf += nd; } if (nrdf > 0) { T /= nrdf; } if (dekindlambda) { *dekindlambda = 0.5*(ekind->dekindl + ekind->dekindl_old); } return T; }
void settle_proj(FILE *fp,int nsettle, t_iatom iatoms[],rvec x[], real dOH,real dHH,real invmO,real invmH, rvec *der,rvec *derp, bool bCalcVir,tensor rmdder) { /* Settle for projection out constraint components * of derivatives of the coordinates. * Berk Hess 2008-1-10 */ /* Initialized data */ static bool bFirst=TRUE; static real imO,imH,invdOH,invdHH; static matrix invmat; real imOn,imHn; matrix mat; int i,m,m2,ow1,hw2,hw3; rvec roh2,roh3,rhh,dc,fc; if (bFirst) { if (fp) fprintf(fp,"Going to use settle for derivatives (%d waters)\n",nsettle); imO = invmO; imH = invmH; /* We normalize the inverse masses with imO for the matrix inversion. * so we can keep using masses of almost zero for frozen particles, * without running out of the float range in m_inv. */ imOn = 1; imHn = imH/imO; /* Construct the constraint coupling matrix */ mat[0][0] = imOn + imHn; mat[0][1] = imOn*(1 - 0.5*dHH*dHH/(dOH*dOH)); mat[0][2] = imHn*0.5*dHH/dOH; mat[1][1] = mat[0][0]; mat[1][2] = mat[0][2]; mat[2][2] = imHn + imHn; mat[1][0] = mat[0][1]; mat[2][0] = mat[0][2]; mat[2][1] = mat[1][2]; m_inv(mat,invmat); msmul(invmat,1/imO,invmat); invdOH = 1/dOH; invdHH = 1/dHH; bFirst = FALSE; } #ifdef PRAGMAS #pragma ivdep #endif for (i=0; i<nsettle; i++) { ow1 = iatoms[i*2+1]; hw2 = ow1 + 1; hw3 = ow1 + 2; for(m=0; m<DIM; m++) roh2[m] = (x[ow1][m] - x[hw2][m])*invdOH; for(m=0; m<DIM; m++) roh3[m] = (x[ow1][m] - x[hw3][m])*invdOH; for(m=0; m<DIM; m++) rhh [m] = (x[hw2][m] - x[hw3][m])*invdHH; /* 18 flops */ /* Determine the projections of der on the bonds */ clear_rvec(dc); for(m=0; m<DIM; m++) dc[0] += (der[ow1][m] - der[hw2][m])*roh2[m]; for(m=0; m<DIM; m++) dc[1] += (der[ow1][m] - der[hw3][m])*roh3[m]; for(m=0; m<DIM; m++) dc[2] += (der[hw2][m] - der[hw3][m])*rhh [m]; /* 27 flops */ /* Determine the correction for the three bonds */ mvmul(invmat,dc,fc); /* 15 flops */ /* Subtract the corrections from derp */ for(m=0; m<DIM; m++) { derp[ow1][m] -= imO*( fc[0]*roh2[m] + fc[1]*roh3[m]); derp[hw2][m] -= imH*(-fc[0]*roh2[m] + fc[2]*rhh [m]); derp[hw3][m] -= imH*(-fc[1]*roh3[m] - fc[2]*rhh [m]); } /* 45 flops */ if (bCalcVir) { /* Determining r x m der is easy, * since fc contains the mass weighted corrections for der. */ for(m=0; m<DIM; m++) { for(m2=0; m2<DIM; m2++) { rmdder[m][m2] += dOH*roh2[m]*roh2[m2]*fc[0] + dOH*roh3[m]*roh3[m2]*fc[1] + dHH*rhh [m]*rhh [m2]*fc[2]; } } } } }
int gmx_vanhove(int argc,char *argv[]) { const char *desc[] = { "g_vanhove computes the Van Hove correlation function.", "The Van Hove G(r,t) is the probability that a particle that is at r0", "at time zero can be found at position r0+r at time t.", "g_vanhove determines G not for a vector r, but for the length of r.", "Thus it gives the probability that a particle moves a distance of r", "in time t.", "Jumps across the periodic boundaries are removed.", "Corrections are made for scaling due to isotropic", "or anisotropic pressure coupling.", "[PAR]", "With option [TT]-om[tt] the whole matrix can be written as a function", "of t and r or as a function of sqrt(t) and r (option [TT]-sqrt[tt]).", "[PAR]", "With option [TT]-or[tt] the Van Hove function is plotted for one", "or more values of t. Option [TT]-nr[tt] sets the number of times,", "option [TT]-fr[tt] the number spacing between the times.", "The binwidth is set with option [TT]-rbin[tt]. The number of bins", "is determined automatically.", "[PAR]", "With option [TT]-ot[tt] the integral up to a certain distance", "(option [TT]-rt[tt]) is plotted as a function of time.", "[PAR]", "For all frames that are read the coordinates of the selected particles", "are stored in memory. Therefore the program may use a lot of memory.", "For options [TT]-om[tt] and [TT]-ot[tt] the program may be slow.", "This is because the calculation scales as the number of frames times", "[TT]-fm[tt] or [TT]-ft[tt].", "Note that with the [TT]-dt[tt] option the memory usage and calculation", "time can be reduced." }; static int fmmax=0,ftmax=0,nlev=81,nr=1,fshift=0; static real sbin=0,rmax=2,rbin=0.01,mmax=0,rint=0; t_pargs pa[] = { { "-sqrt", FALSE, etREAL,{&sbin}, "Use sqrt(t) on the matrix axis which binspacing # in sqrt(ps)" }, { "-fm", FALSE, etINT, {&fmmax}, "Number of frames in the matrix, 0 is plot all" }, { "-rmax", FALSE, etREAL, {&rmax}, "Maximum r in the matrix (nm)" }, { "-rbin", FALSE, etREAL, {&rbin}, "Binwidth in the matrix and for -or (nm)" }, { "-mmax", FALSE, etREAL, {&mmax}, "Maximum density in the matrix, 0 is calculate (1/nm)" }, { "-nlevels" ,FALSE, etINT, {&nlev}, "Number of levels in the matrix" }, { "-nr", FALSE, etINT, {&nr}, "Number of curves for the -or output" }, { "-fr", FALSE, etINT, {&fshift}, "Frame spacing for the -or output" }, { "-rt", FALSE, etREAL, {&rint}, "Integration limit for the -ot output (nm)" }, { "-ft", FALSE, etINT, {&ftmax}, "Number of frames in the -ot output, 0 is plot all" } }; #define NPA asize(pa) t_filenm fnm[] = { { efTRX, NULL, NULL, ffREAD }, { efTPS, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efXPM, "-om", "vanhove", ffOPTWR }, { efXVG, "-or", "vanhove_r", ffOPTWR }, { efXVG, "-ot", "vanhove_t", ffOPTWR } }; #define NFILE asize(fnm) output_env_t oenv; const char *matfile,*otfile,*orfile; char title[256]; t_topology top; int ePBC; matrix boxtop,box,*sbox,avbox,corr; rvec *xtop,*x,**sx; int isize,nalloc,nallocn,natom; t_trxstatus *status; atom_id *index; char *grpname; int nfr,f,ff,i,m,mat_nx=0,nbin=0,bin,mbin,fbin; real *time,t,invbin=0,rmax2=0,rint2=0,d2; real invsbin=0,matmax,normfac,dt,*tickx,*ticky; char buf[STRLEN],**legend; real **mat=NULL; int *pt=NULL,**pr=NULL,*mcount=NULL,*tcount=NULL,*rcount=NULL; FILE *fp; t_rgb rlo={1,1,1}, rhi={0,0,0}; CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE, NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv); matfile = opt2fn_null("-om",NFILE,fnm); if (opt2parg_bSet("-fr",NPA,pa)) orfile = opt2fn("-or",NFILE,fnm); else orfile = opt2fn_null("-or",NFILE,fnm); if (opt2parg_bSet("-rt",NPA,pa)) otfile = opt2fn("-ot",NFILE,fnm); else otfile = opt2fn_null("-ot",NFILE,fnm); if (!matfile && !otfile && !orfile) { fprintf(stderr, "For output set one (or more) of the output file options\n"); exit(0); } read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xtop,NULL,boxtop, FALSE); get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&isize,&index,&grpname); nalloc = 0; time = NULL; sbox = NULL; sx = NULL; clear_mat(avbox); natom=read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box); nfr = 0; do { if (nfr >= nalloc) { nalloc += 100; srenew(time,nalloc); srenew(sbox,nalloc); srenew(sx,nalloc); } time[nfr] = t; copy_mat(box,sbox[nfr]); /* This assumes that the off-diagonal box elements * are not affected by jumps across the periodic boundaries. */ m_add(avbox,box,avbox); snew(sx[nfr],isize); for(i=0; i<isize; i++) copy_rvec(x[index[i]],sx[nfr][i]); nfr++; } while (read_next_x(oenv,status,&t,natom,x,box)); /* clean up */ sfree(x); close_trj(status); fprintf(stderr,"Read %d frames\n",nfr); dt = (time[nfr-1] - time[0])/(nfr - 1); /* Some ugly rounding to get nice nice times in the output */ dt = (int)(10000.0*dt + 0.5)/10000.0; invbin = 1.0/rbin; if (matfile) { if (fmmax <= 0 || fmmax >= nfr) fmmax = nfr - 1; snew(mcount,fmmax); nbin = (int)(rmax*invbin + 0.5); if (sbin == 0) { mat_nx = fmmax + 1; } else { invsbin = 1.0/sbin; mat_nx = sqrt(fmmax*dt)*invsbin + 1; } snew(mat,mat_nx); for(f=0; f<mat_nx; f++) snew(mat[f],nbin); rmax2 = sqr(nbin*rbin); /* Initialize time zero */ mat[0][0] = nfr*isize; mcount[0] += nfr; } else { fmmax = 0; } if (orfile) { snew(pr,nr); nalloc = 0; snew(rcount,nr); } if (otfile) { if (ftmax <= 0) ftmax = nfr - 1; snew(tcount,ftmax); snew(pt,nfr); rint2 = rint*rint; /* Initialize time zero */ pt[0] = nfr*isize; tcount[0] += nfr; } else { ftmax = 0; } msmul(avbox,1.0/nfr,avbox); for(f=0; f<nfr; f++) { if (f % 100 == 0) fprintf(stderr,"\rProcessing frame %d",f); /* Scale all the configuration to the average box */ m_inv_ur0(sbox[f],corr); mmul_ur0(avbox,corr,corr); for(i=0; i<isize; i++) { mvmul_ur0(corr,sx[f][i],sx[f][i]); if (f > 0) { /* Correct for periodic jumps */ for(m=DIM-1; m>=0; m--) { while(sx[f][i][m] - sx[f-1][i][m] > 0.5*avbox[m][m]) rvec_dec(sx[f][i],avbox[m]); while(sx[f][i][m] - sx[f-1][i][m] <= -0.5*avbox[m][m]) rvec_inc(sx[f][i],avbox[m]); } } } for(ff=0; ff<f; ff++) { fbin = f - ff; if (fbin <= fmmax || fbin <= ftmax) { if (sbin == 0) mbin = fbin; else mbin = (int)(sqrt(fbin*dt)*invsbin + 0.5); for(i=0; i<isize; i++) { d2 = distance2(sx[f][i],sx[ff][i]); if (mbin < mat_nx && d2 < rmax2) { bin = (int)(sqrt(d2)*invbin + 0.5); if (bin < nbin) { mat[mbin][bin] += 1; } } if (fbin <= ftmax && d2 <= rint2) pt[fbin]++; } if (matfile) mcount[mbin]++; if (otfile) tcount[fbin]++; } } if (orfile) { for(fbin=0; fbin<nr; fbin++) { ff = f - (fbin + 1)*fshift; if (ff >= 0) { for(i=0; i<isize; i++) { d2 = distance2(sx[f][i],sx[ff][i]); bin = (int)(sqrt(d2)*invbin); if (bin >= nalloc) { nallocn = 10*(bin/10) + 11; for(m=0; m<nr; m++) { srenew(pr[m],nallocn); for(i=nalloc; i<nallocn; i++) pr[m][i] = 0; } nalloc = nallocn; } pr[fbin][bin]++; } rcount[fbin]++; } } } } fprintf(stderr,"\n"); if (matfile) { matmax = 0; for(f=0; f<mat_nx; f++) { normfac = 1.0/(mcount[f]*isize*rbin); for(i=0; i<nbin; i++) { mat[f][i] *= normfac; if (mat[f][i] > matmax && (f!=0 || i!=0)) matmax = mat[f][i]; } } fprintf(stdout,"Value at (0,0): %.3f, maximum of the rest %.3f\n", mat[0][0],matmax); if (mmax > 0) matmax = mmax; snew(tickx,mat_nx); for(f=0; f<mat_nx; f++) { if (sbin == 0) tickx[f] = f*dt; else tickx[f] = f*sbin; } snew(ticky,nbin+1); for(i=0; i<=nbin; i++) ticky[i] = i*rbin; fp = ffopen(matfile,"w"); write_xpm(fp,MAT_SPATIAL_Y,"Van Hove function","G (1/nm)", sbin==0 ? "time (ps)" : "sqrt(time) (ps^1/2)","r (nm)", mat_nx,nbin,tickx,ticky,mat,0,matmax,rlo,rhi,&nlev); ffclose(fp); } if (orfile) { fp = xvgropen(orfile,"Van Hove function","r (nm)","G (nm\\S-1\\N)",oenv); fprintf(fp,"@ subtitle \"for particles in group %s\"\n",grpname); snew(legend,nr); for(fbin=0; fbin<nr; fbin++) { sprintf(buf,"%g ps",(fbin + 1)*fshift*dt); legend[fbin] = strdup(buf); } xvgr_legend(fp,nr,(const char**)legend,oenv); for(i=0; i<nalloc; i++) { fprintf(fp,"%g",i*rbin); for(fbin=0; fbin<nr; fbin++) fprintf(fp," %g", (real)pr[fbin][i]/(rcount[fbin]*isize*rbin*(i==0 ? 0.5 : 1))); fprintf(fp,"\n"); } ffclose(fp); } if (otfile) { sprintf(buf,"Probability of moving less than %g nm",rint); fp = xvgropen(otfile,buf,"t (ps)","",oenv); fprintf(fp,"@ subtitle \"for particles in group %s\"\n",grpname); for(f=0; f<=ftmax; f++) fprintf(fp,"%g %g\n",f*dt,(real)pt[f]/(tcount[f]*isize)); ffclose(fp); } do_view(oenv, matfile,NULL); do_view(oenv, orfile,NULL); do_view(oenv, otfile,NULL); thanx(stderr); return 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); }
void settle_proj(FILE *fp, gmx_settledata_t settled,int econq, int nsettle, t_iatom iatoms[],rvec x[], rvec *der,rvec *derp, gmx_bool bCalcVir,tensor rmdder,t_vetavars *vetavar) { /* Settle for projection out constraint components * of derivatives of the coordinates. * Berk Hess 2008-1-10 */ settleparam_t *p; real imO,imH,dOH,dHH,invdOH,invdHH; matrix invmat; int i,m,m2,ow1,hw2,hw3; rvec roh2,roh3,rhh,dc,fc,fcv; rvec derm[3],derpm[3]; real invvscale,vscale_nhc,veta; real kfacOH,kfacHH; if (econq == econqForce) { p = &settled->mass1; } else { p = &settled->massw; } imO = p->imO; imH = p->imH; copy_mat(p->invmat,invmat); dOH = p->dOH; dHH = p->dHH; invdOH = p->invdOH; invdHH = p->invdHH; veta = vetavar->veta; vscale_nhc = vetavar->vscale_nhc[0]; /* assume the first temperature control group. */ #ifdef PRAGMAS #pragma ivdep #endif for (i=0; i<nsettle; i++) { ow1 = iatoms[i*2+1]; hw2 = ow1 + 1; hw3 = ow1 + 2; for(m=0; m<DIM; m++) { /* in the velocity case, these are the velocities, so we need to modify with the pressure control velocities! */ derm[0][m] = vscale_nhc*der[ow1][m] + veta*x[ow1][m]; derm[1][m] = vscale_nhc*der[hw2][m] + veta*x[hw2][m]; derm[2][m] = vscale_nhc*der[hw3][m] + veta*x[hw3][m]; } /* 27 flops */ for(m=0; m<DIM; m++) { roh2[m] = (x[ow1][m] - x[hw2][m])*invdOH; roh3[m] = (x[ow1][m] - x[hw3][m])*invdOH; rhh [m] = (x[hw2][m] - x[hw3][m])*invdHH; } /* 18 flops */ /* Determine the projections of der(modified) on the bonds */ clear_rvec(dc); for(m=0; m<DIM; m++) { dc[0] += (derm[0][m] - derm[1][m])*roh2[m]; dc[1] += (derm[0][m] - derm[2][m])*roh3[m]; dc[2] += (derm[1][m] - derm[2][m])*rhh [m]; } /* 27 flops */ /* Determine the correction for the three bonds */ mvmul(invmat,dc,fc); /* 15 flops */ /* divide velocity by vscale_nhc for determining constrained velocities, since they have not yet been multiplied */ svmul(1.0/vscale_nhc,fc,fcv); /* 7? flops */ /* Subtract the corrections from derp */ for(m=0; m<DIM; m++) { derp[ow1][m] -= imO*( fcv[0]*roh2[m] + fcv[1]*roh3[m]); derp[hw2][m] -= imH*(-fcv[0]*roh2[m] + fcv[2]*rhh [m]); derp[hw3][m] -= imH*(-fcv[1]*roh3[m] - fcv[2]*rhh [m]); } /* 45 flops */ if (bCalcVir) { /* Determining r \dot m der is easy, * since fc contains the mass weighted corrections for der. */ for(m=0; m<DIM; m++) { for(m2=0; m2<DIM; m2++) { rmdder[m][m2] += dOH*roh2[m]*roh2[m2]*fcv[0] + dOH*roh3[m]*roh3[m2]*fcv[1] + dHH*rhh [m]*rhh [m2]*fcv[2]; } } } } /* conrect rmdder, which will be used to calcualate the virial; we need to use the unscaled multipliers in the virial */ msmul(rmdder,1.0/vetavar->vscale,rmdder); }