t_topology *read_top(const char *fn,int *ePBC) { int epbc,natoms; t_topology *top; snew(top,1); epbc = read_tpx_top(fn,NULL,NULL,&natoms,NULL,NULL,NULL,top); if (ePBC) *ePBC = epbc; return top; }
t_topology *read_top(const char *fn, int *ePBC) { int epbc, natoms; t_topology *top; snew(top, 1); epbc = read_tpx_top(fn, nullptr, nullptr, &natoms, nullptr, nullptr, top); if (ePBC) { *ePBC = epbc; } return top; }
t_topology *read_top(char *fn,int *ePBC) { int epbc,step,natoms; real t,lambda; t_topology *top; snew(top,1); epbc = read_tpx_top(fn,&step,&t,&lambda,NULL,NULL, &natoms,NULL,NULL,NULL,top); if (ePBC) *ePBC = epbc; return top; }
int gmx_polystat(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] plots static properties of polymers as a function of time", "and prints the average.[PAR]", "By default it determines the average end-to-end distance and radii", "of gyration of polymers. It asks for an index group and split this", "into molecules. The end-to-end distance is then determined using", "the first and the last atom in the index group for each molecules.", "For the radius of gyration the total and the three principal components", "for the average gyration tensor are written.", "With option [TT]-v[tt] the eigenvectors are written.", "With option [TT]-pc[tt] also the average eigenvalues of the individual", "gyration tensors are written.", "With option [TT]-i[tt] the mean square internal distances are", "written.[PAR]", "With option [TT]-p[tt] the persistence length is determined.", "The chosen index group should consist of atoms that are", "consecutively bonded in the polymer mainchains.", "The persistence length is then determined from the cosine of", "the angles between bonds with an index difference that is even,", "the odd pairs are not used, because straight polymer backbones", "are usually all trans and therefore only every second bond aligns.", "The persistence length is defined as number of bonds where", "the average cos reaches a value of 1/e. This point is determined", "by a linear interpolation of [LOG]<cos>[log]." }; static gmx_bool bMW = TRUE, bPC = FALSE; t_pargs pa[] = { { "-mw", FALSE, etBOOL, {&bMW}, "Use the mass weighting for radii of gyration" }, { "-pc", FALSE, etBOOL, {&bPC}, "Plot average eigenvalues" } }; t_filenm fnm[] = { { efTPR, nullptr, nullptr, ffREAD }, { efTRX, "-f", nullptr, ffREAD }, { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, "-o", "polystat", ffWRITE }, { efXVG, "-v", "polyvec", ffOPTWR }, { efXVG, "-p", "persist", ffOPTWR }, { efXVG, "-i", "intdist", ffOPTWR } }; #define NFILE asize(fnm) t_topology *top; gmx_output_env_t *oenv; int ePBC; int isize, *index, nmol, *molind, mol, nat_min = 0, nat_max = 0; char *grpname; t_trxstatus *status; real t; rvec *x, *bond = nullptr; matrix box; int natoms, i, j, frame, ind0, ind1, a, d, d2, ord[DIM] = {0}; dvec cm, sum_eig = {0, 0, 0}; double **gyr, **gyr_all, eig[DIM], **eigv; double sum_eed2, sum_eed2_tot, sum_gyro, sum_gyro_tot, sum_pers_tot; int *ninp = nullptr; double *sum_inp = nullptr, pers; double *intd, ymax, ymin; double mmol, m; char title[STRLEN]; FILE *out, *outv, *outp, *outi; const char *leg[8] = { "end to end", "<R\\sg\\N>", "<R\\sg\\N> eig1", "<R\\sg\\N> eig2", "<R\\sg\\N> eig3", "<R\\sg\\N eig1>", "<R\\sg\\N eig2>", "<R\\sg\\N eig3>" }; char **legp, buf[STRLEN]; gmx_rmpbc_t gpbc = nullptr; if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } snew(top, 1); ePBC = read_tpx_top(ftp2fn(efTPR, NFILE, fnm), nullptr, box, &natoms, nullptr, nullptr, top); fprintf(stderr, "Select a group of polymer mainchain atoms:\n"); get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname); snew(molind, top->mols.nr+1); nmol = 0; mol = -1; for (i = 0; i < isize; i++) { if (i == 0 || index[i] >= top->mols.index[mol+1]) { molind[nmol++] = i; do { mol++; } while (index[i] >= top->mols.index[mol+1]); } } molind[nmol] = i; nat_min = top->atoms.nr; nat_max = 0; for (mol = 0; mol < nmol; mol++) { nat_min = std::min(nat_min, molind[mol+1]-molind[mol]); nat_max = std::max(nat_max, molind[mol+1]-molind[mol]); } fprintf(stderr, "Group %s consists of %d molecules\n", grpname, nmol); fprintf(stderr, "Group size per molecule, min: %d atoms, max %d atoms\n", nat_min, nat_max); sprintf(title, "Size of %d polymers", nmol); out = xvgropen(opt2fn("-o", NFILE, fnm), title, output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); xvgr_legend(out, bPC ? 8 : 5, leg, oenv); if (opt2bSet("-v", NFILE, fnm)) { outv = xvgropen(opt2fn("-v", NFILE, fnm), "Principal components", output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); snew(legp, DIM*DIM); for (d = 0; d < DIM; d++) { for (d2 = 0; d2 < DIM; d2++) { sprintf(buf, "eig%d %c", d+1, 'x'+d2); legp[d*DIM+d2] = gmx_strdup(buf); } } xvgr_legend(outv, DIM*DIM, (const char**)legp, oenv); } else { outv = nullptr; } if (opt2bSet("-p", NFILE, fnm)) { outp = xvgropen(opt2fn("-p", NFILE, fnm), "Persistence length", output_env_get_xvgr_tlabel(oenv), "bonds", oenv); snew(bond, nat_max-1); snew(sum_inp, nat_min/2); snew(ninp, nat_min/2); } else { outp = nullptr; } if (opt2bSet("-i", NFILE, fnm)) { outi = xvgropen(opt2fn("-i", NFILE, fnm), "Internal distances", "n", "<R\\S2\\N(n)>/n (nm\\S2\\N)", oenv); i = index[molind[1]-1] - index[molind[0]]; /* Length of polymer -1 */ snew(intd, i); } else { intd = nullptr; outi = nullptr; } natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); snew(gyr, DIM); snew(gyr_all, DIM); snew(eigv, DIM); for (d = 0; d < DIM; d++) { snew(gyr[d], DIM); snew(gyr_all[d], DIM); snew(eigv[d], DIM); } frame = 0; sum_eed2_tot = 0; sum_gyro_tot = 0; sum_pers_tot = 0; gpbc = gmx_rmpbc_init(&top->idef, ePBC, natoms); do { gmx_rmpbc(gpbc, natoms, box, x); sum_eed2 = 0; for (d = 0; d < DIM; d++) { clear_dvec(gyr_all[d]); } if (bPC) { clear_dvec(sum_eig); } if (outp) { for (i = 0; i < nat_min/2; i++) { sum_inp[i] = 0; ninp[i] = 0; } } for (mol = 0; mol < nmol; mol++) { ind0 = molind[mol]; ind1 = molind[mol+1]; /* Determine end to end distance */ sum_eed2 += distance2(x[index[ind0]], x[index[ind1-1]]); /* Determine internal distances */ if (outi) { calc_int_dist(intd, x, index[ind0], index[ind1-1]); } /* Determine the radius of gyration */ clear_dvec(cm); for (d = 0; d < DIM; d++) { clear_dvec(gyr[d]); } mmol = 0; for (i = ind0; i < ind1; i++) { a = index[i]; if (bMW) { m = top->atoms.atom[a].m; } else { m = 1; } mmol += m; for (d = 0; d < DIM; d++) { cm[d] += m*x[a][d]; for (d2 = 0; d2 < DIM; d2++) { gyr[d][d2] += m*x[a][d]*x[a][d2]; } } } dsvmul(1/mmol, cm, cm); for (d = 0; d < DIM; d++) { for (d2 = 0; d2 < DIM; d2++) { gyr[d][d2] = gyr[d][d2]/mmol - cm[d]*cm[d2]; gyr_all[d][d2] += gyr[d][d2]; } } if (bPC) { gyro_eigen(gyr, eig, eigv, ord); for (d = 0; d < DIM; d++) { sum_eig[d] += eig[ord[d]]; } } if (outp) { for (i = ind0; i < ind1-1; i++) { rvec_sub(x[index[i+1]], x[index[i]], bond[i-ind0]); unitv(bond[i-ind0], bond[i-ind0]); } for (i = ind0; i < ind1-1; i++) { for (j = 0; (i+j < ind1-1 && j < nat_min/2); j += 2) { sum_inp[j] += iprod(bond[i-ind0], bond[i-ind0+j]); ninp[j]++; } } } } sum_eed2 /= nmol; sum_gyro = 0; for (d = 0; d < DIM; d++) { for (d2 = 0; d2 < DIM; d2++) { gyr_all[d][d2] /= nmol; } sum_gyro += gyr_all[d][d]; } gyro_eigen(gyr_all, eig, eigv, ord); fprintf(out, "%10.3f %8.4f %8.4f %8.4f %8.4f %8.4f", t*output_env_get_time_factor(oenv), std::sqrt(sum_eed2), sqrt(sum_gyro), std::sqrt(eig[ord[0]]), std::sqrt(eig[ord[1]]), std::sqrt(eig[ord[2]])); if (bPC) { for (d = 0; d < DIM; d++) { fprintf(out, " %8.4f", std::sqrt(sum_eig[d]/nmol)); } } fprintf(out, "\n"); if (outv) { fprintf(outv, "%10.3f", t*output_env_get_time_factor(oenv)); for (d = 0; d < DIM; d++) { for (d2 = 0; d2 < DIM; d2++) { fprintf(outv, " %6.3f", eigv[ord[d]][d2]); } } fprintf(outv, "\n"); } sum_eed2_tot += sum_eed2; sum_gyro_tot += sum_gyro; if (outp) { i = -1; for (j = 0; j < nat_min/2; j += 2) { sum_inp[j] /= ninp[j]; if (i == -1 && sum_inp[j] <= std::exp(-1.0)) { i = j; } } if (i == -1) { pers = j; } else { /* Do linear interpolation on a log scale */ pers = i - 2.0 + 2.0*(std::log(sum_inp[i-2]) + 1.0)/(std::log(sum_inp[i-2]) - std::log(sum_inp[i])); } fprintf(outp, "%10.3f %8.4f\n", t*output_env_get_time_factor(oenv), pers); sum_pers_tot += pers; } frame++; } while (read_next_x(oenv, status, &t, x, box)); gmx_rmpbc_done(gpbc); close_trx(status); xvgrclose(out); if (outv) { xvgrclose(outv); } if (outp) { xvgrclose(outp); } sum_eed2_tot /= frame; sum_gyro_tot /= frame; sum_pers_tot /= frame; fprintf(stdout, "\nAverage end to end distance: %.3f (nm)\n", std::sqrt(sum_eed2_tot)); fprintf(stdout, "\nAverage radius of gyration: %.3f (nm)\n", std::sqrt(sum_gyro_tot)); if (opt2bSet("-p", NFILE, fnm)) { fprintf(stdout, "\nAverage persistence length: %.2f bonds\n", sum_pers_tot); } /* Handle printing of internal distances. */ if (outi) { if (output_env_get_print_xvgr_codes(oenv)) { fprintf(outi, "@ xaxes scale Logarithmic\n"); } ymax = -1; ymin = 1e300; j = index[molind[1]-1] - index[molind[0]]; /* Polymer length -1. */ for (i = 0; i < j; i++) { intd[i] /= (i + 1) * frame * nmol; if (intd[i] > ymax) { ymax = intd[i]; } if (intd[i] < ymin) { ymin = intd[i]; } } xvgr_world(outi, 1, ymin, j, ymax, oenv); for (i = 0; i < j; i++) { fprintf(outi, "%d %8.4f\n", i+1, intd[i]); } xvgrclose(outi); } do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy"); if (opt2bSet("-v", NFILE, fnm)) { do_view(oenv, opt2fn("-v", NFILE, fnm), "-nxy"); } if (opt2bSet("-p", NFILE, fnm)) { do_view(oenv, opt2fn("-p", NFILE, fnm), "-nxy"); } return 0; }
void set_file(t_x11 *x11,t_manager *man,char *trajectory,char *status) { gmx_atomprop_t aps; char buf[256],quote[256]; t_tpxheader sh; t_atoms *at; bool *bB; int i,idum; real rdum; read_tpxheader(status,&sh,TRUE,NULL,NULL); snew(man->ix,sh.natoms); snew(man->zz,sh.natoms); snew(man->col,sh.natoms); snew(man->size,sh.natoms); snew(man->vdw,sh.natoms); snew(man->bLabel,sh.natoms); snew(man->bVis,sh.natoms); for(i=0; (i<sh.natoms); i++) man->bVis[i]=FALSE; man->bPbc=FALSE; snew(man->szLab,sh.natoms); snew(man->bHydro,sh.natoms); snew(bB,sh.natoms); read_tpx_top(status,&(man->step),&(man->time),&rdum,NULL,man->box, &man->natom,NULL,NULL,NULL,&man->top); man->natom= read_first_x(&man->status,trajectory,&(man->time),&(man->x),man->box); man->trajfile=strdup(trajectory); if (man->natom > man->top.atoms.nr) gmx_fatal(FARGS,"Topology %s (%d atoms) and trajectory %s (%d atoms) " "do not match",status,man->top.atoms.nr, trajectory,man->natom); cool_quote(quote,255,NULL); sprintf(buf,"%s: %s",*man->top.name,quote); man->title.text = strdup(buf); man->view = init_view(man->box); at = &(man->top.atoms); aps = gmx_atomprop_init(); for(i=0; (i<man->natom); i++) { char *aname=*(at->atomname[i]); int resnr=at->atom[i].resnr; man->col[i]=Type2Color(aname); snew(man->szLab[i],20); sprintf(man->szLab[i],"%s%d, %s",*(at->resname[resnr]),resnr+1,aname); man->bHydro[i]=(toupper(aname[0])=='H'); if ( man->bHydro[i] ) man->vdw[i]=0; else if (!gmx_atomprop_query(aps,epropVDW, *(at->resname[resnr]),aname, &(man->vdw[i]))) man->vdw[i] = 0; } gmx_atomprop_destroy(aps); add_bpl(man,&(man->top.idef),bB); for(i=0; (i<man->natom); i++) if (!bB[i]) add_object(man,eOSingle,(atom_id) i,0); sfree(bB); ExposeWin(x11->disp,man->molw->wd.self); }
void set_file(t_x11 *x11, t_manager *man, const char *trajectory, const char *status) { gmx_atomprop_t aps; t_tpxheader sh; t_atoms *at; bool *bB; int i; read_tpxheader(status, &sh, true); snew(man->ix, sh.natoms); snew(man->zz, sh.natoms); snew(man->col, sh.natoms); snew(man->size, sh.natoms); snew(man->vdw, sh.natoms); snew(man->bLabel, sh.natoms); snew(man->bVis, sh.natoms); for (i = 0; (i < sh.natoms); i++) { man->bVis[i] = false; } man->bPbc = false; snew(man->szLab, sh.natoms); snew(man->bHydro, sh.natoms); snew(bB, sh.natoms); read_tpx_top(status, nullptr, man->box, &man->natom, nullptr, nullptr, &man->top); man->gpbc = gmx_rmpbc_init(&man->top.idef, -1, man->natom); man->natom = read_first_x(man->oenv, &man->status, trajectory, &(man->time), &(man->x), man->box); man->trajfile = gmx_strdup(trajectory); if (man->natom > man->top.atoms.nr) { gmx_fatal(FARGS, "Topology %s (%d atoms) and trajectory %s (%d atoms) " "do not match", status, man->top.atoms.nr, trajectory, man->natom); } man->title.text = gmx_strdup(gmx::formatString("%s: %s", *man->top.name, gmx::getCoolQuote().c_str()).c_str()); man->view = init_view(man->box); at = &(man->top.atoms); aps = gmx_atomprop_init(); for (i = 0; (i < man->natom); i++) { char *aname = *(at->atomname[i]); t_resinfo *ri = &at->resinfo[at->atom[i].resind]; man->col[i] = Type2Color(aname); snew(man->szLab[i], 20); if (ri->ic != ' ') { std::sprintf(man->szLab[i], "%s%d%c, %s", *ri->name, ri->nr, ri->ic, aname); } else { std::sprintf(man->szLab[i], "%s%d, %s", *ri->name, ri->nr, aname); } man->bHydro[i] = (toupper(aname[0]) == 'H'); if (man->bHydro[i]) { man->vdw[i] = 0; } else if (!gmx_atomprop_query(aps, epropVDW, *ri->name, aname, &(man->vdw[i]))) { man->vdw[i] = 0; } } gmx_atomprop_destroy(aps); add_bpl(man, &(man->top.idef), bB); for (i = 0; (i < man->natom); i++) { if (!bB[i]) { add_object(man, eOSingle, (int) i, 0); } } sfree(bB); ExposeWin(x11->disp, man->molw->wd.self); }
int gmx_spol(int argc, char *argv[]) { t_topology *top; t_inputrec *ir; t_atom *atom; t_trxstatus *status; int nrefat, natoms, nf, ntot; real t; rvec *x, xref, trial, dx = {0}, dip, dir; matrix box; FILE *fp; int *isize, nrefgrp; atom_id **index, *molindex; char **grpname; real rmin2, rmax2, rcut, rcut2, rdx2 = 0, rtry2, qav, q, dip2, invbw; int nbin, i, m, mol, a0, a1, a, d; double sdip, sdip2, sinp, sdinp, nmol; int *hist; t_pbc pbc; gmx_rmpbc_t gpbc = NULL; const char *desc[] = { "[THISMODULE] analyzes dipoles around a solute; it is especially useful", "for polarizable water. A group of reference atoms, or a center", "of mass reference (option [TT]-com[tt]) and a group of solvent", "atoms is required. The program splits the group of solvent atoms", "into molecules. For each solvent molecule the distance to the", "closest atom in reference group or to the COM is determined.", "A cumulative distribution of these distances is plotted.", "For each distance between [TT]-rmin[tt] and [TT]-rmax[tt]", "the inner product of the distance vector", "and the dipole of the solvent molecule is determined.", "For solvent molecules with net charge (ions), the net charge of the ion", "is subtracted evenly from all atoms in the selection of each ion.", "The average of these dipole components is printed.", "The same is done for the polarization, where the average dipole is", "subtracted from the instantaneous dipole. The magnitude of the average", "dipole is set with the option [TT]-dip[tt], the direction is defined", "by the vector from the first atom in the selected solvent group", "to the midpoint between the second and the third atom." }; output_env_t oenv; static gmx_bool bCom = FALSE; static int srefat = 1; static real rmin = 0.0, rmax = 0.32, refdip = 0, bw = 0.01; t_pargs pa[] = { { "-com", FALSE, etBOOL, {&bCom}, "Use the center of mass as the reference postion" }, { "-refat", FALSE, etINT, {&srefat}, "The reference atom of the solvent molecule" }, { "-rmin", FALSE, etREAL, {&rmin}, "Maximum distance (nm)" }, { "-rmax", FALSE, etREAL, {&rmax}, "Maximum distance (nm)" }, { "-dip", FALSE, etREAL, {&refdip}, "The average dipole (D)" }, { "-bw", FALSE, etREAL, {&bw}, "The bin width" } }; t_filenm fnm[] = { { efTRX, NULL, NULL, ffREAD }, { efTPR, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efXVG, NULL, "scdist", ffWRITE } }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } snew(top, 1); snew(ir, 1); read_tpx_top(ftp2fn(efTPR, NFILE, fnm), ir, box, &natoms, NULL, NULL, NULL, top); /* get index groups */ printf("Select a group of reference particles and a solvent group:\n"); snew(grpname, 2); snew(index, 2); snew(isize, 2); get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 2, isize, index, grpname); if (bCom) { nrefgrp = 1; nrefat = isize[0]; } else { nrefgrp = isize[0]; nrefat = 1; } spol_atom2molindex(&(isize[1]), index[1], &(top->mols)); srefat--; /* initialize reading trajectory: */ natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); rcut = 0.99*std::sqrt(max_cutoff2(ir->ePBC, box)); if (rcut == 0) { rcut = 10*rmax; } rcut2 = sqr(rcut); invbw = 1/bw; nbin = static_cast<int>(rcut*invbw)+2; snew(hist, nbin); rmin2 = sqr(rmin); rmax2 = sqr(rmax); nf = 0; ntot = 0; sdip = 0; sdip2 = 0; sinp = 0; sdinp = 0; molindex = top->mols.index; atom = top->atoms.atom; gpbc = gmx_rmpbc_init(&top->idef, ir->ePBC, natoms); /* start analysis of trajectory */ do { /* make molecules whole again */ gmx_rmpbc(gpbc, natoms, box, x); set_pbc(&pbc, ir->ePBC, box); if (bCom) { calc_com_pbc(nrefat, top, x, &pbc, index[0], xref, ir->ePBC); } for (m = 0; m < isize[1]; m++) { mol = index[1][m]; a0 = molindex[mol]; a1 = molindex[mol+1]; for (i = 0; i < nrefgrp; i++) { pbc_dx(&pbc, x[a0+srefat], bCom ? xref : x[index[0][i]], trial); rtry2 = norm2(trial); if (i == 0 || rtry2 < rdx2) { copy_rvec(trial, dx); rdx2 = rtry2; } } if (rdx2 < rcut2) { hist[static_cast<int>(std::sqrt(rdx2)*invbw)+1]++; } if (rdx2 >= rmin2 && rdx2 < rmax2) { unitv(dx, dx); clear_rvec(dip); qav = 0; for (a = a0; a < a1; a++) { qav += atom[a].q; } qav /= (a1 - a0); for (a = a0; a < a1; a++) { q = atom[a].q - qav; for (d = 0; d < DIM; d++) { dip[d] += q*x[a][d]; } } for (d = 0; d < DIM; d++) { dir[d] = -x[a0][d]; } for (a = a0+1; a < a0+3; a++) { for (d = 0; d < DIM; d++) { dir[d] += 0.5*x[a][d]; } } unitv(dir, dir); svmul(ENM2DEBYE, dip, dip); dip2 = norm2(dip); sdip += std::sqrt(dip2); sdip2 += dip2; for (d = 0; d < DIM; d++) { sinp += dx[d]*dip[d]; sdinp += dx[d]*(dip[d] - refdip*dir[d]); } ntot++; } } nf++; } while (read_next_x(oenv, status, &t, x, box)); gmx_rmpbc_done(gpbc); /* clean up */ sfree(x); close_trj(status); fprintf(stderr, "Average number of molecules within %g nm is %.1f\n", rmax, static_cast<real>(ntot)/nf); if (ntot > 0) { sdip /= ntot; sdip2 /= ntot; sinp /= ntot; sdinp /= ntot; fprintf(stderr, "Average dipole: %f (D), std.dev. %f\n", sdip, std::sqrt(sdip2-sqr(sdip))); fprintf(stderr, "Average radial component of the dipole: %f (D)\n", sinp); fprintf(stderr, "Average radial component of the polarization: %f (D)\n", sdinp); } fp = xvgropen(opt2fn("-o", NFILE, fnm), "Cumulative solvent distribution", "r (nm)", "molecules", oenv); nmol = 0; for (i = 0; i <= nbin; i++) { nmol += hist[i]; fprintf(fp, "%g %g\n", i*bw, nmol/nf); } xvgrclose(fp); do_view(oenv, opt2fn("-o", NFILE, fnm), NULL); return 0; }
int gmx_dipoles(int argc,char *argv[]) { const char *desc[] = { "[TT]g_dipoles[tt] computes the total dipole plus fluctuations of a simulation", "system. From this you can compute e.g. the dielectric constant for", "low-dielectric media.", "For molecules with a net charge, the net charge is subtracted at", "center of mass of the molecule.[PAR]", "The file [TT]Mtot.xvg[tt] contains the total dipole moment of a frame, the", "components as well as the norm of the vector.", "The file [TT]aver.xvg[tt] contains < |Mu|^2 > and |< Mu >|^2 during the", "simulation.", "The file [TT]dipdist.xvg[tt] contains the distribution of dipole moments during", "the simulation", "The value of [TT]-mumax[tt] is used as the highest value in the distribution graph.[PAR]", "Furthermore, the dipole autocorrelation function will be computed when", "option [TT]-corr[tt] is used. The output file name is given with the [TT]-c[tt]", "option.", "The correlation functions can be averaged over all molecules", "([TT]mol[tt]), plotted per molecule separately ([TT]molsep[tt])", "or it can be computed over the total dipole moment of the simulation box", "([TT]total[tt]).[PAR]", "Option [TT]-g[tt] produces a plot of the distance dependent Kirkwood", "G-factor, as well as the average cosine of the angle between the dipoles", "as a function of the distance. The plot also includes gOO and hOO", "according to Nymand & Linse, J. Chem. Phys. 112 (2000) pp 6386-6395. In the same plot, ", "we also include the energy per scale computed by taking the inner product of", "the dipoles divided by the distance to the third power.[PAR]", "[PAR]", "EXAMPLES[PAR]", "[TT]g_dipoles -corr mol -P 1 -o dip_sqr -mu 2.273 -mumax 5.0[tt][PAR]", "This will calculate the autocorrelation function of the molecular", "dipoles using a first order Legendre polynomial of the angle of the", "dipole vector and itself a time t later. For this calculation 1001", "frames will be used. Further, the dielectric constant will be calculated", "using an [GRK]epsilon[grk]RF of infinity (default), temperature of 300 K (default) and", "an average dipole moment of the molecule of 2.273 (SPC). For the", "distribution function a maximum of 5.0 will be used." }; real mu_max=5, mu_aver=-1,rcmax=0; real epsilonRF=0.0, temp=300; gmx_bool bAverCorr=FALSE,bMolCorr=FALSE,bPairs=TRUE,bPhi=FALSE; const char *corrtype[]={NULL, "none", "mol", "molsep", "total", NULL}; const char *axtitle="Z"; int nslices = 10; /* nr of slices defined */ int skip=0,nFA=0,nFB=0,ncos=1; int nlevels=20,ndegrees=90; output_env_t oenv; t_pargs pa[] = { { "-mu", FALSE, etREAL, {&mu_aver}, "dipole of a single molecule (in Debye)" }, { "-mumax", FALSE, etREAL, {&mu_max}, "max dipole in Debye (for histogram)" }, { "-epsilonRF",FALSE, etREAL, {&epsilonRF}, "epsilon of the reaction field used during the simulation, needed for dielectric constant calculation. WARNING: 0.0 means infinity (default)" }, { "-skip", FALSE, etINT, {&skip}, "Skip steps in the output (but not in the computations)" }, { "-temp", FALSE, etREAL, {&temp}, "Average temperature of the simulation (needed for dielectric constant calculation)" }, { "-corr", FALSE, etENUM, {corrtype}, "Correlation function to calculate" }, { "-pairs", FALSE, etBOOL, {&bPairs}, "Calculate |cos [GRK]theta[grk]| between all pairs of molecules. May be slow" }, { "-ncos", FALSE, etINT, {&ncos}, "Must be 1 or 2. Determines whether the <cos> is computed between all molecules in one group, or between molecules in two different groups. This turns on the [TT]-gkr[tt] flag." }, { "-axis", FALSE, etSTR, {&axtitle}, "Take the normal on the computational box in direction X, Y or Z." }, { "-sl", FALSE, etINT, {&nslices}, "Divide the box in #nr slices." }, { "-gkratom", FALSE, etINT, {&nFA}, "Use the n-th atom of a molecule (starting from 1) to calculate the distance between molecules rather than the center of charge (when 0) in the calculation of distance dependent Kirkwood factors" }, { "-gkratom2", FALSE, etINT, {&nFB}, "Same as previous option in case ncos = 2, i.e. dipole interaction between two groups of molecules" }, { "-rcmax", FALSE, etREAL, {&rcmax}, "Maximum distance to use in the dipole orientation distribution (with ncos == 2). If zero, a criterion based on the box length will be used." }, { "-phi", FALSE, etBOOL, {&bPhi}, "Plot the 'torsion angle' defined as the rotation of the two dipole vectors around the distance vector between the two molecules in the [TT].xpm[tt] file from the [TT]-cmap[tt] option. By default the cosine of the angle between the dipoles is plotted." }, { "-nlevels", FALSE, etINT, {&nlevels}, "Number of colors in the cmap output" }, { "-ndegrees", FALSE, etINT, {&ndegrees}, "Number of divisions on the [IT]y[it]-axis in the cmap output (for 180 degrees)" } }; int *gnx; int nFF[2]; atom_id **grpindex; char **grpname=NULL; gmx_bool bCorr,bQuad,bGkr,bMU,bSlab; t_filenm fnm[] = { { efEDR, "-en", NULL, ffOPTRD }, { efTRX, "-f", NULL, ffREAD }, { efTPX, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efXVG, "-o", "Mtot", ffWRITE }, { efXVG, "-eps", "epsilon", ffWRITE }, { efXVG, "-a", "aver", ffWRITE }, { efXVG, "-d", "dipdist", ffWRITE }, { efXVG, "-c", "dipcorr", ffOPTWR }, { efXVG, "-g", "gkr", ffOPTWR }, { efXVG, "-adip","adip", ffOPTWR }, { efXVG, "-dip3d", "dip3d", ffOPTWR }, { efXVG, "-cos", "cosaver", ffOPTWR }, { efXPM, "-cmap","cmap", ffOPTWR }, { efXVG, "-q", "quadrupole", ffOPTWR }, { efXVG, "-slab","slab", ffOPTWR } }; #define NFILE asize(fnm) int npargs; t_pargs *ppa; t_topology *top; int ePBC; int k,natoms; matrix box; CopyRight(stderr,argv[0]); npargs = asize(pa); ppa = add_acf_pargs(&npargs,pa); parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE, NFILE,fnm,npargs,ppa,asize(desc),desc,0,NULL,&oenv); printf("Using %g as mu_max and %g as the dipole moment.\n", mu_max,mu_aver); if (epsilonRF == 0.0) printf("WARNING: EpsilonRF = 0.0, this really means EpsilonRF = infinity\n"); bMU = opt2bSet("-en",NFILE,fnm); if (bMU) gmx_fatal(FARGS,"Due to new ways of treating molecules in GROMACS the total dipole in the energy file may be incorrect, because molecules can be split over periodic boundary conditions before computing the dipole. Please use your trajectory file."); bQuad = opt2bSet("-q",NFILE,fnm); bGkr = opt2bSet("-g",NFILE,fnm); if (opt2parg_bSet("-ncos",asize(pa),pa)) { if ((ncos != 1) && (ncos != 2)) gmx_fatal(FARGS,"ncos has to be either 1 or 2"); bGkr = TRUE; } bSlab = (opt2bSet("-slab",NFILE,fnm) || opt2parg_bSet("-sl",asize(pa),pa) || opt2parg_bSet("-axis",asize(pa),pa)); if (bMU) { bAverCorr = TRUE; if (bQuad) { printf("WARNING: Can not determine quadrupoles from energy file\n"); bQuad = FALSE; } if (bGkr) { printf("WARNING: Can not determine Gk(r) from energy file\n"); bGkr = FALSE; ncos = 1; } if (mu_aver == -1) printf("WARNING: Can not calculate Gk and gk, since you did\n" " not enter a valid dipole for the molecules\n"); } snew(top,1); ePBC = read_tpx_top(ftp2fn(efTPX,NFILE,fnm),NULL,box, &natoms,NULL,NULL,NULL,top); snew(gnx,ncos); snew(grpname,ncos); snew(grpindex,ncos); get_index(&top->atoms,ftp2fn_null(efNDX,NFILE,fnm), ncos,gnx,grpindex,grpname); for(k=0; (k<ncos); k++) { dipole_atom2molindex(&gnx[k],grpindex[k],&(top->mols)); neutralize_mols(gnx[k],grpindex[k],&(top->mols),top->atoms.atom); } nFF[0] = nFA; nFF[1] = nFB; do_dip(top,ePBC,det(box),ftp2fn(efTRX,NFILE,fnm), opt2fn("-o",NFILE,fnm),opt2fn("-eps",NFILE,fnm), opt2fn("-a",NFILE,fnm),opt2fn("-d",NFILE,fnm), opt2fn_null("-cos",NFILE,fnm), opt2fn_null("-dip3d",NFILE,fnm),opt2fn_null("-adip",NFILE,fnm), bPairs,corrtype[0], opt2fn("-c",NFILE,fnm), bGkr, opt2fn("-g",NFILE,fnm), bPhi, &nlevels, ndegrees, ncos, opt2fn("-cmap",NFILE,fnm),rcmax, bQuad, opt2fn("-q",NFILE,fnm), bMU, opt2fn("-en",NFILE,fnm), gnx,grpindex,mu_max,mu_aver,epsilonRF,temp,nFF,skip, bSlab,nslices,axtitle,opt2fn("-slab",NFILE,fnm),oenv); do_view(oenv,opt2fn("-o",NFILE,fnm),"-autoscale xy -nxy"); do_view(oenv,opt2fn("-eps",NFILE,fnm),"-autoscale xy -nxy"); do_view(oenv,opt2fn("-a",NFILE,fnm),"-autoscale xy -nxy"); do_view(oenv,opt2fn("-d",NFILE,fnm),"-autoscale xy"); do_view(oenv,opt2fn("-c",NFILE,fnm),"-autoscale xy"); thanx(stderr); return 0; }
static void init_gmx(t_x11 *x11, char *program, int nfile, t_filenm fnm[], const output_env_t oenv) { Pixmap pm; t_gmx *gmx; XSizeHints hints; int w0, h0; int natom, natom_trx; t_topology top; int ePBC; matrix box; t_trxframe fr; t_trxstatus *status; char quote[256]; snew(gmx, 1); snew(gmx->wd, 1); ePBC = read_tpx_top(ftp2fn(efTPR, nfile, fnm), NULL, box, &natom, NULL, NULL, &top); read_first_frame(oenv, &status, ftp2fn(efTRX, nfile, fnm), &fr, TRX_DONT_SKIP); close_trx(status); natom_trx = fr.natoms; /* Creates a simple window */ w0 = DisplayWidth(x11->disp, x11->screen)-132; h0 = DisplayHeight(x11->disp, x11->screen)-140; bromacs(quote, 255); InitWin(gmx->wd, 0, 0, w0, h0, 3, quote); gmx->wd->self = XCreateSimpleWindow(x11->disp, x11->root, gmx->wd->x, gmx->wd->y, gmx->wd->width, gmx->wd->height, gmx->wd->bwidth, WHITE, BLACK); pm = XCreatePixmapFromBitmapData(x11->disp, x11->root, (char *)gromacs_bits, gromacs_width, gromacs_height, WHITE, BLACK, 1); hints.flags = PMinSize; hints.min_width = 2*EWIDTH+40; hints.min_height = EHEIGHT+LDHEIGHT+LEGHEIGHT+40; XSetStandardProperties(x11->disp, gmx->wd->self, gmx->wd->text, program, pm, NULL, 0, &hints); x11->RegisterCallback(x11, gmx->wd->self, x11->root, MainCallBack, gmx); x11->SetInputMask(x11, gmx->wd->self, ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask | ExposureMask | StructureNotifyMask); /* The order of creating windows is important here! */ /* Manager */ gmx->man = init_man(x11, gmx->wd->self, 0, 0, 1, 1, WHITE, BLACK, ePBC, box, oenv); gmx->logo = init_logo(x11, gmx->wd->self, false); /* Now put all windows in the proper place */ move_gmx(x11, gmx, w0, h0, false); XMapWindow(x11->disp, gmx->wd->self); map_man(x11, gmx->man); /* Pull Down menu */ gmx->pd = init_pd(x11, gmx->wd->self, gmx->wd->width, x11->fg, x11->bg, MSIZE, gmx_pd_size, gmx_pd, MenuTitle); /* Dialogs & Filters */ gmx->filter = init_filter(&(top.atoms), ftp2fn_null(efNDX, nfile, fnm), natom_trx); init_dlgs(x11, gmx); /* Now do file operations */ set_file(x11, gmx->man, ftp2fn(efTRX, nfile, fnm), ftp2fn(efTPR, nfile, fnm)); ShowDlg(gmx->dlgs[edFilter]); }