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.
38 * Implements the Bias class.
40 * \author Viveca Lindahl
41 * \author Berk Hess <hess@kth.se>
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"
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
))
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
,
101 double *awhPotential
,
102 double *potentialJump
,
103 const gmx_multisim_t
*ms
,
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
);
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.
150 if (params_
.convolveForce
)
152 state_
.calcConvolvedForce(dimParams_
, grid_
, probWeightNeighbor
,
155 potential
= -convolvedBias
*params_
.invBeta
;
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.");
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.
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_
,
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
,
203 GMX_RELEASE_ASSERT(thisRankDoesIO_
== MASTER(cr
), "The master rank should do I/O, the other ranks should not");
207 GMX_RELEASE_ASSERT(biasHistory
!= nullptr, "On the master rank we need a valid history object to restore from");
208 state_
.restoreFromHistory(*biasHistory
, grid_
);
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
,
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
);