LCOV - code coverage report
Current view: top level - eds - EDS.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 452 488 92.6 %
Date: 2024-10-11 08:09:47 Functions: 20 23 87.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             : Copyright (c) 2017 of Glen Hocky and Andrew White
       3             : 
       4             : The eds module is free software: you can redistribute it and/or modify
       5             : it under the terms of the GNU Lesser General Public License as published by
       6             : the Free Software Foundation, either version 3 of the License, or
       7             : (at your option) any later version.
       8             : 
       9             : The eds module is distributed in the hope that it will be useful,
      10             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             : GNU Lesser General Public License for more details.
      13             : 
      14             : You should have received a copy of the GNU Lesser General Public License
      15             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      16             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      17             : #include "bias/Bias.h"
      18             : #include "bias/ReweightBase.h"
      19             : #include "core/ActionAtomistic.h"
      20             : #include "core/ActionRegister.h"
      21             : #include "core/Atoms.h"
      22             : #include "core/PlumedMain.h"
      23             : #include "tools/File.h"
      24             : #include "tools/Matrix.h"
      25             : #include "tools/Random.h"
      26             : 
      27             : #include <iostream>
      28             : 
      29             : using namespace PLMD;
      30             : using namespace bias;
      31             : 
      32             : // namespace is lowercase to match
      33             : // module names being all lowercase
      34             : 
      35             : namespace PLMD
      36             : {
      37             : namespace eds
      38             : {
      39             : 
      40             : //+PLUMEDOC EDSMOD_BIAS EDS
      41             : /*
      42             : Add a linear bias on a set of observables.
      43             : 
      44             : This force is the same as the linear part of the bias in \ref
      45             : RESTRAINT, but this bias has the ability to compute the prefactors
      46             : adaptively using the scheme of White and Voth \cite white2014efficient
      47             : in order to match target observable values for a set of CVs.
      48             : Further updates to the algorithm are described in \cite hocky2017cgds
      49             : and you can read a review on the method and its applications here: \cite Amirkulova2019Recent.
      50             : 
      51             : You can
      52             : see a tutorial on EDS specifically for biasing coordination number at
      53             : <a
      54             : href="http://thewhitelab.org/blog/tutorial/2017/05/10/lammps-coordination-number-tutorial/">
      55             : Andrew White's webpage</a>.
      56             : 
      57             : The addition to the potential is of the form
      58             : \f[
      59             :   \sum_i \frac{\alpha_i}{s_i} x_i
      60             : \f]
      61             : 
      62             : where for CV \f$x_i\f$, a coupling constant \f${\alpha}_i\f$ is determined
      63             : adaptively or set by the user to match a target value for
      64             : \f$x_i\f$. \f$s_i\f$ is a scale parameter, which by default is set to
      65             : the target value. It may also be set separately.
      66             : 
      67             : \warning
      68             : It is not possible to set the target value of the observable
      69             : to zero with the default value of \f$s_i\f$ as this will cause a
      70             : divide-by-zero error. Instead, set \f$s_i=1\f$ or modify the CV so the
      71             : desired target value is no longer zero.
      72             : 
      73             : Notice that a similar method is available as \ref MAXENT, although with different features and using a different optimization algorithm.
      74             : 
      75             : \par Virial
      76             : 
      77             : The bias forces modify the virial and this can change your simulation density if the bias is used in an NPT simulation.
      78             : One way to avoid changing the virial contribution from the bias is to add the keyword VIRIAL=1.0, which changes how the bias
      79             : is computed to minimize its contribution to the virial. This can also lead to smaller magnitude biases that are more robust if
      80             : transferred to other systems.  VIRIAL=1.0 can be a reasonable starting point and increasing the value changes the balance between matching
      81             : the set-points and minimizing the virial. See \cite Amirkulova2019Recent for details on the equations. Since the coupling constants
      82             : are unique with a single CV, VIRIAL is not applicable with a single CV. When used with multiple CVs, the CVs should be correlated
      83             : which is almost always the case.
      84             : 
      85             : \par Weighting
      86             : 
      87             : EDS computes means and variances as part of its algorithm. If you are
      88             : also using a biasing method like metadynamics, you may wish to remove
      89             : the effect of this bias in your EDS computations so that EDS works on
      90             : the canonical values (reweighted to be unbiased).  For example, you may be using
      91             : metadynamics to bias a dihedral angle to enhance sampling and be using
      92             : EDS to set the average distance between two particular atoms. Specifically:
      93             : 
      94             : \plumedfile
      95             : # set-up metadynamics
      96             : t: TORSION ATOMS=1,2,3,4
      97             : md: METAD ARG=d SIGMA=0.2 HEIGHT=0.3 PACE=500 TEMP=300
      98             : # compute bias weights
      99             : bias: REWEIGHT_METAD TEMP=300
     100             : # now do EDS on distance while removing effect of metadynamics
     101             : d: DISTANCE ATOMS=4,7
     102             : eds: EDS ARG=d CENTER=3.0 PERIOD=100 TEMP=300 LOGWEIGHTS=bias
     103             : \endplumedfile
     104             : 
     105             : This is an approximation though because EDS uses a finite samples while running to get means/variances.
     106             : At the end of a run,
     107             : you should ensure this approach worked and indeed your reweighted CV matches the target value.
     108             : 
     109             : \par Examples
     110             : 
     111             : The following input for a harmonic oscillator of two beads will
     112             : adaptively find a linear bias to change the mean and variance to the
     113             : target values. The PRINT line shows how to access the value of the
     114             : coupling constants.
     115             : 
     116             : \plumedfile
     117             : dist: DISTANCE ATOMS=1,2
     118             : # this is the squared of the distance
     119             : dist2: COMBINE ARG=dist POWERS=2 PERIODIC=NO
     120             : 
     121             : # bias mean and variance
     122             : eds: EDS ARG=dist,dist2 CENTER=2.0,1.0 PERIOD=100 TEMP=1.0
     123             : PRINT ARG=dist,dist2,eds.dist_coupling,eds.dist2_coupling,eds.bias,eds.force2 FILE=colvars.dat STRIDE=100
     124             : \endplumedfile
     125             : 
     126             : <hr>
     127             : 
     128             : Rather than trying to find the coupling constants adaptively, one can ramp up to a constant value.
     129             : \plumedfile
     130             : dist: DISTANCE ATOMS=1,2
     131             : dist2: COMBINE ARG=dist POWERS=2 PERIODIC=NO
     132             : 
     133             : # ramp couplings from 0,0 to -1,1 over 50000 steps
     134             : eds: EDS ARG=dist,dist2 CENTER=2.0,1.0 FIXED=-1,1 RAMP PERIOD=50000 TEMP=1.0
     135             : 
     136             : # same as above, except starting at -0.5,0.5 rather than default of 0,0
     137             : eds2: EDS ARG=dist,dist2 CENTER=2.0,1.0 FIXED=-1,1 INIT=-0.5,0.5 RAMP PERIOD=50000 TEMP=1.0
     138             : \endplumedfile
     139             : 
     140             : <hr>
     141             : A restart file can be added to dump information needed to restart/continue simulation using these parameters every PERIOD.
     142             : \plumedfile
     143             : dist: DISTANCE ATOMS=1,2
     144             : dist2: COMBINE ARG=dist POWERS=2 PERIODIC=NO
     145             : 
     146             : # add the option to write to a restart file
     147             : eds: EDS ARG=dist,dist2 CENTER=2.0,1.0 PERIOD=100 TEMP=1.0 OUT_RESTART=checkpoint.eds
     148             : \endplumedfile
     149             : 
     150             : The first few lines of the restart file that is output if we run a calculation with one CV will look something like this:
     151             : 
     152             : \auxfile{restart.eds}
     153             : #! FIELDS time d1_center d1_set d1_target d1_coupling d1_maxrange d1_maxgrad d1_accum d1_mean d1_std
     154             : #! SET adaptive  1
     155             : #! SET update_period  1
     156             : #! SET seed  0
     157             : #! SET kbt    2.4943
     158             :    0.0000   1.0000   0.0000   0.0000   0.0000   7.4830   0.1497   0.0000   0.0000   0.0000
     159             :    1.0000   1.0000   0.0000   0.0000   0.0000   7.4830   0.1497   0.0000   0.0000   0.0000
     160             :    2.0000   1.0000  -7.4830   0.0000   0.0000   7.4830   0.1497   0.0224   0.0000   0.0000
     161             :    3.0000   1.0000  -7.4830   0.0000  -7.4830   7.4830   0.1497   0.0224   0.0000   0.0000
     162             :    4.0000   1.0000  -7.4830   0.0000  -7.4830   7.4830   0.1497   0.0224   0.0000   0.0000
     163             : \endauxfile
     164             : 
     165             : <hr>
     166             : 
     167             : Read in a previous restart file. Adding RESTART flag makes output append
     168             : \plumedfile
     169             : d1: DISTANCE ATOMS=1,2
     170             : 
     171             : eds: EDS ARG=d1 CENTER=2.0 PERIOD=100 TEMP=1.0 IN_RESTART=restart.eds RESTART=YES
     172             : \endplumedfile
     173             : 
     174             : <hr>
     175             : 
     176             : Read in a previous restart file and freeze the bias at the final level from the previous simulation
     177             : \plumedfile
     178             : d1: DISTANCE ATOMS=1,2
     179             : 
     180             : eds: EDS ARG=d1 CENTER=2.0 TEMP=1.0 IN_RESTART=restart.eds FREEZE
     181             : \endplumedfile
     182             : 
     183             : <hr>
     184             : 
     185             : Read in a previous restart file and freeze the bias at the mean from the previous simulation
     186             : \plumedfile
     187             : d1: DISTANCE ATOMS=1,2
     188             : 
     189             : eds: EDS ARG=d1 CENTER=2.0 TEMP=1.0 IN_RESTART=restart.eds FREEZE MEAN
     190             : \endplumedfile
     191             : 
     192             : 
     193             : */
     194             : //+ENDPLUMEDOC
     195             : 
     196             : class EDS : public Bias
     197             : {
     198             : 
     199             : private:
     200             :   /*We will get this and store it once, since on-the-fly changing number of CVs will be fatal*/
     201             :   const unsigned int ncvs_;
     202             :   std::vector<double> center_;
     203             :   std::vector<Value *> center_values_;
     204             :   ReweightBase *logweights_; // weights to use if reweighting averages
     205             :   std::vector<double> scale_;
     206             :   std::vector<double> current_coupling_;   // actually current coupling
     207             :   std::vector<double> set_coupling_;       // what our coupling is ramping up to. Equal to current_coupling when gathering stats
     208             :   std::vector<double> target_coupling_;    // used when loaded to reach a value
     209             :   std::vector<double> max_coupling_range_; // used for adaptive range
     210             :   std::vector<double> max_coupling_grad_;  // maximum allowed gradient
     211             :   std::vector<double> coupling_rate_;
     212             :   std::vector<double> coupling_accum_;
     213             :   std::vector<double> means_;
     214             :   std::vector<double> differences_;
     215             :   std::vector<double> alpha_vector_;
     216             :   std::vector<double> alpha_vector_2_;
     217             :   std::vector<double> ssds_;
     218             :   std::vector<double> step_size_;
     219             :   std::vector<double> pseudo_virial_;
     220             :   std::vector<Value *> out_coupling_;
     221             :   Matrix<double> covar_;
     222             :   Matrix<double> covar2_;
     223             :   Matrix<double> lm_inv_;
     224             :   std::string in_restart_name_;
     225             :   std::string out_restart_name_;
     226             :   std::string fmt_;
     227             :   OFile out_restart_;
     228             :   IFile in_restart_;
     229             :   bool b_c_values_;
     230             :   bool b_adaptive_;
     231             :   bool b_freeze_;
     232             :   bool b_equil_;
     233             :   bool b_ramp_;
     234             :   bool b_covar_;
     235             :   bool b_restart_;
     236             :   bool b_write_restart_;
     237             :   bool b_lm_;
     238             :   bool b_virial_;
     239             :   bool b_update_virial_;
     240             :   bool b_weights_;
     241             :   int seed_;
     242             :   int update_period_;
     243             :   int avg_coupling_count_;
     244             :   int update_calls_;
     245             :   double kbt_;
     246             :   double multi_prop_;
     247             :   double lm_mixing_par_;
     248             :   double virial_scaling_;
     249             :   double pseudo_virial_sum_; // net virial for all cvs in current period
     250             :   double max_logweight_;     // maximum observed max logweight for period
     251             :   double wsum_;              // sum of weights thus far
     252             :   Random rand_;
     253             :   Value *value_force2_;
     254             :   Value *value_pressure_;
     255             : 
     256             :   /*read input restart. b_mean sets if we use mean or final value for freeze*/
     257             :   void readInRestart(const bool b_mean);
     258             :   /*setup output restart*/
     259             :   void setupOutRestart();
     260             :   /*write output restart*/
     261             :   void writeOutRestart();
     262             :   void update_statistics();
     263             :   void update_pseudo_virial();
     264             :   void calc_lm_step_size();
     265             :   void calc_covar_step_size();
     266             :   void calc_ssd_step_size();
     267             :   void reset_statistics();
     268             :   void update_bias();
     269             :   void apply_bias();
     270             : 
     271             : public:
     272             :   explicit EDS(const ActionOptions &);
     273             :   void calculate();
     274             :   void update();
     275             :   void turnOnDerivatives();
     276             :   static void registerKeywords(Keywords &keys);
     277             :   ~EDS();
     278             : };
     279             : 
     280       10435 : PLUMED_REGISTER_ACTION(EDS, "EDS")
     281             : 
     282           9 : void EDS::registerKeywords(Keywords &keys)
     283             : {
     284           9 :   Bias::registerKeywords(keys);
     285           9 :   keys.use("ARG");
     286          18 :   keys.add("optional", "CENTER", "The desired centers (equilibrium values) which will be sought during the adaptive linear biasing. This is for fixed centers");
     287          18 :   keys.add("optional", "CENTER_ARG", "The desired centers (equilibrium values) which will be sought during the adaptive linear biasing. "
     288             :            "CENTER_ARG is for calculated centers, e.g. from a CV or analysis. ");
     289             : 
     290          18 :   keys.add("optional", "PERIOD", "Steps over which to adjust bias for adaptive or ramping");
     291          18 :   keys.add("compulsory", "RANGE", "25.0", "The (starting) maximum increase in coupling constant per PERIOD (in \\f$k_B T\\f$/[BIAS_SCALE unit]) for each CV based");
     292          18 :   keys.add("compulsory", "SEED", "0", "Seed for random order of changing bias");
     293          18 :   keys.add("compulsory", "INIT", "0", "Starting value for coupling constant");
     294          18 :   keys.add("compulsory", "FIXED", "0", "Fixed target values for coupling constant. Non-adaptive.");
     295          18 :   keys.add("optional", "BIAS_SCALE", "A divisor to set the units of the bias. "
     296             :            "If not set, this will be the CENTER value by default (as is done in White and Voth 2014).");
     297          18 :   keys.add("optional", "TEMP", "The system temperature. If not provided will be taken from MD code (if available)");
     298          18 :   keys.add("optional", "MULTI_PROP", "What proportion of dimensions to update at each step. "
     299             :            "Must be in interval [1,0), where 1 indicates all and any other indicates a stochastic update. "
     300             :            "If not set, default is 1 / N, where N is the number of CVs. ");
     301          18 :   keys.add("optional", "VIRIAL", "Add an update penalty for having non-zero virial contributions. Only makes sense with multiple correlated CVs.");
     302          18 :   keys.add("optional", "LOGWEIGHTS", "Add weights to use for computing statistics. For example, if biasing with metadynamics.");
     303          18 :   keys.addFlag("LM", false, "Use Levenberg-Marquadt algorithm along with simultaneous keyword. Otherwise use gradient descent.");
     304          18 :   keys.add("compulsory", "LM_MIXING", "1", "Initial mixing parameter when using Levenberg-Marquadt minimization.");
     305          18 :   keys.add("optional", "RESTART_FMT", "the format that should be used to output real numbers in EDS restarts");
     306          18 :   keys.add("optional", "OUT_RESTART", "Output file for all information needed to continue EDS simulation. "
     307             :            "If you have the RESTART directive set (global or for EDS), this file will be appended to. "
     308             :            "Note that the header will be printed again if appending.");
     309          18 :   keys.add("optional", "IN_RESTART", "Read this file to continue an EDS simulation. "
     310             :            "If same as OUT_RESTART and you have not set the RESTART directive, the file will be backed-up and overwritten with new output. "
     311             :            "If you do have the RESTART flag set and it is the same name as OUT_RESTART, this file will be appended.");
     312             : 
     313          18 :   keys.addFlag("RAMP", false, "Slowly increase bias constant to a fixed value");
     314          18 :   keys.addFlag("COVAR", false, "Utilize the covariance matrix when updating the bias. Default Off, but may be enabled due to other options");
     315          18 :   keys.addFlag("FREEZE", false, "Fix bias at current level (only used for restarting).");
     316          18 :   keys.addFlag("MEAN", false, "Instead of using final bias level from restart, use average. Can only be used in conjunction with FREEZE");
     317             : 
     318           9 :   keys.use("RESTART");
     319             : 
     320          18 :   keys.addOutputComponent("force2", "default", "squared value of force from the bias");
     321          18 :   keys.addOutputComponent("pressure", "default", "If using virial keyword, this is the current sum of virial terms. It is in units of pressure (energy / vol^3)");
     322          18 :   keys.addOutputComponent("_coupling", "default", "For each named CV biased, there will be a corresponding output CV_coupling storing the current linear bias prefactor.");
     323           9 : }
     324             : 
     325           8 : EDS::EDS(const ActionOptions &ao) : PLUMED_BIAS_INIT(ao),
     326           8 :   ncvs_(getNumberOfArguments()),
     327           8 :   scale_(ncvs_, 0.0),
     328           8 :   current_coupling_(ncvs_, 0.0),
     329           8 :   set_coupling_(ncvs_, 0.0),
     330           8 :   target_coupling_(ncvs_, 0.0),
     331           8 :   max_coupling_range_(ncvs_, 25.0),
     332           8 :   max_coupling_grad_(ncvs_, 0.0),
     333           8 :   coupling_rate_(ncvs_, 1.0),
     334           8 :   coupling_accum_(ncvs_, 0.0),
     335           8 :   means_(ncvs_, 0.0),
     336           8 :   step_size_(ncvs_, 0.0),
     337           8 :   pseudo_virial_(ncvs_),
     338           8 :   out_coupling_(ncvs_, NULL),
     339           8 :   in_restart_name_(""),
     340           8 :   out_restart_name_(""),
     341           8 :   fmt_("%f"),
     342           8 :   b_adaptive_(true),
     343           8 :   b_freeze_(false),
     344           8 :   b_equil_(true),
     345           8 :   b_ramp_(false),
     346           8 :   b_covar_(false),
     347           8 :   b_restart_(false),
     348           8 :   b_write_restart_(false),
     349           8 :   b_lm_(false),
     350           8 :   b_virial_(false),
     351           8 :   b_weights_(false),
     352           8 :   seed_(0),
     353           8 :   update_period_(0),
     354           8 :   avg_coupling_count_(1),
     355           8 :   update_calls_(0),
     356           8 :   kbt_(0.0),
     357           8 :   multi_prop_(-1.0),
     358           8 :   lm_mixing_par_(0.1),
     359           8 :   virial_scaling_(0.),
     360           8 :   pseudo_virial_sum_(0.0),
     361           8 :   max_logweight_(0.0),
     362           8 :   wsum_(0.0),
     363          32 :   value_force2_(NULL)
     364             : {
     365           8 :   double temp = -1.0;
     366           8 :   bool b_mean = false;
     367             :   std::vector<Value *> wvalues;
     368             : 
     369           8 :   addComponent("force2");
     370           8 :   componentIsNotPeriodic("force2");
     371           8 :   value_force2_ = getPntrToComponent("force2");
     372             : 
     373          20 :   for (unsigned int i = 0; i < ncvs_; ++i)
     374             :   {
     375          12 :     std::string comp = getPntrToArgument(i)->getName() + "_coupling";
     376          12 :     addComponent(comp);
     377          12 :     componentIsNotPeriodic(comp);
     378          12 :     out_coupling_[i] = getPntrToComponent(comp);
     379             :   }
     380             : 
     381           8 :   parseVector("CENTER", center_);
     382           8 :   parseArgumentList("CENTER_ARG", center_values_);
     383           8 :   parseArgumentList("LOGWEIGHTS", wvalues);
     384           8 :   parseVector("BIAS_SCALE", scale_);
     385           8 :   parseVector("RANGE", max_coupling_range_);
     386           8 :   parseVector("FIXED", target_coupling_);
     387           8 :   parseVector("INIT", set_coupling_);
     388           8 :   parse("PERIOD", update_period_);
     389           8 :   parse("TEMP", temp);
     390           8 :   parse("SEED", seed_);
     391           8 :   parse("MULTI_PROP", multi_prop_);
     392           8 :   parse("LM_MIXING", lm_mixing_par_);
     393           8 :   parse("RESTART_FMT", fmt_);
     394           8 :   parse("VIRIAL", virial_scaling_);
     395           8 :   fmt_ = " " + fmt_; // add space since parse strips them
     396           8 :   parse("OUT_RESTART", out_restart_name_);
     397           8 :   parseFlag("LM", b_lm_);
     398           8 :   parseFlag("RAMP", b_ramp_);
     399           8 :   parseFlag("FREEZE", b_freeze_);
     400           8 :   parseFlag("MEAN", b_mean);
     401           8 :   parseFlag("COVAR", b_covar_);
     402           8 :   parse("IN_RESTART", in_restart_name_);
     403           8 :   checkRead();
     404             : 
     405             :   /*
     406             :    * Things that are different when using changing centers:
     407             :    * 1. Scale
     408             :    * 2. The log file
     409             :    * 3. Reading Restarts
     410             :    */
     411             : 
     412           8 :   if (center_.size() == 0)
     413             :   {
     414           1 :     if (center_values_.size() == 0)
     415           0 :       error("Must set either CENTER or CENTER_ARG");
     416           1 :     else if (center_values_.size() != ncvs_)
     417           0 :       error("CENTER_ARG must contain the same number of variables as ARG");
     418           1 :     b_c_values_ = true;
     419           1 :     center_.resize(ncvs_);
     420           1 :     log.printf("  EDS will use possibly varying centers\n");
     421             :   }
     422             :   else
     423             :   {
     424           7 :     if (center_.size() != ncvs_)
     425           0 :       error("Must have same number of CENTER arguments as ARG arguments");
     426           7 :     else if (center_values_.size() != 0)
     427           0 :       error("You can only set CENTER or CENTER_ARG. Not both");
     428           7 :     b_c_values_ = false;
     429           7 :     log.printf("  EDS will use fixed centers\n");
     430             :   }
     431             : 
     432             :   // check for weights
     433           8 :   if (wvalues.size() > 1)
     434             :   {
     435           0 :     error("LOGWEIGHTS can only support one weight set. Please only pass one action");
     436             :   }
     437           8 :   else if (wvalues.size() == 1)
     438             :   {
     439           1 :     logweights_ = dynamic_cast<ReweightBase *>(wvalues[0]->getPntrToAction());
     440           1 :     b_weights_ = true;
     441             :   }
     442             : 
     443           8 :   log.printf("  setting scaling:");
     444           8 :   if (scale_.size() > 0 && scale_.size() < ncvs_)
     445             :   {
     446           0 :     error("the number of BIAS_SCALE values be the same as number of CVs");
     447             :   }
     448           8 :   else if (scale_.size() == 0 && b_c_values_)
     449             :   {
     450           0 :     log.printf(" Setting SCALE to be 1 for all CVs\n");
     451           0 :     scale_.resize(ncvs_);
     452           0 :     for (unsigned int i = 0; i < ncvs_; ++i)
     453           0 :       scale_[i] = 1;
     454             :   }
     455           8 :   else if (scale_.size() == 0 && !b_c_values_)
     456             :   {
     457           2 :     log.printf(" (default) ");
     458             : 
     459           2 :     scale_.resize(ncvs_);
     460           6 :     for (unsigned int i = 0; i < scale_.size(); ++i)
     461             :     {
     462           4 :       if (center_[i] == 0)
     463           0 :         error("BIAS_SCALE parameter has been set to CENTER value of 0 (as is default). This will divide by 0, so giving up. See doc for EDS bias");
     464           4 :       scale_[i] = center_[i];
     465             :     }
     466             :   }
     467             :   else
     468             :   {
     469          14 :     for (unsigned int i = 0; i < scale_.size(); ++i)
     470           8 :       log.printf(" %f", scale_[i]);
     471             :   }
     472           8 :   log.printf("\n");
     473             : 
     474           8 :   if (b_lm_)
     475             :   {
     476           1 :     log.printf("  EDS will perform Levenberg-Marquardt minimization with mixing parameter = %f\n", lm_mixing_par_);
     477           1 :     differences_.resize(ncvs_);
     478           1 :     alpha_vector_.resize(ncvs_);
     479           1 :     alpha_vector_2_.resize(ncvs_);
     480           1 :     covar_.resize(ncvs_, ncvs_);
     481           1 :     covar2_.resize(ncvs_, ncvs_);
     482           1 :     lm_inv_.resize(ncvs_, ncvs_);
     483           1 :     covar2_ *= 0;
     484           1 :     lm_inv_ *= 0;
     485           1 :     if (multi_prop_ != 1)
     486           0 :       log.printf("     WARNING - doing LM minimization but MULTI_PROP!=1\n");
     487             :   }
     488           7 :   else if (b_covar_)
     489             :   {
     490           1 :     log.printf("  EDS will utilize covariance matrix for update steps\n");
     491           1 :     covar_.resize(ncvs_, ncvs_);
     492             :   }
     493             :   else
     494             :   {
     495           6 :     log.printf("  EDS will utilize variance for update steps\n");
     496           6 :     ssds_.resize(ncvs_);
     497             :   }
     498             : 
     499           8 :   b_virial_ = virial_scaling_;
     500             : 
     501           8 :   if (b_virial_)
     502             :   {
     503           1 :     if (ncvs_ == 1)
     504           0 :       error("Minimizing the virial is only valid with multiply correlated collective variables.");
     505             :     // check that the CVs can be used to compute pseudo-virial
     506           1 :     log.printf("  EDS will compute virials of CVs and penalize with scale of %f. Checking CVs are valid...", virial_scaling_);
     507           4 :     for (unsigned int i = 0; i < ncvs_; ++i)
     508             :     {
     509           3 :       auto a = dynamic_cast<ActionAtomistic *>(getPntrToArgument(i)->getPntrToAction());
     510           3 :       if (!a)
     511           0 :         error("If using VIRIAL keyword, you must have normal CVs as arguments to EDS. Offending action: " + getPntrToArgument(i)->getPntrToAction()->getName());
     512             :       // cppcheck-suppress nullPointerRedundantCheck
     513           3 :       if (!(a->getPbc().isOrthorombic()))
     514           3 :         log.printf("  WARNING: EDS Virial should have a orthorombic cell\n");
     515             :     }
     516           1 :     log.printf("done.\n");
     517           1 :     addComponent("pressure");
     518           1 :     componentIsNotPeriodic("pressure");
     519           1 :     value_pressure_ = getPntrToComponent("pressure");
     520             :   }
     521             : 
     522           8 :   if (b_mean && !b_freeze_)
     523             :   {
     524           0 :     error("EDS keyword MEAN can only be used along with keyword FREEZE");
     525             :   }
     526             : 
     527           8 :   if (in_restart_name_ != "")
     528             :   {
     529           2 :     b_restart_ = true;
     530           2 :     log.printf("  reading simulation information from file: %s\n", in_restart_name_.c_str());
     531           2 :     readInRestart(b_mean);
     532             :   }
     533             :   else
     534             :   {
     535             : 
     536           6 :     if (temp >= 0.0)
     537           6 :       kbt_ = plumed.getAtoms().getKBoltzmann() * temp;
     538             :     else
     539           0 :       kbt_ = plumed.getAtoms().getKbT();
     540             : 
     541             :     // in driver, this results in kbt of 0
     542           6 :     if (kbt_ == 0)
     543             :     {
     544           0 :       error("  Unable to determine valid kBT. "
     545             :             "Could be because you are runnning from driver or MD didn't give temperature.\n"
     546             :             "Consider setting temperature manually with the TEMP keyword.");
     547             :       kbt_ = 1;
     548             :     }
     549             : 
     550           6 :     log.printf("  kBT = %f\n", kbt_);
     551           6 :     log.printf("  Updating every %i steps\n", update_period_);
     552             : 
     553           6 :     if (!b_c_values_)
     554             :     {
     555           5 :       log.printf("  with centers:");
     556          14 :       for (unsigned int i = 0; i < ncvs_; ++i)
     557             :       {
     558           9 :         log.printf(" %f ", center_[i]);
     559             :       }
     560             :     }
     561             :     else
     562             :     {
     563           1 :       log.printf("  with actions centers:");
     564           2 :       for (unsigned int i = 0; i < ncvs_; ++i)
     565             :       {
     566           1 :         log.printf(" %s ", center_values_[i]->getName().c_str());
     567             :         // add dependency on these actions
     568           1 :         addDependency(center_values_[i]->getPntrToAction());
     569             :       }
     570             :     }
     571             : 
     572           6 :     log.printf("\n  with initial ranges / rates:\n");
     573          16 :     for (unsigned int i = 0; i < max_coupling_range_.size(); ++i)
     574             :     {
     575             :       // this is just an empirical guess. Bigger range, bigger grads. Less frequent updates, bigger changes
     576             :       //
     577             :       // using the current maxing out scheme, max_coupling_range is the biggest step that can be taken in any given interval
     578          10 :       max_coupling_range_[i] *= kbt_;
     579          10 :       max_coupling_grad_[i] = max_coupling_range_[i];
     580          10 :       log.printf("    %f / %f\n", max_coupling_range_[i], max_coupling_grad_[i]);
     581             :     }
     582             : 
     583           6 :     if (seed_ > 0)
     584             :     {
     585           2 :       log.printf("  setting random seed = %i", seed_);
     586           2 :       rand_.setSeed(seed_);
     587             :     }
     588             : 
     589          16 :     for (unsigned int i = 0; i < ncvs_; ++i)
     590          10 :       if (target_coupling_[i] != 0.0)
     591           1 :         b_adaptive_ = false;
     592             : 
     593           6 :     if (!b_adaptive_)
     594             :     {
     595           1 :       if (b_ramp_)
     596             :       {
     597           1 :         log.printf("  ramping up coupling constants over %i steps\n", update_period_);
     598             :       }
     599             : 
     600           1 :       log.printf("  with starting coupling constants");
     601           2 :       for (unsigned int i = 0; i < set_coupling_.size(); ++i)
     602           1 :         log.printf(" %f", set_coupling_[i]);
     603           1 :       log.printf("\n");
     604           1 :       log.printf("  and final coupling constants");
     605           2 :       for (unsigned int i = 0; i < target_coupling_.size(); ++i)
     606           1 :         log.printf(" %f", target_coupling_[i]);
     607           1 :       log.printf("\n");
     608             :     }
     609             : 
     610             :     // now do setup
     611           6 :     if (b_ramp_)
     612             :     {
     613           1 :       update_period_ *= -1;
     614             :     }
     615             : 
     616          16 :     for (unsigned int i = 0; i < set_coupling_.size(); ++i)
     617          10 :       current_coupling_[i] = set_coupling_[i];
     618             : 
     619             :     // if b_adaptive_, then first half will be used for equilibrating and second half for statistics
     620           6 :     if (update_period_ > 0)
     621             :     {
     622           5 :       update_period_ /= 2;
     623             :     }
     624             :   }
     625             : 
     626           8 :   if (b_freeze_)
     627             :   {
     628           1 :     b_adaptive_ = false;
     629           1 :     update_period_ = 0;
     630           1 :     if (b_mean)
     631             :     {
     632           1 :       log.printf("  freezing bias at the average level from the restart file\n");
     633             :     }
     634             :     else
     635             :     {
     636           0 :       log.printf("  freezing bias at current level\n");
     637             :     }
     638             :   }
     639             : 
     640           8 :   if (multi_prop_ == -1.0)
     641             :   {
     642           5 :     log.printf("  Will update each dimension stochastically with probability 1 / number of CVs\n");
     643           5 :     multi_prop_ = 1.0 / ncvs_;
     644             :   }
     645           3 :   else if (multi_prop_ > 0 && multi_prop_ <= 1.0)
     646             :   {
     647           3 :     log.printf("  Will update each dimension stochastically with probability %f\n", multi_prop_);
     648             :   }
     649             :   else
     650             :   {
     651           0 :     error("  MULTI_PROP must be between 0 and 1\n");
     652             :   }
     653             : 
     654           8 :   if (out_restart_name_.length() > 0)
     655             :   {
     656           8 :     log.printf("  writing restart information every %i steps to file %s with format %s\n", abs(update_period_), out_restart_name_.c_str(), fmt_.c_str());
     657           8 :     b_write_restart_ = true;
     658           8 :     setupOutRestart();
     659             :   }
     660             : 
     661          16 :   log << "  Bibliography " << plumed.cite("White and Voth, J. Chem. Theory Comput. 10 (8), 3023-3030 (2014)") << "\n";
     662          24 :   log << "  Bibliography " << plumed.cite("G. M. Hocky, T. Dannenhoffer-Lafage, G. A. Voth, J. Chem. Theory Comput. 13 (9), 4593-4603 (2017)") << "\n";
     663           8 : }
     664             : 
     665           2 : void EDS::readInRestart(const bool b_mean)
     666             : {
     667           2 :   int adaptive_i = 0;
     668             : 
     669           2 :   in_restart_.open(in_restart_name_);
     670             : 
     671           4 :   if (in_restart_.FieldExist("kbt"))
     672             :   {
     673           2 :     in_restart_.scanField("kbt", kbt_);
     674             :   }
     675             :   else
     676             :   {
     677           0 :     error("No field 'kbt' in restart file");
     678             :   }
     679           2 :   log.printf("  with kBT = %f\n", kbt_);
     680             : 
     681           4 :   if (in_restart_.FieldExist("update_period"))
     682             :   {
     683           2 :     in_restart_.scanField("update_period", update_period_);
     684             :   }
     685             :   else
     686             :   {
     687           0 :     error("No field 'update_period' in restart file");
     688             :   }
     689           2 :   log.printf("  Updating every %i steps\n", update_period_);
     690             : 
     691           4 :   if (in_restart_.FieldExist("adaptive"))
     692             :   {
     693             :     // note, no version of scanField for boolean
     694           2 :     in_restart_.scanField("adaptive", adaptive_i);
     695             :   }
     696             :   else
     697             :   {
     698           0 :     error("No field 'adaptive' in restart file");
     699             :   }
     700           2 :   b_adaptive_ = bool(adaptive_i);
     701             : 
     702           4 :   if (in_restart_.FieldExist("seed"))
     703             :   {
     704           2 :     in_restart_.scanField("seed", seed_);
     705             :   }
     706             :   else
     707             :   {
     708           0 :     error("No field 'seed' in restart file");
     709             :   }
     710           2 :   if (seed_ > 0)
     711             :   {
     712           0 :     log.printf("  setting random seed = %i", seed_);
     713           0 :     rand_.setSeed(seed_);
     714             :   }
     715             : 
     716             :   double time, tmp;
     717           2 :   std::vector<double> avg_bias = std::vector<double>(center_.size());
     718             :   unsigned int N = 0;
     719             :   std::string cv_name;
     720             : 
     721          24 :   while (in_restart_.scanField("time", time))
     722             :   {
     723             : 
     724          20 :     for (unsigned int i = 0; i < ncvs_; ++i)
     725             :     {
     726             :       cv_name = getPntrToArgument(i)->getName();
     727          20 :       in_restart_.scanField(cv_name + "_center", set_coupling_[i]);
     728          20 :       in_restart_.scanField(cv_name + "_set", set_coupling_[i]);
     729          20 :       in_restart_.scanField(cv_name + "_target", target_coupling_[i]);
     730          20 :       in_restart_.scanField(cv_name + "_coupling", current_coupling_[i]);
     731          20 :       in_restart_.scanField(cv_name + "_maxrange", max_coupling_range_[i]);
     732          20 :       in_restart_.scanField(cv_name + "_maxgrad", max_coupling_grad_[i]);
     733          20 :       in_restart_.scanField(cv_name + "_accum", coupling_accum_[i]);
     734          10 :       in_restart_.scanField(cv_name + "_mean", means_[i]);
     735          20 :       if (in_restart_.FieldExist(cv_name + "_pseudovirial"))
     736             :       {
     737           0 :         if (b_virial_)
     738           0 :           in_restart_.scanField(cv_name + "_pseudovirial", pseudo_virial_[i]);
     739             :         else // discard the field
     740           0 :           in_restart_.scanField(cv_name + "_pseudovirial", tmp);
     741             :       }
     742             :       // unused due to difference between covar/nocovar
     743          20 :       in_restart_.scanField(cv_name + "_std", tmp);
     744             : 
     745          10 :       avg_bias[i] += current_coupling_[i];
     746             :     }
     747          10 :     N++;
     748             : 
     749          10 :     in_restart_.scanField();
     750             :   }
     751             : 
     752           2 :   log.printf("  with centers:");
     753           4 :   for (unsigned int i = 0; i < center_.size(); ++i)
     754             :   {
     755           2 :     log.printf(" %f", center_[i]);
     756             :   }
     757           2 :   log.printf("\n  and scaling:");
     758           4 :   for (unsigned int i = 0; i < scale_.size(); ++i)
     759             :   {
     760           2 :     log.printf(" %f", scale_[i]);
     761             :   }
     762             : 
     763           2 :   log.printf("\n  with initial ranges / rates:\n");
     764           4 :   for (unsigned int i = 0; i < max_coupling_range_.size(); ++i)
     765             :   {
     766           2 :     log.printf("    %f / %f\n", max_coupling_range_[i], max_coupling_grad_[i]);
     767             :   }
     768             : 
     769           2 :   if (!b_adaptive_ && update_period_ < 0)
     770             :   {
     771           0 :     log.printf("  ramping up coupling constants over %i steps\n", -update_period_);
     772             :   }
     773             : 
     774           2 :   if (b_mean)
     775             :   {
     776           1 :     log.printf("Loaded in averages for coupling constants...\n");
     777           2 :     for (unsigned int i = 0; i < current_coupling_.size(); ++i)
     778           1 :       current_coupling_[i] = avg_bias[i] / N;
     779           2 :     for (unsigned int i = 0; i < current_coupling_.size(); ++i)
     780           1 :       set_coupling_[i] = avg_bias[i] / N;
     781             :   }
     782             : 
     783           2 :   log.printf("  with current coupling constants:\n    ");
     784           4 :   for (unsigned int i = 0; i < current_coupling_.size(); ++i)
     785           2 :     log.printf(" %f", current_coupling_[i]);
     786           2 :   log.printf("\n");
     787           2 :   log.printf("  with initial coupling constants:\n    ");
     788           4 :   for (unsigned int i = 0; i < set_coupling_.size(); ++i)
     789           2 :     log.printf(" %f", set_coupling_[i]);
     790           2 :   log.printf("\n");
     791           2 :   log.printf("  and final coupling constants:\n    ");
     792           4 :   for (unsigned int i = 0; i < target_coupling_.size(); ++i)
     793           2 :     log.printf(" %f", target_coupling_[i]);
     794           2 :   log.printf("\n");
     795             : 
     796           2 :   in_restart_.close();
     797           2 : }
     798             : 
     799           8 : void EDS::setupOutRestart()
     800             : {
     801           8 :   out_restart_.link(*this);
     802           8 :   out_restart_.fmtField(fmt_);
     803           8 :   out_restart_.open(out_restart_name_);
     804             :   out_restart_.setHeavyFlush();
     805             : 
     806          16 :   out_restart_.addConstantField("adaptive").printField("adaptive", b_adaptive_);
     807          16 :   out_restart_.addConstantField("update_period").printField("update_period", update_period_);
     808          16 :   out_restart_.addConstantField("seed").printField("seed", seed_);
     809          16 :   out_restart_.addConstantField("kbt").printField("kbt", kbt_);
     810           8 : }
     811             : 
     812          27 : void EDS::writeOutRestart()
     813             : {
     814             :   std::string cv_name;
     815          27 :   out_restart_.printField("time", getTimeStep() * getStep());
     816             : 
     817          66 :   for (unsigned int i = 0; i < ncvs_; ++i)
     818             :   {
     819             :     cv_name = getPntrToArgument(i)->getName();
     820          78 :     out_restart_.printField(cv_name + "_center", center_[i]);
     821          78 :     out_restart_.printField(cv_name + "_set", set_coupling_[i]);
     822          78 :     out_restart_.printField(cv_name + "_target", target_coupling_[i]);
     823          78 :     out_restart_.printField(cv_name + "_coupling", current_coupling_[i]);
     824          78 :     out_restart_.printField(cv_name + "_maxrange", max_coupling_range_[i]);
     825          78 :     out_restart_.printField(cv_name + "_maxgrad", max_coupling_grad_[i]);
     826          78 :     out_restart_.printField(cv_name + "_accum", coupling_accum_[i]);
     827          39 :     out_restart_.printField(cv_name + "_mean", means_[i]);
     828          39 :     if (b_virial_)
     829          18 :       out_restart_.printField(cv_name + "_pseudovirial", pseudo_virial_[i]);
     830          39 :     if (!b_covar_ && !b_lm_)
     831          42 :       out_restart_.printField(cv_name + "_std", ssds_[i] / (fmax(1, update_calls_ - 1)));
     832             :     else
     833          36 :       out_restart_.printField(cv_name + "_std", covar_(i, i) / (fmax(1, update_calls_ - 1)));
     834             :   }
     835          27 :   out_restart_.printField();
     836          27 : }
     837             : 
     838          40 : void EDS::calculate()
     839             : {
     840             : 
     841             :   // get center values from action if necessary
     842          40 :   if (b_c_values_)
     843          10 :     for (unsigned int i = 0; i < ncvs_; ++i)
     844           5 :       center_[i] = center_values_[i]->get();
     845             : 
     846          40 :   apply_bias();
     847          40 : }
     848             : 
     849          40 : void EDS::apply_bias()
     850             : {
     851             :   // Compute linear force as in "restraint"
     852             :   double ene = 0, totf2 = 0, cv, m, f;
     853             : 
     854         100 :   for (unsigned int i = 0; i < ncvs_; ++i)
     855             :   {
     856          60 :     cv = difference(i, center_[i], getArgument(i));
     857          60 :     m = current_coupling_[i];
     858          60 :     f = -m;
     859          60 :     ene += m * cv;
     860             :     setOutputForce(i, f);
     861          60 :     totf2 += f * f;
     862             :   }
     863             : 
     864             :   setBias(ene);
     865          40 :   value_force2_->set(totf2);
     866          40 : }
     867             : 
     868          12 : void EDS::update_statistics()
     869             : {
     870             :   double s, N, w = 1.0;
     871          12 :   std::vector<double> deltas(ncvs_);
     872             : 
     873             :   // update weight max, if necessary
     874          12 :   if (b_weights_)
     875             :   {
     876           2 :     w = logweights_->getLogWeight();
     877           2 :     if (max_logweight_ < w)
     878             :     {
     879             :       // we have new max. Need to shift existing values
     880           0 :       wsum_ *= exp(max_logweight_ - w);
     881           0 :       max_logweight_ = w;
     882             :     }
     883             :     // convert to weight
     884           2 :     w = exp(w - max_logweight_);
     885           2 :     wsum_ += w;
     886             :     N = wsum_;
     887             :   }
     888             :   else
     889             :   {
     890          10 :     N = fmax(1, update_calls_);
     891             :   }
     892             : 
     893             :   // Welford, West, and Hanso online variance method
     894             :   // with weights (default =  1.0)
     895          32 :   for (unsigned int i = 0; i < ncvs_; ++i)
     896             :   {
     897          20 :     deltas[i] = difference(i, means_[i], getArgument(i)) * w;
     898          20 :     means_[i] += deltas[i] / N;
     899          20 :     if (!b_covar_ && !b_lm_)
     900           8 :       ssds_[i] += deltas[i] * difference(i, means_[i], getArgument(i));
     901             :   }
     902          12 :   if (b_covar_ || b_lm_)
     903             :   {
     904          16 :     for (unsigned int i = 0; i < ncvs_; ++i)
     905             :     {
     906          36 :       for (unsigned int j = i; j < ncvs_; ++j)
     907             :       {
     908          24 :         s = (N - 1) * deltas[i] * deltas[j] / N / N - covar_(i, j) / N;
     909          24 :         covar_(i, j) += s;
     910             :         // do this so we don't double count
     911          24 :         covar_(j, i) = covar_(i, j);
     912             :       }
     913             :     }
     914             :   }
     915          12 :   if (b_virial_)
     916           2 :     update_pseudo_virial();
     917          12 : }
     918             : 
     919           8 : void EDS::reset_statistics()
     920             : {
     921          20 :   for (unsigned int i = 0; i < ncvs_; ++i)
     922             :   {
     923          12 :     means_[i] = 0;
     924          12 :     if (!b_covar_ && !b_lm_)
     925           6 :       ssds_[i] = 0;
     926             :   }
     927           8 :   if (b_covar_ || b_lm_)
     928           8 :     for (unsigned int i = 0; i < ncvs_; ++i)
     929          24 :       for (unsigned int j = 0; j < ncvs_; ++j)
     930          18 :         covar_(i, j) = 0;
     931           8 :   if (b_virial_)
     932             :   {
     933           4 :     for (unsigned int i = 0; i < ncvs_; ++i)
     934           3 :       pseudo_virial_[i] = 0;
     935           1 :     pseudo_virial_sum_ = 0;
     936             :   }
     937           8 :   if (b_weights_)
     938             :   {
     939           2 :     wsum_ = 0;
     940           2 :     max_logweight_ = 0;
     941             :   }
     942           8 : }
     943             : 
     944           1 : void EDS::calc_lm_step_size()
     945             : {
     946             :   // calulcate step size
     947             :   // uses scale here, which by default is center
     948             : 
     949           1 :   mult(covar_, covar_, covar2_);
     950           4 :   for (unsigned int i = 0; i < ncvs_; ++i)
     951             :   {
     952           3 :     differences_[i] = difference(i, center_[i], means_[i]);
     953           3 :     covar2_[i][i] += lm_mixing_par_ * covar2_[i][i];
     954             :   }
     955             : 
     956             :   // "step_size_vec" = 2*inv(covar*covar+ lambda diag(covar*covar))*covar*(mean-center)
     957           1 :   mult(covar_, differences_, alpha_vector_);
     958           1 :   Invert(covar2_, lm_inv_);
     959           1 :   mult(lm_inv_, alpha_vector_, alpha_vector_2_);
     960             : 
     961           4 :   for (unsigned int i = 0; i < ncvs_; ++i)
     962             :   {
     963           3 :     step_size_[i] = 2 * alpha_vector_2_[i] / kbt_ / scale_[i];
     964             :   }
     965           1 : }
     966             : 
     967           1 : void EDS::calc_covar_step_size()
     968             : {
     969             :   // calulcate step size
     970             :   // uses scale here, which by default is center
     971             :   double tmp;
     972           4 :   for (unsigned int i = 0; i < ncvs_; ++i)
     973             :   {
     974             :     tmp = 0;
     975          12 :     for (unsigned int j = 0; j < ncvs_; ++j)
     976           9 :       tmp += difference(i, center_[i], means_[i]) * covar_(i, j);
     977           3 :     step_size_[i] = 2 * tmp / kbt_ / scale_[i] * update_calls_ / fmax(1, update_calls_ - 1);
     978             :   }
     979           1 : }
     980             : 
     981           6 : void EDS::calc_ssd_step_size()
     982             : {
     983             :   double tmp;
     984          12 :   for (unsigned int i = 0; i < ncvs_; ++i)
     985             :   {
     986           6 :     tmp = 2. * difference(i, center_[i], means_[i]) * ssds_[i] / fmax(1, update_calls_ - 1);
     987           6 :     step_size_[i] = tmp / kbt_ / scale_[i];
     988             :   }
     989           6 : }
     990             : 
     991           2 : void EDS::update_pseudo_virial()
     992             : {
     993             :   // We want to compute the bias force on each atom times the position
     994             :   //  of the atoms.
     995             :   double p, netp = 0, netpv = 0;
     996             :   double volume = 0;
     997           8 :   for (unsigned int i = 0; i < ncvs_; ++i)
     998             :   {
     999             :     // checked in setup to ensure this cast is valid.
    1000           6 :     ActionAtomistic *cv = dynamic_cast<ActionAtomistic *>(getPntrToArgument(i)->getPntrToAction());
    1001             :     Tensor &v(cv->modifyVirial());
    1002           6 :     Tensor box(cv->getBox());
    1003             :     const unsigned int natoms = cv->getNumberOfAtoms();
    1004           6 :     if (!volume)
    1005           2 :       volume = box.determinant();
    1006             : 
    1007             :     // pressure contribution is -dBias / dV
    1008             :     // dBias / dV = alpha / w * dCV / dV
    1009             :     // to get partial of CV wrt to volume
    1010             :     // dCV/dV = sum dCV/dvij * vij / V
    1011             :     // where vij is box element
    1012             :     // add diagonal of virial tensor to get net pressure
    1013             :     // TODO: replace this with adjugate (Jacobi's Formula)   for non-orthorombic case(?)
    1014           6 :     p = v(0, 0) * box(0, 0) + v(1, 1) * box(1, 1) + v(2, 2) * box(2, 2);
    1015           6 :     p /= volume;
    1016             : 
    1017           6 :     netp += p;
    1018             : 
    1019             :     // now scale for correct units in EDS algorithm
    1020           6 :     p *= (volume) / (kbt_ * natoms);
    1021             : 
    1022             :     // compute running mean of scaled
    1023           6 :     if (set_coupling_[i] != 0)
    1024           0 :       pseudo_virial_[i] = (p - pseudo_virial_[i]) / (fmax(1, update_calls_));
    1025             :     else
    1026           6 :       pseudo_virial_[i] = 0;
    1027             :     // update net pressure
    1028           6 :     netpv += pseudo_virial_[i];
    1029             :   }
    1030             :   // update pressure
    1031           2 :   value_pressure_->set(netp);
    1032           2 :   pseudo_virial_sum_ = netpv;
    1033           2 : }
    1034             : 
    1035           8 : void EDS::update_bias()
    1036             : {
    1037           8 :   log.flush();
    1038           8 :   if (b_lm_)
    1039           1 :     calc_lm_step_size();
    1040           7 :   else if (b_covar_)
    1041           1 :     calc_covar_step_size();
    1042             :   else
    1043           6 :     calc_ssd_step_size();
    1044             : 
    1045          20 :   for (unsigned int i = 0; i < ncvs_; ++i)
    1046             :   {
    1047             : 
    1048             :     // multidimesional stochastic step
    1049          12 :     if (ncvs_ == 1 || (rand_.RandU01() < (multi_prop_)))
    1050             :     {
    1051             : 
    1052          12 :       if (b_virial_)
    1053             :       {
    1054             :         // apply virial regularization
    1055             :         //  P * dP/dcoupling
    1056             :         //  coupling is already included in virial term due to plumed propogating from bias to forces
    1057             :         //  thus we need to divide by it to get the derivative (since force is linear in coupling)
    1058           3 :         if (fabs(set_coupling_[i]) > 0.000000001) // my heuristic for if EDS has started to prevent / 0
    1059             :           // scale^2 here is to align units
    1060           0 :           step_size_[i] -= 2 * scale_[i] * scale_[i] * virial_scaling_ * pseudo_virial_sum_ * pseudo_virial_sum_ / set_coupling_[i];
    1061             :       }
    1062          12 :       if (step_size_[i] == 0)
    1063           4 :         continue;
    1064             : 
    1065             :       // clip gradient
    1066           8 :       step_size_[i] = copysign(fmin(fabs(step_size_[i]), max_coupling_grad_[i]), step_size_[i]);
    1067           8 :       coupling_accum_[i] += step_size_[i] * step_size_[i];
    1068             : 
    1069             :       // equation 5 in White and Voth, JCTC 2014
    1070             :       // no negative sign because it's in step_size
    1071           8 :       set_coupling_[i] += step_size_[i] * max_coupling_range_[i] / sqrt(coupling_accum_[i]);
    1072           8 :       coupling_rate_[i] = (set_coupling_[i] - current_coupling_[i]) / update_period_;
    1073             :     }
    1074             :     else
    1075             :     {
    1076             :       // do not change the bias
    1077           0 :       coupling_rate_[i] = 0;
    1078             :     }
    1079             :   }
    1080             : 
    1081             :   // reset means/vars
    1082           8 :   reset_statistics();
    1083           8 : }
    1084             : 
    1085          40 : void EDS::update()
    1086             : {
    1087             :   // adjust parameters according to EDS recipe
    1088          40 :   update_calls_++;
    1089             : 
    1090             :   // if we aren't wating for the bias to equilibrate, set flag to collect data
    1091             :   // want statistics before writing restart
    1092          40 :   if (!b_equil_ && update_period_ > 0)
    1093          12 :     update_statistics();
    1094             : 
    1095             :   // write restart with correct statistics before bias update
    1096             :   // check if we're ramping or doing normal updates and then restart if needed. The ramping check
    1097             :   // is complicated because we could be frozen, finished ramping or not ramping.
    1098             :   // The + 2 is so we have an extra line showing that the bias isn't changing (for my sanity and yours)
    1099          40 :   if (b_write_restart_)
    1100             :   {
    1101          40 :     if (getStep() == 0 ||
    1102          32 :         ((update_period_ < 0 && !b_freeze_ && update_calls_ <= fabs(update_period_) + 2) ||
    1103          24 :          (update_period_ > 0 && update_calls_ % update_period_ == 0)))
    1104          27 :       writeOutRestart();
    1105             :   }
    1106             : 
    1107             :   int b_finished_equil_flag = 1;
    1108             : 
    1109             :   // assume forces already applied and saved
    1110             :   // are we ramping to a constant value and not done equilibrating?
    1111          40 :   if (update_period_ < 0)
    1112             :   {
    1113           5 :     if (update_calls_ <= fabs(update_period_) && !b_freeze_)
    1114             :     {
    1115           4 :       for (unsigned int i = 0; i < ncvs_; ++i)
    1116           2 :         current_coupling_[i] += (target_coupling_[i] - set_coupling_[i]) / fabs(update_period_);
    1117             :     }
    1118             :     // make sure we don't reset update calls
    1119             :     b_finished_equil_flag = 0;
    1120             :   }
    1121          35 :   else if (update_period_ == 0)
    1122             :   { // do we have a no-update case?
    1123             :     // not updating
    1124             :     // pass
    1125             :   }
    1126          30 :   else if (b_equil_)
    1127             :   {
    1128             :     // equilibrating
    1129             :     // check if we've reached the setpoint
    1130          48 :     for (unsigned int i = 0; i < ncvs_; ++i)
    1131             :     {
    1132          30 :       if (coupling_rate_[i] == 0 || pow(current_coupling_[i] - set_coupling_[i], 2) < pow(coupling_rate_[i], 2))
    1133             :       {
    1134          14 :         b_finished_equil_flag &= 1;
    1135             :       }
    1136             :       else
    1137             :       {
    1138          16 :         current_coupling_[i] += coupling_rate_[i];
    1139             :         b_finished_equil_flag = 0;
    1140             :       }
    1141             :     }
    1142             :   }
    1143             : 
    1144             :   // reduce all the flags
    1145          40 :   if (b_equil_ && b_finished_equil_flag)
    1146             :   {
    1147          11 :     b_equil_ = false;
    1148          11 :     update_calls_ = 0;
    1149             :   }
    1150             : 
    1151             :   // Now we update coupling constant, if necessary
    1152          40 :   if (!b_equil_ && update_period_ > 0 && update_calls_ == update_period_ && !b_freeze_)
    1153             :   {
    1154           8 :     update_bias();
    1155           8 :     update_calls_ = 0;
    1156           8 :     avg_coupling_count_++;
    1157           8 :     b_equil_ = true; // back to equilibration now
    1158             :   }                  // close update if
    1159             : 
    1160             :   // pass couplings out so they are accessible
    1161         100 :   for (unsigned int i = 0; i < ncvs_; ++i)
    1162             :   {
    1163          60 :     out_coupling_[i]->set(current_coupling_[i]);
    1164             :   }
    1165          40 : }
    1166             : 
    1167          16 : EDS::~EDS()
    1168             : {
    1169           8 :   out_restart_.close();
    1170          24 : }
    1171             : 
    1172           0 : void EDS::turnOnDerivatives()
    1173             : {
    1174             :   // do nothing
    1175             :   // this is to avoid errors triggered when a bias is used as a CV
    1176             :   // (This is done in ExtendedLagrangian.cpp)
    1177           0 : }
    1178             : 
    1179             : }
    1180             : } // close the 2 namespaces

Generated by: LCOV version 1.15