GPU version of update and constraints can now be used for FEP, except mass and constraints
free-energy perturbation.
+
+Reduce time spent in grompp with large numbers of distance restraints
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+The time `gmx grompp` spent processing distance restraint has been
+changed from quadratic in the number of restraints to linear.
+
+:issue:`3457`
bool bAppend)
{
t_iparams newparam;
- int type;
int rc;
if ((rc = assign_param(ftype, &newparam, forceparams, comb, reppow)) < 0)
if (!bAppend)
{
- for (type = start; (type < ffparams->numTypes()); type++)
+ if (ftype != F_DISRES)
{
- if (ffparams->functype[type] == ftype)
+ for (int type = start; type < ffparams->numTypes(); type++)
{
- if (memcmp(&newparam, &ffparams->iparams[type], static_cast<size_t>(sizeof(newparam))) == 0)
+ // Note that the first condition is always met by starting the loop at start
+ if (ffparams->functype[type] == ftype
+ && memcmp(&newparam, &ffparams->iparams[type], static_cast<size_t>(sizeof(newparam))) == 0)
{
return type;
}
}
}
+ else
+ {
+ // Distance restraints should have unique labels and pairs with the same label
+ // should be consecutive, so we here we only need to check the last type in the list.
+ // This changes the complexity from quadratic to linear in the number of restraints.
+ const int type = ffparams->numTypes() - 1;
+ if (type >= 0 && ffparams->functype[type] == ftype
+ && memcmp(&newparam, &ffparams->iparams[type], static_cast<size_t>(sizeof(newparam))) == 0)
+ {
+ return type;
+ }
+ }
}
- else
- {
- type = ffparams->numTypes();
- }
+
+ const int type = ffparams->numTypes();
ffparams->iparams.push_back(newparam);
ffparams->functype.push_back(ftype);