namespace gmx
{
-bool BiasParams::isCheckStep(std::size_t numPointsInHistogram,
- gmx_int64_t step) const
-{
- int numStepsUpdateFreeEnergy = numSamplesUpdateFreeEnergy_*numStepsSampleCoord_;
- int numStepsCheck = (1 + numPointsInHistogram/numSamplesUpdateFreeEnergy_)*numStepsUpdateFreeEnergy;
-
- if (step > 0 && step % numStepsCheck == 0)
- {
- GMX_ASSERT(isUpdateFreeEnergyStep(step), "We should only check at free-energy update steps");
-
- return true;
- }
- else
- {
- return false;
- }
-}
-
namespace
{
return numStepsUpdateTarget;
}
+/*! \brief Determines the step interval for checking for covering.
+ *
+ * \param[in] awhParams AWH parameters.
+ * \param[in] dimParams Parameters for the dimensions of the coordinate.
+ * \param[in] gridAxis The Grid axes.
+ * \returns the check interval in steps.
+ */
+gmx_int64_t calcCheckCoveringInterval(const AwhParams &awhParams,
+ const std::vector<DimParams> &dimParams,
+ const std::vector<GridAxis> &gridAxis)
+{
+ /* Each sample will have a width of sigma. To cover the axis a
+ minimum number of samples of width sigma is required. */
+ int minNumSamplesCover = 0;
+ for (size_t d = 0; d < gridAxis.size(); d++)
+ {
+ GMX_RELEASE_ASSERT(dimParams[d].betak > 0, "Inverse temperature (beta) and force constant (k) should be positive.");
+ double sigma = 1.0/std::sqrt(dimParams[d].betak);
+
+ /* The additional sample is here because to cover a discretized
+ axis of length sigma one needs two samples, one for each
+ end point. */
+ GMX_RELEASE_ASSERT(gridAxis[d].length()/sigma < std::numeric_limits<int>::max(), "The axis length in units of sigma should fit in an int");
+ int numSamplesCover = static_cast<int>(std::ceil(gridAxis[d].length()/sigma)) + 1;
+
+ /* The minimum number of samples needed for simultaneously
+ covering all axes is limited by the axis requiring most
+ samples. */
+ minNumSamplesCover = std::max(minNumSamplesCover, numSamplesCover);
+ }
+
+ /* Convert to number of steps using the sampling frequency. The
+ check interval should be a multiple of the update step
+ interval. */
+ int numStepsUpdate = awhParams.numSamplesUpdateFreeEnergy*awhParams.nstSampleCoord;
+ GMX_RELEASE_ASSERT(awhParams.numSamplesUpdateFreeEnergy > 0, "When checking for AWH coverings, the number of samples per AWH update need to be > 0.");
+ int numUpdatesCheck = std::max(1, minNumSamplesCover/awhParams.numSamplesUpdateFreeEnergy);
+ int numStepsCheck = numUpdatesCheck*numStepsUpdate;
+
+ GMX_RELEASE_ASSERT(numStepsCheck % numStepsUpdate == 0, "Only check covering at free energy update steps");
+
+ return numStepsCheck;
+}
+
/*! \brief
* Returns an approximation of the geometry factor used for initializing the AWH update size.
*
numStepsSampleCoord_(awhParams.nstSampleCoord),
numSamplesUpdateFreeEnergy_(awhParams.numSamplesUpdateFreeEnergy),
numStepsUpdateTarget_(calcTargetUpdateInterval(awhParams, awhBiasParams)),
+ numStepsCheckCovering_(calcCheckCoveringInterval(awhParams, dimParams, gridAxis)),
eTarget(awhBiasParams.eTarget),
freeEnergyCutoffInKT(beta*awhBiasParams.targetCutoff),
temperatureScaleFactor(awhBiasParams.targetBetaScaling),