int gmx_traj(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] plots coordinates, velocities, forces and/or the box.", "With [TT]-com[tt] the coordinates, velocities and forces are", "calculated for the center of mass of each group.", "When [TT]-mol[tt] is set, the numbers in the index file are", "interpreted as molecule numbers and the same procedure as with", "[TT]-com[tt] is used for each molecule.[PAR]", "Option [TT]-ot[tt] plots the temperature of each group,", "provided velocities are present in the trajectory file.", "No corrections are made for constrained degrees of freedom!", "This implies [TT]-com[tt].[PAR]", "Options [TT]-ekt[tt] and [TT]-ekr[tt] plot the translational and", "rotational kinetic energy of each group,", "provided velocities are present in the trajectory file.", "This implies [TT]-com[tt].[PAR]", "Options [TT]-cv[tt] and [TT]-cf[tt] write the average velocities", "and average forces as temperature factors to a [REF].pdb[ref] file with", "the average coordinates or the coordinates at [TT]-ctime[tt].", "The temperature factors are scaled such that the maximum is 10.", "The scaling can be changed with the option [TT]-scale[tt].", "To get the velocities or forces of one", "frame set both [TT]-b[tt] and [TT]-e[tt] to the time of", "desired frame. When averaging over frames you might need to use", "the [TT]-nojump[tt] option to obtain the correct average coordinates.", "If you select either of these option the average force and velocity", "for each atom are written to an [REF].xvg[ref] file as well", "(specified with [TT]-av[tt] or [TT]-af[tt]).[PAR]", "Option [TT]-vd[tt] computes a velocity distribution, i.e. the", "norm of the vector is plotted. In addition in the same graph", "the kinetic energy distribution is given." }; static gmx_bool bMol = FALSE, bCom = FALSE, bPBC = TRUE, bNoJump = FALSE; static gmx_bool bX = TRUE, bY = TRUE, bZ = TRUE, bNorm = FALSE, bFP = FALSE; static int ngroups = 1; static real ctime = -1, scale = 0, binwidth = 1; t_pargs pa[] = { { "-com", FALSE, etBOOL, {&bCom}, "Plot data for the com of each group" }, { "-pbc", FALSE, etBOOL, {&bPBC}, "Make molecules whole for COM" }, { "-mol", FALSE, etBOOL, {&bMol}, "Index contains molecule numbers iso atom numbers" }, { "-nojump", FALSE, etBOOL, {&bNoJump}, "Remove jumps of atoms across the box" }, { "-x", FALSE, etBOOL, {&bX}, "Plot X-component" }, { "-y", FALSE, etBOOL, {&bY}, "Plot Y-component" }, { "-z", FALSE, etBOOL, {&bZ}, "Plot Z-component" }, { "-ng", FALSE, etINT, {&ngroups}, "Number of groups to consider" }, { "-len", FALSE, etBOOL, {&bNorm}, "Plot vector length" }, { "-fp", FALSE, etBOOL, {&bFP}, "Full precision output" }, { "-bin", FALSE, etREAL, {&binwidth}, "Binwidth for velocity histogram (nm/ps)" }, { "-ctime", FALSE, etREAL, {&ctime}, "Use frame at this time for x in [TT]-cv[tt] and [TT]-cf[tt] instead of the average x" }, { "-scale", FALSE, etREAL, {&scale}, "Scale factor for [REF].pdb[ref] output, 0 is autoscale" } }; FILE *outx = NULL, *outv = NULL, *outf = NULL, *outb = NULL, *outt = NULL; FILE *outekt = NULL, *outekr = NULL; t_topology top; int ePBC; real *mass, time; const char *indexfn; t_trxframe fr, frout; int flags, nvhisto = 0, *vhisto = NULL; rvec *xtop, *xp = NULL; rvec *sumx = NULL, *sumv = NULL, *sumf = NULL; matrix topbox; t_trxstatus *status; t_trxstatus *status_out = NULL; gmx_rmpbc_t gpbc = NULL; int i, j; int nr_xfr, nr_vfr, nr_ffr; char **grpname; int *isize0, *isize; int **index0, **index; int *atndx; t_block *mols; gmx_bool bTop, bOX, bOXT, bOV, bOF, bOB, bOT, bEKT, bEKR, bCV, bCF; gmx_bool bDim[4], bDum[4], bVD; char sffmt[STRLEN], sffmt6[STRLEN]; const char *box_leg[6] = { "XX", "YY", "ZZ", "YX", "ZX", "ZY" }; gmx_output_env_t *oenv; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPS, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efXVG, "-ox", "coord", ffOPTWR }, { efTRX, "-oxt", "coord", ffOPTWR }, { efXVG, "-ov", "veloc", ffOPTWR }, { efXVG, "-of", "force", ffOPTWR }, { efXVG, "-ob", "box", ffOPTWR }, { efXVG, "-ot", "temp", ffOPTWR }, { efXVG, "-ekt", "ektrans", ffOPTWR }, { efXVG, "-ekr", "ekrot", ffOPTWR }, { efXVG, "-vd", "veldist", ffOPTWR }, { efPDB, "-cv", "veloc", ffOPTWR }, { efPDB, "-cf", "force", ffOPTWR }, { efXVG, "-av", "all_veloc", ffOPTWR }, { efXVG, "-af", "all_force", ffOPTWR } }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } if (bMol) { fprintf(stderr, "Interpreting indexfile entries as molecules.\n" "Using center of mass.\n"); } bOX = opt2bSet("-ox", NFILE, fnm); bOXT = opt2bSet("-oxt", NFILE, fnm); bOV = opt2bSet("-ov", NFILE, fnm); bOF = opt2bSet("-of", NFILE, fnm); bOB = opt2bSet("-ob", NFILE, fnm); bOT = opt2bSet("-ot", NFILE, fnm); bEKT = opt2bSet("-ekt", NFILE, fnm); bEKR = opt2bSet("-ekr", NFILE, fnm); bCV = opt2bSet("-cv", NFILE, fnm) || opt2bSet("-av", NFILE, fnm); bCF = opt2bSet("-cf", NFILE, fnm) || opt2bSet("-af", NFILE, fnm); bVD = opt2bSet("-vd", NFILE, fnm) || opt2parg_bSet("-bin", asize(pa), pa); if (bMol || bOT || bEKT || bEKR) { bCom = TRUE; } bDim[XX] = bX; bDim[YY] = bY; bDim[ZZ] = bZ; bDim[DIM] = bNorm; if (bFP) { sprintf(sffmt, "\t%s", gmx_real_fullprecision_pfmt); } else { sprintf(sffmt, "\t%%g"); } sprintf(sffmt6, "%s%s%s%s%s%s", sffmt, sffmt, sffmt, sffmt, sffmt, sffmt); bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, NULL, topbox, bCom && (bOX || bOXT || bOV || bOT || bEKT || bEKR)); sfree(xtop); if ((bMol || bCV || bCF) && !bTop) { gmx_fatal(FARGS, "Need a run input file for option -mol, -cv or -cf"); } if (bMol) { indexfn = ftp2fn(efNDX, NFILE, fnm); } else { indexfn = ftp2fn_null(efNDX, NFILE, fnm); } if (!(bCom && !bMol)) { ngroups = 1; } snew(grpname, ngroups); snew(isize0, ngroups); snew(index0, ngroups); get_index(&(top.atoms), indexfn, ngroups, isize0, index0, grpname); if (bMol) { mols = &(top.mols); atndx = mols->index; ngroups = isize0[0]; snew(isize, ngroups); snew(index, ngroups); for (i = 0; i < ngroups; i++) { if (index0[0][i] < 0 || index0[0][i] >= mols->nr) { gmx_fatal(FARGS, "Molecule index (%d) is out of range (%d-%d)", index0[0][i]+1, 1, mols->nr); } isize[i] = atndx[index0[0][i]+1] - atndx[index0[0][i]]; snew(index[i], isize[i]); for (j = 0; j < isize[i]; j++) { index[i][j] = atndx[index0[0][i]] + j; } } } else { isize = isize0; index = index0; } if (bCom) { snew(mass, top.atoms.nr); for (i = 0; i < top.atoms.nr; i++) { mass[i] = top.atoms.atom[i].m; } } else { mass = NULL; } flags = 0; if (bOX) { flags = flags | TRX_READ_X; outx = xvgropen(opt2fn("-ox", NFILE, fnm), bCom ? "Center of mass" : "Coordinate", output_env_get_xvgr_tlabel(oenv), "Coordinate (nm)", oenv); make_legend(outx, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv); } if (bOXT) { flags = flags | TRX_READ_X; status_out = open_trx(opt2fn("-oxt", NFILE, fnm), "w"); } if (bOV) { flags = flags | TRX_READ_V; outv = xvgropen(opt2fn("-ov", NFILE, fnm), bCom ? "Center of mass velocity" : "Velocity", output_env_get_xvgr_tlabel(oenv), "Velocity (nm/ps)", oenv); make_legend(outv, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv); } if (bOF) { flags = flags | TRX_READ_F; outf = xvgropen(opt2fn("-of", NFILE, fnm), "Force", output_env_get_xvgr_tlabel(oenv), "Force (kJ mol\\S-1\\N nm\\S-1\\N)", oenv); make_legend(outf, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv); } if (bOB) { outb = xvgropen(opt2fn("-ob", NFILE, fnm), "Box vector elements", output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); xvgr_legend(outb, 6, box_leg, oenv); } if (bOT) { bDum[XX] = FALSE; bDum[YY] = FALSE; bDum[ZZ] = FALSE; bDum[DIM] = TRUE; flags = flags | TRX_READ_V; outt = xvgropen(opt2fn("-ot", NFILE, fnm), "Temperature", output_env_get_xvgr_tlabel(oenv), "(K)", oenv); make_legend(outt, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv); } if (bEKT) { bDum[XX] = FALSE; bDum[YY] = FALSE; bDum[ZZ] = FALSE; bDum[DIM] = TRUE; flags = flags | TRX_READ_V; outekt = xvgropen(opt2fn("-ekt", NFILE, fnm), "Center of mass translation", output_env_get_xvgr_tlabel(oenv), "Energy (kJ mol\\S-1\\N)", oenv); make_legend(outekt, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv); } if (bEKR) { bDum[XX] = FALSE; bDum[YY] = FALSE; bDum[ZZ] = FALSE; bDum[DIM] = TRUE; flags = flags | TRX_READ_X | TRX_READ_V; outekr = xvgropen(opt2fn("-ekr", NFILE, fnm), "Center of mass rotation", output_env_get_xvgr_tlabel(oenv), "Energy (kJ mol\\S-1\\N)", oenv); make_legend(outekr, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv); } if (bVD) { flags = flags | TRX_READ_V; } if (bCV) { flags = flags | TRX_READ_X | TRX_READ_V; } if (bCF) { flags = flags | TRX_READ_X | TRX_READ_F; } if ((flags == 0) && !bOB) { fprintf(stderr, "Please select one or more output file options\n"); exit(0); } read_first_frame(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &fr, flags); if ((bOV || bOF) && fn2ftp(ftp2fn(efTRX, NFILE, fnm)) == efXTC) { gmx_fatal(FARGS, "Cannot extract velocities or forces since your input XTC file does not contain them."); } if (bCV || bCF) { snew(sumx, fr.natoms); } if (bCV) { snew(sumv, fr.natoms); } if (bCF) { snew(sumf, fr.natoms); } nr_xfr = 0; nr_vfr = 0; nr_ffr = 0; if (bCom && bPBC) { gpbc = gmx_rmpbc_init(&top.idef, ePBC, fr.natoms); } do { time = output_env_conv_time(oenv, fr.time); if (fr.bX && bNoJump && fr.bBox) { 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]); } } if (fr.bX && bCom && bPBC) { gmx_rmpbc_trxfr(gpbc, &fr); } if (bVD && fr.bV) { update_histo(isize[0], index[0], fr.v, &nvhisto, &vhisto, binwidth); } if (bOX && fr.bX) { print_data(outx, time, fr.x, mass, bCom, ngroups, isize, index, bDim, sffmt); } if (bOXT && fr.bX) { frout = fr; if (!frout.bAtoms) { frout.atoms = &top.atoms; frout.bAtoms = TRUE; } write_trx_x(status_out, &frout, mass, bCom, ngroups, isize, index); } if (bOV && fr.bV) { print_data(outv, time, fr.v, mass, bCom, ngroups, isize, index, bDim, sffmt); } if (bOF && fr.bF) { print_data(outf, time, fr.f, NULL, bCom, ngroups, isize, index, bDim, sffmt); } if (bOB && fr.bBox) { fprintf(outb, "\t%g", fr.time); fprintf(outb, sffmt6, fr.box[XX][XX], fr.box[YY][YY], fr.box[ZZ][ZZ], fr.box[YY][XX], fr.box[ZZ][XX], fr.box[ZZ][YY]); fprintf(outb, "\n"); } if (bOT && fr.bV) { fprintf(outt, " %g", time); for (i = 0; i < ngroups; i++) { fprintf(outt, sffmt, temp(fr.v, mass, isize[i], index[i])); } fprintf(outt, "\n"); } if (bEKT && fr.bV) { fprintf(outekt, " %g", time); for (i = 0; i < ngroups; i++) { fprintf(outekt, sffmt, ektrans(fr.v, mass, isize[i], index[i])); } fprintf(outekt, "\n"); } if (bEKR && fr.bX && fr.bV) { fprintf(outekr, " %g", time); for (i = 0; i < ngroups; i++) { fprintf(outekr, sffmt, ekrot(fr.x, fr.v, mass, isize[i], index[i])); } fprintf(outekr, "\n"); } if ((bCV || bCF) && fr.bX && (ctime < 0 || (fr.time >= ctime*0.999999 && fr.time <= ctime*1.000001))) { for (i = 0; i < fr.natoms; i++) { rvec_inc(sumx[i], fr.x[i]); } nr_xfr++; } if (bCV && fr.bV) { for (i = 0; i < fr.natoms; i++) { rvec_inc(sumv[i], fr.v[i]); } nr_vfr++; } if (bCF && fr.bF) { for (i = 0; i < fr.natoms; i++) { rvec_inc(sumf[i], fr.f[i]); } nr_ffr++; } } while (read_next_frame(oenv, status, &fr)); if (gpbc != NULL) { gmx_rmpbc_done(gpbc); } /* clean up a bit */ close_trj(status); if (bOX) { xvgrclose(outx); } if (bOXT) { close_trx(status_out); } if (bOV) { xvgrclose(outv); } if (bOF) { xvgrclose(outf); } if (bOB) { xvgrclose(outb); } if (bOT) { xvgrclose(outt); } if (bEKT) { xvgrclose(outekt); } if (bEKR) { xvgrclose(outekr); } if (bVD) { print_histo(opt2fn("-vd", NFILE, fnm), nvhisto, vhisto, binwidth, oenv); } if (bCV || bCF) { if (nr_xfr > 1) { if (ePBC != epbcNONE && !bNoJump) { fprintf(stderr, "\nWARNING: More than one frame was used for option -cv or -cf\n" "If atoms jump across the box you should use the -nojump or -ctime option\n\n"); } for (i = 0; i < isize[0]; i++) { svmul(1.0/nr_xfr, sumx[index[0][i]], sumx[index[0][i]]); } } else if (nr_xfr == 0) { fprintf(stderr, "\nWARNING: No coordinate frames found for option -cv or -cf\n\n"); } } if (bCV) { write_pdb_bfac(opt2fn("-cv", NFILE, fnm), opt2fn("-av", NFILE, fnm), "average velocity", &(top.atoms), ePBC, topbox, isize[0], index[0], nr_xfr, sumx, nr_vfr, sumv, bDim, scale, oenv); } if (bCF) { write_pdb_bfac(opt2fn("-cf", NFILE, fnm), opt2fn("-af", NFILE, fnm), "average force", &(top.atoms), ePBC, topbox, isize[0], index[0], nr_xfr, sumx, nr_ffr, sumf, bDim, scale, oenv); } /* view it */ view_all(oenv, NFILE, fnm); return 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); }
int gmx_traj(int argc,char *argv[]) { static char *desc[] = { "g_traj plots coordinates, velocities, forces and/or the box.", "With [TT]-com[tt] the coordinates, velocities and forces are", "calculated for the center of mass of each group.", "When [TT]-mol[tt] is set, the numbers in the index file are", "interpreted as molecule numbers and the same procedure as with", "[TT]-com[tt] is used for each molecule.[PAR]", "Option [TT]-ot[tt] plots the temperature of each group,", "provided velocities are present in the trajectory file.", "No corrections are made for constrained degrees of freedom!", "This implies [TT]-com[tt].[PAR]", "Options [TT]-ekt[tt] and [TT]-ekr[tt] plot the translational and", "rotational kinetic energy of each group,", "provided velocities are present in the trajectory file.", "This implies [TT]-com[tt].[PAR]", "Options [TT]-cv[tt] and [TT]-cf[tt] write the average velocities", "and average forces as temperature factors to a pdb file with", "the average coordinates. The temperature factors are scaled such", "that the maximum is 10. The scaling can be changed with the option", "[TT]-scale[tt]. To get the velocities or forces of one", "frame set both [TT]-b[tt] and [TT]-e[tt] to the time of", "desired frame. When averaging over frames you might need to use", "the [TT]-nojump[tt] option to obtain the correct average coordinates.", "If you select either of these option the average force and velocity", "for each atom are written to an xvg file as well", "(specified with [TT]-av[tt] or [TT]-af[tt]).[PAR]", "Option [TT]-vd[tt] computes a velocity distribution, i.e. the", "norm of the vector is plotted. In addition in the same graph", "the kinetic energy distribution is given." }; static bool bMol=FALSE,bCom=FALSE,bNoJump=FALSE; static bool bX=TRUE,bY=TRUE,bZ=TRUE,bNorm=FALSE; static int ngroups=1; static real scale=0,binwidth=1; t_pargs pa[] = { { "-com", FALSE, etBOOL, {&bCom}, "Plot data for the com of each group" }, { "-mol", FALSE, etBOOL, {&bMol}, "Index contains molecule numbers iso atom numbers" }, { "-nojump", FALSE, etBOOL, {&bNoJump}, "Remove jumps of atoms across the box" }, { "-x", FALSE, etBOOL, {&bX}, "Plot X-component" }, { "-y", FALSE, etBOOL, {&bY}, "Plot Y-component" }, { "-z", FALSE, etBOOL, {&bZ}, "Plot Z-component" }, { "-ng", FALSE, etINT, {&ngroups}, "Number of groups to consider" }, { "-len", FALSE, etBOOL, {&bNorm}, "Plot vector length" }, { "-bin", FALSE, etREAL, {&binwidth}, "Binwidth for velocity histogram (nm/ps)" }, { "-scale", FALSE, etREAL, {&scale}, "Scale factor for pdb output, 0 is autoscale" } }; FILE *outx=NULL,*outv=NULL,*outf=NULL,*outb=NULL,*outt=NULL; FILE *outekt=NULL,*outekr=NULL; t_topology top; int ePBC; real *mass,time; char title[STRLEN],*indexfn; t_trxframe fr,frout; int flags,nvhisto=0,*vhisto=NULL; rvec *xtop,*xp=NULL; rvec *sumxv=NULL,*sumv=NULL,*sumxf=NULL,*sumf=NULL; matrix topbox; int status,status_out=-1; int i,j,n; int nr_xfr,nr_vfr,nr_ffr; char **grpname; int *isize0,*isize; atom_id **index0,**index; atom_id *atndx; t_block *mols; bool bTop,bOX,bOXT,bOV,bOF,bOB,bOT,bEKT,bEKR,bCV,bCF; bool bDim[4],bDum[4],bVD; char *box_leg[6] = { "XX", "YY", "ZZ", "YX", "ZX", "ZY" }; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPS, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efXVG, "-ox", "coord.xvg", ffOPTWR }, { efTRX, "-oxt","coord.xtc", ffOPTWR }, { efXVG, "-ov", "veloc.xvg", ffOPTWR }, { efXVG, "-of", "force.xvg", ffOPTWR }, { efXVG, "-ob", "box.xvg", ffOPTWR }, { efXVG, "-ot", "temp.xvg", ffOPTWR }, { efXVG, "-ekt","ektrans.xvg", ffOPTWR }, { efXVG, "-ekr","ekrot.xvg", ffOPTWR }, { efXVG, "-vd", "veldist.xvg", ffOPTWR }, { efPDB, "-cv", "veloc.pdb", ffOPTWR }, { efPDB, "-cf", "force.pdb", ffOPTWR }, { efXVG, "-av", "all_veloc.xvg", ffOPTWR }, { efXVG, "-af", "all_force.xvg", ffOPTWR } }; #define NFILE asize(fnm) CopyRight(stderr,argv[0]); parse_common_args(&argc,argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW | PCA_BE_NICE, NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL); if (bMol) fprintf(stderr,"Interpreting indexfile entries as molecules.\n" "Using center of mass.\n"); bOX = opt2bSet("-ox",NFILE,fnm); bOXT = opt2bSet("-oxt",NFILE,fnm); bOV = opt2bSet("-ov",NFILE,fnm); bOF = opt2bSet("-of",NFILE,fnm); bOB = opt2bSet("-ob",NFILE,fnm); bOT = opt2bSet("-ot",NFILE,fnm); bEKT = opt2bSet("-ekt",NFILE,fnm); bEKR = opt2bSet("-ekr",NFILE,fnm); bCV = opt2bSet("-cv",NFILE,fnm) || opt2bSet("-av",NFILE,fnm); bCF = opt2bSet("-cf",NFILE,fnm) || opt2bSet("-af",NFILE,fnm); bVD = opt2bSet("-vd",NFILE,fnm) || opt2parg_bSet("-bin",asize(pa),pa); if (bMol || bOT || bEKT || bEKR) bCom = TRUE; bDim[XX] = bX; bDim[YY] = bY; bDim[ZZ] = bZ; bDim[DIM] = bNorm; bTop = read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC, &xtop,NULL,topbox, bCom && (bOX || bOXT || bOV || bOT || bEKT || bEKR)); sfree(xtop); if ((bMol || bCV || bCF) && !bTop) gmx_fatal(FARGS,"Need a run input file for option -mol, -cv or -cf"); if (bMol) indexfn = ftp2fn(efNDX,NFILE,fnm); else indexfn = ftp2fn_null(efNDX,NFILE,fnm); if (!(bCom && !bMol)) ngroups = 1; snew(grpname,ngroups); snew(isize0,ngroups); snew(index0,ngroups); get_index(&(top.atoms),indexfn,ngroups,isize0,index0,grpname); if (bMol) { mols=&(top.mols); atndx = mols->index; ngroups = isize0[0]; snew(isize,ngroups); snew(index,ngroups); for (i=0; i<ngroups; i++) { if (index0[0][i] < 0 || index0[0][i] >= mols->nr) gmx_fatal(FARGS,"Molecule index (%d) is out of range (%d-%d)", index0[0][i]+1,1,mols->nr); isize[i] = atndx[index0[0][i]+1] - atndx[index0[0][i]]; snew(index[i],isize[i]); for(j=0; j<isize[i]; j++) index[i][j] = atndx[index0[0][i]] + j; } } else { isize = isize0; index = index0; } if (bCom) { snew(mass,top.atoms.nr); for(i=0; i<top.atoms.nr; i++) mass[i] = top.atoms.atom[i].m; } else mass = NULL; flags = 0; if (bOX) { flags = flags | TRX_READ_X; outx = xvgropen(opt2fn("-ox",NFILE,fnm), bCom ? "Center of mass" : "Coordinate", xvgr_tlabel(),"Coordinate (nm)"); make_legend(outx,ngroups,isize0[0],index0[0],grpname,bCom,bMol,bDim); } if (bOXT) { flags = flags | TRX_READ_X; status_out = open_trx(opt2fn("-oxt",NFILE,fnm),"w"); } if (bOV) { flags = flags | TRX_READ_V; outv = xvgropen(opt2fn("-ov",NFILE,fnm), bCom ? "Center of mass velocity" : "Velocity", xvgr_tlabel(),"Velocity (nm/ps)"); make_legend(outv,ngroups,isize0[0],index0[0],grpname,bCom,bMol,bDim); } if (bOF) { flags = flags | TRX_READ_F; outf = xvgropen(opt2fn("-of",NFILE,fnm),"Force", xvgr_tlabel(),"Force (kJ mol\\S-1\\N nm\\S-1\\N)"); make_legend(outf,ngroups,isize0[0],index0[0],grpname,bCom,bMol,bDim); } if (bOB) { outb = xvgropen(opt2fn("-ob",NFILE,fnm),"Box vector elements", xvgr_tlabel(),"(nm)"); xvgr_legend(outb,6,box_leg); } if (bOT) { bDum[XX] = FALSE; bDum[YY] = FALSE; bDum[ZZ] = FALSE; bDum[DIM] = TRUE; flags = flags | TRX_READ_V; outt = xvgropen(opt2fn("-ot",NFILE,fnm),"Temperature",xvgr_tlabel(),"(K)"); make_legend(outt,ngroups,isize[0],index[0],grpname,bCom,bMol,bDum); } if (bEKT) { bDum[XX] = FALSE; bDum[YY] = FALSE; bDum[ZZ] = FALSE; bDum[DIM] = TRUE; flags = flags | TRX_READ_V; outekt = xvgropen(opt2fn("-ekt",NFILE,fnm),"Center of mass translation", xvgr_tlabel(),"Energy (kJ mol\\S-1\\N)"); make_legend(outekt,ngroups,isize[0],index[0],grpname,bCom,bMol,bDum); } if (bEKR) { bDum[XX] = FALSE; bDum[YY] = FALSE; bDum[ZZ] = FALSE; bDum[DIM] = TRUE; flags = flags | TRX_READ_X | TRX_READ_V; outekr = xvgropen(opt2fn("-ekr",NFILE,fnm),"Center of mass rotation", xvgr_tlabel(),"Energy (kJ mol\\S-1\\N)"); make_legend(outekr,ngroups,isize[0],index[0],grpname,bCom,bMol,bDum); } if (bVD) flags = flags | TRX_READ_V; if (bCV) flags = flags | TRX_READ_X | TRX_READ_V; if (bCF) flags = flags | TRX_READ_X | TRX_READ_F; if ((flags == 0) && !bOB) { fprintf(stderr,"Please select one or more output file options\n"); exit(0); } read_first_frame(&status,ftp2fn(efTRX,NFILE,fnm),&fr,flags); if (bCV) { snew(sumxv,fr.natoms); snew(sumv,fr.natoms); } if (bCF) { snew(sumxf,fr.natoms); snew(sumf,fr.natoms); } nr_xfr = 0; nr_vfr = 0; nr_ffr = 0; do { time = convert_time(fr.time); if (fr.bX && bNoJump && fr.bBox) { 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]); } if (fr.bX && bCom) rm_pbc(&(top.idef),ePBC,fr.natoms,fr.box,fr.x,fr.x); if (bVD && fr.bV) update_histo(isize[0],index[0],fr.v,&nvhisto,&vhisto,binwidth); if (bOX && fr.bX) print_data(outx,time,fr.x,mass,bCom,ngroups,isize,index,bDim); if (bOXT && fr.bX) { frout = fr; if (!frout.bAtoms) { frout.atoms = &top.atoms; frout.bAtoms = TRUE; } write_trx_x(status_out,&frout,mass,bCom,ngroups,isize,index); } if (bOV && fr.bV) print_data(outv,time,fr.v,mass,bCom,ngroups,isize,index,bDim); if (bOF && fr.bF) print_data(outf,time,fr.f,NULL,bCom,ngroups,isize,index,bDim); if (bOB && fr.bBox) fprintf(outb,"\t%g\t%g\t%g\t%g\t%g\t%g\t%g\n",fr.time, fr.box[XX][XX],fr.box[YY][YY],fr.box[ZZ][ZZ], fr.box[YY][XX],fr.box[ZZ][XX],fr.box[ZZ][YY]); if (bOT && fr.bV) { fprintf(outt," %g",time); for(i=0; i<ngroups; i++) fprintf(outt,"\t%g",temp(fr.v,mass,isize[i],index[i])); fprintf(outt,"\n"); } if (bEKT && fr.bV) { fprintf(outekt," %g",time); for(i=0; i<ngroups; i++) fprintf(outekt,"\t%g",ektrans(fr.v,mass,isize[i],index[i])); fprintf(outekt,"\n"); } if (bEKR && fr.bX && fr.bV) { fprintf(outekr," %g",time); for(i=0; i<ngroups; i++) fprintf(outekr,"\t%g",ekrot(fr.x,fr.v,mass,isize[i],index[i])); fprintf(outekr,"\n"); } if (bCV) { if (fr.bX) { for(i=0; i<fr.natoms; i++) rvec_inc(sumxv[i],fr.x[i]); nr_xfr++; } if (fr.bV) { for(i=0; i<fr.natoms; i++) rvec_inc(sumv[i],fr.v[i]); nr_vfr++; } } if (bCF) { if (fr.bX) { for(i=0; i<fr.natoms; i++) rvec_inc(sumxf[i],fr.x[i]); nr_xfr++; } if (fr.bF) { for(i=0; i<fr.natoms; i++) rvec_inc(sumf[i],fr.f[i]); nr_ffr++; } } } while(read_next_frame(status,&fr)); /* clean up a bit */ close_trj(status); if (bOX) fclose(outx); if (bOXT) close_trx(status_out); if (bOV) fclose(outv); if (bOF) fclose(outf); if (bOB) fclose(outb); if (bOT) fclose(outt); if (bEKT) fclose(outekt); if (bEKR) fclose(outekr); if (bVD) print_histo(opt2fn("-vd",NFILE,fnm),nvhisto,vhisto,binwidth); if ((bCV || bCF) && (nr_vfr>1 || nr_ffr>1) && !bNoJump) fprintf(stderr,"WARNING: More than one frame was used for option -cv or -cf\n" "If atoms jump across the box you should use the -nojump option\n"); if (bCV) write_pdb_bfac(opt2fn("-cv",NFILE,fnm), opt2fn("-av",NFILE,fnm),"average velocity",&(top.atoms), ePBC,topbox,isize[0],index[0],nr_xfr,sumxv, nr_vfr,sumv,bDim,scale); if (bCF) write_pdb_bfac(opt2fn("-cf",NFILE,fnm), opt2fn("-af",NFILE,fnm),"average force",&(top.atoms), ePBC,topbox,isize[0],index[0],nr_xfr,sumxf, nr_ffr,sumf,bDim,scale); /* view it */ view_all(NFILE, fnm); thanx(stderr); return 0; }