LCOV - code coverage report
Current view: top level - bias - PBMetaD.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 617 735 83.9 %
Date: 2026-03-30 13:16:06 Functions: 16 18 88.9 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2015-2023 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed 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
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #include "Bias.h"
      23             : #include "ActionRegister.h"
      24             : #include "core/ActionSet.h"
      25             : #include "core/PlumedMain.h"
      26             : #include "core/Atoms.h"
      27             : #include "core/FlexibleBin.h"
      28             : #include "tools/Exception.h"
      29             : #include "tools/Grid.h"
      30             : #include "tools/Matrix.h"
      31             : #include "tools/OpenMP.h"
      32             : #include "tools/Random.h"
      33             : #include "tools/File.h"
      34             : #include <ctime>
      35             : #include <numeric>
      36             : #if defined(__PLUMED_HAS_GETCWD)
      37             : #include <unistd.h>
      38             : #endif
      39             : 
      40             : namespace PLMD {
      41             : namespace bias {
      42             : 
      43             : //+PLUMEDOC BIAS PBMETAD
      44             : /*
      45             : Used to performed Parallel Bias metadynamics.
      46             : 
      47             : This action activate Parallel Bias Metadynamics (PBMetaD) \cite pbmetad, a version of metadynamics \cite metad in which
      48             : multiple low-dimensional bias potentials are applied in parallel.
      49             : In the current implementation, these have the form of mono-dimensional metadynamics bias
      50             : potentials:
      51             : 
      52             : \f[
      53             : {V(s_1,t), ..., V(s_N,t)}
      54             : \f]
      55             : 
      56             : where:
      57             : 
      58             : \f[
      59             : V(s_i,t) = \sum_{ k \tau < t} W_i(k \tau)
      60             : \exp\left(
      61             : - \frac{(s_i-s_i^{(0)}(k \tau))^2}{2\sigma_i^2}
      62             : \right).
      63             : \f]
      64             : 
      65             : To ensure the convergence of each mono-dimensional bias potential to the corresponding free energy,
      66             : at each deposition step the Gaussian heights are multiplied by the so-called conditional term:
      67             : 
      68             : \f[
      69             : W_i(k \tau)=W_0 \frac{\exp\left(
      70             : - \frac{V(s_i,k \tau)}{k_B T}
      71             : \right)}{\sum_{i=1}^N
      72             : \exp\left(
      73             : - \frac{V(s_i,k \tau)}{k_B T}
      74             : \right)}
      75             : \f]
      76             : 
      77             : where \f$W_0\f$ is the initial Gaussian height.
      78             : 
      79             : The PBMetaD bias potential is defined by:
      80             : 
      81             : \f[
      82             : V_{PB}(\vec{s},t) = -k_B T \log{\sum_{i=1}^N
      83             : \exp\left(
      84             : - \frac{V(s_i,t)}{k_B T}
      85             : \right)}.
      86             : \f]
      87             : 
      88             : 
      89             : Information on the Gaussian functions that build each bias potential are printed to
      90             : multiple HILLS files, which
      91             : are used both to restart the calculation and to reconstruct the mono-dimensional
      92             : free energies as a function of the corresponding CVs.
      93             : These can be reconstructed using the \ref sum_hills utility because the final bias is given
      94             : by:
      95             : 
      96             : \f[
      97             : V(s_i) = -F(s_i)
      98             : \f]
      99             : 
     100             : Currently, only a subset of the \ref METAD options are available in PBMetaD.
     101             : 
     102             : The bias potentials can be stored on a grid to increase performances of long PBMetaD simulations.
     103             : You should
     104             : provide either the number of bins for every collective variable (GRID_BIN) or
     105             : the desired grid spacing (GRID_SPACING). In case you provide both PLUMED will use
     106             : the most conservative choice (highest number of bins) for each dimension.
     107             : In case you do not provide any information about bin size (neither GRID_BIN nor GRID_SPACING)
     108             : and if Gaussian width is fixed PLUMED will use 1/5 of the Gaussian width as grid spacing.
     109             : This default choice should be reasonable for most applications.
     110             : 
     111             : Another option that is available is well-tempered metadynamics \cite Barducci:2008. In this
     112             : variant of PBMetaD the heights of the Gaussian hills are scaled at each step by the
     113             : additional well-tempered metadynamics term.
     114             : This  ensures that each bias converges more smoothly. It should be noted that, in the case of well-tempered metadynamics, in
     115             : the output printed the Gaussian height is re-scaled using the bias factor.
     116             : Also notice that with well-tempered metadynamics the HILLS files do not contain the bias,
     117             : but the negative of the free-energy estimate. This choice has the advantage that
     118             : one can restart a simulation using a different value for the \f$\Delta T\f$. The applied bias will be scaled accordingly.
     119             : 
     120             : Note that you can use here also the flexible Gaussian approach  \cite Branduardi:2012dl
     121             : in which you can adapt the Gaussian to the extent of Cartesian space covered by a variable or
     122             : to the space in collective variable covered in a given time. In this case the width of the deposited
     123             : Gaussian potential is denoted by one value only that is a Cartesian space (ADAPTIVE=GEOM) or a time
     124             : (ADAPTIVE=DIFF). Note that a specific integration technique for the deposited Gaussian kernels
     125             : should be used in this case. Check the documentation for utility sum_hills.
     126             : 
     127             : With the keyword INTERVAL one changes the metadynamics algorithm setting the bias force equal to zero
     128             : outside boundary \cite baftizadeh2012protein. If, for example, metadynamics is performed on a CV s and one is interested only
     129             : to the free energy for s > boundary, the history dependent potential is still updated according to the above
     130             : equations but the metadynamics force is set to zero for s < boundary. Notice that Gaussian kernels are added also
     131             : if s < boundary, as the tails of these Gaussian kernels influence VG in the relevant region s > boundary. In this way, the
     132             : force on the system in the region s > boundary comes from both metadynamics and the force field, in the region
     133             : s < boundary only from the latter. This approach allows obtaining a history-dependent bias potential VG that
     134             : fluctuates around a stable estimator, equal to the negative of the free energy far enough from the
     135             : boundaries. Note that:
     136             : - It works only for one-dimensional biases;
     137             : - It works both with and without GRID;
     138             : - The interval limit boundary in a region where the free energy derivative is not large;
     139             : - If in the region outside the limit boundary the system has a free energy minimum, the INTERVAL keyword should
     140             :   be used together with a \ref UPPER_WALLS or \ref LOWER_WALLS at boundary.
     141             : 
     142             : For systems with multiple CVs that share identical properties, PBMetaD with partitioned families can be used
     143             : to group them under one bias potential that each contributes to \cite Prakash2018PF. This is done with a list
     144             : of PF keywords, where each PF* argument contains the list of CVs from ARG to be placed in that family. Once
     145             : invoked, each CV in ARG must be placed in exactly one PF, even if it results in families containing only one CV.
     146             : Additionally, in cases where each of SIGMA or GRID entry would correspond to each ARG entry, they now correspond to
     147             : each PF and must be adjusted accordingly.
     148             : 
     149             : Multiple walkers  \cite multiplewalkers can also be used. See below the examples.
     150             : 
     151             : \par Examples
     152             : 
     153             : The following input is for PBMetaD calculation using as
     154             : collective variables the distance between atoms 3 and 5
     155             : and the distance between atoms 2 and 4. The value of the CVs and
     156             : the PBMetaD bias potential are written to the COLVAR file every 100 steps.
     157             : \plumedfile
     158             : DISTANCE ATOMS=3,5 LABEL=d1
     159             : DISTANCE ATOMS=2,4 LABEL=d2
     160             : PBMETAD ARG=d1,d2 SIGMA=0.2,0.2 HEIGHT=0.3 PACE=500 LABEL=pb FILE=HILLS_d1,HILLS_d2
     161             : PRINT ARG=d1,d2,pb.bias STRIDE=100 FILE=COLVAR
     162             : \endplumedfile
     163             : (See also \ref DISTANCE and \ref PRINT).
     164             : 
     165             : \par
     166             : If you use well-tempered metadynamics, you should specify a single bias factor and initial
     167             : Gaussian height.
     168             : \plumedfile
     169             : DISTANCE ATOMS=3,5 LABEL=d1
     170             : DISTANCE ATOMS=2,4 LABEL=d2
     171             : PBMETAD ...
     172             : ARG=d1,d2 SIGMA=0.2,0.2 HEIGHT=0.3
     173             : PACE=500 BIASFACTOR=8 LABEL=pb
     174             : FILE=HILLS_d1,HILLS_d2
     175             : ... PBMETAD
     176             : PRINT ARG=d1,d2,pb.bias STRIDE=100 FILE=COLVAR
     177             : \endplumedfile
     178             : 
     179             : \par
     180             : Using partitioned families, each CV in ARG must be in exactly one family. Here,
     181             : the distance between atoms 1,2 is degenerate with 2,4, but not with the
     182             : distance between 3,5. Note that two SIGMA are provided to match the two PF.
     183             : \plumedfile
     184             : DISTANCE ATOMS=3,5 LABEL=d1
     185             : DISTANCE ATOMS=2,4 LABEL=d2
     186             : DISTANCE ATOMS=1,2 LABEL=d3
     187             : PBMETAD ...
     188             : ARG=d1,d2,d3 SIGMA=0.2,0.2 HEIGHT=0.3
     189             : PF0=d1 PF1=d2,d3
     190             : PACE=500 BIASFACTOR=8 LABEL=pb
     191             : FILE=HILLS_d1,HILLS_d2
     192             : ... PBMETAD
     193             : PRINT ARG=d1,d2,d3,pb.bias STRIDE=100 FILE=COLVAR
     194             : \endplumedfile
     195             : 
     196             : \par
     197             : The following input enables the MPI version of multiple-walkers.
     198             : \plumedfile
     199             : DISTANCE ATOMS=3,5 LABEL=d1
     200             : DISTANCE ATOMS=2,4 LABEL=d2
     201             : PBMETAD ...
     202             : ARG=d1,d2 SIGMA=0.2,0.2 HEIGHT=0.3
     203             : PACE=500 BIASFACTOR=8 LABEL=pb
     204             : FILE=HILLS_d1,HILLS_d2
     205             : WALKERS_MPI
     206             : ... PBMETAD
     207             : PRINT ARG=d1,d2,pb.bias STRIDE=100 FILE=COLVAR
     208             : \endplumedfile
     209             : 
     210             : \par
     211             : The disk version of multiple-walkers can be
     212             : enabled by setting the number of walker used, the id of the
     213             : current walker which interprets the input file, the directory where the
     214             : hills containing files resides, and the frequency to read the other walkers.
     215             : Here is an example
     216             : \plumedfile
     217             : DISTANCE ATOMS=3,5 LABEL=d1
     218             : DISTANCE ATOMS=2,4 LABEL=d2
     219             : PBMETAD ...
     220             : ARG=d1,d2 SIGMA=0.2,0.2 HEIGHT=0.3
     221             : PACE=500 BIASFACTOR=8 LABEL=pb
     222             : FILE=HILLS_d1,HILLS_d2
     223             : WALKERS_N=10
     224             : WALKERS_ID=3
     225             : WALKERS_DIR=../
     226             : WALKERS_RSTRIDE=100
     227             : ... PBMETAD
     228             : PRINT ARG=d1,d2,pb.bias STRIDE=100 FILE=COLVAR
     229             : \endplumedfile
     230             : where  WALKERS_N is the total number of walkers, WALKERS_ID is the
     231             : id of the present walker (starting from 0 ) and the WALKERS_DIR is the directory
     232             : where all the walkers are located. WALKERS_RSTRIDE is the number of step between
     233             : one update and the other.
     234             : 
     235             : */
     236             : //+ENDPLUMEDOC
     237             : 
     238             : class PBMetaD : public Bias {
     239             : 
     240             : private:
     241             :   struct Gaussian {
     242             :     std::vector<double> center;
     243             :     std::vector<double> sigma;
     244             :     double height;
     245             :     bool   multivariate; // this is required to discriminate the one dimensional case
     246             :     std::vector<double> invsigma;
     247        1120 :     Gaussian(const std::vector<double> & center,const std::vector<double> & sigma, double height, bool multivariate):
     248        1120 :       center(center),sigma(sigma),height(height),multivariate(multivariate),invsigma(sigma) {
     249             :       // to avoid troubles from zero element in flexible hills
     250        2240 :       for(unsigned i=0; i<invsigma.size(); ++i)
     251        1120 :         if(std::abs(invsigma[i])>1.e-20) {
     252        1120 :           invsigma[i]=1.0/invsigma[i] ;
     253             :         } else {
     254           0 :           invsigma[i]=0.0;
     255             :         }
     256        1120 :     }
     257             :   };
     258             :   // general setup
     259             :   double kbt_;
     260             :   int stride_;
     261             :   // well-tempered MetaD
     262             :   bool welltemp_;
     263             :   double biasf_;
     264             :   // output files format
     265             :   std::string fmt_;
     266             :   // first step?
     267             :   bool isFirstStep_;
     268             :   // Gaussian starting parameters
     269             :   double height0_;
     270             :   std::vector<double> sigma0_;
     271             :   std::vector<double> sigma0min_;
     272             :   std::vector<double> sigma0max_;
     273             :   // Gaussians
     274             :   std::vector<std::vector<Gaussian> > hills_;
     275             :   std::vector<FlexibleBin> flexbin_;
     276             :   int adaptive_;
     277             :   std::vector<std::unique_ptr<OFile>> hillsOfiles_;
     278             :   std::vector<std::unique_ptr<IFile>> ifiles_;
     279             :   std::vector<std::string> ifilesnames_;
     280             :   // Grids
     281             :   bool grid_;
     282             :   std::vector<std::unique_ptr<GridBase>> BiasGrids_;
     283             :   std::vector<std::unique_ptr<OFile>> gridfiles_;
     284             :   int wgridstride_;
     285             :   // Partitioned Families
     286             :   unsigned int pf_n_; // initialize number of partitioned families
     287             :   std::vector<int> pfs_; //std::vector length of arguments that holds which pf# each cv belongs in
     288             :   std::vector<Value*> pfhold_; // std::vector length of pf_n which stores a pointer to the first argument fed to each family
     289             :   bool do_pf_; // if partitioned families are enabled
     290             :   // multiple walkers
     291             :   int mw_n_;
     292             :   std::string mw_dir_;
     293             :   int mw_id_;
     294             :   int mw_rstride_;
     295             :   bool walkers_mpi_;
     296             :   size_t mpi_nw_;
     297             :   unsigned mpi_id_;
     298             :   std::vector<std::string> hillsfname_;
     299             :   // intervals
     300             :   std::vector<double> uppI_;
     301             :   std::vector<double> lowI_;
     302             :   std::vector<bool>  doInt_;
     303             :   // variable for selector
     304             :   std::string selector_;
     305             :   bool  do_select_;
     306             :   unsigned select_value_;
     307             :   unsigned current_value_;
     308             : 
     309             :   double stretchA=1.0;
     310             :   double stretchB=0.0;
     311             : 
     312             :   bool noStretchWarningDone=false;
     313             : 
     314           0 :   void noStretchWarning() {
     315           0 :     if(!noStretchWarningDone) {
     316           0 :       log<<"\nWARNING: you are using a HILLS file with Gaussian kernels, PLUMED 2.8 uses stretched Gaussians by default\n";
     317             :     }
     318           0 :     noStretchWarningDone=true;
     319           0 :   }
     320             : 
     321             :   void   readGaussians(unsigned iarg, IFile*);
     322             :   void   writeGaussian(unsigned iarg, const Gaussian&, OFile*);
     323             :   void   addGaussian(unsigned iarg, const Gaussian&);
     324             :   double getBiasAndDerivatives(unsigned iarg, const std::vector<double>&, double* der=NULL);
     325             :   double evaluateGaussian(unsigned iarg, const std::vector<double>&, const Gaussian&,double* der=NULL);
     326             :   std::vector<unsigned> getGaussianSupport(unsigned iarg, const Gaussian&);
     327             :   bool   scanOneHill(unsigned iarg, IFile *ifile,  std::vector<Value> &v, std::vector<double> &center, std::vector<double>  &sigma, double &height, bool &multivariate);
     328             : 
     329             : public:
     330             :   explicit PBMetaD(const ActionOptions&);
     331             :   void calculate() override;
     332             :   void update() override;
     333             :   static void registerKeywords(Keywords& keys);
     334             :   bool checkNeedsGradients()const override;
     335             : };
     336             : 
     337       13869 : PLUMED_REGISTER_ACTION(PBMetaD,"PBMETAD")
     338             : 
     339          46 : void PBMetaD::registerKeywords(Keywords& keys) {
     340          46 :   Bias::registerKeywords(keys);
     341          46 :   keys.use("ARG");
     342          92 :   keys.add("compulsory","SIGMA","the widths of the Gaussian hills");
     343          92 :   keys.add("compulsory","PACE","the frequency for hill addition, one for all biases");
     344          92 :   keys.add("optional","FILE","files in which the lists of added hills are stored, default names are assigned using arguments if FILE is not found");
     345          92 :   keys.add("optional","HEIGHT","the height of the Gaussian hills, one for all biases. Compulsory unless TAU, TEMP and BIASFACTOR are given");
     346          92 :   keys.add("optional","FMT","specify format for HILLS files (useful for decrease the number of digits in regtests)");
     347          92 :   keys.add("optional","BIASFACTOR","use well tempered metadynamics with this bias factor, one for all biases.  Please note you must also specify temp");
     348          92 :   keys.add("optional","TEMP","the system temperature - this is only needed if you are doing well-tempered metadynamics");
     349          92 :   keys.add("optional","TAU","in well tempered metadynamics, sets height to (k_B Delta T*pace*timestep)/tau");
     350          92 :   keys.add("optional","GRID_MIN","the lower bounds for the grid");
     351          92 :   keys.add("optional","GRID_MAX","the upper bounds for the grid");
     352          92 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
     353          92 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
     354          92 :   keys.addFlag("GRID_SPARSE",false,"use a sparse grid to store hills");
     355          92 :   keys.addFlag("GRID_NOSPLINE",false,"don't use spline interpolation with grids");
     356          92 :   keys.add("optional","GRID_WSTRIDE", "frequency for dumping the grid");
     357          92 :   keys.add("optional","GRID_WFILES", "dump grid for the bias, default names are used if GRID_WSTRIDE is used without GRID_WFILES.");
     358          92 :   keys.add("optional","GRID_RFILES", "read grid for the bias");
     359          92 :   keys.add("optional","ADAPTIVE","use a geometric (=GEOM) or diffusion (=DIFF) based hills width scheme. Sigma is one number that has distance units or timestep dimensions");
     360          92 :   keys.add("optional","SIGMA_MAX","the upper bounds for the sigmas (in CV units) when using adaptive hills. Negative number means no bounds ");
     361          92 :   keys.add("optional","SIGMA_MIN","the lower bounds for the sigmas (in CV units) when using adaptive hills. Negative number means no bounds ");
     362          92 :   keys.add("numbered","PF", "specify which CVs belong in a partitioned family. Once a PF is specified, all CVs in ARG must be placed in a PF even if there is one CV per PF”");
     363          92 :   keys.add("optional","SELECTOR", "add forces and do update based on the value of SELECTOR");
     364          92 :   keys.add("optional","SELECTOR_ID", "value of SELECTOR");
     365          92 :   keys.add("optional","WALKERS_ID", "walker id");
     366          92 :   keys.add("optional","WALKERS_N", "number of walkers");
     367          92 :   keys.add("optional","WALKERS_DIR", "shared directory with the hills files from all the walkers");
     368          92 :   keys.add("optional","WALKERS_RSTRIDE","stride for reading hills files");
     369          92 :   keys.addFlag("WALKERS_MPI",false,"Switch on MPI version of multiple walkers - not compatible with WALKERS_* options other than WALKERS_DIR");
     370          92 :   keys.add("optional","INTERVAL_MIN","one dimensional lower limits, outside the limits the system will not feel the biasing force.");
     371          92 :   keys.add("optional","INTERVAL_MAX","one dimensional upper limits, outside the limits the system will not feel the biasing force.");
     372          46 :   keys.use("RESTART");
     373          46 :   keys.use("UPDATE_FROM");
     374          46 :   keys.use("UPDATE_UNTIL");
     375          46 : }
     376             : 
     377          42 : PBMetaD::PBMetaD(const ActionOptions& ao):
     378             :   PLUMED_BIAS_INIT(ao),
     379          42 :   kbt_(0.0),
     380          42 :   stride_(0),
     381          42 :   welltemp_(false),
     382          42 :   biasf_(1.0),
     383          42 :   isFirstStep_(true),
     384          42 :   height0_(std::numeric_limits<double>::max()),
     385          42 :   adaptive_(FlexibleBin::none),
     386          42 :   grid_(false),
     387          42 :   wgridstride_(0),
     388          42 :   pf_n_(0), do_pf_(false),
     389          42 :   mw_n_(1), mw_dir_(""), mw_id_(0), mw_rstride_(1),
     390          42 :   walkers_mpi_(false), mpi_nw_(0),
     391          42 :   do_select_(false) {
     392             : 
     393             :   // parse the flexible hills
     394             :   std::string adaptiveoption;
     395             :   adaptiveoption="NONE";
     396          84 :   parse("ADAPTIVE",adaptiveoption);
     397          42 :   if(adaptiveoption=="GEOM") {
     398           0 :     log.printf("  Uses Geometry-based hills width: sigma must be in distance units and only one sigma is needed\n");
     399           0 :     adaptive_=FlexibleBin::geometry;
     400          42 :   } else if(adaptiveoption=="DIFF") {
     401           4 :     log.printf("  Uses Diffusion-based hills width: sigma must be in time steps and only one sigma is needed\n");
     402           4 :     adaptive_=FlexibleBin::diffusion;
     403          38 :   } else if(adaptiveoption=="NONE") {
     404          38 :     adaptive_=FlexibleBin::none;
     405             :   } else {
     406           0 :     error("I do not know this type of adaptive scheme");
     407             :   }
     408             : 
     409          42 :   parse("FMT",fmt_);
     410             : 
     411             :   // Partitioned Families - fill with -1 to mark as invalid
     412          42 :   pfs_.assign(getNumberOfArguments(), -1);
     413          42 :   pfhold_.resize(getNumberOfArguments());
     414             :   std::vector<Value*> familyargs;
     415          42 :   for(int i = 0;; i++) {
     416         100 :     parseArgumentList("PF", i, familyargs);
     417          50 :     if (familyargs.empty()) {
     418             :       break;
     419             :     }
     420             : 
     421           8 :     do_pf_ = true;
     422           8 :     log << "  Identified Partitioned Family " << i << ":";
     423          20 :     for (unsigned j = 0; j < familyargs.size(); j++) {
     424          12 :       log << " " << familyargs[j]->getName();
     425             :       // loop through the argument list to make sure it exists and assign it
     426             :       bool foundArg = false;
     427          48 :       for (unsigned argnum = 0; argnum < getNumberOfArguments(); argnum++) {
     428          36 :         if (familyargs[j]->getName() == getPntrToArgument(argnum)->getName()) {
     429             :           foundArg = true;
     430          12 :           if (pfs_[argnum] != -1) {
     431           0 :             error(familyargs[j]->getName() + " already present in PF" + std::to_string(pfs_[argnum]));
     432             :           }
     433          12 :           pfs_[argnum] = i;  // store the pf# for each cv
     434          12 :           if (pfhold_[i] == nullptr) {
     435             :             // if this is the first argument in the family, store a pointer for it (this is for HILLS & GRID files)
     436           8 :             pfhold_[i] = getPntrToArgument(argnum);
     437             :           }
     438             :         }
     439             :       }
     440          12 :       if (!foundArg) {
     441           0 :         error(familyargs[j]->getName() + " in PF" + std::to_string(i) + " not found in ARG");
     442             :       }
     443             :     }
     444           8 :     log << "\n";
     445           8 :     pf_n_++;
     446           8 :   }
     447             : 
     448             :   // if PF were specified, every argument gets treated as its own PF
     449          42 :   if (!do_pf_) {
     450          38 :     pf_n_ = getNumberOfArguments();
     451         114 :     for(unsigned i=0; i < pf_n_; i++) {
     452          76 :       pfhold_[i] = getPntrToArgument(i);
     453          76 :       pfs_[i] = i;
     454             :     }
     455             :   } else {
     456             :     // If we are doing PF, make sure each argument got assigned to a family.
     457          16 :     for (unsigned i = 0; i < getNumberOfArguments(); i++) {
     458          12 :       if (pfs_[i] == -1) {
     459           0 :         error(getPntrToArgument(i)->getName() + " was not assigned a PF");
     460             :       }
     461             :     }
     462             :   }
     463             : 
     464             :   // parse the sigma
     465          42 :   parseVector("SIGMA",sigma0_);
     466          42 :   if(adaptive_==FlexibleBin::none) {
     467             :     // if you use normal sigma you need one sigma per argument
     468          38 :     if( sigma0_.size()!=pf_n_ ) {
     469           0 :       std::string fields = do_pf_ ? "PFs" : "arguments";
     470           0 :       error("number of " + fields + " does not match number of SIGMA parameters");
     471             :     }
     472             :   } else {
     473             :     // if you use flexible hills you need one sigma
     474           4 :     if(sigma0_.size()!=1) {
     475           0 :       error("If you choose ADAPTIVE you need only one sigma according to your choice of type (GEOM/DIFF)");
     476             :     }
     477             :     // if adaptive then the number must be an integer
     478           4 :     if(adaptive_==FlexibleBin::diffusion) {
     479           4 :       if(int(sigma0_[0])-sigma0_[0]>1.e-9 || int(sigma0_[0])-sigma0_[0] <-1.e-9 || int(sigma0_[0])<1 ) {
     480           0 :         error("In case of adaptive hills with diffusion, the sigma must be an integer which is the number of time steps\n");
     481             :       }
     482             :     }
     483             :     // here evtl parse the sigma min and max values
     484           8 :     parseVector("SIGMA_MIN",sigma0min_);
     485           4 :     if(sigma0min_.size()>0 && sigma0min_.size()!=pf_n_) {
     486           0 :       error("the number of SIGMA_MIN values be the same of the number of the arguments/PF");
     487           4 :     } else if(sigma0min_.size()==0) {
     488           0 :       sigma0min_.resize(pf_n_);
     489           0 :       for(unsigned i=0; i<pf_n_; i++) {
     490           0 :         sigma0min_[i]=-1.;
     491             :       }
     492             :     }
     493             : 
     494           8 :     parseVector("SIGMA_MAX",sigma0max_);
     495           4 :     if(sigma0max_.size()>0 && sigma0max_.size()!=pf_n_) {
     496           0 :       error("the number of SIGMA_MAX values be the same of the number of the arguments/PF");
     497           4 :     } else if(sigma0max_.size()==0) {
     498           4 :       sigma0max_.resize(pf_n_);
     499          12 :       for(unsigned i=0; i<pf_n_; i++) {
     500           8 :         sigma0max_[i]=-1.;
     501             :       }
     502             :     }
     503             : 
     504          12 :     for(unsigned i=0; i<pf_n_; i++) {
     505             :       std::vector<double> tmp_smin, tmp_smax;
     506           8 :       tmp_smin.resize(1,sigma0min_[i]);
     507           8 :       tmp_smax.resize(1,sigma0max_[i]);
     508          16 :       flexbin_.push_back(FlexibleBin(adaptive_,this,i,sigma0_[0],tmp_smin,tmp_smax));
     509             :     }
     510             :   }
     511             : 
     512             :   // note: HEIGHT is not compulsory, since one could use the TAU keyword, see below
     513          42 :   parse("HEIGHT",height0_);
     514          42 :   parse("PACE",stride_);
     515          42 :   if(stride_<=0) {
     516           0 :     error("frequency for hill addition is nonsensical");
     517             :   }
     518             : 
     519             : 
     520          84 :   parseVector("FILE",hillsfname_);
     521          42 :   if(hillsfname_.size()==0) {
     522          30 :     for(unsigned i=0; i< pf_n_; i++) {
     523          20 :       std::string name = do_pf_ ? "HILLS.PF"+std::to_string(i) : "HILLS."+getPntrToArgument(i)->getName();
     524          20 :       hillsfname_.push_back(name);
     525             :     }
     526             :   }
     527          42 :   if( hillsfname_.size()!=pf_n_ ) {
     528           0 :     error("number of FILE arguments does not match number of HILLS files");
     529             :   }
     530             : 
     531          42 :   parse("BIASFACTOR",biasf_);
     532          42 :   if( biasf_<1.0 ) {
     533           0 :     error("well tempered bias factor is nonsensical");
     534             :   }
     535          42 :   double temp=0.0;
     536          42 :   parse("TEMP",temp);
     537          42 :   if(temp>0.0) {
     538          42 :     kbt_=plumed.getAtoms().getKBoltzmann()*temp;
     539             :   } else {
     540           0 :     kbt_=plumed.getAtoms().getKbT();
     541             :   }
     542          42 :   if(biasf_>1.0) {
     543          41 :     if(kbt_==0.0) {
     544           0 :       error("Unless the MD engine passes the temperature to plumed, with well-tempered metad you must specify it using TEMP");
     545             :     }
     546          41 :     welltemp_=true;
     547             :   }
     548          42 :   double tau=0.0;
     549          42 :   parse("TAU",tau);
     550          42 :   if(tau==0.0) {
     551          42 :     if(height0_==std::numeric_limits<double>::max()) {
     552           0 :       error("At least one between HEIGHT and TAU should be specified");
     553             :     }
     554             :     // if tau is not set, we compute it here from the other input parameters
     555          42 :     if(welltemp_) {
     556          41 :       tau=(kbt_*(biasf_-1.0))/height0_*getTimeStep()*stride_;
     557             :     }
     558             :   } else {
     559           0 :     if(!welltemp_) {
     560           0 :       error("TAU only makes sense in well-tempered metadynamics");
     561             :     }
     562           0 :     if(height0_!=std::numeric_limits<double>::max()) {
     563           0 :       error("At most one between HEIGHT and TAU should be specified");
     564             :     }
     565           0 :     height0_=(kbt_*(biasf_-1.0))/tau*getTimeStep()*stride_;
     566             :   }
     567             : 
     568             : 
     569             :   // Multiple walkers
     570          42 :   parse("WALKERS_N",mw_n_);
     571          42 :   parse("WALKERS_ID",mw_id_);
     572          42 :   if(mw_n_<=mw_id_) {
     573           0 :     error("walker ID should be a numerical value less than the total number of walkers");
     574             :   }
     575          42 :   parse("WALKERS_DIR",mw_dir_);
     576          42 :   parse("WALKERS_RSTRIDE",mw_rstride_);
     577             : 
     578             :   // MPI version
     579          42 :   parseFlag("WALKERS_MPI",walkers_mpi_);
     580             : 
     581             :   // Grid file
     582          84 :   parse("GRID_WSTRIDE",wgridstride_);
     583             :   std::vector<std::string> gridfilenames_;
     584          42 :   parseVector("GRID_WFILES",gridfilenames_);
     585          42 :   if (wgridstride_ == 0 && gridfilenames_.size() > 0) {
     586           0 :     error("frequency with which to output grid not specified use GRID_WSTRIDE");
     587             :   }
     588          42 :   if(gridfilenames_.size()==0 && wgridstride_ > 0) {
     589          12 :     for(unsigned i=0; i<pf_n_; i++) {
     590           8 :       std::string name = do_pf_ ? "GRID.PF"+std::to_string(i) : "GRID."+getPntrToArgument(i)->getName();
     591           8 :       gridfilenames_.push_back(name);
     592             :     }
     593             :   }
     594          42 :   if(gridfilenames_.size() > 0 && hillsfname_.size() > 0 && gridfilenames_.size() != hillsfname_.size()) {
     595           0 :     error("number of GRID_WFILES arguments does not match number of HILLS files");
     596             :   }
     597             : 
     598             :   // Read grid
     599             :   std::vector<std::string> gridreadfilenames_;
     600          42 :   parseVector("GRID_RFILES",gridreadfilenames_);
     601             : 
     602             :   // Grid Stuff
     603          42 :   std::vector<std::string> gmin(pf_n_);
     604          84 :   parseVector("GRID_MIN",gmin);
     605          42 :   if(gmin.size()!=pf_n_ && gmin.size()!=0) {
     606           0 :     error("not enough values for GRID_MIN");
     607             :   }
     608          42 :   std::vector<std::string> gmax(pf_n_);
     609          84 :   parseVector("GRID_MAX",gmax);
     610          42 :   if(gmax.size()!=pf_n_ && gmax.size()!=0) {
     611           0 :     error("not enough values for GRID_MAX");
     612             :   }
     613          42 :   std::vector<unsigned> gbin(pf_n_);
     614             :   std::vector<double>   gspacing;
     615          84 :   parseVector("GRID_BIN",gbin);
     616          42 :   if(gbin.size()!=pf_n_ && gbin.size()!=0) {
     617           0 :     error("not enough values for GRID_BIN");
     618             :   }
     619          84 :   parseVector("GRID_SPACING",gspacing);
     620          42 :   if(gspacing.size()!=pf_n_ && gspacing.size()!=0) {
     621           0 :     error("not enough values for GRID_SPACING");
     622             :   }
     623          42 :   if(gmin.size()!=gmax.size()) {
     624           0 :     error("GRID_MAX and GRID_MIN should be either present or absent");
     625             :   }
     626          42 :   if(gspacing.size()!=0 && gmin.size()==0) {
     627           0 :     error("If GRID_SPACING is present also GRID_MIN and GRID_MAX should be present");
     628             :   }
     629          42 :   if(gbin.size()!=0     && gmin.size()==0) {
     630           0 :     error("If GRID_BIN is present also GRID_MIN and GRID_MAX should be present");
     631             :   }
     632          42 :   if(gmin.size()!=0) {
     633          10 :     if(gbin.size()==0 && gspacing.size()==0) {
     634          10 :       if(adaptive_==FlexibleBin::none) {
     635           6 :         log<<"  Binsize not specified, 1/5 of sigma will be be used\n";
     636           6 :         plumed_assert(sigma0_.size()==pf_n_);
     637           6 :         gspacing.resize(pf_n_);
     638          18 :         for(unsigned i=0; i<gspacing.size(); i++) {
     639          12 :           gspacing[i]=0.2*sigma0_[i];
     640             :         }
     641             :       } else {
     642             :         // with adaptive hills and grid a sigma min must be specified
     643          12 :         for(unsigned i=0; i<sigma0min_.size(); i++)
     644           8 :           if(sigma0min_[i]<=0) {
     645           0 :             error("When using ADAPTIVE Gaussians on a grid SIGMA_MIN must be specified");
     646             :           }
     647           4 :         log<<"  Binsize not specified, 1/5 of sigma_min will be be used\n";
     648           4 :         gspacing.resize(pf_n_);
     649          12 :         for(unsigned i=0; i<gspacing.size(); i++) {
     650           8 :           gspacing[i]=0.2*sigma0min_[i];
     651             :         }
     652             :       }
     653           0 :     } else if(gspacing.size()!=0 && gbin.size()==0) {
     654           0 :       log<<"  The number of bins will be estimated from GRID_SPACING\n";
     655           0 :     } else if(gspacing.size()!=0 && gbin.size()!=0) {
     656           0 :       log<<"  You specified both GRID_BIN and GRID_SPACING\n";
     657           0 :       log<<"  The more conservative (highest) number of bins will be used for each variable\n";
     658             :     }
     659          10 :     if(gbin.size()==0) {
     660          10 :       gbin.assign(pf_n_,1);
     661             :     }
     662          10 :     if(gspacing.size()!=0)
     663          30 :       for(unsigned i=0; i<pf_n_; i++) {
     664             :         double a,b;
     665          20 :         Tools::convert(gmin[i],a);
     666          20 :         Tools::convert(gmax[i],b);
     667          20 :         unsigned n=std::ceil(((b-a)/gspacing[i]));
     668          20 :         if(gbin[i]<n) {
     669          20 :           gbin[i]=n;
     670             :         }
     671             :       }
     672             :   }
     673          42 :   if(gbin.size()>0) {
     674          10 :     grid_=true;
     675             :   }
     676             : 
     677          42 :   bool sparsegrid=false;
     678          42 :   parseFlag("GRID_SPARSE",sparsegrid);
     679          42 :   bool nospline=false;
     680          42 :   parseFlag("GRID_NOSPLINE",nospline);
     681          42 :   bool spline=!nospline;
     682          42 :   if(!grid_&&gridfilenames_.size() > 0) {
     683           0 :     error("To write a grid you need first to define it!");
     684             :   }
     685          42 :   if(!grid_&&gridreadfilenames_.size() > 0) {
     686           0 :     error("To read a grid you need first to define it!");
     687             :   }
     688             : 
     689          42 :   doInt_.resize(pf_n_,false);
     690             :   // Interval keyword
     691          42 :   parseVector("INTERVAL_MIN",lowI_);
     692          84 :   parseVector("INTERVAL_MAX",uppI_);
     693             :   // various checks
     694          42 :   if(lowI_.size()!=uppI_.size()) {
     695           0 :     error("both a lower and an upper limits must be provided with INTERVAL");
     696             :   }
     697          42 :   if(lowI_.size()!=0 && lowI_.size()!=pf_n_) {
     698           0 :     error("check number of argument of INTERVAL");
     699             :   }
     700          50 :   for(unsigned i=0; i<lowI_.size(); ++i) {
     701           8 :     if(uppI_[i]<lowI_[i]) {
     702           0 :       error("The Upper limit must be greater than the Lower limit!");
     703             :     }
     704           8 :     if(pfhold_[i]->isPeriodic()) {
     705           0 :       warning("INTERVAL is not used for periodic variables");
     706             :     } else {
     707             :       doInt_[i]=true;
     708             :     }
     709             :   }
     710             : 
     711             :   // parse selector stuff
     712          84 :   parse("SELECTOR", selector_);
     713          42 :   if(selector_.length()>0) {
     714           1 :     do_select_ = true;
     715           1 :     select_value_ = 0; // set defalt value or it might be not initialized if the user does not pass SELECTOR_ID
     716           2 :     parse("SELECTOR_ID", select_value_);
     717             :   }
     718             : 
     719          42 :   checkRead();
     720             : 
     721          42 :   log.printf("  Gaussian width ");
     722          42 :   if (adaptive_==FlexibleBin::diffusion) {
     723           4 :     log.printf(" (Note: The units of sigma are in timesteps) ");
     724             :   }
     725          42 :   if (adaptive_==FlexibleBin::geometry) {
     726           0 :     log.printf(" (Note: The units of sigma are in dist units) ");
     727             :   }
     728         122 :   for(unsigned i=0; i<sigma0_.size(); ++i) {
     729          80 :     log.printf(" %f",sigma0_[i]);
     730             :   }
     731          42 :   log.printf("  Gaussian height %f\n",height0_);
     732          42 :   log.printf("  Gaussian deposition pace %d\n",stride_);
     733          42 :   log.printf("  Gaussian files ");
     734         126 :   for(unsigned i=0; i<hillsfname_.size(); ++i) {
     735          84 :     log.printf("%s ",hillsfname_[i].c_str());
     736             :   }
     737          42 :   log.printf("\n");
     738          42 :   if(welltemp_) {
     739          41 :     log.printf("  Well-Tempered Bias Factor %f\n",biasf_);
     740          41 :     log.printf("  Hills relaxation time (tau) %f\n",tau);
     741          41 :     log.printf("  KbT %f\n",kbt_);
     742             :   }
     743             : 
     744          42 :   if(do_select_) {
     745           1 :     log.printf("  Add forces and update bias based on the value of SELECTOR %s\n",selector_.c_str());
     746           1 :     log.printf("  Id of the SELECTOR for this action %u\n", select_value_);
     747             :   }
     748             : 
     749          42 :   if(mw_n_>1) {
     750           0 :     if(walkers_mpi_) {
     751           0 :       error("MPI version of multiple walkers is not compatible with filesystem version of multiple walkers");
     752             :     }
     753           0 :     log.printf("  %d multiple walkers active\n",mw_n_);
     754           0 :     log.printf("  walker id %d\n",mw_id_);
     755           0 :     log.printf("  reading stride %d\n",mw_rstride_);
     756           0 :     if(mw_dir_!="") {
     757           0 :       log.printf("  directory with hills files %s\n",mw_dir_.c_str());
     758             :     }
     759             :   } else {
     760          42 :     if(walkers_mpi_) {
     761          34 :       log.printf("  Multiple walkers active using MPI communnication\n");
     762          34 :       if(mw_dir_!="") {
     763           0 :         log.printf("  directory with hills files %s\n",mw_dir_.c_str());
     764             :       }
     765          34 :       if(comm.Get_rank()==0) {
     766             :         // Only root of group can communicate with other walkers
     767          18 :         mpi_nw_ = multi_sim_comm.Get_size();
     768          18 :         mpi_id_ = multi_sim_comm.Get_rank();
     769             :       }
     770             :       // Communicate to the other members of the same group
     771             :       // info abount number of walkers and walker index
     772          34 :       comm.Bcast(mpi_nw_,0);
     773          34 :       comm.Bcast(mpi_id_,0);
     774             :     }
     775             :   }
     776             : 
     777         126 :   for(unsigned i=0; i<doInt_.size(); i++) {
     778          84 :     if(doInt_[i]) {
     779           8 :       log.printf("  Upper and Lower limits boundaries for the bias of CV %u are activated\n", i);
     780             :     }
     781             :   }
     782          42 :   if(grid_) {
     783          10 :     log.printf("  Grid min");
     784          30 :     for(unsigned i=0; i<gmin.size(); ++i) {
     785          20 :       log.printf(" %s",gmin[i].c_str() );
     786             :     }
     787          10 :     log.printf("\n");
     788          10 :     log.printf("  Grid max");
     789          30 :     for(unsigned i=0; i<gmax.size(); ++i) {
     790          20 :       log.printf(" %s",gmax[i].c_str() );
     791             :     }
     792          10 :     log.printf("\n");
     793          10 :     log.printf("  Grid bin");
     794          30 :     for(unsigned i=0; i<gbin.size(); ++i) {
     795          20 :       log.printf(" %u",gbin[i]);
     796             :     }
     797          10 :     log.printf("\n");
     798          10 :     if(spline) {
     799          10 :       log.printf("  Grid uses spline interpolation\n");
     800             :     }
     801          10 :     if(sparsegrid) {
     802           0 :       log.printf("  Grid uses sparse grid\n");
     803             :     }
     804          10 :     if(wgridstride_>0) {
     805          18 :       for(unsigned i=0; i<gridfilenames_.size(); ++i) {
     806          12 :         log.printf("  Grid is written on file %s with stride %d\n",gridfilenames_[i].c_str(),wgridstride_);
     807             :       }
     808             :     }
     809          10 :     if(gridreadfilenames_.size()>0) {
     810           3 :       for(unsigned i=0; i<gridreadfilenames_.size(); ++i) {
     811           2 :         log.printf("  Reading bias from grid in file %s \n",gridreadfilenames_[i].c_str());
     812             :       }
     813             :     }
     814             :   }
     815             : 
     816             :   // initializing vector of hills
     817          42 :   hills_.resize(pf_n_);
     818             : 
     819             :   // restart from external grid
     820             :   bool restartedFromGrid=false;
     821             : 
     822             :   // initializing and checking grid
     823          42 :   if(grid_) {
     824             :     // check for mesh and sigma size
     825          30 :     for(unsigned i=0; i<pf_n_; i++) {
     826             :       double a,b;
     827          20 :       int family = pfs_[i]; // point to families instead of arguments
     828          20 :       Tools::convert(gmin[family],a);
     829          20 :       Tools::convert(gmax[family],b);
     830          20 :       double mesh=(b-a)/((double)gbin[family]);
     831          20 :       if(adaptive_==FlexibleBin::none) {
     832          12 :         if(mesh>0.5*sigma0_[i]) {
     833           0 :           log<<"  WARNING: Using a PBMETAD with a Grid Spacing larger than half of the Gaussians width can produce artifacts\n";
     834             :         }
     835             :       } else {
     836           8 :         if(mesh>0.5*sigma0min_[i]||sigma0min_[i]<0.) {
     837           0 :           log<<"  WARNING: to use a PBMETAD with a GRID and ADAPTIVE you need to set a Grid Spacing larger than half of the Gaussians \n";
     838             :         }
     839             :       }
     840             :     }
     841          10 :     std::string funcl=getLabel() + ".bias";
     842          30 :     for(unsigned i=0; i<pf_n_; ++i) {
     843          20 :       std::vector<Value*> args(1);
     844          20 :       args[0] = pfhold_[i];  //Use first argument in family for interactions.
     845          20 :       std::vector<std::string> gmin_t(1);
     846          20 :       std::vector<std::string> gmax_t(1);
     847          20 :       std::vector<unsigned>    gbin_t(1);
     848             :       gmin_t[0] = gmin[i];
     849             :       gmax_t[0] = gmax[i];
     850          20 :       gbin_t[0] = gbin[i];
     851          20 :       std::unique_ptr<GridBase> BiasGrid_;
     852             :       // Read grid from file
     853          20 :       if(gridreadfilenames_.size()>0) {
     854           2 :         IFile gridfile;
     855           2 :         gridfile.link(*this);
     856           2 :         if(gridfile.FileExist(gridreadfilenames_[i])) {
     857           2 :           gridfile.open(gridreadfilenames_[i]);
     858             :         } else {
     859           0 :           error("The GRID file you want to read: " + gridreadfilenames_[i] + ", cannot be found!");
     860             :         }
     861           2 :         std::string funcl = getLabel() + ".bias";
     862           4 :         BiasGrid_=GridBase::create(funcl, args, gridfile, gmin_t, gmax_t, gbin_t, sparsegrid, spline, true);
     863           2 :         if(BiasGrid_->getDimension() != args.size()) {
     864           0 :           error("mismatch between dimensionality of input grid and number of arguments");
     865             :         }
     866           4 :         if(pfhold_[i]->isPeriodic() != BiasGrid_->getIsPeriodic()[0]) {
     867           0 :           error("periodicity mismatch between arguments and input bias");
     868             :         }
     869           2 :         log.printf("  Restarting from %s:\n",gridreadfilenames_[i].c_str());
     870           2 :         if(getRestart()) {
     871             :           restartedFromGrid=true;
     872             :         }
     873           2 :       } else {
     874          18 :         if(!sparsegrid) {
     875          18 :           BiasGrid_=Tools::make_unique<Grid>(funcl,args,gmin_t,gmax_t,gbin_t,spline,true);
     876             :         } else           {
     877           0 :           BiasGrid_=Tools::make_unique<SparseGrid>(funcl,args,gmin_t,gmax_t,gbin_t,spline,true);
     878             :         }
     879          18 :         std::vector<std::string> actualmin=BiasGrid_->getMin();
     880          18 :         std::vector<std::string> actualmax=BiasGrid_->getMax();
     881             :         std::string is;
     882          18 :         Tools::convert(i,is);
     883          18 :         if(gmin_t[0]!=actualmin[0]) {
     884           0 :           error("GRID_MIN["+is+"] must be adjusted to "+actualmin[0]+" to fit periodicity");
     885             :         }
     886          18 :         if(gmax_t[0]!=actualmax[0]) {
     887           0 :           error("GRID_MAX["+is+"] must be adjusted to "+actualmax[0]+" to fit periodicity");
     888             :         }
     889          18 :       }
     890          20 :       BiasGrids_.emplace_back(std::move(BiasGrid_));
     891          40 :     }
     892             :   }
     893             : 
     894             : 
     895             : 
     896             : // creating vector of ifile* for hills reading
     897             : // open all files at the beginning and read Gaussians if restarting
     898             : 
     899          84 :   for(int j=0; j<mw_n_; ++j) {
     900         126 :     for(unsigned i=0; i<hillsfname_.size(); ++i) {
     901          84 :       unsigned k=j*hillsfname_.size()+i;
     902             :       std::string fname;
     903          84 :       if(mw_dir_!="") {
     904           0 :         if(mw_n_>1) {
     905           0 :           std::stringstream out;
     906           0 :           out << j;
     907           0 :           fname = mw_dir_+"/"+hillsfname_[i]+"."+out.str();
     908           0 :         } else if(walkers_mpi_) {
     909           0 :           fname = mw_dir_+"/"+hillsfname_[i];
     910             :         } else {
     911             :           fname = hillsfname_[i];
     912             :         }
     913             :       } else {
     914          84 :         if(mw_n_>1) {
     915           0 :           std::stringstream out;
     916           0 :           out << j;
     917           0 :           fname = hillsfname_[i]+"."+out.str();
     918           0 :         } else {
     919             :           fname = hillsfname_[i];
     920             :         }
     921             :       }
     922          84 :       ifiles_.emplace_back(Tools::make_unique<IFile>());
     923             :       // this is just a shortcut pointer to the last element:
     924             :       IFile *ifile = ifiles_.back().get();
     925          84 :       ifile->link(*this);
     926          84 :       ifilesnames_.push_back(fname);
     927          84 :       if(ifile->FileExist(fname)) {
     928          18 :         ifile->open(fname);
     929          18 :         if(getRestart()&&!restartedFromGrid) {
     930           2 :           log.printf("  Restarting from %s:",ifilesnames_[k].c_str());
     931           2 :           readGaussians(i,ifiles_[k].get());
     932             :         }
     933          18 :         ifiles_[k]->reset(false);
     934             :         // close only the walker own hills file for later writing
     935          18 :         if(j==mw_id_) {
     936          18 :           ifiles_[k]->close();
     937             :         }
     938             :       } else {
     939             :         // in case a file does not exist and we are restarting, complain that the file was not found
     940          66 :         if(getRestart()) {
     941           2 :           log<<"  WARNING: restart file "<<fname<<" not found\n";
     942             :         }
     943             :       }
     944             :     }
     945             :   }
     946             : 
     947          42 :   comm.Barrier();
     948          42 :   if(comm.Get_rank()==0 && walkers_mpi_) {
     949          18 :     multi_sim_comm.Barrier();
     950             :   }
     951             : 
     952             :   // open hills files for writing
     953         126 :   for(unsigned i=0; i<hillsfname_.size(); ++i) {
     954          84 :     auto ofile=Tools::make_unique<OFile>();
     955          84 :     ofile->link(*this);
     956             :     // if MPI multiple walkers, only rank 0 will write to file
     957          84 :     if(walkers_mpi_) {
     958          68 :       int r=0;
     959          68 :       if(comm.Get_rank()==0) {
     960          36 :         r=multi_sim_comm.Get_rank();
     961             :       }
     962          68 :       comm.Bcast(r,0);
     963          68 :       if(r>0) {
     964          34 :         ifilesnames_[mw_id_*hillsfname_.size()+i]="/dev/null";
     965             :       }
     966         136 :       ofile->enforceSuffix("");
     967             :     }
     968          84 :     if(mw_n_>1) {
     969           0 :       ofile->enforceSuffix("");
     970             :     }
     971          84 :     ofile->open(ifilesnames_[mw_id_*hillsfname_.size()+i]);
     972          84 :     if(fmt_.length()>0) {
     973          24 :       ofile->fmtField(fmt_);
     974             :     }
     975         168 :     ofile->addConstantField("multivariate");
     976         168 :     ofile->addConstantField("kerneltype");
     977          84 :     if(doInt_[i]) {
     978          16 :       ofile->addConstantField("lower_int").printField("lower_int",lowI_[i]);
     979          16 :       ofile->addConstantField("upper_int").printField("upper_int",uppI_[i]);
     980             :     }
     981          84 :     ofile->setHeavyFlush();
     982             :     // output periodicities of variables
     983          84 :     ofile->setupPrintValue( pfhold_[i] );  //assuming cvs in the same family have the same periodicity and boundaries.
     984             :     // push back
     985          84 :     hillsOfiles_.emplace_back(std::move(ofile));
     986          84 :   }
     987             : 
     988             :   // Dump grid to files
     989          42 :   if(wgridstride_ > 0) {
     990          18 :     for(unsigned i = 0; i < gridfilenames_.size(); ++i) {
     991          12 :       auto ofile=Tools::make_unique<OFile>();
     992          12 :       ofile->link(*this);
     993          12 :       std::string gridfname_tmp = gridfilenames_[i];
     994          12 :       if(walkers_mpi_) {
     995           8 :         int r = 0;
     996           8 :         if(comm.Get_rank() == 0) {
     997           4 :           r = multi_sim_comm.Get_rank();
     998             :         }
     999           8 :         comm.Bcast(r, 0);
    1000           8 :         if(r>0) {
    1001             :           gridfname_tmp = "/dev/null";
    1002             :         }
    1003          16 :         ofile->enforceSuffix("");
    1004             :       }
    1005          12 :       if(mw_n_>1) {
    1006           0 :         ofile->enforceSuffix("");
    1007             :       }
    1008          12 :       ofile->open(gridfname_tmp);
    1009          12 :       ofile->setHeavyFlush();
    1010          12 :       gridfiles_.emplace_back(std::move(ofile));
    1011          12 :     }
    1012             :   }
    1013             : 
    1014          84 :   log<<"  Bibliography "<<plumed.cite("Pfaendtner and Bonomi. J. Chem. Theory Comput. 11, 5062 (2015)");
    1015          42 :   if(doInt_[0])
    1016           8 :     log<<plumed.cite(
    1017           8 :          "Baftizadeh, Cossio, Pietrucci, and Laio, Curr. Phys. Chem. 2, 79 (2012)");
    1018          42 :   if(mw_n_>1||walkers_mpi_)
    1019          68 :     log<<plumed.cite(
    1020          68 :          "Raiteri, Laio, Gervasio, Micheletti, and Parrinello, J. Phys. Chem. B 110, 3533 (2006)");
    1021          42 :   if(adaptive_!=FlexibleBin::none)
    1022           8 :     log<<plumed.cite(
    1023           8 :          "Branduardi, Bussi, and Parrinello, J. Chem. Theory Comput. 8, 2247 (2012)");
    1024          42 :   if (do_pf_) {
    1025           8 :     log<<plumed.cite("Prakash, Fu, Bonomi, and Pfaendtner, J. Chem. Theory Comput. 14, 4985 (2018)");
    1026             :   }
    1027          42 :   log<<"\n";
    1028             : 
    1029             : 
    1030          84 : }
    1031             : 
    1032           2 : void PBMetaD::readGaussians(unsigned iarg, IFile *ifile) {
    1033           2 :   std::vector<double> center(1);
    1034           2 :   std::vector<double> sigma(1);
    1035             :   double height;
    1036             :   int nhills=0;
    1037           2 :   bool multivariate=false;
    1038           2 :   int family=pfs_[iarg];
    1039             : 
    1040             :   std::vector<Value> tmpvalues;
    1041           4 :   tmpvalues.push_back( Value( this, pfhold_[family]->getName(), false ) );
    1042             : 
    1043          10 :   while(scanOneHill(iarg,ifile,tmpvalues,center,sigma,height,multivariate)) {
    1044             :     ;
    1045           8 :     nhills++;
    1046           8 :     if(welltemp_) {
    1047           8 :       height*=(biasf_-1.0)/biasf_;
    1048             :     }
    1049           8 :     addGaussian(family, Gaussian(center,sigma,height,multivariate));
    1050             :   }
    1051           2 :   log.printf("      %d Gaussians read\n",nhills);
    1052           4 : }
    1053             : 
    1054        1112 : void PBMetaD::writeGaussian(unsigned iarg, const Gaussian& hill, OFile *ofile) {
    1055        1112 :   int family=pfs_[iarg];
    1056        2224 :   ofile->printField("time",getTimeStep()*getStep());
    1057        1112 :   ofile->printField(pfhold_[family],hill.center[0]);
    1058             : 
    1059        2224 :   ofile->printField("kerneltype","stretched-gaussian");
    1060        1112 :   if(hill.multivariate) {
    1061         288 :     ofile->printField("multivariate","true");
    1062         144 :     double lower = std::sqrt(1./hill.sigma[0]);
    1063         288 :     ofile->printField("sigma_"+pfhold_[family]->getName()+"_"+
    1064         144 :                       pfhold_[family]->getName(),lower);
    1065             :   } else {
    1066        1936 :     ofile->printField("multivariate","false");
    1067        1936 :     ofile->printField("sigma_"+pfhold_[family]->getName(),hill.sigma[0]);
    1068             :   }
    1069        1112 :   double height=hill.height;
    1070        1112 :   if(welltemp_) {
    1071        1104 :     height *= biasf_/(biasf_-1.0);
    1072             :   }
    1073        1112 :   ofile->printField("height",height);
    1074        1112 :   ofile->printField("biasf",biasf_);
    1075        1112 :   if(mw_n_>1) {
    1076           0 :     ofile->printField("clock",int(std::time(0)));
    1077             :   }
    1078        1112 :   ofile->printField();
    1079        1112 : }
    1080             : 
    1081        1120 : void PBMetaD::addGaussian(unsigned iarg, const Gaussian& hill) {
    1082        1120 :   if(!grid_) {
    1083         912 :     hills_[iarg].push_back(hill);
    1084             :   } else {
    1085         208 :     std::vector<unsigned> nneighb=getGaussianSupport(iarg, hill);
    1086         208 :     std::vector<Grid::index_t> neighbors=BiasGrids_[iarg]->getNeighbors(hill.center,nneighb);
    1087         208 :     std::vector<double> der(1);
    1088         208 :     std::vector<double> xx(1);
    1089         208 :     if(comm.Get_size()==1) {
    1090        1520 :       for(unsigned i=0; i<neighbors.size(); ++i) {
    1091        1480 :         Grid::index_t ineigh=neighbors[i];
    1092        1480 :         der[0]=0.0;
    1093        1480 :         BiasGrids_[iarg]->getPoint(ineigh,xx);
    1094        1480 :         double bias=evaluateGaussian(iarg,xx,hill,&der[0]);
    1095        1480 :         BiasGrids_[iarg]->addValueAndDerivatives(ineigh,bias,der);
    1096             :       }
    1097             :     } else {
    1098         168 :       unsigned stride=comm.Get_size();
    1099         168 :       unsigned rank=comm.Get_rank();
    1100         168 :       std::vector<double> allder(neighbors.size(),0.0);
    1101         168 :       std::vector<double> allbias(neighbors.size(),0.0);
    1102        3276 :       for(unsigned i=rank; i<neighbors.size(); i+=stride) {
    1103        3108 :         Grid::index_t ineigh=neighbors[i];
    1104        3108 :         BiasGrids_[iarg]->getPoint(ineigh,xx);
    1105        3108 :         allbias[i]=evaluateGaussian(iarg,xx,hill,&allder[i]);
    1106             :       }
    1107         168 :       comm.Sum(allbias);
    1108         168 :       comm.Sum(allder);
    1109        6384 :       for(unsigned i=0; i<neighbors.size(); ++i) {
    1110        6216 :         Grid::index_t ineigh=neighbors[i];
    1111        6216 :         der[0]=allder[i];
    1112        6216 :         BiasGrids_[iarg]->addValueAndDerivatives(ineigh,allbias[i],der);
    1113             :       }
    1114             :     }
    1115             :   }
    1116        1120 : }
    1117             : 
    1118         208 : std::vector<unsigned> PBMetaD::getGaussianSupport(unsigned iarg, const Gaussian& hill) {
    1119             :   std::vector<unsigned> nneigh;
    1120             :   double cutoff;
    1121         208 :   if(hill.multivariate) {
    1122         144 :     double maxautoval=1./hill.sigma[0];
    1123         144 :     cutoff=std::sqrt(2.0*dp2cutoff*maxautoval);
    1124             :   } else {
    1125          64 :     cutoff=std::sqrt(2.0*dp2cutoff)*hill.sigma[0];
    1126             :   }
    1127             : 
    1128         208 :   if(doInt_[iarg]) {
    1129         144 :     if(hill.center[0]+cutoff > uppI_[iarg] || hill.center[0]-cutoff < lowI_[iarg]) {
    1130             :       // in this case, we updated the entire grid to avoid problems
    1131           0 :       return BiasGrids_[iarg]->getNbin();
    1132             :     } else {
    1133         144 :       nneigh.push_back( static_cast<unsigned>(ceil(cutoff/BiasGrids_[iarg]->getDx()[0])));
    1134             :       return nneigh;
    1135             :     }
    1136             :   }
    1137             : 
    1138          64 :   nneigh.push_back( static_cast<unsigned>(ceil(cutoff/BiasGrids_[iarg]->getDx()[0])) );
    1139             : 
    1140             :   return nneigh;
    1141             : }
    1142             : 
    1143        1296 : double PBMetaD::getBiasAndDerivatives(unsigned iarg, const std::vector<double>& cv, double* der) {
    1144        1296 :   double bias=0.0;
    1145        1296 :   int family = pfs_[iarg];
    1146        1296 :   if(!grid_) {
    1147        1000 :     unsigned stride=comm.Get_size();
    1148        1000 :     unsigned rank=comm.Get_rank();
    1149        5520 :     for(unsigned i=rank; i<hills_[family].size(); i+=stride) {
    1150        4520 :       bias += evaluateGaussian(iarg,cv,hills_[family][i],der);
    1151             :     }
    1152        1000 :     comm.Sum(bias);
    1153        1000 :     if(der) {
    1154         540 :       comm.Sum(der,1);
    1155             :     }
    1156             :   } else {
    1157         296 :     if(der) {
    1158         160 :       std::vector<double> vder(1);
    1159         160 :       bias = BiasGrids_[family]->getValueAndDerivatives(cv,vder);
    1160         160 :       der[0] = vder[0];
    1161             :     } else {
    1162         136 :       bias = BiasGrids_[family]->getValue(cv);
    1163             :     }
    1164             :   }
    1165             : 
    1166        1296 :   return bias;
    1167             : }
    1168             : 
    1169        9108 : double PBMetaD::evaluateGaussian(unsigned iarg, const std::vector<double>& cv, const Gaussian& hill, double* der) {
    1170             :   double bias=0.0;
    1171             : // I use a pointer here because cv is const (and should be const)
    1172             : // but when using doInt it is easier to locally replace cv[0] with
    1173             : // the upper/lower limit in case it is out of range
    1174             :   const double *pcv=NULL;
    1175             :   double tmpcv[1]; // tmp array with cv (to be used with doInt_)
    1176        9108 :   tmpcv[0]=cv[0];
    1177             :   bool isOutOfInt = false;
    1178        9108 :   if(doInt_[iarg]) {
    1179        2664 :     if(cv[0]<lowI_[iarg]) {
    1180             :       tmpcv[0]=lowI_[iarg];
    1181             :       isOutOfInt = true;
    1182        2664 :     } else if(cv[0]>uppI_[iarg]) {
    1183             :       tmpcv[0]=uppI_[iarg];
    1184             :       isOutOfInt = true;
    1185             :     }
    1186             :   }
    1187             :   pcv=&(tmpcv[0]);
    1188             : 
    1189        9108 :   if(hill.multivariate) {
    1190        2664 :     double dp  = difference(iarg, hill.center[0], pcv[0]);
    1191        2664 :     double dp2 = 0.5 * dp * dp * hill.sigma[0];
    1192        2664 :     if(dp2<dp2cutoff) {
    1193        2534 :       bias = hill.height*std::exp(-dp2);
    1194        2534 :       if(der && !isOutOfInt) {
    1195        2534 :         der[0] += -bias * dp * hill.sigma[0] * stretchA;
    1196             :       }
    1197        2534 :       bias=stretchA*bias+hill.height*stretchB;
    1198             :     }
    1199             :   } else {
    1200        6444 :     double dp  = difference(iarg, hill.center[0], pcv[0]) * hill.invsigma[0];
    1201        6444 :     double dp2 = 0.5 * dp * dp;
    1202        6444 :     if(dp2<dp2cutoff) {
    1203        6363 :       bias = hill.height*std::exp(-dp2);
    1204        6363 :       if(der && !isOutOfInt) {
    1205        4107 :         der[0] += -bias * dp * hill.invsigma[0] * stretchA;
    1206             :       }
    1207        6363 :       bias=stretchA*bias+hill.height*stretchB;
    1208             :     }
    1209             :   }
    1210             : 
    1211        9108 :   return bias;
    1212             : }
    1213             : 
    1214         340 : void PBMetaD::calculate() {
    1215             :   // this is because presently there is no way to properly pass information
    1216             :   // on adaptive hills (diff) after exchanges:
    1217         340 :   if(adaptive_==FlexibleBin::diffusion && getExchangeStep()) {
    1218           0 :     error("ADAPTIVE=DIFF is not compatible with replica exchange");
    1219             :   }
    1220             : 
    1221         340 :   std::vector<double> cv(1);
    1222             :   double der[1];
    1223         340 :   std::vector<double> bias(getNumberOfArguments());
    1224         340 :   std::vector<double> deriv(getNumberOfArguments());
    1225             : 
    1226         340 :   double ncv = (double) getNumberOfArguments();
    1227             :   double bmin = 1.0e+19;
    1228        1040 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
    1229         700 :     cv[0]    = getArgument(i);
    1230         700 :     der[0]   = 0.0;
    1231         700 :     bias[i]  = getBiasAndDerivatives(i, cv, der);
    1232         700 :     deriv[i] = der[0];
    1233         700 :     if(bias[i] < bmin) {
    1234             :       bmin = bias[i];
    1235             :     }
    1236             :   }
    1237             :   double ene = 0.;
    1238        1040 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
    1239         700 :     ene += std::exp((-bias[i]+bmin)/kbt_);
    1240             :   }
    1241             : 
    1242             :   // set Forces - set them to zero if SELECTOR is active
    1243         340 :   if(do_select_) {
    1244           5 :     current_value_ = static_cast<unsigned>(plumed.passMap[selector_]);
    1245             :   }
    1246             : 
    1247         340 :   if(!do_select_ || select_value_==current_value_) {
    1248        1040 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
    1249         700 :       const double f = - std::exp((-bias[i]+bmin)/kbt_) / (ene) * deriv[i];
    1250         700 :       setOutputForce(i, f);
    1251             :     }
    1252             :   }
    1253             : 
    1254         340 :   if(do_select_ && select_value_!=current_value_) {
    1255           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
    1256           0 :       setOutputForce(i, 0.0);
    1257             :     }
    1258             :   }
    1259             : 
    1260             :   // set bias
    1261         340 :   ene = -kbt_ * (std::log(ene) - std::log(ncv)) + bmin;
    1262             :   setBias(ene);
    1263         340 : }
    1264             : 
    1265         340 : void PBMetaD::update() {
    1266             :   bool multivariate;
    1267             :   // adding hills criteria
    1268             :   bool nowAddAHill;
    1269         340 :   if(getStep()%stride_==0 && !isFirstStep_) {
    1270             :     nowAddAHill=true;
    1271             :   } else {
    1272             :     nowAddAHill=false;
    1273          50 :     isFirstStep_=false;
    1274             :   }
    1275             : 
    1276             :   // if you use adaptive, call the FlexibleBin
    1277         340 :   if(adaptive_!=FlexibleBin::none) {
    1278         120 :     for(unsigned i=0; i<getNumberOfArguments(); i++) {
    1279          80 :       flexbin_[i].update(nowAddAHill,i);
    1280             :     }
    1281             :     multivariate=true;
    1282             :   } else {
    1283             :     multivariate=false;
    1284             :   }
    1285             : 
    1286         340 :   if(nowAddAHill && (!do_select_ || select_value_==current_value_)) {
    1287             :     // get all biases and heights
    1288         290 :     std::vector<double> cv(getNumberOfArguments());
    1289         290 :     std::vector<double> bias(getNumberOfArguments());
    1290         290 :     std::vector<double> thissigma(getNumberOfArguments());
    1291         290 :     std::vector<double> height(getNumberOfArguments());
    1292         290 :     std::vector<double> cv_tmp(1);
    1293         290 :     std::vector<double> sigma_tmp(1);
    1294             :     double norm = 0.0;
    1295             :     double bmin = 1.0e+19;
    1296         886 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
    1297         596 :       int family=pfs_[i];
    1298             :       // get flex/sigmas for each family and assign them to this args sigma
    1299         596 :       if(adaptive_!=FlexibleBin::none) {
    1300          72 :         thissigma[i]=flexbin_[family].getInverseMatrix(i)[0];
    1301             :       } else {
    1302         524 :         thissigma[i]=sigma0_[family];
    1303             :       }
    1304         596 :       cv[i]     = getArgument(i);
    1305         596 :       cv_tmp[0] = getArgument(i);
    1306         596 :       bias[i] = getBiasAndDerivatives(i, cv_tmp);
    1307         596 :       if(bias[i] < bmin) {
    1308             :         bmin = bias[i];
    1309             :       }
    1310             :     }
    1311             :     // calculate heights and norm
    1312         886 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
    1313         596 :       double h = std::exp((-bias[i]+bmin)/kbt_);
    1314         596 :       norm += h;
    1315         596 :       height[i] = h;
    1316             :     }
    1317             :     // normalize and apply welltemp correction
    1318         886 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
    1319         596 :       height[i] *=  height0_ / norm;
    1320         596 :       if(welltemp_) {
    1321         588 :         height[i] *= std::exp(-bias[i]/(kbt_*(biasf_-1.0)));
    1322             :       }
    1323             :     }
    1324             : 
    1325             :     // MPI Multiple walkers: share hills and add them all
    1326         290 :     if(walkers_mpi_) {
    1327             :       // Allocate arrays to store all walkers hills
    1328         258 :       std::vector<double> all_cv(mpi_nw_*cv.size(), 0.0);
    1329         258 :       std::vector<double> all_sigma(mpi_nw_*getNumberOfArguments(), 0.0);
    1330         258 :       std::vector<double> all_height(mpi_nw_*height.size(), 0.0);
    1331         258 :       if(comm.Get_rank()==0) {
    1332             :         // fill in value
    1333         390 :         for(unsigned i=0; i<getNumberOfArguments(); ++i) {
    1334         260 :           unsigned j = mpi_id_ * getNumberOfArguments() + i;
    1335         260 :           all_cv[j] = cv[i];
    1336         260 :           all_sigma[j]  = thissigma[i];
    1337         260 :           all_height[j] = height[i];
    1338             :         }
    1339             :         // Communicate (only root)
    1340         130 :         multi_sim_comm.Sum(&all_cv[0], all_cv.size());
    1341         130 :         multi_sim_comm.Sum(&all_sigma[0], all_sigma.size());
    1342         130 :         multi_sim_comm.Sum(&all_height[0], all_height.size());
    1343             :       }
    1344             :       // Share info with group members
    1345         258 :       comm.Sum(&all_cv[0], all_cv.size());
    1346         258 :       comm.Sum(&all_sigma[0], all_sigma.size());
    1347         258 :       comm.Sum(&all_height[0], all_height.size());
    1348             :       // now add hills one by one
    1349         774 :       for(unsigned j=0; j<mpi_nw_; ++j) {
    1350        1548 :         for(unsigned i=0; i<getNumberOfArguments(); ++i) {
    1351             :           // Add CVs of same family together and write to same file
    1352        1032 :           int family = pfs_[i];
    1353        1032 :           cv_tmp[0]    = all_cv[j*cv.size()+i];
    1354        1032 :           double height_tmp = all_height[j*cv.size()+i];
    1355        1032 :           sigma_tmp[0] = all_sigma[j*cv.size()+i];
    1356        1032 :           Gaussian newhill = Gaussian(cv_tmp, sigma_tmp, height_tmp, multivariate);
    1357        1032 :           addGaussian(family, newhill);
    1358        1032 :           writeGaussian(i, newhill, hillsOfiles_[family].get());
    1359        1032 :         }
    1360             :       }
    1361             :       // just add your own hills
    1362             :     } else {
    1363         112 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
    1364             :         // Add CVs of same family together and write to same file
    1365          80 :         int family = pfs_[i];
    1366          80 :         cv_tmp[0] = cv[i];
    1367          80 :         if(adaptive_!=FlexibleBin::none) {
    1368           0 :           sigma_tmp[0]=thissigma[i];
    1369             :         } else {
    1370          80 :           sigma_tmp[0] = sigma0_[family];
    1371             :         }
    1372          80 :         Gaussian newhill = Gaussian(cv_tmp, sigma_tmp, height[i], multivariate);
    1373          80 :         addGaussian(family, newhill);
    1374          80 :         writeGaussian(i, newhill, hillsOfiles_[family].get());
    1375          80 :       }
    1376             :     }
    1377             :   }
    1378             : 
    1379             :   // write grid files
    1380         340 :   if(wgridstride_>0 && (getStep()%wgridstride_==0 || getCPT())) {
    1381          14 :     int r = 0;
    1382          14 :     if(walkers_mpi_) {
    1383           4 :       if(comm.Get_rank()==0) {
    1384           2 :         r=multi_sim_comm.Get_rank();
    1385             :       }
    1386           4 :       comm.Bcast(r,0);
    1387             :     }
    1388          14 :     if(r==0) {
    1389          36 :       for(unsigned i=0; i<gridfiles_.size(); ++i) {
    1390          24 :         gridfiles_[i]->rewind();
    1391          24 :         BiasGrids_[i]->writeToFile(*gridfiles_[i]);
    1392          24 :         gridfiles_[i]->flush();
    1393             :       }
    1394             :     }
    1395             :   }
    1396             : 
    1397             :   // if multiple walkers and time to read Gaussians
    1398         340 :   if(mw_n_>1 && getStep()%mw_rstride_==0) {
    1399           0 :     for(int j=0; j<mw_n_; ++j) {
    1400           0 :       for(unsigned i=0; i<hillsfname_.size(); ++i) {
    1401           0 :         unsigned k=j*hillsfname_.size()+i;
    1402             :         // don't read your own Gaussians
    1403           0 :         if(j==mw_id_) {
    1404           0 :           continue;
    1405             :         }
    1406             :         // if the file is not open yet
    1407           0 :         if(!(ifiles_[k]->isOpen())) {
    1408             :           // check if it exists now and open it!
    1409           0 :           if(ifiles_[k]->FileExist(ifilesnames_[k])) {
    1410           0 :             ifiles_[k]->open(ifilesnames_[k]);
    1411           0 :             ifiles_[k]->reset(false);
    1412             :           }
    1413             :           // otherwise read the new Gaussians
    1414             :         } else {
    1415           0 :           log.printf("  Reading hills from %s:",ifilesnames_[k].c_str());
    1416           0 :           readGaussians(i,ifiles_[k].get());
    1417           0 :           ifiles_[k]->reset(false);
    1418             :         }
    1419             :       }
    1420             :     }
    1421             :   }
    1422             : 
    1423         340 : }
    1424             : 
    1425             : /// takes a pointer to the file and a template string with values v and gives back the next center, sigma and height
    1426          10 : bool PBMetaD::scanOneHill(unsigned iarg, IFile *ifile, std::vector<Value> &tmpvalues, std::vector<double> &center, std::vector<double> &sigma, double &height, bool &multivariate) {
    1427             :   double dummy;
    1428          10 :   multivariate=false;
    1429          10 :   Value* argPtr = pfhold_[pfs_[iarg]];
    1430          20 :   if(ifile->scanField("time",dummy)) {
    1431           8 :     ifile->scanField( &tmpvalues[0] );
    1432           8 :     if( tmpvalues[0].isPeriodic() && ! argPtr->isPeriodic() ) {
    1433           0 :       error("in hills file periodicity for variable " + tmpvalues[0].getName() + " does not match periodicity in input");
    1434           8 :     } else if( tmpvalues[0].isPeriodic() ) {
    1435             :       std::string imin, imax;
    1436           0 :       tmpvalues[0].getDomain( imin, imax );
    1437             :       std::string rmin, rmax;
    1438           0 :       argPtr->getDomain( rmin, rmax );
    1439           0 :       if( imin!=rmin || imax!=rmax ) {
    1440           0 :         error("in hills file periodicity for variable " + tmpvalues[0].getName() + " does not match periodicity in input");
    1441             :       }
    1442             :     }
    1443           8 :     center[0]=tmpvalues[0].get();
    1444           8 :     std::string ktype="stretched-gaussian";
    1445          16 :     if( ifile->FieldExist("kerneltype") ) {
    1446          16 :       ifile->scanField("kerneltype",ktype);
    1447             :     }
    1448             : 
    1449           8 :     if( ktype=="gaussian" ) {
    1450           0 :       noStretchWarning();
    1451           8 :     } else if( ktype!="stretched-gaussian") {
    1452           0 :       error("non Gaussian kernels are not supported in MetaD");
    1453             :     }
    1454             : 
    1455             :     std::string sss;
    1456          16 :     ifile->scanField("multivariate",sss);
    1457           8 :     if(sss=="true") {
    1458           0 :       multivariate=true;
    1459           8 :     } else if(sss=="false") {
    1460           8 :       multivariate=false;
    1461             :     } else {
    1462           0 :       plumed_merror("cannot parse multivariate = "+ sss);
    1463             :     }
    1464           8 :     if(multivariate) {
    1465           0 :       ifile->scanField("sigma_"+argPtr->getName()+"_"+
    1466             :                        argPtr->getName(),sigma[0]);
    1467           0 :       sigma[0] = 1./(sigma[0]*sigma[0]);
    1468             :     } else {
    1469          16 :       ifile->scanField("sigma_"+argPtr->getName(),sigma[0]);
    1470             :     }
    1471           8 :     ifile->scanField("height",height);
    1472           8 :     ifile->scanField("biasf",dummy);
    1473          16 :     if(ifile->FieldExist("clock")) {
    1474           0 :       ifile->scanField("clock",dummy);
    1475             :     }
    1476          16 :     if(ifile->FieldExist("lower_int")) {
    1477           0 :       ifile->scanField("lower_int",dummy);
    1478             :     }
    1479          16 :     if(ifile->FieldExist("upper_int")) {
    1480           0 :       ifile->scanField("upper_int",dummy);
    1481             :     }
    1482           8 :     ifile->scanField();
    1483             :     return true;
    1484             :   } else {
    1485             :     return false;
    1486             :   }
    1487             : 
    1488             : }
    1489             : 
    1490         340 : bool PBMetaD::checkNeedsGradients()const {
    1491         340 :   if(adaptive_==FlexibleBin::geometry) {
    1492           0 :     if(getStep()%stride_==0 && !isFirstStep_) {
    1493             :       return true;
    1494             :     } else {
    1495           0 :       return false;
    1496             :     }
    1497             :   } else {
    1498             :     return false;
    1499             :   }
    1500             : }
    1501             : 
    1502             : }
    1503             : }
    1504             : 

Generated by: LCOV version 1.16