int izone,
const gmx::Range<int>& atomRange)
{
- int mb = 0;
- int mt = 0;
- int mol = 0;
- int atomIndexInMolecule = 0;
-
const auto ddBondedChecking = rt->options().ddBondedChecking;
int numBondedInteractions = 0;
for (int i : atomRange)
{
/* Get the global atom number */
- const int globalAtomIndex = globalAtomIndices[i];
- global_atomnr_to_moltype_ind(
- rt->molblockIndices(), globalAtomIndex, &mb, &mt, &mol, &atomIndexInMolecule);
+ const int globalAtomIndex = globalAtomIndices[i];
+ const MolecularTopologyAtomIndices mtai =
+ globalAtomIndexToMoltypeIndices(rt->molblockIndices(), globalAtomIndex);
/* Check all intramolecular interactions assigned to this atom */
- gmx::ArrayRef<const int> index = rt->interactionListForMoleculeType(mt).index;
- gmx::ArrayRef<const t_iatom> rtil = rt->interactionListForMoleculeType(mt).il;
+ const auto& ilistMol = rt->interactionListForMoleculeType(mtai.moleculeType);
+ gmx::ArrayRef<const int> index = ilistMol.index;
+ gmx::ArrayRef<const t_iatom> rtil = ilistMol.il;
numBondedInteractions += assignInteractionsForAtom<InteractionConnectivity::Intramolecular>(
i,
globalAtomIndex,
- atomIndexInMolecule,
+ mtai.atomIndex,
index,
rtil,
- index[atomIndexInMolecule],
- index[atomIndexInMolecule + 1],
+ index[mtai.atomIndex],
+ index[mtai.atomIndex + 1],
ga2la,
zones,
checkDistanceMultiBody,
// Assign position restraints, when present, for the home zone
if (izone == 0 && rt->hasPositionRestraints())
{
- numBondedInteractions += assignPositionRestraintsForAtom(
- i,
- mol,
- atomIndexInMolecule,
- rt->interactionListForMoleculeType(mt).numAtomsInMolecule,
- rtil,
- index[atomIndexInMolecule],
- index[atomIndexInMolecule + 1],
- molb[mb],
- ip_in,
- idef);
+ numBondedInteractions += assignPositionRestraintsForAtom(i,
+ mtai.moleculeIndex,
+ mtai.atomIndex,
+ ilistMol.numAtomsInMolecule,
+ rtil,
+ index[mtai.atomIndex],
+ index[mtai.atomIndex + 1],
+ molb[mtai.blockIndex],
+ ip_in,
+ idef);
}
if (rt->hasIntermolecularInteractions())
{
/* Check all intermolecular interactions assigned to this atom */
- index = rt->interactionListForIntermolecularInteractions().index;
- rtil = rt->interactionListForIntermolecularInteractions().il;
+ const auto& ilistIntermol = rt->interactionListForIntermolecularInteractions();
+ index = ilistIntermol.index;
+ rtil = ilistIntermol.il;
numBondedInteractions += assignInteractionsForAtom<InteractionConnectivity::Intermolecular>(
i,
if (atomInfo[at] & gmx::sc_atomInfo_Exclusion)
{
- int mb = 0;
- int mt = 0;
- int mol = 0;
- int a_mol = 0;
-
/* Copy the exclusions from the global top */
- int a_gl = globalAtomIndices[at];
- global_atomnr_to_moltype_ind(molblockIndices, a_gl, &mb, &mt, &mol, &a_mol);
- const auto excls = moltype[mt].excls[a_mol];
- for (const int aj_mol : excls)
+ const int globalAtomIndex = globalAtomIndices[at];
+ const MolecularTopologyAtomIndices mtai =
+ globalAtomIndexToMoltypeIndices(molblockIndices, globalAtomIndex);
+ const auto& excls = moltype[mtai.moleculeType].excls[mtai.atomIndex];
+ for (const int excludedAtomIndexInMolecule : excls)
{
- if (const auto* jEntry = ga2la.find(a_gl + aj_mol - a_mol))
+ if (const auto* jEntry =
+ ga2la.find(globalAtomIndex + excludedAtomIndexInMolecule - mtai.atomIndex))
{
/* This check is not necessary, but it can reduce
* the number of exclusions in the list, which in turn
|| (rtOptions.includeSettles && ftype == F_SETTLE));
}
-void global_atomnr_to_moltype_ind(ArrayRef<const MolblockIndices> molblockIndices,
- int i_gl,
- int* mb,
- int* mt,
- int* mol,
- int* i_mol)
+MolecularTopologyAtomIndices globalAtomIndexToMoltypeIndices(const gmx::ArrayRef<const MolblockIndices> molblockIndices,
+ const int globalAtomIndex)
{
- const MolblockIndices* mbi = molblockIndices.data();
- int start = 0;
- int end = molblockIndices.size(); /* exclusive */
- int mid = 0;
+ // Find the molblock the atom belongs to using bisection
+ int start = 0;
+ int end = molblockIndices.size(); /* exclusive */
+ int mid = 0;
- /* binary search for molblock_ind */
- while (TRUE)
+ while (true)
{
mid = (start + end) / 2;
- if (i_gl >= mbi[mid].a_end)
+ if (globalAtomIndex >= molblockIndices[mid].a_end)
{
start = mid + 1;
}
- else if (i_gl < mbi[mid].a_start)
+ else if (globalAtomIndex < molblockIndices[mid].a_start)
{
end = mid;
}
}
}
- *mb = mid;
- mbi += mid;
+ const MolblockIndices& mbi = molblockIndices[mid];
- *mt = mbi->type;
- *mol = (i_gl - mbi->a_start) / mbi->natoms_mol;
- *i_mol = (i_gl - mbi->a_start) - (*mol) * mbi->natoms_mol;
+ MolecularTopologyAtomIndices mtai;
+
+ mtai.blockIndex = mid;
+ mtai.moleculeType = mbi.type;
+ mtai.moleculeIndex = (globalAtomIndex - mbi.a_start) / mbi.natoms_mol;
+ mtai.atomIndex = (globalAtomIndex - mbi.a_start) - mtai.moleculeIndex * mbi.natoms_mol;
+
+ return mtai;
}
/*! \brief Returns the maximum number of exclusions per atom */
/*! \brief Return whether interactions of type \p ftype need to be assigned exactly once */
bool dd_check_ftype(int ftype, const ReverseTopOptions& rtOptions);
-/*! \brief Return global topology molecule information for global atom index \p i_gl */
-void global_atomnr_to_moltype_ind(gmx::ArrayRef<const MolblockIndices> molblockIndices,
- int i_gl,
- int* mb,
- int* mt,
- int* mol,
- int* i_mol);
+//! Molecular topology indices of a global molecule a global atom belongs to
+struct MolecularTopologyAtomIndices
+{
+ //! The index of the molecule block
+ int blockIndex;
+ //! The molecule type
+ int moleculeType;
+ //! The index of the molecule in the block
+ int moleculeIndex;
+ //! The index of the atom in the molecule
+ int atomIndex;
+};
+
+//! Return global topology molecule information for global atom index \p globalAtomIndex
+MolecularTopologyAtomIndices globalAtomIndexToMoltypeIndices(gmx::ArrayRef<const MolblockIndices> molblockIndices,
+ int globalAtomIndex);
/*! \brief Make the reverse ilist: a list of bonded interactions linked to atoms */
void make_reverse_ilist(const InteractionLists& ilist,