if (ddpCount == dd->ddp_count)
{
/* The local state and DD are in sync, use the DD indices */
- atomGroups = gmx::constArrayRefFromArray(dd->globalAtomGroupIndices.data(), dd->ncg_home);
+ atomGroups = gmx::constArrayRefFromArray(dd->globalAtomGroupIndices.data(), dd->numHomeAtoms);
nat_home = dd->comm->atomRanges.numHomeAtoms();
}
else if (ddpCountCgGl == ddpCount)
}
dd_scatter(dd, 2 * sizeof(int), ibuf, buf2);
- dd->ncg_home = buf2[0];
+ dd->numHomeAtoms = buf2[0];
dd->comm->atomRanges.setEnd(DDAtomRanges::Type::Home, buf2[1]);
- dd->globalAtomGroupIndices.resize(dd->ncg_home);
+ dd->globalAtomGroupIndices.resize(dd->numHomeAtoms);
dd->globalAtomIndices.resize(dd->comm->atomRanges.numHomeAtoms());
if (bMaster)
bMaster ? ma->intBuffer.data() : nullptr,
bMaster ? ma->intBuffer.data() + dd->nnodes : nullptr,
bMaster ? ma->atomGroups.data() : nullptr,
- dd->ncg_home * sizeof(int),
+ dd->numHomeAtoms * sizeof(int),
dd->globalAtomGroupIndices.data());
if (debug)
{
fprintf(debug, "Home charge groups:\n");
- for (int i = 0; i < dd->ncg_home; i++)
+ for (int i = 0; i < dd->numHomeAtoms; i++)
{
fprintf(debug, " %d", dd->globalAtomGroupIndices[i]);
if (i % 10 == 9)
gmx_incons("The MD state does not match the domain decomposition state");
}
- state->cg_gl.resize(dd.ncg_home);
- for (int i = 0; i < dd.ncg_home; i++)
+ state->cg_gl.resize(dd.numHomeAtoms);
+ for (int i = 0; i < dd.numHomeAtoms; i++)
{
state->cg_gl[i] = dd.globalAtomGroupIndices[i];
}
#include "gromacs/math/vectypes.h"
#include "gromacs/utility/real.h"
-struct cginfo_mb_t;
+struct AtomInfoWithinMoleculeBlock;
struct gmx_domdec_t;
struct gmx_ddbox_t;
struct gmx_domdec_zones_t;
/*! \brief Generate a list of links between atoms that are linked by bonded interactions
*
- * Also stores whether atoms are linked in \p cginfo_mb.
+ * Also stores whether atoms are linked in \p atomInfoForEachMoleculeBlock.
*/
-void makeBondedLinks(gmx_domdec_t* dd, const gmx_mtop_t& mtop, gmx::ArrayRef<cginfo_mb_t> cginfo_mb);
+void makeBondedLinks(gmx_domdec_t* dd,
+ const gmx_mtop_t& mtop,
+ gmx::ArrayRef<AtomInfoWithinMoleculeBlock> atomInfoForEachMoleculeBlock);
/*! \brief Calculate the maximum distance involved in 2-body and multi-body bonded interactions */
void dd_bonded_cg_distance(const gmx::MDLogger& mdlog,
/*! \brief Looks up SETTLE constraints for a range of charge-groups */
static void atoms_to_settles(gmx_domdec_t* dd,
const gmx_mtop_t& mtop,
- const int* cginfo,
+ const int* atomInfo,
gmx::ArrayRef<const std::vector<int>> at2settle_mt,
int cg_start,
int cg_end,
int mb = 0;
for (int a = cg_start; a < cg_end; a++)
{
- if (GET_CGINFO_SETTLE(cginfo[a]))
+ if (GET_CGINFO_SETTLE(atomInfo[a]))
{
int a_gl = dd->globalAtomIndices[a];
int a_mol = 0;
/*! \brief Looks up constraint for the local atoms */
static void atoms_to_constraints(gmx_domdec_t* dd,
const gmx_mtop_t& mtop,
- const int* cginfo,
+ const int* atomInfo,
gmx::ArrayRef<const ListOfLists<int>> at2con_mt,
int nrec,
InteractionList* ilc_local,
int mb = 0;
int nhome = 0;
- for (int a = 0; a < dd->ncg_home; a++)
+ for (int a = 0; a < dd->numHomeAtoms; a++)
{
- if (GET_CGINFO_CONSTR(cginfo[a]))
+ if (GET_CGINFO_CONSTR(atomInfo[a]))
{
int a_gl = dd->globalAtomIndices[a];
int molnr = 0;
int dd_make_local_constraints(gmx_domdec_t* dd,
int at_start,
const struct gmx_mtop_t& mtop,
- const int* cginfo,
+ const int* atomInfo,
gmx::Constraints* constr,
int nrec,
gmx::ArrayRef<InteractionList> il_local)
if (at2settle_mt.empty())
{
- atoms_to_constraints(dd, mtop, cginfo, at2con_mt, nrec, ilc_local, ireq);
+ atoms_to_constraints(dd, mtop, atomInfo, at2con_mt, nrec, ilc_local, ireq);
}
else
{
{
if (!at2con_mt.empty() && thread == 0)
{
- atoms_to_constraints(dd, mtop, cginfo, at2con_mt, nrec, ilc_local, ireq);
+ atoms_to_constraints(dd, mtop, atomInfo, at2con_mt, nrec, ilc_local, ireq);
}
if (thread >= t0_set)
/* Distribute the settle check+assignments over
* dc->nthread or dc->nthread-1 threads.
*/
- const int cg0 = (dd->ncg_home * (thread - t0_set)) / (dc->nthread - t0_set);
- const int cg1 = (dd->ncg_home * (thread - t0_set + 1)) / (dc->nthread - t0_set);
+ const int cg0 = (dd->numHomeAtoms * (thread - t0_set)) / (dc->nthread - t0_set);
+ const int cg1 = (dd->numHomeAtoms * (thread - t0_set + 1)) / (dc->nthread - t0_set);
InteractionList* ilst = (thread == t0_set) ? ils_local : &dc->ils[thread];
ilst->clear();
ireqt.clear();
}
- atoms_to_settles(dd, mtop, cginfo, at2settle_mt, cg0, cg1, ilst, &ireqt);
+ atoms_to_settles(dd, mtop, atomInfo, at2settle_mt, cg0, cg1, ilst, &ireqt);
}
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
int dd_make_local_constraints(struct gmx_domdec_t* dd,
int at_start,
const struct gmx_mtop_t& mtop,
- const int* cginfo,
+ const int* atomInfo,
gmx::Constraints* constr,
int nrec,
gmx::ArrayRef<InteractionList> il_local);
gmx_domdec_constraints_t* constraints = nullptr;
gmx_domdec_specat_comm_t* constraint_comm = nullptr;
- /* The number of home atom groups */
- int ncg_home = 0;
+ /* The number of home atoms */
+ int numHomeAtoms = 0;
/* Global atom group indices for the home and all non-home groups */
std::vector<int> globalAtomGroupIndices;
gmx_domdec_zones_t* zones,
ArrayRef<const MolblockIndices> molblockIndices,
const std::vector<gmx_moltype_t>& moltype,
- const int* cginfo,
+ const int* atomInfo,
ListOfLists<int>* lexcls,
int iz,
int at_start,
{
exclusionsForAtom.clear();
- if (GET_CGINFO_EXCL_INTER(cginfo[at]))
+ if (GET_CGINFO_EXCL_INTER(atomInfo[at]))
{
int mb = 0;
int mt = 0;
static int make_local_bondeds_excls(gmx_domdec_t* dd,
gmx_domdec_zones_t* zones,
const gmx_mtop_t& mtop,
- const int* cginfo,
+ const int* atomInfo,
const bool checkDistanceMultiBody,
const ivec rcheck,
const gmx_bool checkDistanceTwoBody,
zones,
rt->molblockIndices(),
mtop.moltype,
- cginfo,
+ atomInfo,
excl_t,
izone,
cg0t,
int numBondedInteractionsToReduce = make_local_bondeds_excls(dd,
zones,
mtop,
- fr->cginfo.data(),
+ fr->atomInfo.data(),
checkDistanceMultiBody,
rcheck,
checkDistanceTwoBody,
}
}
-void makeBondedLinks(gmx_domdec_t* dd, const gmx_mtop_t& mtop, gmx::ArrayRef<cginfo_mb_t> cginfo_mb)
+void makeBondedLinks(gmx_domdec_t* dd,
+ const gmx_mtop_t& mtop,
+ gmx::ArrayRef<AtomInfoWithinMoleculeBlock> atomInfoForEachMoleculeBlock)
{
if (!dd->comm->systemInfo.filterBondedCommunication)
link->nalloc_a = 0;
link->a = nullptr;
- link->index[0] = 0;
- int cg_offset = 0;
- int ncgi = 0;
+ link->index[0] = 0;
+ int indexOfFirstAtomInMolecule = 0;
+ int numLinkedAtoms = 0;
for (size_t mb = 0; mb < mtop.molblock.size(); mb++)
{
const gmx_molblock_t& molb = mtop.molblock[mb];
reverse_ilist_t ril;
make_reverse_ilist(molt.ilist, &molt.atoms, rtOptions, AtomLinkRule::AllAtomsInBondeds, &ril);
- cginfo_mb_t* cgi_mb = &cginfo_mb[mb];
+ AtomInfoWithinMoleculeBlock* atomInfoOfMoleculeBlock = &atomInfoForEachMoleculeBlock[mb];
int mol = 0;
for (mol = 0; mol < (mtop.bIntermolecularInteractions ? molb.nmol : 1); mol++)
{
for (int a = 0; a < molt.atoms.nr; a++)
{
- int cg_gl = cg_offset + a;
- link->index[cg_gl + 1] = link->index[cg_gl];
- int i = ril.index[a];
+ int atomIndex = indexOfFirstAtomInMolecule + a;
+ link->index[atomIndex + 1] = link->index[atomIndex];
+ int i = ril.index[a];
while (i < ril.index[a + 1])
{
int ftype = ril.il[i++];
int aj = ril.il[i + j];
if (aj != a)
{
- check_link(link, cg_gl, cg_offset + aj);
+ check_link(link, atomIndex, indexOfFirstAtomInMolecule + aj);
}
}
i += nral_rt(ftype);
if (mtop.bIntermolecularInteractions)
{
- int i = ril_intermol.index[cg_gl];
- while (i < ril_intermol.index[cg_gl + 1])
+ int i = ril_intermol.index[atomIndex];
+ while (i < ril_intermol.index[atomIndex + 1])
{
int ftype = ril_intermol.il[i++];
int nral = NRAL(ftype);
* this has been checked above.
*/
int aj = ril_intermol.il[i + j];
- check_link(link, cg_gl, aj);
+ check_link(link, atomIndex, aj);
}
i += nral_rt(ftype);
}
}
- if (link->index[cg_gl + 1] - link->index[cg_gl] > 0)
+ if (link->index[atomIndex + 1] - link->index[atomIndex] > 0)
{
- SET_CGINFO_BOND_INTER(cgi_mb->cginfo[a]);
- ncgi++;
+ SET_CGINFO_BOND_INTER(atomInfoOfMoleculeBlock->atomInfo[a]);
+ numLinkedAtoms++;
}
}
- cg_offset += molt.atoms.nr;
+ indexOfFirstAtomInMolecule += molt.atoms.nr;
}
- int nlink_mol = link->index[cg_offset] - link->index[cg_offset - molt.atoms.nr];
+ int nlink_mol = link->index[indexOfFirstAtomInMolecule]
+ - link->index[indexOfFirstAtomInMolecule - molt.atoms.nr];
if (debug)
{
{
for (int a = 0; a < molt.atoms.nr; a++)
{
- int cg_gl = cg_offset + a;
- link->index[cg_gl + 1] = link->index[cg_gl + 1 - molt.atoms.nr] + nlink_mol;
- for (int j = link->index[cg_gl]; j < link->index[cg_gl + 1]; j++)
+ int atomIndex = indexOfFirstAtomInMolecule + a;
+ link->index[atomIndex + 1] = link->index[atomIndex + 1 - molt.atoms.nr] + nlink_mol;
+ for (int j = link->index[atomIndex]; j < link->index[atomIndex + 1]; j++)
{
link->a[j] = link->a[j - nlink_mol] + molt.atoms.nr;
}
- if (link->index[cg_gl + 1] - link->index[cg_gl] > 0
- && cg_gl - cgi_mb->cg_start < cgi_mb->cg_mod)
+ if (link->index[atomIndex + 1] - link->index[atomIndex] > 0
+ && atomIndex - atomInfoOfMoleculeBlock->indexOfFirstAtomInMoleculeBlock
+ < gmx::ssize(atomInfoOfMoleculeBlock->atomInfo))
{
- SET_CGINFO_BOND_INTER(cgi_mb->cginfo[cg_gl - cgi_mb->cg_start]);
- ncgi++;
+ SET_CGINFO_BOND_INTER(
+ atomInfoOfMoleculeBlock
+ ->atomInfo[atomIndex - atomInfoOfMoleculeBlock->indexOfFirstAtomInMoleculeBlock]);
+ numLinkedAtoms++;
}
}
- cg_offset += molt.atoms.nr;
+ indexOfFirstAtomInMolecule += molt.atoms.nr;
}
}
}
if (debug)
{
- fprintf(debug, "Of the %d atoms %d are linked via bonded interactions\n", mtop.natoms, ncgi);
+ fprintf(debug, "Of the %d atoms %d are linked via bonded interactions\n", mtop.natoms, numLinkedAtoms);
}
dd->comm->bondedLinks = link;
}
//! Sets the charge-group zones to be equal to the home zone.
-static void set_zones_ncg_home(gmx_domdec_t* dd)
+static void set_zones_numHomeAtoms(gmx_domdec_t* dd)
{
gmx_domdec_zones_t* zones;
int i;
zones->cg_range[0] = 0;
for (i = 1; i < zones->n + 1; i++)
{
- zones->cg_range[i] = dd->ncg_home;
+ zones->cg_range[i] = dd->numHomeAtoms;
}
- /* zone_ncg1[0] should always be equal to ncg_home */
- dd->comm->zone_ncg1[0] = dd->ncg_home;
+ /* zone_ncg1[0] should always be equal to numHomeAtoms */
+ dd->comm->zone_ncg1[0] = dd->numHomeAtoms;
}
//! Restore atom groups for the charge groups.
globalAtomGroupIndices[i] = atomGroupsState[i];
}
- dd->ncg_home = atomGroupsState.size();
+ dd->numHomeAtoms = atomGroupsState.size();
dd->comm->atomRanges.setEnd(DDAtomRanges::Type::Home, atomGroupsState.ssize());
- set_zones_ncg_home(dd);
+ set_zones_numHomeAtoms(dd);
}
-//! Sets the cginfo structures.
-static void dd_set_cginfo(gmx::ArrayRef<const int> index_gl, int cg0, int cg1, t_forcerec* fr)
+//! Sets the atom info structures.
+static void dd_set_atominfo(gmx::ArrayRef<const int> index_gl, int cg0, int cg1, t_forcerec* fr)
{
if (fr != nullptr)
{
- gmx::ArrayRef<cginfo_mb_t> cginfo_mb = fr->cginfo_mb;
- gmx::ArrayRef<int> cginfo = fr->cginfo;
+ gmx::ArrayRef<AtomInfoWithinMoleculeBlock> atomInfoForEachMoleculeBlock =
+ fr->atomInfoForEachMoleculeBlock;
+ gmx::ArrayRef<int> atomInfo = fr->atomInfo;
for (int cg = cg0; cg < cg1; cg++)
{
- cginfo[cg] = ddcginfo(cginfo_mb, index_gl[cg]);
+ atomInfo[cg] = ddGetAtomInfo(atomInfoForEachMoleculeBlock, index_gl[cg]);
}
}
}
std::vector<int>& globalAtomIndices = dd->globalAtomIndices;
gmx_ga2la_t& ga2la = *dd->ga2la;
- if (zone2cg[1] != dd->ncg_home)
+ if (zone2cg[1] != dd->numHomeAtoms)
{
gmx_incons("dd->ncg_zone is not up to date");
}
}
//! Merge atom buffers.
-static void merge_cg_buffers(int ncell,
- gmx_domdec_comm_dim_t* cd,
- int pulse,
- int* ncg_cell,
- gmx::ArrayRef<int> index_gl,
- const int* recv_i,
- gmx::ArrayRef<gmx::RVec> x,
- gmx::ArrayRef<const gmx::RVec> recv_vr,
- gmx::ArrayRef<cginfo_mb_t> cginfo_mb,
- gmx::ArrayRef<int> cginfo)
+static void merge_cg_buffers(int ncell,
+ gmx_domdec_comm_dim_t* cd,
+ int pulse,
+ int* ncg_cell,
+ gmx::ArrayRef<int> index_gl,
+ const int* recv_i,
+ gmx::ArrayRef<gmx::RVec> x,
+ gmx::ArrayRef<const gmx::RVec> recv_vr,
+ gmx::ArrayRef<AtomInfoWithinMoleculeBlock> atomInfoForEachMoleculeBlock,
+ gmx::ArrayRef<int> atomInfo)
{
gmx_domdec_ind_t *ind, *ind_p;
int p, cell, c, cg, cg0, cg1, cg_gl;
{
index_gl[cg + shift] = index_gl[cg];
x[cg + shift] = x[cg];
- cginfo[cg + shift] = cginfo[cg];
+ atomInfo[cg + shift] = atomInfo[cg];
}
/* Correct the already stored send indices for the shift */
for (p = 1; p <= pulse; p++)
index_gl[cg1] = recv_i[cg0];
x[cg1] = recv_vr[cg0];
/* Copy information */
- cg_gl = index_gl[cg1];
- cginfo[cg1] = ddcginfo(cginfo_mb, cg_gl);
+ cg_gl = index_gl[cg1];
+ atomInfo[cg1] = ddGetAtomInfo(atomInfoForEachMoleculeBlock, cg_gl);
cg0++;
cg1++;
}
gmx_bool bDist2B,
gmx_bool bDistMB,
gmx::ArrayRef<const gmx::RVec> coordinates,
- gmx::ArrayRef<const int> cginfo,
+ gmx::ArrayRef<const int> atomInfo,
std::vector<int>* localAtomGroups,
dd_comm_setup_work_t* work)
{
if (r2 < r_comm2
|| (bDistBonded && ((bDistMB && rb2 < r_bcomm2) || (bDist2B && r2 < r_bcomm2))
&& (!bBondComm
- || (GET_CGINFO_BOND_INTER(cginfo[cg])
+ || (GET_CGINFO_BOND_INTER(atomInfo[cg])
&& missing_link(*comm->bondedLinks, globalAtomGroupIndices[cg], *dd->ga2la)))))
{
/* Store the local and global atom group indices and position */
v_1 = ddbox->v[dim1];
}
- zone_cg_range = zones->cg_range.data();
- gmx::ArrayRef<cginfo_mb_t> cginfo_mb = fr->cginfo_mb;
+ zone_cg_range = zones->cg_range.data();
+ gmx::ArrayRef<AtomInfoWithinMoleculeBlock> atomInfoForEachMoleculeBlock =
+ fr->atomInfoForEachMoleculeBlock;
zone_cg_range[0] = 0;
- zone_cg_range[1] = dd->ncg_home;
- comm->zone_ncg1[0] = dd->ncg_home;
- pos_cg = dd->ncg_home;
+ zone_cg_range[1] = dd->numHomeAtoms;
+ comm->zone_ncg1[0] = dd->numHomeAtoms;
+ pos_cg = dd->numHomeAtoms;
nat_tot = comm->atomRanges.numHomeAtoms();
nzone = 1;
bDist2B,
bDistMB,
state->x,
- fr->cginfo,
+ fr->atomInfo,
th == 0 ? &ind->index : &work.localAtomGroupBuffer,
&work);
}
}
ddSendrecv<int>(dd, dim_ind, dddirBackward, work.atomGroupBuffer, integerBufferRef);
- /* Make space for cginfo */
+ /* Make space for atominfo */
dd_resize_atominfo_and_state(fr, state, pos_cg + ind->nrecv[nzone]);
/* Communicate the coordinates */
for (int i = 0; i < ind->nrecv[zone]; i++)
{
int globalAtomIndex = dd->globalAtomGroupIndices[pos_cg];
- fr->cginfo[pos_cg] = ddcginfo(cginfo_mb, globalAtomIndex);
+ fr->atomInfo[pos_cg] =
+ ddGetAtomInfo(atomInfoForEachMoleculeBlock, globalAtomIndex);
pos_cg++;
}
if (p == 0)
integerBufferRef.data(),
state->x,
rvecBufferRef,
- fr->cginfo_mb,
- fr->cginfo);
+ fr->atomInfoForEachMoleculeBlock,
+ fr->atomInfo);
pos_cg += ind->nrecv[nzone];
}
nat_tot += ind->nrecv[nzone + 1];
if (!bBondComm)
{
- /* We don't need to update cginfo, since that was alrady done above.
+ /* We don't need to update atominfo, since that was already done above.
* So we pass NULL for the forcerec.
*/
- dd_set_cginfo(dd->globalAtomGroupIndices, dd->ncg_home, dd->globalAtomGroupIndices.size(), nullptr);
+ dd_set_atominfo(
+ dd->globalAtomGroupIndices, dd->numHomeAtoms, dd->globalAtomGroupIndices.size(), nullptr);
}
if (debug)
dd_sort_order_nbnxn(fr, &sort->sorted);
/* We alloc with the old size, since cgindex is still old */
- DDBufferAccess<gmx::RVec> rvecBuffer(dd->comm->rvecBuffer, dd->ncg_home);
+ DDBufferAccess<gmx::RVec> rvecBuffer(dd->comm->rvecBuffer, dd->numHomeAtoms);
/* Set the new home atom/charge group count */
- dd->ncg_home = sort->sorted.size();
+ dd->numHomeAtoms = sort->sorted.size();
if (debug)
{
- fprintf(debug, "Set the new home atom count to %d\n", dd->ncg_home);
+ fprintf(debug, "Set the new home atom count to %d\n", dd->numHomeAtoms);
}
/* Reorder the state */
gmx::ArrayRef<const gmx_cgsort_t> cgsort = sort->sorted;
- GMX_RELEASE_ASSERT(cgsort.ssize() == dd->ncg_home, "We should sort all the home atom groups");
+ GMX_RELEASE_ASSERT(cgsort.ssize() == dd->numHomeAtoms,
+ "We should sort all the home atom groups");
if (state->flags & enumValueToBitMask(StateEntry::X))
{
/* Reorder the global cg index */
orderVector<int>(cgsort, dd->globalAtomGroupIndices, &sort->intBuffer);
- /* Reorder the cginfo */
- orderVector<int>(cgsort, fr->cginfo, &sort->intBuffer);
+ /* Reorder the atom info */
+ orderVector<int>(cgsort, fr->atomInfo, &sort->intBuffer);
/* Set the home atom number */
- dd->comm->atomRanges.setEnd(DDAtomRanges::Type::Home, dd->ncg_home);
+ dd->comm->atomRanges.setEnd(DDAtomRanges::Type::Home, dd->numHomeAtoms);
/* The atoms are now exactly in grid order, update the grid order */
fr->nbv->setLocalAtomOrder();
distributeState(mdlog, dd, top_global, state_global, ddbox, state_local);
/* Ensure that we have space for the new distribution */
- dd_resize_atominfo_and_state(fr, state_local, dd->ncg_home);
+ dd_resize_atominfo_and_state(fr, state_local, dd->numHomeAtoms);
inc_nrnb(nrnb, eNR_CGCM, comm->atomRanges.numHomeAtoms());
- dd_set_cginfo(dd->globalAtomGroupIndices, 0, dd->ncg_home, fr);
+ dd_set_atominfo(dd->globalAtomGroupIndices, 0, dd->numHomeAtoms, fr);
}
else if (state_local->ddp_count != dd->ddp_count)
{
/* Restore the atom group indices from state_local */
restoreAtomGroups(dd, state_local);
make_dd_indices(dd, 0);
- ncgindex_set = dd->ncg_home;
+ ncgindex_set = dd->numHomeAtoms;
inc_nrnb(nrnb, eNR_CGCM, comm->atomRanges.numHomeAtoms());
- dd_set_cginfo(dd->globalAtomGroupIndices, 0, dd->ncg_home, fr);
+ dd_set_atominfo(dd->globalAtomGroupIndices, 0, dd->numHomeAtoms, fr);
set_ddbox(*dd, bMasterState, state_local->box, true, state_local->x, &ddbox);
if (comm->systemInfo.useUpdateGroups)
{
comm->updateGroupsCog->addCogs(
- gmx::arrayRefFromArray(dd->globalAtomGroupIndices.data(), dd->ncg_home), state_local->x);
+ gmx::arrayRefFromArray(dd->globalAtomGroupIndices.data(), dd->numHomeAtoms),
+ state_local->x);
}
/* Check if we should sort the charge groups */
{
wallcycle_sub_start(wcycle, WallCycleSubCounter::DDRedist);
- ncgindex_set = dd->ncg_home;
+ ncgindex_set = dd->numHomeAtoms;
dd_redistribute_cg(fplog, step, dd, ddbox.tric_dir, state_local, fr, nrnb, &ncg_moved);
GMX_RELEASE_ASSERT(bSortCG, "Sorting is required after redistribution");
if (comm->systemInfo.useUpdateGroups)
{
comm->updateGroupsCog->addCogs(
- gmx::arrayRefFromArray(dd->globalAtomGroupIndices.data(), dd->ncg_home),
+ gmx::arrayRefFromArray(dd->globalAtomGroupIndices.data(), dd->numHomeAtoms),
state_local->x);
}
&ddbox,
&comm->cell_x0,
&comm->cell_x1,
- dd->ncg_home,
+ dd->numHomeAtoms,
as_rvec_array(state_local->x.data()),
cell_ns_x0,
cell_ns_x1);
/* Fill the ns grid with the home cell,
* so we can sort with the indices.
*/
- set_zones_ncg_home(dd);
+ set_zones_numHomeAtoms(dd);
set_zones_size(dd, state_local->box, &ddbox, 0, 1, ncg_moved);
comm->zones.size[0].bb_x0,
comm->zones.size[0].bb_x1,
comm->updateGroupsCog.get(),
- { 0, dd->ncg_home },
+ { 0, dd->numHomeAtoms },
comm->zones.dens_zone0,
- fr->cginfo,
+ fr->atomInfo,
state_local->x,
ncg_moved,
bRedist ? comm->movedBuffer.data() : nullptr);
if (debug)
{
- fprintf(debug, "Step %s, sorting the %d home charge groups\n", gmx_step_str(step, sbuf), dd->ncg_home);
+ fprintf(debug, "Step %s, sorting the %d home charge groups\n", gmx_step_str(step, sbuf), dd->numHomeAtoms);
}
dd_sort_state(dd, fr, state_local);
wallcycle_sub_start(wcycle, WallCycleSubCounter::DDSetupComm);
/* Set the induces for the home atoms */
- set_zones_ncg_home(dd);
+ set_zones_numHomeAtoms(dd);
make_dd_indices(dd, ncgindex_set);
/* Setup up the communication and communicate the coordinates */
setup_dd_communication(dd, state_local->box, &ddbox, fr, state_local);
/* Set the indices for the halo atoms */
- make_dd_indices(dd, dd->ncg_home);
+ make_dd_indices(dd, dd->numHomeAtoms);
/* Set the charge group boundaries for neighbor searching */
set_cg_boundaries(&comm->zones);
n = dd_make_local_constraints(dd,
n,
top_global,
- fr->cginfo.data(),
+ fr->atomInfo.data(),
constr,
inputrec.nProjOrder,
top_local->idef.il);
bool bV = (state->flags & enumValueToBitMask(StateEntry::V)) != 0;
bool bCGP = (state->flags & enumValueToBitMask(StateEntry::Cgp)) != 0;
- DDBufferAccess<int> moveBuffer(comm->intBuffer, dd->ncg_home);
+ DDBufferAccess<int> moveBuffer(comm->intBuffer, dd->numHomeAtoms);
gmx::ArrayRef<int> move = moveBuffer.buffer;
const int npbcdim = dd->unitCellInfo.npbcdim;
cell_x0,
cell_x1,
moveLimits,
- (thread * dd->ncg_home) / nthread,
- ((thread + 1) * dd->ncg_home) / nthread,
+ (thread * dd->numHomeAtoms) / nthread,
+ ((thread + 1) * dd->numHomeAtoms) / nthread,
move);
}
}
int ncg[DIM * 2] = { 0 };
int nat[DIM * 2] = { 0 };
- for (int cg = 0; cg < dd->ncg_home; cg++)
+ for (int cg = 0; cg < dd->numHomeAtoms; cg++)
{
if (move[cg] >= 0)
{
}
inc_nrnb(nrnb, eNR_CGCM, comm->atomRanges.numHomeAtoms());
- inc_nrnb(nrnb, eNR_RESETX, dd->ncg_home);
+ inc_nrnb(nrnb, eNR_RESETX, dd->numHomeAtoms);
*ncg_moved = 0;
for (int i = 0; i < dd->ndim * 2; i++)
copyMovedAtomsToBufferPerAtom(move, nvec, vectorIndex++, state->cg_p.rvec_array(), comm);
}
- int* moved = getMovedBuffer(comm, 0, dd->ncg_home);
+ int* moved = getMovedBuffer(comm, 0, dd->numHomeAtoms);
clear_and_mark_ind(move, dd->globalAtomIndices, dd->ga2la, moved);
/* Now we can remove the excess global atom-group indices from the list */
- dd->globalAtomGroupIndices.resize(dd->ncg_home);
+ dd->globalAtomGroupIndices.resize(dd->numHomeAtoms);
/* We reuse the intBuffer without reacquiring since we are in the same scope */
DDBufferAccess<int>& flagBuffer = moveBuffer;
- gmx::ArrayRef<const cginfo_mb_t> cginfo_mb = fr->cginfo_mb;
+ gmx::ArrayRef<const AtomInfoWithinMoleculeBlock> atomInfoForEachMoleculeBlock =
+ fr->atomInfoForEachMoleculeBlock;
/* Temporarily store atoms passed to our rank at the end of the range */
- int home_pos_cg = dd->ncg_home;
- int home_pos_at = dd->ncg_home;
+ int home_pos_cg = dd->numHomeAtoms;
+ int home_pos_at = dd->numHomeAtoms;
for (int d = 0; d < dd->ndim; d++)
{
DDBufferAccess<gmx::RVec> rvecBuffer(comm->rvecBuffer, 0);
buf_pos++;
/* Set the cginfo */
- fr->cginfo[home_pos_cg] = ddcginfo(cginfo_mb, globalAtomGroupIndex);
+ fr->atomInfo[home_pos_cg] =
+ ddGetAtomInfo(atomInfoForEachMoleculeBlock, globalAtomGroupIndex);
auto x = makeArrayRef(state->x);
auto v = makeArrayRef(state->v);
}
/* Note that the indices are now only partially up to date
- * and ncg_home and nat_home are not the real count, since there are
+ * and numHomeAtoms and nat_home are not the real count, since there are
* "holes" in the arrays for the charge groups that moved to neighbors.
*/
/* We need to clear the moved flags for the received atoms,
* because the moved buffer will be passed to the nbnxm gridding call.
*/
- moved = getMovedBuffer(comm, dd->ncg_home, home_pos_cg);
+ moved = getMovedBuffer(comm, dd->numHomeAtoms, home_pos_cg);
- for (int i = dd->ncg_home; i < home_pos_cg; i++)
+ for (int i = dd->numHomeAtoms; i < home_pos_cg; i++)
{
moved[i] = 0;
}
- dd->ncg_home = home_pos_cg;
+ dd->numHomeAtoms = home_pos_cg;
comm->atomRanges.setEnd(DDAtomRanges::Type::Home, home_pos_at);
if (debug)
fprintf(debug,
"Finished repartitioning: cgs moved out %d, new home %d\n",
*ncg_moved,
- dd->ncg_home - *ncg_moved);
+ dd->numHomeAtoms - *ncg_moved);
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
void dd_resize_atominfo_and_state(t_forcerec* fr, t_state* state, const int numAtoms)
{
- fr->cginfo.resize(numAtoms);
+ fr->atomInfo.resize(numAtoms);
/* We use x during the setup of the atom communication */
state_change_natoms(state, numAtoms);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
/*! \brief Ensure box obeys the screw restrictions, fatal error if not */
void check_screw_box(const matrix box);
-/*! \brief Return the charge group information flags for charge group cg */
-static inline int ddcginfo(gmx::ArrayRef<const cginfo_mb_t> cginfo_mb, int cg)
+/*! \brief Return the atom information flags for atom a */
+static inline int ddGetAtomInfo(gmx::ArrayRef<const AtomInfoWithinMoleculeBlock> atomInfoForEachMoleculeBlock,
+ int a)
{
size_t index = 0;
- while (cg >= cginfo_mb[index].cg_end)
+ while (a >= atomInfoForEachMoleculeBlock[index].indexOfLastAtomInMoleculeBlock)
{
index++;
}
- const cginfo_mb_t& cgimb = cginfo_mb[index];
+ const AtomInfoWithinMoleculeBlock& atomInfoOfMoleculeBlock = atomInfoForEachMoleculeBlock[index];
- return cgimb.cginfo[(cg - cgimb.cg_start) % cgimb.cg_mod];
+ return atomInfoOfMoleculeBlock.atomInfo[(a - atomInfoOfMoleculeBlock.indexOfFirstAtomInMoleculeBlock)
+ % atomInfoOfMoleculeBlock.atomInfo.size()];
};
/*! \brief Returns the number of MD steps for which load has been recorded */
return grid;
}
-enum
+//! What kind of constraint affects an atom
+enum class ConstraintTypeForAtom : int
{
- acNONE = 0,
- acCONSTRAINT,
- acSETTLE
+ None, //!< No constraint active
+ Constraint, //!< F_CONSTR or F_CONSTRNC active
+ Settle, //! F_SETTLE active
};
-static std::vector<cginfo_mb_t> init_cginfo_mb(const gmx_mtop_t& mtop, const t_forcerec* fr)
+static std::vector<AtomInfoWithinMoleculeBlock> makeAtomInfoForEachMoleculeBlock(const gmx_mtop_t& mtop,
+ const t_forcerec* fr)
{
- gmx_bool* type_VDW;
- int* a_con;
-
- snew(type_VDW, fr->ntype);
+ std::vector<bool> atomUsesVdw(fr->ntype, false);
for (int ai = 0; ai < fr->ntype; ai++)
{
- type_VDW[ai] = FALSE;
for (int j = 0; j < fr->ntype; j++)
{
- type_VDW[ai] = type_VDW[ai] || fr->haveBuckingham || C6(fr->nbfp, fr->ntype, ai, j) != 0
- || C12(fr->nbfp, fr->ntype, ai, j) != 0;
+ atomUsesVdw[ai] = atomUsesVdw[ai] || fr->haveBuckingham || C6(fr->nbfp, fr->ntype, ai, j) != 0
+ || C12(fr->nbfp, fr->ntype, ai, j) != 0;
}
}
- std::vector<cginfo_mb_t> cginfoPerMolblock;
- int a_offset = 0;
+ std::vector<AtomInfoWithinMoleculeBlock> atomInfoForEachMoleculeBlock;
+ int indexOfFirstAtomInMoleculeBlock = 0;
for (size_t mb = 0; mb < mtop.molblock.size(); mb++)
{
const gmx_molblock_t& molb = mtop.molblock[mb];
const gmx_moltype_t& molt = mtop.moltype[molb.type];
const auto& excl = molt.excls;
- /* Check if the cginfo is identical for all molecules in this block.
+ /* Check if all molecules in this block have identical
+ * atominfo. (That's true unless some kind of group- or
+ * distance-based algorithm is involved, e.g. QM/MM groups
+ * affecting multiple molecules within a block differently.)
* If so, we only need an array of the size of one molecule.
- * Otherwise we make an array of #mol times #cgs per molecule.
+ * Otherwise we make an array of #mol times #atoms per
+ * molecule.
*/
- gmx_bool bId = TRUE;
+ bool allMoleculesWithinBlockAreIdentical = true;
for (int m = 0; m < molb.nmol; m++)
{
- const int am = m * molt.atoms.nr;
+ const int numAtomsInAllMolecules = m * molt.atoms.nr;
for (int a = 0; a < molt.atoms.nr; a++)
{
- if (getGroupType(mtop.groups, SimulationAtomGroupType::QuantumMechanics, a_offset + am + a)
- != getGroupType(mtop.groups, SimulationAtomGroupType::QuantumMechanics, a_offset + a))
+ if (getGroupType(mtop.groups,
+ SimulationAtomGroupType::QuantumMechanics,
+ indexOfFirstAtomInMoleculeBlock + numAtomsInAllMolecules + a)
+ != getGroupType(mtop.groups,
+ SimulationAtomGroupType::QuantumMechanics,
+ indexOfFirstAtomInMoleculeBlock + a))
{
- bId = FALSE;
+ allMoleculesWithinBlockAreIdentical = false;
}
if (!mtop.groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].empty())
{
- if (mtop.groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics][a_offset + am + a]
- != mtop.groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics][a_offset + a])
+ if (mtop.groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics]
+ [indexOfFirstAtomInMoleculeBlock + numAtomsInAllMolecules + a]
+ != mtop.groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics]
+ [indexOfFirstAtomInMoleculeBlock + a])
{
- bId = FALSE;
+ allMoleculesWithinBlockAreIdentical = false;
}
}
}
}
- cginfo_mb_t cginfo_mb;
- cginfo_mb.cg_start = a_offset;
- cginfo_mb.cg_end = a_offset + molb.nmol * molt.atoms.nr;
- cginfo_mb.cg_mod = (bId ? 1 : molb.nmol) * molt.atoms.nr;
- cginfo_mb.cginfo.resize(cginfo_mb.cg_mod);
- gmx::ArrayRef<int> cginfo = cginfo_mb.cginfo;
+ AtomInfoWithinMoleculeBlock atomInfoOfMoleculeBlock;
+ atomInfoOfMoleculeBlock.indexOfFirstAtomInMoleculeBlock = indexOfFirstAtomInMoleculeBlock;
+ atomInfoOfMoleculeBlock.indexOfLastAtomInMoleculeBlock =
+ indexOfFirstAtomInMoleculeBlock + molb.nmol * molt.atoms.nr;
+ int atomInfoSize = (allMoleculesWithinBlockAreIdentical ? 1 : molb.nmol) * molt.atoms.nr;
+ atomInfoOfMoleculeBlock.atomInfo.resize(atomInfoSize);
/* Set constraints flags for constrained atoms */
- snew(a_con, molt.atoms.nr);
+ std::vector<ConstraintTypeForAtom> constraintTypeOfAtom(molt.atoms.nr, ConstraintTypeForAtom::None);
for (int ftype = 0; ftype < F_NRE; ftype++)
{
if (interaction_function[ftype].flags & IF_CONSTRAINT)
const int nral = NRAL(ftype);
for (int ia = 0; ia < molt.ilist[ftype].size(); ia += 1 + nral)
{
- int a;
-
- for (a = 0; a < nral; a++)
+ for (int a = 0; a < nral; a++)
{
- a_con[molt.ilist[ftype].iatoms[ia + 1 + a]] =
- (ftype == F_SETTLE ? acSETTLE : acCONSTRAINT);
+ constraintTypeOfAtom[molt.ilist[ftype].iatoms[ia + 1 + a]] =
+ (ftype == F_SETTLE ? ConstraintTypeForAtom::Settle
+ : ConstraintTypeForAtom::Constraint);
}
}
}
}
- for (int m = 0; m < (bId ? 1 : molb.nmol); m++)
+ for (int m = 0; m < (allMoleculesWithinBlockAreIdentical ? 1 : molb.nmol); m++)
{
- const int molculeOffsetInBlock = m * molt.atoms.nr;
+ const int moleculeOffsetInBlock = m * molt.atoms.nr;
for (int a = 0; a < molt.atoms.nr; a++)
{
- const t_atom& atom = molt.atoms.atom[a];
- int& atomInfo = cginfo[molculeOffsetInBlock + a];
+ const t_atom& atom = molt.atoms.atom[a];
+ int& atomInfo = atomInfoOfMoleculeBlock.atomInfo[moleculeOffsetInBlock + a];
- /* Store the energy group in cginfo */
+ /* Store the energy group in atomInfo */
int gid = getGroupType(mtop.groups,
SimulationAtomGroupType::EnergyOutput,
- a_offset + molculeOffsetInBlock + a);
+ indexOfFirstAtomInMoleculeBlock + moleculeOffsetInBlock + a);
SET_CGINFO_GID(atomInfo, gid);
- bool bHaveVDW = (type_VDW[atom.type] || type_VDW[atom.typeB]);
+ bool bHaveVDW = (atomUsesVdw[atom.type] || atomUsesVdw[atom.typeB]);
bool bHaveQ = (atom.q != 0 || atom.qB != 0);
bool haveExclusions = false;
}
}
- switch (a_con[a])
+ switch (constraintTypeOfAtom[a])
{
- case acCONSTRAINT: SET_CGINFO_CONSTR(atomInfo); break;
- case acSETTLE: SET_CGINFO_SETTLE(atomInfo); break;
+ case ConstraintTypeForAtom::Constraint: SET_CGINFO_CONSTR(atomInfo); break;
+ case ConstraintTypeForAtom::Settle: SET_CGINFO_SETTLE(atomInfo); break;
default: break;
}
if (haveExclusions)
}
}
- sfree(a_con);
-
- cginfoPerMolblock.push_back(cginfo_mb);
+ atomInfoForEachMoleculeBlock.push_back(atomInfoOfMoleculeBlock);
- a_offset += molb.nmol * molt.atoms.nr;
+ indexOfFirstAtomInMoleculeBlock += molb.nmol * molt.atoms.nr;
}
- sfree(type_VDW);
- return cginfoPerMolblock;
+ return atomInfoForEachMoleculeBlock;
}
-static std::vector<int> cginfo_expand(const int nmb, gmx::ArrayRef<const cginfo_mb_t> cgi_mb)
+static std::vector<int> expandAtomInfo(const int nmb,
+ gmx::ArrayRef<const AtomInfoWithinMoleculeBlock> atomInfoForEachMoleculeBlock)
{
- const int ncg = cgi_mb[nmb - 1].cg_end;
+ const int numAtoms = atomInfoForEachMoleculeBlock[nmb - 1].indexOfLastAtomInMoleculeBlock;
- std::vector<int> cginfo(ncg);
+ std::vector<int> atomInfo(numAtoms);
int mb = 0;
- for (int cg = 0; cg < ncg; cg++)
+ for (int a = 0; a < numAtoms; a++)
{
- while (cg >= cgi_mb[mb].cg_end)
+ while (a >= atomInfoForEachMoleculeBlock[mb].indexOfLastAtomInMoleculeBlock)
{
mb++;
}
- cginfo[cg] = cgi_mb[mb].cginfo[(cg - cgi_mb[mb].cg_start) % cgi_mb[mb].cg_mod];
+ atomInfo[a] = atomInfoForEachMoleculeBlock[mb]
+ .atomInfo[(a - atomInfoForEachMoleculeBlock[mb].indexOfFirstAtomInMoleculeBlock)
+ % atomInfoForEachMoleculeBlock[mb].atomInfo.size()];
}
- return cginfo;
+ return atomInfo;
}
/* Sets the sum of charges (squared) and C6 in the system in fr.
}
/* Set all the static charge group info */
- forcerec->cginfo_mb = init_cginfo_mb(mtop, forcerec);
+ forcerec->atomInfoForEachMoleculeBlock = makeAtomInfoForEachMoleculeBlock(mtop, forcerec);
if (!DOMAINDECOMP(commrec))
{
- forcerec->cginfo = cginfo_expand(mtop.molblock.size(), forcerec->cginfo_mb);
+ forcerec->atomInfo = expandAtomInfo(mtop.molblock.size(), forcerec->atomInfoForEachMoleculeBlock);
}
if (!DOMAINDECOMP(commrec))
nullptr,
{ 0, mdatoms->homenr },
-1,
- fr->cginfo,
+ fr->atomInfo,
x.unpaddedArrayRef(),
0,
nullptr);
else
{
wallcycle_sub_start(wcycle, WallCycleSubCounter::NBSGridNonLocal);
- nbnxn_put_on_grid_nonlocal(nbv, domdec_zones(cr->dd), fr->cginfo, x.unpaddedArrayRef());
+ nbnxn_put_on_grid_nonlocal(nbv, domdec_zones(cr->dd), fr->atomInfo, x.unpaddedArrayRef());
wallcycle_sub_stop(wcycle, WallCycleSubCounter::NBSGridNonLocal);
}
nbv->setAtomProperties(gmx::constArrayRefFromArray(mdatoms->typeA, mdatoms->nr),
gmx::constArrayRefFromArray(mdatoms->chargeA, mdatoms->nr),
- fr->cginfo);
+ fr->atomInfo);
wallcycle_stop(wcycle, WallCycleCounter::NS);
{
GMX_RELEASE_ASSERT(fr, "fr was NULL while cr->duty was DUTY_PP");
/* This call is not included in init_domain_decomposition
- * because fr->cginfo_mb is set later.
+ * because fr->atomInfoForEachMoleculeBlock is set later.
*/
- makeBondedLinks(cr->dd, mtop, fr->cginfo_mb);
+ makeBondedLinks(cr->dd, mtop, fr->atomInfoForEachMoleculeBlock);
}
if (runScheduleWork.simulationWork.useGpuBufferOps)
fr->nbv->changePairlistRadii(inputrec->rlist, inputrec->rlist);
ngid = groups->groups[SimulationAtomGroupType::EnergyOutput].size();
- gid_tp = GET_CGINFO_GID(fr->cginfo[a_tp0]);
+ gid_tp = GET_CGINFO_GID(fr->atomInfo[a_tp0]);
for (int a = a_tp0 + 1; a < a_tp1; a++)
{
- if (GET_CGINFO_GID(fr->cginfo[a]) != gid_tp)
+ if (GET_CGINFO_GID(fr->atomInfo[a]) != gid_tp)
{
fprintf(fplog,
"NOTE: Atoms in the molecule to insert belong to different energy groups.\n"
rvec vzero = { 0, 0, 0 };
rvec boxDiagonal = { box[XX][XX], box[YY][YY], box[ZZ][ZZ] };
nbnxn_put_on_grid(
- fr->nbv.get(), box, 0, vzero, boxDiagonal, nullptr, { 0, a_tp0 }, -1, fr->cginfo, x, 0, nullptr);
+ fr->nbv.get(), box, 0, vzero, boxDiagonal, nullptr, { 0, a_tp0 }, -1, fr->atomInfo, x, 0, nullptr);
step = cr->nodeid * stepblocksize;
while (step < nsteps)
/* Put the inserted molecule on it's own search grid */
nbnxn_put_on_grid(
- fr->nbv.get(), box, 1, x_init, x_init, nullptr, { a_tp0, a_tp1 }, -1, fr->cginfo, x, 0, nullptr);
+ fr->nbv.get(), box, 1, x_init, x_init, nullptr, { a_tp0, a_tp1 }, -1, fr->atomInfo, x, 0, nullptr);
/* TODO: Avoid updating all atoms at every bNS step */
fr->nbv->setAtomProperties(gmx::constArrayRefFromArray(mdatoms->typeA, mdatoms->nr),
gmx::constArrayRefFromArray(mdatoms->chargeA, mdatoms->nr),
- fr->cginfo);
+ fr->atomInfo);
fr->nbv->constructPairlist(InteractionLocality::Local, top.excls, step, nrnb);
class WholeMoleculeTransform;
} // namespace gmx
-/* macros for the cginfo data in forcerec
+/* macros for the atom info data in forcerec
*
* Since the tpx format support max 256 energy groups, we do the same here.
* Note that we thus have bits 8-14 still unused.
- *
- * The maximum cg size in cginfo is 63
- * because we only have space for 6 bits in cginfo,
- * this cg size entry is actually only read with domain decomposition.
*/
#define SET_CGINFO_GID(cgi, gid) (cgi) = (((cgi) & ~255) | (gid))
#define GET_CGINFO_GID(cgi) ((cgi)&255)
//! Check the cuttoff
real cutoff_inf(real cutoff);
-struct cginfo_mb_t
+/*! \brief Contains information about each atom in a molecule block of
+ * the global topology. */
+struct AtomInfoWithinMoleculeBlock
{
- int cg_start = 0;
- int cg_end = 0;
- int cg_mod = 0;
- std::vector<int> cginfo;
+ //! Index within the system of the first atom in the molecule block
+ int indexOfFirstAtomInMoleculeBlock = 0;
+ //! Index within the system of the last atom in the molecule block
+ int indexOfLastAtomInMoleculeBlock = 0;
+ /*! \brief Atom info for each atom in the block.
+ *
+ * The typical case is that all atoms are identical for each
+ * molecule of the block, and if so this vector has size equal to
+ * the number of atoms in the molecule.
+ *
+ * An example of an atypical case is QM/MM, where multiple
+ * molecules might be present and different molecules have
+ * different atoms within any one QM group or region. Now there are
+ * multiple kinds of molecules with the same connectivity, so we simply
+ * write out the atom info for the entire molecule block. Then the
+ * size equals the product of the number of atoms in the
+ * molecule and the number of molecules.
+ *
+ * The vector needs to be indexed accordingly. */
+ std::vector<int> atomInfo;
};
/* Free energy */
FreeEnergyPerturbationType efep = FreeEnergyPerturbationType::No;
- /* Information about atom properties for the molecule blocks in the system */
- std::vector<cginfo_mb_t> cginfo_mb;
+ /* Information about atom properties for the molecule blocks in the global topology */
+ std::vector<AtomInfoWithinMoleculeBlock> atomInfoForEachMoleculeBlock;
/* Information about atom properties for local and non-local atoms */
- std::vector<int> cginfo;
+ std::vector<int> atomInfo;
std::vector<gmx::RVec> shift_vec;