void writeSystemInformation(TextWriter *writer, const gmx_mtop_t &top, bool writeFormattedText) { int nmol, nvsite = 0; gmx_mtop_atomloop_block_t aloop; const t_atom *atom; writeHeader(writer, "Simulation system", "subsection", writeFormattedText); aloop = gmx_mtop_atomloop_block_init(&top); while (gmx_mtop_atomloop_block_next(aloop, &atom, &nmol)) { if (atom->ptype == eptVSite) { nvsite += nmol; } } { writer->writeLine(formatString("A system of %d molecules (%d atoms) was simulated.", gmx_mtop_num_molecules(top), top.natoms-nvsite)); } if (nvsite) { writer->writeLine(formatString("Virtual sites were used in some of the molecules.")); } writer->ensureEmptyLine(); }
/*! \brief Count the different particle types in a system * * Routine prints a warning to stderr in case an unknown particle type * is encountered. * \param[in] fplog Print what we have found if not NULL * \param[in] mtop Molecular topology. * \returns Array holding the number of particles of a type */ static std::array<int, eptNR> countPtypes(FILE *fplog, gmx_mtop_t *mtop) { std::array<int, eptNR> nptype = { { 0 } }; /* Count number of shells, and find their indices */ for (int i = 0; (i < eptNR); i++) { nptype[i] = 0; } gmx_mtop_atomloop_block_t aloopb = gmx_mtop_atomloop_block_init(mtop); int nmol; t_atom *atom; while (gmx_mtop_atomloop_block_next(aloopb, &atom, &nmol)) { switch (atom->ptype) { case eptAtom: case eptVSite: case eptShell: nptype[atom->ptype] += nmol; break; default: fprintf(stderr, "Warning unsupported particle type %d in countPtypes", static_cast<int>(atom->ptype)); } } if (fplog) { /* Print the number of each particle type */ int n = 0; for (const auto &i : nptype) { if (i != 0) { fprintf(fplog, "There are: %d %ss\n", i, ptype_str[n]); } n++; } } return nptype; }
static void tpx2system(FILE *fp, gmx_mtop_t *mtop) { int i, nmol, nvsite = 0; gmx_mtop_atomloop_block_t aloop; t_atom *atom; fprintf(fp, "\\subsection{Simulation system}\n"); aloop = gmx_mtop_atomloop_block_init(mtop); while (gmx_mtop_atomloop_block_next(aloop, &atom, &nmol)) { if (atom->ptype == eptVSite) { nvsite += nmol; } } fprintf(fp, "A system of %d molecules (%d atoms) was simulated.\n", mtop->mols.nr, mtop->natoms-nvsite); if (nvsite) { fprintf(fp, "Virtual sites were used in some of the molecules.\n"); } fprintf(fp, "\n\n"); }
gmx_shellfc_t init_shell_flexcon(FILE *fplog, gmx_bool bCutoffSchemeIsVerlet, gmx_mtop_t *mtop, int nflexcon, rvec *x) { struct gmx_shellfc *shfc; t_shell *shell; int *shell_index = NULL, *at2cg; t_atom *atom; int n[eptNR], ns, nshell, nsi; int i, j, nmol, type, mb, mt, a_offset, cg, mol, ftype, nra; real qS, alpha; int aS, aN = 0; /* Shell and nucleus */ int bondtypes[] = { F_BONDS, F_HARMONIC, F_CUBICBONDS, F_POLARIZATION, F_ANHARM_POL, F_WATER_POL }; #define NBT asize(bondtypes) t_iatom *ia; gmx_mtop_atomloop_block_t aloopb; gmx_mtop_atomloop_all_t aloop; gmx_ffparams_t *ffparams; gmx_molblock_t *molb; gmx_moltype_t *molt; t_block *cgs; /* Count number of shells, and find their indices */ for (i = 0; (i < eptNR); i++) { n[i] = 0; } aloopb = gmx_mtop_atomloop_block_init(mtop); while (gmx_mtop_atomloop_block_next(aloopb, &atom, &nmol)) { n[atom->ptype] += nmol; } if (fplog) { /* Print the number of each particle type */ for (i = 0; (i < eptNR); i++) { if (n[i] != 0) { fprintf(fplog, "There are: %d %ss\n", n[i], ptype_str[i]); } } } nshell = n[eptShell]; if (nshell == 0 && nflexcon == 0) { /* We're not doing shells or flexible constraints */ return NULL; } if (bCutoffSchemeIsVerlet) { gmx_fatal(FARGS, "The shell code does not work with the Verlet cut-off scheme.\n"); } snew(shfc, 1); shfc->nflexcon = nflexcon; if (nshell == 0) { return shfc; } /* We have shells: fill the shell data structure */ /* Global system sized array, this should be avoided */ snew(shell_index, mtop->natoms); aloop = gmx_mtop_atomloop_all_init(mtop); nshell = 0; while (gmx_mtop_atomloop_all_next(aloop, &i, &atom)) { if (atom->ptype == eptShell) { shell_index[i] = nshell++; } } snew(shell, nshell); /* Initiate the shell structures */ for (i = 0; (i < nshell); i++) { shell[i].shell = NO_ATID; shell[i].nnucl = 0; shell[i].nucl1 = NO_ATID; shell[i].nucl2 = NO_ATID; shell[i].nucl3 = NO_ATID; /* shell[i].bInterCG=FALSE; */ shell[i].k_1 = 0; shell[i].k = 0; } ffparams = &mtop->ffparams; /* Now fill the structures */ shfc->bInterCG = FALSE; ns = 0; a_offset = 0; for (mb = 0; mb < mtop->nmolblock; mb++) { molb = &mtop->molblock[mb]; molt = &mtop->moltype[molb->type]; cgs = &molt->cgs; snew(at2cg, molt->atoms.nr); for (cg = 0; cg < cgs->nr; cg++) { for (i = cgs->index[cg]; i < cgs->index[cg+1]; i++) { at2cg[i] = cg; } } atom = molt->atoms.atom; for (mol = 0; mol < molb->nmol; mol++) { for (j = 0; (j < NBT); j++) { ia = molt->ilist[bondtypes[j]].iatoms; for (i = 0; (i < molt->ilist[bondtypes[j]].nr); ) { type = ia[0]; ftype = ffparams->functype[type]; nra = interaction_function[ftype].nratoms; /* Check whether we have a bond with a shell */ aS = NO_ATID; switch (bondtypes[j]) { case F_BONDS: case F_HARMONIC: case F_CUBICBONDS: case F_POLARIZATION: case F_ANHARM_POL: if (atom[ia[1]].ptype == eptShell) { aS = ia[1]; aN = ia[2]; } else if (atom[ia[2]].ptype == eptShell) { aS = ia[2]; aN = ia[1]; } break; case F_WATER_POL: aN = ia[4]; /* Dummy */ aS = ia[5]; /* Shell */ break; default: gmx_fatal(FARGS, "Death Horror: %s, %d", __FILE__, __LINE__); } if (aS != NO_ATID) { qS = atom[aS].q; /* Check whether one of the particles is a shell... */ nsi = shell_index[a_offset+aS]; if ((nsi < 0) || (nsi >= nshell)) { gmx_fatal(FARGS, "nsi is %d should be within 0 - %d. aS = %d", nsi, nshell, aS); } if (shell[nsi].shell == NO_ATID) { shell[nsi].shell = a_offset + aS; ns++; } else if (shell[nsi].shell != a_offset+aS) { gmx_fatal(FARGS, "Weird stuff in %s, %d", __FILE__, __LINE__); } if (shell[nsi].nucl1 == NO_ATID) { shell[nsi].nucl1 = a_offset + aN; } else if (shell[nsi].nucl2 == NO_ATID) { shell[nsi].nucl2 = a_offset + aN; } else if (shell[nsi].nucl3 == NO_ATID) { shell[nsi].nucl3 = a_offset + aN; } else { if (fplog) { pr_shell(fplog, ns, shell); } gmx_fatal(FARGS, "Can not handle more than three bonds per shell\n"); } if (at2cg[aS] != at2cg[aN]) { /* shell[nsi].bInterCG = TRUE; */ shfc->bInterCG = TRUE; } switch (bondtypes[j]) { case F_BONDS: case F_HARMONIC: shell[nsi].k += ffparams->iparams[type].harmonic.krA; break; case F_CUBICBONDS: shell[nsi].k += ffparams->iparams[type].cubic.kb; break; case F_POLARIZATION: case F_ANHARM_POL: if (!gmx_within_tol(qS, atom[aS].qB, GMX_REAL_EPS*10)) { gmx_fatal(FARGS, "polarize can not be used with qA(%e) != qB(%e) for atom %d of molecule block %d", qS, atom[aS].qB, aS+1, mb+1); } shell[nsi].k += sqr(qS)*ONE_4PI_EPS0/ ffparams->iparams[type].polarize.alpha; break; case F_WATER_POL: if (!gmx_within_tol(qS, atom[aS].qB, GMX_REAL_EPS*10)) { gmx_fatal(FARGS, "water_pol can not be used with qA(%e) != qB(%e) for atom %d of molecule block %d", qS, atom[aS].qB, aS+1, mb+1); } alpha = (ffparams->iparams[type].wpol.al_x+ ffparams->iparams[type].wpol.al_y+ ffparams->iparams[type].wpol.al_z)/3.0; shell[nsi].k += sqr(qS)*ONE_4PI_EPS0/alpha; break; default: gmx_fatal(FARGS, "Death Horror: %s, %d", __FILE__, __LINE__); } shell[nsi].nnucl++; } ia += nra+1; i += nra+1; } } a_offset += molt->atoms.nr; } /* Done with this molecule type */ sfree(at2cg); } /* Verify whether it's all correct */ if (ns != nshell) { gmx_fatal(FARGS, "Something weird with shells. They may not be bonded to something"); } for (i = 0; (i < ns); i++) { shell[i].k_1 = 1.0/shell[i].k; } if (debug) { pr_shell(debug, ns, shell); } shfc->nshell_gl = ns; shfc->shell_gl = shell; shfc->shell_index_gl = shell_index; shfc->bPredict = (getenv("GMX_NOPREDICT") == NULL); shfc->bRequireInit = FALSE; if (!shfc->bPredict) { if (fplog) { fprintf(fplog, "\nWill never predict shell positions\n"); } } else { shfc->bRequireInit = (getenv("GMX_REQUIRE_SHELL_INIT") != NULL); if (shfc->bRequireInit && fplog) { fprintf(fplog, "\nWill always initiate shell positions\n"); } } if (shfc->bPredict) { if (x) { predict_shells(fplog, x, NULL, 0, shfc->nshell_gl, shfc->shell_gl, NULL, mtop, TRUE); } if (shfc->bInterCG) { if (fplog) { fprintf(fplog, "\nNOTE: there all shells that are connected to particles outside thier own charge group, will not predict shells positions during the run\n\n"); } shfc->bPredict = FALSE; } } return shfc; }