Remove unnecessary includes of arrayref.h
[alexxy/gromacs.git] / src / gromacs / awh / biasstate.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2015,2016,2017,2018,2019,2020, 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.
8  *
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.
13  *
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.
18  *
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.
23  *
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.
31  *
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.
34  */
35
36 /*! \internal \file
37  *
38  * \brief
39  * Declares the BiasState class.
40  *
41  * The data members of this class are the state variables of the bias.
42  * All interaction from the outside happens through the Bias class, which
43  * holds important helper classes such as DimParams and BiasGrid.
44  * This class holds many methods, but more are const methods that compute
45  * properties of the state.
46  *
47  * \author Viveca Lindahl
48  * \author Berk Hess <hess@kth.se>
49  * \ingroup module_awh
50  */
51
52 #ifndef GMX_AWH_BIASSTATE_H
53 #define GMX_AWH_BIASSTATE_H
54
55 #include <cstdio>
56
57 #include <vector>
58
59 #include "gromacs/math/vectypes.h"
60 #include "gromacs/utility/alignedallocator.h"
61 #include "gromacs/utility/basedefinitions.h"
62 #include "gromacs/utility/gmxassert.h"
63
64 #include "coordstate.h"
65 #include "dimparams.h"
66 #include "histogramsize.h"
67
68 struct gmx_multisim_t;
69 struct t_commrec;
70
71 namespace gmx
72 {
73
74 template<typename>
75 class ArrayRef;
76 struct AwhBiasHistory;
77 struct AwhBiasParams;
78 class BiasParams;
79 class BiasGrid;
80 class GridAxis;
81 class PointState;
82
83 /*! \internal
84  * \brief The state of a bias.
85  *
86  * The bias state has the current coordinate state: its value and the grid point
87  * it maps to (the grid point of the umbrella potential if needed). It contains
88  * a vector with the state for each point on the grid. It also
89  * counts the number of updates issued and tracks which points have been sampled
90  * since last update. Finally, the convergence state is a global property set
91  * ultimately by the histogram size histogramSize in the sub-class HistogramSize,
92  * since the update sizes are ~ 1/histogramSize.
93  */
94 class BiasState
95 {
96 public:
97     /*! \brief Constructor.
98      *
99      * Constructs the global state and the point states on a provided
100      * geometric grid passed in \p grid.
101      *
102      * \param[in] awhBiasParams         The Bias parameters from inputrec.
103      * \param[in] histogramSizeInitial  The estimated initial histogram size.
104      *                                  This is floating-point, since histograms use weighted
105      *                                  entries and grow by a floating-point scaling factor.
106      * \param[in] dimParams             The dimension parameters.
107      * \param[in] grid                  The bias grid.
108      */
109     BiasState(const AwhBiasParams&          awhBiasParams,
110               double                        histogramSizeInitial,
111               const std::vector<DimParams>& dimParams,
112               const BiasGrid&               grid);
113
114     /*! \brief
115      * Restore the bias state from history.
116      *
117      * \param[in] biasHistory  Bias history struct.
118      * \param[in] grid         The bias grid.
119      */
120     void restoreFromHistory(const AwhBiasHistory& biasHistory, const BiasGrid& grid);
121
122     /*! \brief
123      * Broadcast the bias state over the MPI ranks in this simulation.
124      *
125      * \param[in] commRecord  Struct for communication.
126      */
127     void broadcast(const t_commrec* commRecord);
128
129     /*! \brief
130      * Allocate and initialize a bias history with the given bias state.
131      *
132      * This function will be called at the start of a new simulation.
133      * Note that this only sets the correct size and does produce
134      * a valid history object, but with all data set to zero.
135      * Actual history data is set by \ref updateHistory.
136      *
137      * \param[in,out] biasHistory  AWH history to initialize.
138      */
139     void initHistoryFromState(AwhBiasHistory* biasHistory) const;
140
141     /*! \brief
142      * Update the bias state history with the current state.
143      *
144      * \param[out] biasHistory  Bias history struct.
145      * \param[in]  grid         The bias grid.
146      */
147     void updateHistory(AwhBiasHistory* biasHistory, const BiasGrid& grid) const;
148
149 private:
150     /*! \brief Convolves the given PMF using the given AWH bias.
151      *
152      * \note: The PMF is in single precision, because it is a statistical
153      *        quantity and therefore never reaches full float precision.
154      *
155      * \param[in] dimParams     The bias dimensions parameters
156      * \param[in] grid          The grid.
157      * \param[in,out] convolvedPmf  Array returned will be of the same length as the AWH grid to store the convolved PMF in.
158      */
159     void calcConvolvedPmf(const std::vector<DimParams>& dimParams,
160                           const BiasGrid&               grid,
161                           std::vector<float>*           convolvedPmf) const;
162
163     /*! \brief
164      * Convolves the PMF and sets the initial free energy to its convolution.
165      *
166      * \param[in] dimParams  The bias dimensions parameters
167      * \param[in] grid       The bias grid.
168      */
169     void setFreeEnergyToConvolvedPmf(const std::vector<DimParams>& dimParams, const BiasGrid& grid);
170
171     /*! \brief
172      * Normalize the PMF histogram.
173      *
174      * \param[in] numSharingSims  The number of simulations sharing the bias.
175      */
176     void normalizePmf(int numSharingSims);
177
178 public:
179     /*! \brief
180      * Initialize the state of grid coordinate points.
181      *
182      * \param[in] awhBiasParams   Bias parameters from inputrec.
183      * \param[in] dimParams       The dimension parameters.
184      * \param[in] grid            The grid.
185      * \param[in] params          The bias parameters.
186      * \param[in] filename        Name of file to read PMF and target from.
187      * \param[in] numBias         The number of biases.
188      */
189     void initGridPointState(const AwhBiasParams&          awhBiasParams,
190                             const std::vector<DimParams>& dimParams,
191                             const BiasGrid&               grid,
192                             const BiasParams&             params,
193                             const std::string&            filename,
194                             int                           numBias);
195
196     /*! \brief
197      * Performs statistical checks on the collected histograms and warns if issues are detected.
198      *
199      * \param[in]     grid            The grid.
200      * \param[in]     biasIndex       The index of the bias we are checking for.
201      * \param[in]     t               Time.
202      * \param[in,out] fplog           Output file for warnings.
203      * \param[in]     maxNumWarnings  Don't issue more than this number of warnings.
204      * \returns the number of warnings issued.
205      */
206     int warnForHistogramAnomalies(const BiasGrid& grid, int biasIndex, double t, FILE* fplog, int maxNumWarnings) const;
207
208     /*! \brief
209      * Calculates and sets the force the coordinate experiences from an umbrella centered at the given point.
210      *
211      * The umbrella potential is an harmonic potential given by 0.5k(coord value - point value)^2. This
212      * value is also returned.
213      *
214      * \param[in]     dimParams  The bias dimensions parameters.
215      * \param[in]     grid       The grid.
216      * \param[in]     point      Point for umbrella center.
217      * \param[in,out] force      Force vector to set.
218      * Returns the umbrella potential.
219      */
220     double calcUmbrellaForceAndPotential(const std::vector<DimParams>& dimParams,
221                                          const BiasGrid&               grid,
222                                          int                           point,
223                                          gmx::ArrayRef<double>         force) const;
224
225     /*! \brief
226      * Calculates and sets the convolved force acting on the coordinate.
227      *
228      * The convolved force is the weighted sum of forces from umbrellas
229      * located at each point in the grid.
230      *
231      * \param[in]     dimParams           The bias dimensions parameters.
232      * \param[in]     grid                The grid.
233      * \param[in]     probWeightNeighbor  Probability weights of the neighbors.
234      * \param[in]     forceWorkBuffer     Force work buffer, values only used internally.
235      * \param[in,out] force               Bias force vector to set.
236      */
237     void calcConvolvedForce(const std::vector<DimParams>& dimParams,
238                             const BiasGrid&               grid,
239                             gmx::ArrayRef<const double>   probWeightNeighbor,
240                             gmx::ArrayRef<double>         forceWorkBuffer,
241                             gmx::ArrayRef<double>         force) const;
242
243     /*! \brief
244      * Move the center point of the umbrella potential.
245      *
246      * A new umbrella center is sampled from the biased distibution. Also, the bias
247      * force is updated and the new potential is return.
248      *
249      * This function should only be called when the bias force is not being convolved.
250      * It is assumed that the probability distribution has been updated.
251      *
252      * \param[in] dimParams           Bias dimension parameters.
253      * \param[in] grid                The grid.
254      * \param[in] probWeightNeighbor  Probability weights of the neighbors.
255      * \param[in,out] biasForce       The AWH bias force.
256      * \param[in] step                Step number, needed for the random number generator.
257      * \param[in] seed                Random seed.
258      * \param[in] indexSeed           Second random seed, should be the bias Index.
259      * \returns the new potential value.
260      */
261     double moveUmbrella(const std::vector<DimParams>& dimParams,
262                         const BiasGrid&               grid,
263                         gmx::ArrayRef<const double>   probWeightNeighbor,
264                         gmx::ArrayRef<double>         biasForce,
265                         int64_t                       step,
266                         int64_t                       seed,
267                         int                           indexSeed);
268
269 private:
270     /*! \brief
271      * Gets the histogram rescaling factors needed for skipped updates.
272      *
273      * \param[in]  params             The bias parameters.
274      * \param[out] weighthistScaling  Scaling factor for the reference weight histogram.
275      * \param[out] logPmfsumScaling   Log of the scaling factor for the PMF histogram.
276      */
277     void getSkippedUpdateHistogramScaleFactors(const BiasParams& params,
278                                                double*           weighthistScaling,
279                                                double*           logPmfsumScaling) const;
280
281 public:
282     /*! \brief
283      * Do all previously skipped updates.
284      * Public for use by tests.
285      *
286      * \param[in] params  The bias parameters.
287      */
288     void doSkippedUpdatesForAllPoints(const BiasParams& params);
289
290     /*! \brief
291      * Do previously skipped updates in this neighborhood.
292      *
293      * \param[in] params  The bias parameters.
294      * \param[in] grid    The grid.
295      */
296     void doSkippedUpdatesInNeighborhood(const BiasParams& params, const BiasGrid& grid);
297
298 private:
299     /*! \brief
300      * Reset the range used to make the local update list.
301      *
302      * \param[in] grid  The grid.
303      */
304     void resetLocalUpdateRange(const BiasGrid& grid);
305
306     /*! \brief
307      * Returns the new size of the reference weight histogram in the initial stage.
308      *
309      * This function also takes care resetting the histogram used for covering checks
310      * and for exiting the initial stage.
311      *
312      * \param[in]     params            The bias parameters.
313      * \param[in]     t                 Time.
314      * \param[in]     detectedCovering  True if we detected that the sampling interval has been sufficiently covered.
315      * \param[in,out] fplog             Log file.
316      * \returns the new histogram size.
317      */
318     double newHistogramSizeInitialStage(const BiasParams& params, double t, bool detectedCovering, FILE* fplog);
319
320     /*! \brief
321      * Check if the sampling region has been covered "enough" or not.
322      *
323      * A one-dimensional interval is defined as covered if each point has
324      * accumulated the same weight as is in the peak of a discretized normal
325      * distribution. For multiple dimensions, the weights are simply projected
326      * onto each dimension and the multidimensional space is covered if each
327      * dimension is.
328      *
329      * \note The covering criterion for multiple dimensions could improved, e.g.
330      * by using a path finding algorithm.
331      *
332      * \param[in] params        The bias parameters.
333      * \param[in] dimParams     Bias dimension parameters.
334      * \param[in] grid          The grid.
335      * \param[in] commRecord    Struct for intra-simulation communication.
336      * \param[in] multiSimComm  Struct for multi-simulation communication.
337      * \returns true if covered.
338      */
339     bool isSamplingRegionCovered(const BiasParams&             params,
340                                  const std::vector<DimParams>& dimParams,
341                                  const BiasGrid&               grid,
342                                  const t_commrec*              commRecord,
343                                  const gmx_multisim_t*         multiSimComm) const;
344
345     /*! \brief
346      * Return the new reference weight histogram size for the current update.
347      *
348      * This function also takes care of checking for covering in the initial stage.
349      *
350      * \param[in]     params   The bias parameters.
351      * \param[in]     t        Time.
352      * \param[in]     covered  True if the sampling interval has been covered enough.
353      * \param[in,out] fplog    Log file.
354      * \returns the new histogram size.
355      */
356     double newHistogramSize(const BiasParams& params, double t, bool covered, FILE* fplog);
357
358 public:
359     /*! \brief
360      * Update the reaction coordinate value.
361      *
362      * \param[in] grid        The bias grid.
363      * \param[in] coordValue  The current reaction coordinate value (there are no limits on allowed values).
364      */
365     void setCoordValue(const BiasGrid& grid, const awh_dvec coordValue)
366     {
367         coordState_.setCoordValue(grid, coordValue);
368     }
369
370     /*! \brief
371      * Performs an update of the bias.
372      *
373      * The objective of the update is to use collected samples (probability weights)
374      * to improve the free energy estimate. For sake of efficiency, the update is
375      * local whenever possible, meaning that only points that have actually been sampled
376      * are accessed and updated here. For certain AWH settings or at certain steps
377      * however, global need to be performed. Besides the actual free energy update, this
378      * function takes care of ensuring future convergence of the free energy. Convergence
379      * is obtained by increasing the size of the reference weight histogram in a controlled
380      * (sometimes dynamic) manner. Also, there are AWH variables that are direct functions
381      * of the free energy or sampling history that need to be updated here, namely the target
382      * distribution and the bias function.
383      *
384      * \param[in]     dimParams   The dimension parameters.
385      * \param[in]     grid        The grid.
386      * \param[in]     params      The bias parameters.
387      * \param[in]     commRecord  Struct for intra-simulation communication.
388      * \param[in]     ms          Struct for multi-simulation communication.
389      * \param[in]     t           Time.
390      * \param[in]     step        Time step.
391      * \param[in,out] fplog       Log file.
392      * \param[in,out] updateList  Work space to store a temporary list.
393      */
394     void updateFreeEnergyAndAddSamplesToHistogram(const std::vector<DimParams>& dimParams,
395                                                   const BiasGrid&               grid,
396                                                   const BiasParams&             params,
397                                                   const t_commrec*              commRecord,
398                                                   const gmx_multisim_t*         ms,
399                                                   double                        t,
400                                                   int64_t                       step,
401                                                   FILE*                         fplog,
402                                                   std::vector<int>*             updateList);
403
404     /*! \brief
405      * Update the probability weights and the convolved bias.
406      *
407      * Given a coordinate value, each grid point is assigned a probability
408      * weight, w(point|value), that depends on the current bias function. The sum
409      * of these weights is needed for normalizing the probability sum to 1 but
410      * also equals the effective, or convolved, biasing weight for this coordinate
411      * value. The convolved bias is needed e.g. for extracting the PMF, so we save
412      * it here since this saves us from doing extra exponential function evaluations
413      * later on.
414      *
415      * \param[in]  dimParams  The bias dimensions parameters
416      * \param[in]  grid       The grid.
417      * \param[out] weight     Probability weights of the neighbors, SIMD aligned.
418      * \returns the convolved bias.
419      */
420
421     double updateProbabilityWeightsAndConvolvedBias(const std::vector<DimParams>& dimParams,
422                                                     const BiasGrid&               grid,
423                                                     std::vector<double, AlignedAllocator<double>>* weight) const;
424
425     /*! \brief
426      * Take samples of the current probability weights for future updates and analysis.
427      *
428      * Points in the current neighborhood will now have data meaning they
429      * need to be included in the local update list of the next update.
430      * Therefore, the local update range is also update here.
431      *
432      * \param[in] grid                The grid.
433      * \param[in] probWeightNeighbor  Probability weights of the neighbors.
434      */
435     void sampleProbabilityWeights(const BiasGrid& grid, gmx::ArrayRef<const double> probWeightNeighbor);
436
437     /*! \brief
438      * Sample the reaction coordinate and PMF for future updates or analysis.
439      *
440      * These samples do not affect the (future) sampling and are thus
441      * pure observables. Statisics of these are stored in the energy file.
442      *
443      * \param[in] grid                The grid.
444      * \param[in] probWeightNeighbor  Probability weights of the neighbors.
445      * \param[in] convolvedBias       The convolved bias.
446      */
447     void sampleCoordAndPmf(const BiasGrid&             grid,
448                            gmx::ArrayRef<const double> probWeightNeighbor,
449                            double                      convolvedBias);
450     /*! \brief
451      * Calculates the convolved bias for a given coordinate value.
452      *
453      * The convolved bias is the effective bias acting on the coordinate.
454      * Since the bias here has arbitrary normalization, this only makes
455      * sense as a relative, to other coordinate values, measure of the bias.
456      *
457      * \note If it turns out to be costly to calculate this pointwise
458      * the convolved bias for the whole grid could be returned instead.
459      *
460      * \param[in] dimParams   The bias dimensions parameters
461      * \param[in] grid        The grid.
462      * \param[in] coordValue  Coordinate value.
463      * \returns the convolved bias >= -GMX_FLOAT_MAX.
464      */
465     double calcConvolvedBias(const std::vector<DimParams>& dimParams,
466                              const BiasGrid&               grid,
467                              const awh_dvec&               coordValue) const;
468
469     /*! \brief
470      * Fills the given array with PMF values.
471      *
472      * Points outside of the biasing target region will get PMF = GMX_FLOAT_MAX.
473      * \note: The PMF is in single precision, because it is a statistical
474      *        quantity and therefore never reaches full float precision.
475      *
476      * \param[out] pmf  Array(ref) to be filled with the PMF values, should have the same size as the bias grid.
477      */
478     void getPmf(gmx::ArrayRef<float> /*pmf*/) const;
479
480     /*! \brief Returns the current coordinate state.
481      */
482     const CoordState& coordState() const { return coordState_; }
483
484     /*! \brief Returns a const reference to the point state.
485      */
486     const std::vector<PointState>& points() const { return points_; }
487
488     /*! \brief Returns true if we are in the initial stage.
489      */
490     bool inInitialStage() const { return histogramSize_.inInitialStage(); }
491
492     /*! \brief Returns the current histogram size.
493      */
494     inline HistogramSize histogramSize() const { return histogramSize_; }
495
496     /* Data members */
497 private:
498     CoordState coordState_; /**< The Current coordinate state */
499
500     /* The grid point state */
501     std::vector<PointState> points_; /**< Vector of state of the grid points */
502
503     /* Covering values for each point on the grid */
504     std::vector<double> weightSumCovering_; /**< Accumulated weights for covering checks */
505
506     HistogramSize histogramSize_; /**< Global histogram size related values. */
507
508     /* Track the part of the grid sampled since the last update. */
509     awh_ivec originUpdatelist_; /**< The origin of the rectangular region that has been sampled since last update. */
510     awh_ivec endUpdatelist_; /**< The end of the rectangular region that has been sampled since last update. */
511 };
512
513 //! Linewidth used for warning output
514 static const int c_linewidth = 80 - 2;
515
516 //! Indent used for warning output
517 static const int c_indent = 0;
518
519 } // namespace gmx
520
521 #endif /* GMX_AWH_BIASSTATE_H */