- impl_->numBondedInteractionsToReduce_ = numBondedInteractionsToReduce;
- // Note that it's possible for this to still be true from the last
- // time it was set, e.g. if repartitioning was triggered before
- // global communication that would have acted on the true
- // value. This could happen for example when replica exchange took
- // place soon after a partition.
- impl_->shouldCheckNumberOfBondedInteractions_ = true;
- // Clear the old global value, which is now invalid
- impl_->numBondedInteractionsOverAllDomains_.reset();
-}
-
-bool LocalTopologyChecker::shouldCheckNumberOfBondedInteractions() const
-{
- return impl_->shouldCheckNumberOfBondedInteractions_;
-}
-
-int LocalTopologyChecker::numBondedInteractions() const
-{
- return impl_->numBondedInteractionsToReduce_;
-}
-
-void LocalTopologyChecker::setNumberOfBondedInteractionsOverAllDomains(const int newValue)
-{
- GMX_RELEASE_ASSERT(!impl_->numBondedInteractionsOverAllDomains_.has_value(),
- "Cannot set number of bonded interactions because it is already set");
- impl_->numBondedInteractionsOverAllDomains_.emplace(newValue);
-}
-
-void LocalTopologyChecker::checkNumberOfBondedInteractions(const gmx_localtop_t* top_local,
- ArrayRef<const RVec> x,
- const matrix box)
-{
- if (impl_->shouldCheckNumberOfBondedInteractions_)
- {
- GMX_RELEASE_ASSERT(impl_->numBondedInteractionsOverAllDomains_.has_value(),
- "The check for the total number of bonded interactions requires the "
- "value to have been reduced across all domains");
- if (impl_->numBondedInteractionsOverAllDomains_.value() != impl_->expectedNumGlobalBondedInteractions_)
- {
- dd_print_missing_interactions(impl_->mdlog_,
- impl_->cr_,
- impl_->numBondedInteractionsOverAllDomains_.value(),
- impl_->expectedNumGlobalBondedInteractions_,
- impl_->mtop_,
- top_local,
- x,
- box); // Does not return
- }
- // Now that the value is set and the check complete, future
- // global communication should not compute the value until
- // after the next partitioning.
- impl_->shouldCheckNumberOfBondedInteractions_ = false;
- }
+ // Fill the reduction buffer with the value from this domain to reduce
+ impl_->reductionBuffer_[0] = double(numBondedInteractionsToReduce);
+
+ // Pass the post-reduction callback to the ObservablesReducer via
+ // the callback it gave us for the purpose.
+ //
+ // Note that it's possible that the callbackAfterReduction is already
+ // outstanding, e.g. if repartitioning was triggered before
+ // observables were reduced. This could happen for example when
+ // replica exchange took place soon after a partition. If so, the
+ // callback will be called again. So long as there is no race
+ // between the calls to this function and the calls to
+ // ObservablesReducer for reduction, this will work correctly. It
+ // could be made safer e.g. with checks against duplicate
+ // callbacks, but there is no problem to solve.
+ //
+ // There is no need to check the return value from this callback,
+ // as it is not an error to request reduction at a future step.
+ impl_->callbackToRequireReduction_(ReductionRequirement::Eventually);