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); } }