static void pukeit(const char *db, const char *defstring, char *retstring, int retsize, int *cqnum) { FILE *fp; char **help; int i, nhlp; gmx_rng_t rng; if (be_cool() && ((fp = low_libopen(db, FALSE)) != NULL)) { nhlp = fget_lines(fp, &help); /* for libraries we can use the low-level close routines */ gmx_ffclose(fp); rng = gmx_rng_init(gmx_rng_make_seed()); *cqnum = static_cast<int>(nhlp*gmx_rng_uniform_real(rng)); gmx_rng_destroy(rng); if (strlen(help[*cqnum]) >= STRLEN) { help[*cqnum][STRLEN-1] = '\0'; } strncpy(retstring, help[*cqnum], retsize); for (i = 0; (i < nhlp); i++) { sfree(help[i]); } sfree(help); } else { *cqnum = -1; strncpy(retstring, defstring, retsize); } }
static void line() { gmx_rng_t rng; gmx_stats_t line; int i, dy, ok, n = 1000; real y, a, b, da, db, aver, sigma, error, chi2, R, rfit; const real a0 = 0.23, b0 = 2.7; FILE *fp; for (dy = 0; (dy < 2); dy++) { rng = gmx_rng_init(13); line = gmx_stats_init(); for (i = 0; (i < n); i++) { y = a0*i+b0+50*(gmx_rng_uniform_real(rng)-0.5); if ((ok = gmx_stats_add_point(line, i, y, 0, dy*0.1)) != estatsOK) { fprintf(stderr, "%s\n", gmx_stats_message(ok)); } } /* Line with slope test */ if ((ok = gmx_stats_get_ab(line, elsqWEIGHT_NONE, &a, &b, &da, &db, &chi2, &rfit)) != estatsOK) { fprintf(stderr, "%s\n", gmx_stats_message(ok)); } if ((ok = gmx_stats_get_corr_coeff(line, &R)) != estatsOK) { fprintf(stderr, "%s\n", gmx_stats_message(ok)); } if (dy == 0) { fp = fopen("line0.xvg", "w"); } else { fp = fopen("line1.xvg", "w"); } if ((ok = gmx_stats_dump_xy(line, fp)) != estatsOK) { fprintf(stderr, "%s\n", gmx_stats_message(ok)); } fclose(fp); printf("Line with eqn. y = %gx + %g with noise%s\n", a0, b0, (dy == 0) ? "" : " and uncertainties"); printf("Found: a = %g +/- %g, b = %g +/- %g\n", a, da, b, db); if ((ok = gmx_stats_done(line)) != estatsOK) { fprintf(stderr, "%s\n", gmx_stats_message(ok)); } gmx_rng_destroy(rng); } }
void maxwell_speed(real tempi, unsigned int seed, gmx_mtop_t *mtop, rvec v[]) { gmx_rng_t rng; if (seed == 0) { seed = gmx_rng_make_seed(); fprintf(stderr, "Using random seed %u for generating velocities\n", seed); } rng = gmx_rng_init(seed); low_mspeed(tempi, mtop, v, rng); gmx_rng_destroy(rng); }
void maxwell_speed(real tempi,int seed,gmx_mtop_t *mtop, rvec v[]) { atom_id *dummy; int i; gmx_rng_t rng; if (seed == -1) { seed = make_seed(); fprintf(stderr,"Using random seed %d for generating velocities\n",seed); } rng = gmx_rng_init(seed); low_mspeed(tempi,mtop,v,rng); gmx_rng_destroy(rng); }
int gmx_genion(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] randomly replaces solvent molecules with monoatomic ions.", "The group of solvent molecules should be continuous and all molecules", "should have the same number of atoms.", "The user should add the ion molecules to the topology file or use", "the [TT]-p[tt] option to automatically modify the topology.[PAR]", "The ion molecule type, residue and atom names in all force fields", "are the capitalized element names without sign. This molecule name", "should be given with [TT]-pname[tt] or [TT]-nname[tt], and the", "[TT][molecules][tt] section of your topology updated accordingly,", "either by hand or with [TT]-p[tt]. Do not use an atom name instead!", "[PAR]Ions which can have multiple charge states get the multiplicity", "added, without sign, for the uncommon states only.[PAR]", "For larger ions, e.g. sulfate we recommended using [gmx-insert-molecules]." }; const char *bugs[] = { "If you specify a salt concentration existing ions are not taken into " "account. In effect you therefore specify the amount of salt to be added.", }; static int p_num = 0, n_num = 0, p_q = 1, n_q = -1; static const char *p_name = "NA", *n_name = "CL"; static real rmin = 0.6, conc = 0; static int seed = 1993; static gmx_bool bNeutral = FALSE; static t_pargs pa[] = { { "-np", FALSE, etINT, {&p_num}, "Number of positive ions" }, { "-pname", FALSE, etSTR, {&p_name}, "Name of the positive ion" }, { "-pq", FALSE, etINT, {&p_q}, "Charge of the positive ion" }, { "-nn", FALSE, etINT, {&n_num}, "Number of negative ions" }, { "-nname", FALSE, etSTR, {&n_name}, "Name of the negative ion" }, { "-nq", FALSE, etINT, {&n_q}, "Charge of the negative ion" }, { "-rmin", FALSE, etREAL, {&rmin}, "Minimum distance between ions" }, { "-seed", FALSE, etINT, {&seed}, "Seed for random number generator" }, { "-conc", FALSE, etREAL, {&conc}, "Specify salt concentration (mol/liter). This will add sufficient ions to reach up to the specified concentration as computed from the volume of the cell in the input [REF].tpr[ref] file. Overrides the [TT]-np[tt] and [TT]-nn[tt] options." }, { "-neutral", FALSE, etBOOL, {&bNeutral}, "This option will add enough ions to neutralize the system. These ions are added on top of those specified with [TT]-np[tt]/[TT]-nn[tt] or [TT]-conc[tt]. "} }; t_topology top; rvec *x, *v; real vol, qtot; matrix box; t_atoms atoms; t_pbc pbc; int *repl, ePBC; atom_id *index; char *grpname; gmx_bool *bSet; int i, nw, nwa, nsa, nsalt, iqtot; gmx_output_env_t *oenv; gmx_rng_t rng; t_filenm fnm[] = { { efTPR, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efSTO, "-o", NULL, ffWRITE }, { efTOP, "-p", "topol", ffOPTRW } }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv)) { return 0; } /* Check input for something sensible */ if ((p_num < 0) || (n_num < 0)) { gmx_fatal(FARGS, "Negative number of ions to add?"); } if (conc > 0 && (p_num > 0 || n_num > 0)) { fprintf(stderr, "WARNING: -conc specified, overriding -nn and -np.\n"); } /* Read atom positions and charges */ read_tps_conf(ftp2fn(efTPR, NFILE, fnm), &top, &ePBC, &x, &v, box, FALSE); atoms = top.atoms; /* Compute total charge */ qtot = 0; for (i = 0; (i < atoms.nr); i++) { qtot += atoms.atom[i].q; } iqtot = std::round(qtot); if (conc > 0) { /* Compute number of ions to be added */ vol = det(box); nsalt = std::round(conc*vol*AVOGADRO/1e24); p_num = abs(nsalt*n_q); n_num = abs(nsalt*p_q); } if (bNeutral) { int qdelta = p_num*p_q + n_num*n_q + iqtot; /* Check if the system is neutralizable * is (qdelta == p_q*p_num + n_q*n_num) solvable for p_num and n_num? */ int gcd = gmx_greatest_common_divisor(n_q, p_q); if ((qdelta % gcd) != 0) { gmx_fatal(FARGS, "Can't neutralize this system using -nq %d and" " -pq %d.\n", n_q, p_q); } while (qdelta != 0) { while (qdelta < 0) { p_num++; qdelta += p_q; } while (qdelta > 0) { n_num++; qdelta += n_q; } } } if ((p_num == 0) && (n_num == 0)) { fprintf(stderr, "No ions to add, will just copy input configuration.\n"); } else { printf("Will try to add %d %s ions and %d %s ions.\n", p_num, p_name, n_num, n_name); printf("Select a continuous group of solvent molecules\n"); get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &nwa, &index, &grpname); for (i = 1; i < nwa; i++) { if (index[i] != index[i-1]+1) { gmx_fatal(FARGS, "The solvent group %s is not continuous: " "index[%d]=%d, index[%d]=%d", grpname, i, index[i-1]+1, i+1, index[i]+1); } } nsa = 1; while ((nsa < nwa) && (atoms.atom[index[nsa]].resind == atoms.atom[index[nsa-1]].resind)) { nsa++; } if (nwa % nsa) { gmx_fatal(FARGS, "Your solvent group size (%d) is not a multiple of %d", nwa, nsa); } nw = nwa/nsa; fprintf(stderr, "Number of (%d-atomic) solvent molecules: %d\n", nsa, nw); if (p_num+n_num > nw) { gmx_fatal(FARGS, "Not enough solvent for adding ions"); } if (opt2bSet("-p", NFILE, fnm)) { update_topol(opt2fn("-p", NFILE, fnm), p_num, n_num, p_name, n_name, grpname); } snew(bSet, nw); snew(repl, nw); snew(v, atoms.nr); snew(atoms.pdbinfo, atoms.nr); set_pbc(&pbc, ePBC, box); if (seed == 0) { rng = gmx_rng_init(gmx_rng_make_seed()); } else { rng = gmx_rng_init(seed); } /* Now loop over the ions that have to be placed */ while (p_num-- > 0) { insert_ion(nsa, &nw, bSet, repl, index, x, &pbc, 1, p_q, p_name, &atoms, rmin, rng); } while (n_num-- > 0) { insert_ion(nsa, &nw, bSet, repl, index, x, &pbc, -1, n_q, n_name, &atoms, rmin, rng); } gmx_rng_destroy(rng); fprintf(stderr, "\n"); if (nw) { sort_ions(nsa, nw, repl, index, &atoms, x, p_name, n_name); } sfree(atoms.pdbinfo); atoms.pdbinfo = NULL; } write_sto_conf(ftp2fn(efSTO, NFILE, fnm), *top.name, &atoms, x, NULL, ePBC, box); return 0; }
gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( gmx_sans_t *gsans, rvec *x, matrix box, atom_id *index, int isize, double binwidth, gmx_bool bMC, gmx_bool bNORM, real mcover, unsigned int seed) { gmx_radial_distribution_histogram_t *pr = NULL; rvec dist; double rmax; int i, j; #ifdef GMX_OPENMP double **tgr; int tid; int nthreads; gmx_rng_t *trng = NULL; #endif gmx_large_int_t mc = 0, max; gmx_rng_t rng = NULL; /* allocate memory for pr */ snew(pr, 1); /* set some fields */ pr->binwidth = binwidth; /* * create max dist rvec * dist = box[xx] + box[yy] + box[zz] */ rvec_add(box[XX], box[YY], dist); rvec_add(box[ZZ], dist, dist); rmax = norm(dist); pr->grn = (int)floor(rmax/pr->binwidth)+1; rmax = pr->grn*pr->binwidth; snew(pr->gr, pr->grn); if (bMC) { /* Special case for setting automaticaly number of mc iterations to 1% of total number of direct iterations */ if (mcover == -1) { max = (gmx_large_int_t)floor(0.5*0.01*isize*(isize-1)); } else { max = (gmx_large_int_t)floor(0.5*mcover*isize*(isize-1)); } rng = gmx_rng_init(seed); #ifdef GMX_OPENMP nthreads = gmx_omp_get_max_threads(); snew(tgr, nthreads); snew(trng, nthreads); for (i = 0; i < nthreads; i++) { snew(tgr[i], pr->grn); trng[i] = gmx_rng_init(gmx_rng_uniform_uint32(rng)); } #pragma omp parallel shared(tgr,trng,mc) private(tid,i,j) { tid = gmx_omp_get_thread_num(); /* now starting parallel threads */ #pragma omp for for (mc = 0; mc < max; mc++) { i = (int)floor(gmx_rng_uniform_real(trng[tid])*isize); j = (int)floor(gmx_rng_uniform_real(trng[tid])*isize); if (i != j) { tgr[tid][(int)floor(sqrt(distance2(x[index[i]], x[index[j]]))/binwidth)] += gsans->slength[index[i]]*gsans->slength[index[j]]; } } } /* collecting data from threads */ for (i = 0; i < pr->grn; i++) { for (j = 0; j < nthreads; j++) { pr->gr[i] += tgr[j][i]; } } /* freeing memory for tgr and destroying trng */ for (i = 0; i < nthreads; i++) { sfree(tgr[i]); gmx_rng_destroy(trng[i]); } sfree(tgr); sfree(trng); #else for (mc = 0; mc < max; mc++) { i = (int)floor(gmx_rng_uniform_real(rng)*isize); j = (int)floor(gmx_rng_uniform_real(rng)*isize); if (i != j) { pr->gr[(int)floor(sqrt(distance2(x[index[i]], x[index[j]]))/binwidth)] += gsans->slength[index[i]]*gsans->slength[index[j]]; } } #endif gmx_rng_destroy(rng); } else { #ifdef GMX_OPENMP nthreads = gmx_omp_get_max_threads(); /* Allocating memory for tgr arrays */ snew(tgr, nthreads); for (i = 0; i < nthreads; i++) { snew(tgr[i], pr->grn); } #pragma omp parallel shared(tgr) private(tid,i,j) { tid = gmx_omp_get_thread_num(); /* starting parallel threads */ #pragma omp for for (i = 0; i < isize; i++) { for (j = 0; j < i; j++) { tgr[tid][(int)floor(sqrt(distance2(x[index[i]], x[index[j]]))/binwidth)] += gsans->slength[index[i]]*gsans->slength[index[j]]; } } } /* collecating data for pr->gr */ for (i = 0; i < pr->grn; i++) { for (j = 0; j < nthreads; j++) { pr->gr[i] += tgr[j][i]; } } /* freeing memory for tgr */ for (i = 0; i < nthreads; i++) { sfree(tgr[i]); } sfree(tgr); #else for (i = 0; i < isize; i++) { for (j = 0; j < i; j++) { pr->gr[(int)floor(sqrt(distance2(x[index[i]], x[index[j]]))/binwidth)] += gsans->slength[index[i]]*gsans->slength[index[j]]; } } #endif } /* normalize if needed */ if (bNORM) { normalize_probability(pr->grn, pr->gr); } snew(pr->r, pr->grn); for (i = 0; i < pr->grn; i++) { pr->r[i] = (pr->binwidth*i+pr->binwidth*0.5); } return (gmx_radial_distribution_histogram_t *) pr; }
int gmx_nmens(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] generates an ensemble around an average structure", "in a subspace that is defined by a set of normal modes (eigenvectors).", "The eigenvectors are assumed to be mass-weighted.", "The position along each eigenvector is randomly taken from a Gaussian", "distribution with variance kT/eigenvalue.[PAR]", "By default the starting eigenvector is set to 7, since the first six", "normal modes are the translational and rotational degrees of freedom." }; static int nstruct = 100, first = 7, last = -1, seed = -1; static real temp = 300.0; t_pargs pa[] = { { "-temp", FALSE, etREAL, {&temp}, "Temperature in Kelvin" }, { "-seed", FALSE, etINT, {&seed}, "Random seed, -1 generates a seed from time and pid" }, { "-num", FALSE, etINT, {&nstruct}, "Number of structures to generate" }, { "-first", FALSE, etINT, {&first}, "First eigenvector to use (-1 is select)" }, { "-last", FALSE, etINT, {&last}, "Last eigenvector to use (-1 is till the last)" } }; #define NPA asize(pa) t_trxstatus *out; int status, trjout; t_topology top; int ePBC; t_atoms *atoms; rvec *xtop, *xref, *xav, *xout1, *xout2; gmx_bool bDMR, bDMA, bFit; int nvec, *eignr = NULL; rvec **eigvec = NULL; matrix box; real *eigval, totmass, *invsqrtm, t, disp; int natoms, neigval; char *grpname, title[STRLEN]; const char *indexfile; int i, j, d, s, v; int nout, *iout, noutvec, *outvec; atom_id *index; real rfac, invfr, rhalf, jr; int * eigvalnr; output_env_t oenv; gmx_rng_t rng; unsigned long jran; const unsigned long im = 0xffff; const unsigned long ia = 1093; const unsigned long ic = 18257; t_filenm fnm[] = { { efTRN, "-v", "eigenvec", ffREAD }, { efXVG, "-e", "eigenval", ffREAD }, { efTPS, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efTRO, "-o", "ensemble", ffWRITE } }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_BE_NICE, NFILE, fnm, NPA, pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } indexfile = ftp2fn_null(efNDX, NFILE, fnm); read_eigenvectors(opt2fn("-v", NFILE, fnm), &natoms, &bFit, &xref, &bDMR, &xav, &bDMA, &nvec, &eignr, &eigvec, &eigval); read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &xtop, NULL, box, bDMA); atoms = &top.atoms; printf("\nSelect an index group of %d elements that corresponds to the eigenvectors\n", natoms); get_index(atoms, indexfile, 1, &i, &index, &grpname); if (i != natoms) { gmx_fatal(FARGS, "you selected a group with %d elements instead of %d", i, natoms); } printf("\n"); snew(invsqrtm, natoms); if (bDMA) { for (i = 0; (i < natoms); i++) { invsqrtm[i] = gmx_invsqrt(atoms->atom[index[i]].m); } } else { for (i = 0; (i < natoms); i++) { invsqrtm[i] = 1.0; } } if (last == -1) { last = natoms*DIM; } if (first > -1) { /* make an index from first to last */ nout = last-first+1; snew(iout, nout); for (i = 0; i < nout; i++) { iout[i] = first-1+i; } } else { printf("Select eigenvectors for output, end your selection with 0\n"); nout = -1; iout = NULL; do { nout++; srenew(iout, nout+1); if (1 != scanf("%d", &iout[nout])) { gmx_fatal(FARGS, "Error reading user input"); } iout[nout]--; } while (iout[nout] >= 0); printf("\n"); } /* make an index of the eigenvectors which are present */ snew(outvec, nout); noutvec = 0; for (i = 0; i < nout; i++) { j = 0; while ((j < nvec) && (eignr[j] != iout[i])) { j++; } if ((j < nvec) && (eignr[j] == iout[i])) { outvec[noutvec] = j; iout[noutvec] = iout[i]; noutvec++; } } fprintf(stderr, "%d eigenvectors selected for output\n", noutvec); if (seed == -1) { seed = (int)gmx_rng_make_seed(); rng = gmx_rng_init(seed); } else { rng = gmx_rng_init(seed); } fprintf(stderr, "Using seed %d and a temperature of %g K\n", seed, temp); snew(xout1, natoms); snew(xout2, atoms->nr); out = open_trx(ftp2fn(efTRO, NFILE, fnm), "w"); jran = (unsigned long)((real)im*gmx_rng_uniform_real(rng)); gmx_rng_destroy(rng); for (s = 0; s < nstruct; s++) { for (i = 0; i < natoms; i++) { copy_rvec(xav[i], xout1[i]); } for (j = 0; j < noutvec; j++) { v = outvec[j]; /* (r-0.5) n times: var_n = n * var_1 = n/12 n=4: var_n = 1/3, so multiply with 3 */ rfac = sqrt(3.0 * BOLTZ*temp/eigval[iout[j]]); rhalf = 2.0*rfac; rfac = rfac/(real)im; jran = (jran*ia+ic) & im; jr = (real)jran; jran = (jran*ia+ic) & im; jr += (real)jran; jran = (jran*ia+ic) & im; jr += (real)jran; jran = (jran*ia+ic) & im; jr += (real)jran; disp = rfac * jr - rhalf; for (i = 0; i < natoms; i++) { for (d = 0; d < DIM; d++) { xout1[i][d] += disp*eigvec[v][i][d]*invsqrtm[i]; } } } for (i = 0; i < natoms; i++) { copy_rvec(xout1[i], xout2[index[i]]); } t = s+1; write_trx(out, natoms, index, atoms, 0, t, box, xout2, NULL, NULL); fprintf(stderr, "\rGenerated %d structures", s+1); } fprintf(stderr, "\n"); close_trx(out); return 0; }
int gmx_genconf(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] multiplies a given coordinate file by simply stacking them", "on top of each other, like a small child playing with wooden blocks.", "The program makes a grid of [IT]user-defined[it]", "proportions ([TT]-nbox[tt]), ", "and interspaces the grid point with an extra space [TT]-dist[tt].[PAR]", "When option [TT]-rot[tt] is used the program does not check for overlap", "between molecules on grid points. It is recommended to make the box in", "the input file at least as big as the coordinates + ", "van der Waals radius.[PAR]", "If the optional trajectory file is given, conformations are not", "generated, but read from this file and translated appropriately to", "build the grid." }; const char *bugs[] = { "The program should allow for random displacement of lattice points." }; int vol; t_atoms *atoms; /* list with all atoms */ rvec *x, *xx, *v; /* coordinates? */ real t; vec4 *xrot, *vrot; int ePBC; matrix box, boxx; /* box length matrix */ rvec shift; int natoms; /* number of atoms in one molecule */ int nres; /* number of molecules? */ int i, j, k, l, m, ndx, nrdx, nx, ny, nz; t_trxstatus *status; gmx_bool bTRX; gmx_output_env_t *oenv; gmx_rng_t rng; t_filenm fnm[] = { { efSTX, "-f", "conf", ffREAD }, { efSTO, "-o", "out", ffWRITE }, { efTRX, "-trj", NULL, ffOPTRD } }; #define NFILE asize(fnm) static rvec nrbox = {1, 1, 1}; static int seed = 0; /* seed for random number generator */ static int nmolat = 3; static int nblock = 1; static gmx_bool bShuffle = FALSE; static gmx_bool bSort = FALSE; static gmx_bool bRandom = FALSE; /* False: no random rotations */ static gmx_bool bRenum = TRUE; /* renumber residues */ static rvec dist = {0, 0, 0}; /* space added between molecules ? */ static rvec max_rot = {180, 180, 180}; /* maximum rotation */ t_pargs pa[] = { { "-nbox", FALSE, etRVEC, {nrbox}, "Number of boxes" }, { "-dist", FALSE, etRVEC, {dist}, "Distance between boxes" }, { "-seed", FALSE, etINT, {&seed}, "Random generator seed, if 0 generated from the time" }, { "-rot", FALSE, etBOOL, {&bRandom}, "Randomly rotate conformations" }, { "-shuffle", FALSE, etBOOL, {&bShuffle}, "Random shuffling of molecules" }, { "-sort", FALSE, etBOOL, {&bSort}, "Sort molecules on X coord" }, { "-block", FALSE, etINT, {&nblock}, "Divide the box in blocks on this number of cpus" }, { "-nmolat", FALSE, etINT, {&nmolat}, "Number of atoms per molecule, assumed to start from 0. " "If you set this wrong, it will screw up your system!" }, { "-maxrot", FALSE, etRVEC, {max_rot}, "Maximum random rotation" }, { "-renumber", FALSE, etBOOL, {&bRenum}, "Renumber residues" } }; if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv)) { return 0; } if (seed == 0) { rng = gmx_rng_init(gmx_rng_make_seed()); } else { rng = gmx_rng_init(seed); } bTRX = ftp2bSet(efTRX, NFILE, fnm); nx = (int)(nrbox[XX]+0.5); ny = (int)(nrbox[YY]+0.5); nz = (int)(nrbox[ZZ]+0.5); if ((nx <= 0) || (ny <= 0) || (nz <= 0)) { gmx_fatal(FARGS, "Number of boxes (-nbox) should be larger than zero"); } if ((nmolat <= 0) && bShuffle) { gmx_fatal(FARGS, "Can not shuffle if the molecules only have %d atoms", nmolat); } vol = nx*ny*nz; /* calculate volume in grid points (= nr. molecules) */ t_topology *top; snew(top, 1); atoms = &top->atoms; read_tps_conf(opt2fn("-f", NFILE, fnm), top, &ePBC, &x, &v, box, FALSE); natoms = atoms->nr; nres = atoms->nres; /* nr of residues in one element? */ /* make space for all the atoms */ add_t_atoms(atoms, natoms*(vol-1), nres*(vol-1)); srenew(x, natoms*vol); /* get space for coordinates of all atoms */ srenew(v, natoms*vol); /* velocities. not really needed? */ snew(xrot, natoms); /* get space for rotation matrix? */ snew(vrot, natoms); if (bTRX) { if (!read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &xx, boxx)) { gmx_fatal(FARGS, "No atoms in trajectory %s", ftp2fn(efTRX, NFILE, fnm)); } } else { snew(xx, natoms); for (i = 0; i < natoms; i++) { copy_rvec(x[i], xx[i]); } } for (k = 0; (k < nz); k++) /* loop over all gridpositions */ { shift[ZZ] = k*(dist[ZZ]+box[ZZ][ZZ]); for (j = 0; (j < ny); j++) { shift[YY] = j*(dist[YY]+box[YY][YY])+k*box[ZZ][YY]; for (i = 0; (i < nx); i++) { shift[XX] = i*(dist[XX]+box[XX][XX])+j*box[YY][XX]+k*box[ZZ][XX]; ndx = (i*ny*nz+j*nz+k)*natoms; nrdx = (i*ny*nz+j*nz+k)*nres; /* Random rotation on input coords */ if (bRandom) { rand_rot(natoms, xx, v, xrot, vrot, rng, max_rot); } for (l = 0; (l < natoms); l++) { for (m = 0; (m < DIM); m++) { if (bRandom) { x[ndx+l][m] = xrot[l][m]; v[ndx+l][m] = vrot[l][m]; } else { x[ndx+l][m] = xx[l][m]; v[ndx+l][m] = v[l][m]; } } if (ePBC == epbcSCREW && i % 2 == 1) { /* Rotate around x axis */ for (m = YY; m <= ZZ; m++) { x[ndx+l][m] = box[YY][m] + box[ZZ][m] - x[ndx+l][m]; v[ndx+l][m] = -v[ndx+l][m]; } } for (m = 0; (m < DIM); m++) { x[ndx+l][m] += shift[m]; } atoms->atom[ndx+l].resind = nrdx + atoms->atom[l].resind; atoms->atomname[ndx+l] = atoms->atomname[l]; } for (l = 0; (l < nres); l++) { atoms->resinfo[nrdx+l] = atoms->resinfo[l]; if (bRenum) { atoms->resinfo[nrdx+l].nr += nrdx; } } if (bTRX) { if (!read_next_x(oenv, status, &t, xx, boxx) && ((i+1)*(j+1)*(k+1) < vol)) { gmx_fatal(FARGS, "Not enough frames in trajectory"); } } } } } if (bTRX) { close_trj(status); } /* make box bigger */ for (m = 0; (m < DIM); m++) { box[m][m] += dist[m]; } svmul(nx, box[XX], box[XX]); svmul(ny, box[YY], box[YY]); svmul(nz, box[ZZ], box[ZZ]); if (ePBC == epbcSCREW && nx % 2 == 0) { /* With an even number of boxes in x we can forgot about the screw */ ePBC = epbcXYZ; } /* move_x(natoms*vol,x,box); */ /* put atoms in box? */ atoms->nr *= vol; atoms->nres *= vol; /*depending on how you look at it, this is either a nasty hack or the way it should work*/ if (bRenum) { for (i = 0; i < atoms->nres; i++) { atoms->resinfo[i].nr = i+1; } } if (bShuffle) { randwater(0, atoms->nr/nmolat, nmolat, x, v, rng); } else if (bSort) { sortwater(0, atoms->nr/nmolat, nmolat, x, v); } else if (opt2parg_bSet("-block", asize(pa), pa)) { mkcompact(0, atoms->nr/nmolat, nmolat, x, v, nblock, box); } gmx_rng_destroy(rng); write_sto_conf(opt2fn("-o", NFILE, fnm), *top->name, atoms, x, v, ePBC, box); return 0; }
static void insert_mols(int nmol_insrt, int ntry, int seed, t_atoms *atoms, rvec **x, real **exclusionDistances, t_atoms *atoms_insrt, rvec *x_insrt, real *exclusionDistances_insrt, int ePBC, matrix box, const char* posfn, const rvec deltaR, int enum_rot) { t_pbc pbc; rvec *x_n; int mol; int trial; double **rpos; const real maxInsertRadius = *std::max_element(exclusionDistances_insrt, exclusionDistances_insrt + atoms_insrt->nr); real maxRadius = maxInsertRadius; if (atoms->nr > 0) { const real maxExistingRadius = *std::max_element(*exclusionDistances, *exclusionDistances + atoms->nr); maxRadius = std::max(maxInsertRadius, maxExistingRadius); } // TODO: Make all of this exception-safe. gmx::AnalysisNeighborhood nb; nb.setCutoff(maxInsertRadius + maxRadius); gmx_rng_t rng = gmx_rng_init(seed); set_pbc(&pbc, ePBC, box); snew(x_n, atoms_insrt->nr); /* With -ip, take nmol_insrt from file posfn */ if (posfn != NULL) { int ncol; nmol_insrt = read_xvg(posfn, &rpos, &ncol); if (ncol != 3) { gmx_fatal(FARGS, "Expected 3 columns (x/y/z coordinates) in file %s\n", ncol, posfn); } fprintf(stderr, "Read %d positions from file %s\n\n", nmol_insrt, posfn); } { const int finalAtomCount = atoms->nr + nmol_insrt * atoms_insrt->nr; const int finalResidueCount = atoms->nres + nmol_insrt * atoms_insrt->nres; srenew(atoms->resinfo, finalResidueCount); srenew(atoms->atomname, finalAtomCount); srenew(atoms->atom, finalAtomCount); srenew(*x, finalAtomCount); srenew(*exclusionDistances, finalAtomCount); } trial = mol = 0; while ((mol < nmol_insrt) && (trial < ntry*nmol_insrt)) { fprintf(stderr, "\rTry %d", trial++); rvec offset_x; if (posfn == NULL) { /* insert at random positions */ offset_x[XX] = box[XX][XX] * gmx_rng_uniform_real(rng); offset_x[YY] = box[YY][YY] * gmx_rng_uniform_real(rng); offset_x[ZZ] = box[ZZ][ZZ] * gmx_rng_uniform_real(rng); } else { /* Insert at positions taken from option -ip file */ offset_x[XX] = rpos[XX][mol] + deltaR[XX]*(2 * gmx_rng_uniform_real(rng)-1); offset_x[YY] = rpos[YY][mol] + deltaR[YY]*(2 * gmx_rng_uniform_real(rng)-1); offset_x[ZZ] = rpos[ZZ][mol] + deltaR[ZZ]*(2 * gmx_rng_uniform_real(rng)-1); } generate_trial_conf(atoms_insrt->nr, x_insrt, offset_x, enum_rot, rng, x_n); gmx::AnalysisNeighborhoodPositions pos(*x, atoms->nr); gmx::AnalysisNeighborhoodSearch search = nb.initSearch(&pbc, pos); if (is_insertion_allowed(&search, *exclusionDistances, atoms_insrt->nr, x_n, exclusionDistances_insrt)) { const int firstIndex = atoms->nr; for (int i = 0; i < atoms_insrt->nr; ++i) { copy_rvec(x_n[i], (*x)[firstIndex + i]); (*exclusionDistances)[firstIndex + i] = exclusionDistances_insrt[i]; } merge_atoms_noalloc(atoms, atoms_insrt); ++mol; fprintf(stderr, " success (now %d atoms)!\n", atoms->nr); } } gmx_rng_destroy(rng); srenew(atoms->resinfo, atoms->nres); srenew(atoms->atomname, atoms->nr); srenew(atoms->atom, atoms->nr); srenew(*x, atoms->nr); srenew(*exclusionDistances, atoms->nr); fprintf(stderr, "\n"); /* print number of molecules added */ fprintf(stderr, "Added %d molecules (out of %d requested) of %s\n", mol, nmol_insrt, *atoms_insrt->resinfo[0].name); sfree(x_n); }
static void insert_mols(int nmol_insrt, int ntry, int seed, real defaultDistance, real scaleFactor, t_atoms *atoms, rvec **x, const t_atoms *atoms_insrt, const rvec *x_insrt, int ePBC, matrix box, const std::string &posfn, const rvec deltaR, int enum_rot) { t_pbc pbc; rvec *x_n; fprintf(stderr, "Initialising inter-atomic distances...\n"); gmx_atomprop_t aps = gmx_atomprop_init(); real *exclusionDistances = makeExclusionDistances(atoms, aps, defaultDistance, scaleFactor); real *exclusionDistances_insrt = makeExclusionDistances(atoms_insrt, aps, defaultDistance, scaleFactor); gmx_atomprop_destroy(aps); const real maxInsertRadius = *std::max_element(exclusionDistances_insrt, exclusionDistances_insrt + atoms_insrt->nr); real maxRadius = maxInsertRadius; if (atoms->nr > 0) { const real maxExistingRadius = *std::max_element(exclusionDistances, exclusionDistances + atoms->nr); maxRadius = std::max(maxInsertRadius, maxExistingRadius); } // TODO: Make all of this exception-safe. gmx::AnalysisNeighborhood nb; nb.setCutoff(maxInsertRadius + maxRadius); gmx_rng_t rng = gmx_rng_init(seed); set_pbc(&pbc, ePBC, box); snew(x_n, atoms_insrt->nr); /* With -ip, take nmol_insrt from file posfn */ double **rpos = NULL; if (!posfn.empty()) { int ncol; nmol_insrt = read_xvg(posfn.c_str(), &rpos, &ncol); if (ncol != 3) { gmx_fatal(FARGS, "Expected 3 columns (x/y/z coordinates) in file %s\n", posfn.c_str()); } fprintf(stderr, "Read %d positions from file %s\n\n", nmol_insrt, posfn.c_str()); } { const int finalAtomCount = atoms->nr + nmol_insrt * atoms_insrt->nr; const int finalResidueCount = atoms->nres + nmol_insrt * atoms_insrt->nres; srenew(atoms->resinfo, finalResidueCount); srenew(atoms->atomname, finalAtomCount); srenew(atoms->atom, finalAtomCount); srenew(*x, finalAtomCount); srenew(exclusionDistances, finalAtomCount); } int mol = 0; int trial = 0; int firstTrial = 0; int failed = 0; while ((mol < nmol_insrt) && (trial < ntry*nmol_insrt)) { rvec offset_x; if (posfn.empty()) { // Insert at random positions. offset_x[XX] = box[XX][XX] * gmx_rng_uniform_real(rng); offset_x[YY] = box[YY][YY] * gmx_rng_uniform_real(rng); offset_x[ZZ] = box[ZZ][ZZ] * gmx_rng_uniform_real(rng); } else { // Skip a position if ntry trials were not successful. if (trial >= firstTrial + ntry) { fprintf(stderr, " skipped position (%.3f, %.3f, %.3f)\n", rpos[XX][mol], rpos[YY][mol], rpos[ZZ][mol]); ++mol; ++failed; } // Insert at positions taken from option -ip file. offset_x[XX] = rpos[XX][mol] + deltaR[XX]*(2 * gmx_rng_uniform_real(rng)-1); offset_x[YY] = rpos[YY][mol] + deltaR[YY]*(2 * gmx_rng_uniform_real(rng)-1); offset_x[ZZ] = rpos[ZZ][mol] + deltaR[ZZ]*(2 * gmx_rng_uniform_real(rng)-1); } fprintf(stderr, "\rTry %d", ++trial); generate_trial_conf(atoms_insrt->nr, x_insrt, offset_x, enum_rot, rng, x_n); gmx::AnalysisNeighborhoodPositions pos(*x, atoms->nr); gmx::AnalysisNeighborhoodSearch search = nb.initSearch(&pbc, pos); if (is_insertion_allowed(&search, exclusionDistances, atoms_insrt->nr, x_n, exclusionDistances_insrt)) { const int firstIndex = atoms->nr; for (int i = 0; i < atoms_insrt->nr; ++i) { copy_rvec(x_n[i], (*x)[firstIndex + i]); exclusionDistances[firstIndex + i] = exclusionDistances_insrt[i]; } merge_atoms_noalloc(atoms, atoms_insrt); ++mol; firstTrial = trial; fprintf(stderr, " success (now %d atoms)!\n", atoms->nr); } } gmx_rng_destroy(rng); srenew(atoms->resinfo, atoms->nres); srenew(atoms->atomname, atoms->nr); srenew(atoms->atom, atoms->nr); srenew(*x, atoms->nr); fprintf(stderr, "\n"); /* print number of molecules added */ fprintf(stderr, "Added %d molecules (out of %d requested)\n", mol - failed, nmol_insrt); sfree(x_n); sfree(exclusionDistances); sfree(exclusionDistances_insrt); if (rpos != NULL) { for (int i = 0; i < DIM; ++i) { sfree(rpos[i]); } sfree(rpos); } }