Add SIMD for AWH
[gromacs.git] / src / gromacs / awh / bias.cpp
blob36f3af0e42807a5de75e6e57d79718c8869bbcd8
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
36 /*! \internal \file
37 * \brief
38 * Implements the Bias class.
40 * \author Viveca Lindahl
41 * \author Berk Hess <hess@kth.se>
42 * \ingroup module_awh
45 #include "gmxpre.h"
47 #include "bias.h"
49 #include <assert.h>
51 #include <cmath>
52 #include <cstdio>
53 #include <cstdlib>
54 #include <cstring>
56 #include <algorithm>
58 #include "gromacs/fileio/gmxfio.h"
59 #include "gromacs/gmxlib/network.h"
60 #include "gromacs/math/utilities.h"
61 #include "gromacs/mdtypes/awh-history.h"
62 #include "gromacs/mdtypes/awh-params.h"
63 #include "gromacs/mdtypes/commrec.h"
64 #include "gromacs/utility/exceptions.h"
65 #include "gromacs/utility/gmxassert.h"
66 #include "gromacs/utility/stringutil.h"
68 #include "pointstate.h"
70 namespace gmx
73 void Bias::warnForHistogramAnomalies(double t, gmx_int64_t step, FILE *fplog)
75 const int maxNumWarningsInCheck = 1; /* The maximum number of warnings to print per check */
76 const int maxNumWarningsInRun = 10; /* The maximum number of warnings to print in a run */
78 if (fplog == nullptr || numWarningsIssued_ >= maxNumWarningsInRun || state_.inInitialStage() ||
79 !params_.isCheckStep(state_.points().size(), step))
81 return;
84 numWarningsIssued_ +=
85 state_.warnForHistogramAnomalies(grid_, biasIndex(), t, fplog,
86 maxNumWarningsInCheck);
88 if (numWarningsIssued_ >= maxNumWarningsInRun)
90 fprintf(fplog, "\nawh%d: suppressing future AWH warnings.\n", biasIndex() + 1);
94 void Bias::doSkippedUpdatesForAllPoints()
96 state_.doSkippedUpdatesForAllPoints(params_);
99 void Bias::calcForceAndUpdateBias(const awh_dvec coordValue,
100 awh_dvec biasForce,
101 double *awhPotential,
102 double *potentialJump,
103 const gmx_multisim_t *ms,
104 double t,
105 gmx_int64_t step,
106 gmx_int64_t seed,
107 FILE *fplog)
109 if (step < 0)
111 GMX_THROW(InvalidInputError("The step number is negative which is not supported by the AWH code."));
114 state_.setCoordValue(grid_, coordValue);
116 std::vector < double, AlignedAllocator < double>> &probWeightNeighbor = alignedTempWorkSpace_;
118 /* If the convolved force is needed or this is a sampling step,
119 * the bias in the current neighborhood needs to be up-to-date
120 * and the probablity weights need to be calculated.
122 const bool sampleCoord = params_.isSampleCoordStep(step);
123 const bool moveUmbrella = (sampleCoord || step == 0);
124 double convolvedBias = 0;
125 if (params_.convolveForce || moveUmbrella || sampleCoord)
127 if (params_.skipUpdates())
129 state_.doSkippedUpdatesInNeighborhood(params_, grid_);
132 convolvedBias = state_.updateProbabilityWeightsAndConvolvedBias(dimParams_, grid_, &probWeightNeighbor);
134 if (sampleCoord)
136 state_.sampleCoordAndPmf(grid_, probWeightNeighbor, convolvedBias);
140 const CoordState &coordState = state_.coordState();
142 /* Set the bias force and get the potential contribution from this bias.
143 * The potential jump occurs at different times depending on how
144 * the force is applied (and how the potential is normalized).
145 * For the convolved force it happens when the bias is updated,
146 * for the umbrella when the umbrella is moved.
148 *potentialJump = 0;
149 double potential;
150 if (params_.convolveForce)
152 state_.calcConvolvedForce(dimParams_, grid_, probWeightNeighbor,
153 biasForce);
155 potential = -convolvedBias*params_.invBeta;
157 else
159 /* Umbrella force */
160 GMX_RELEASE_ASSERT(state_.points()[coordState.umbrellaGridpoint()].inTargetRegion(),
161 "AWH bias grid point for the umbrella reference value is outside of the target region.");
162 potential =
163 state_.calcUmbrellaForceAndPotential(dimParams_, grid_, coordState.umbrellaGridpoint(), biasForce);
165 /* Moving the umbrella results in a force correction and
166 * a new potential. The umbrella center is sampled as often as
167 * the coordinate so we know the probability weights needed
168 * for moving the umbrella are up-to-date.
170 if (moveUmbrella)
172 double newPotential = state_.moveUmbrella(dimParams_, grid_, probWeightNeighbor, biasForce, step, seed, params_.biasIndex);
173 *potentialJump = newPotential - potential;
177 /* Update the free energy estimates and bias and other history dependent method parameters */
178 if (params_.isUpdateFreeEnergyStep(step))
180 state_.updateFreeEnergyAndAddSamplesToHistogram(dimParams_, grid_,
181 params_,
182 ms, t, step, fplog,
183 &updateList_);
185 if (params_.convolveForce)
187 /* The update results in a potential jump, so we need the new convolved potential. */
188 double newPotential = -calcConvolvedBias(coordState.coordValue())*params_.invBeta;
189 *potentialJump = newPotential - potential;
193 /* Return the potential. */
194 *awhPotential = potential;
196 /* Check the sampled histograms and potentially warn user if something is suspicious */
197 warnForHistogramAnomalies(t, step, fplog);
200 void Bias::restoreStateFromHistory(const AwhBiasHistory *biasHistory,
201 const t_commrec *cr)
203 GMX_RELEASE_ASSERT(thisRankDoesIO_ == MASTER(cr), "The master rank should do I/O, the other ranks should not");
205 if (MASTER(cr))
207 GMX_RELEASE_ASSERT(biasHistory != nullptr, "On the master rank we need a valid history object to restore from");
208 state_.restoreFromHistory(*biasHistory, grid_);
211 if (PAR(cr))
213 state_.broadcast(cr);
217 void Bias::initHistoryFromState(AwhBiasHistory *biasHistory) const
219 GMX_RELEASE_ASSERT(biasHistory != nullptr, "Need a valid biasHistory");
221 state_.initHistoryFromState(biasHistory);
224 void Bias::updateHistory(AwhBiasHistory *biasHistory) const
226 GMX_RELEASE_ASSERT(biasHistory != nullptr, "Need a valid biasHistory");
228 state_.updateHistory(biasHistory, grid_);
231 Bias::Bias(int biasIndexInCollection,
232 const AwhParams &awhParams,
233 const AwhBiasParams &awhBiasParams,
234 const std::vector<DimParams> &dimParamsInit,
235 double beta,
236 double mdTimeStep,
237 int numSharingSimulations,
238 const std::string &biasInitFilename,
239 ThisRankWillDoIO thisRankWillDoIO,
240 BiasParams::DisableUpdateSkips disableUpdateSkips) :
241 dimParams_(dimParamsInit),
242 grid_(dimParamsInit, awhBiasParams.dimParams),
243 params_(awhParams, awhBiasParams, dimParams_, beta, mdTimeStep, disableUpdateSkips, numSharingSimulations, grid_.axis(), biasIndexInCollection),
244 state_(awhBiasParams, params_.initialHistogramSize, dimParams_, grid_),
245 thisRankDoesIO_(thisRankWillDoIO == ThisRankWillDoIO::Yes),
246 alignedTempWorkSpace_(),
247 numWarningsIssued_(0)
249 /* For a global update updateList covers all points, so reserve that */
250 updateList_.reserve(grid_.numPoints());
252 state_.initGridPointState(awhBiasParams, dimParams_, grid_, params_, biasInitFilename, awhParams.numBias);
255 } // namespace gmx