LCOV - code coverage report
Current view: top level - isdb - Rescale.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 183 217 84.3 %
Date: 2026-11-05 10:19:04 Functions: 10 13 76.9 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2017-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             : /*
      23             : 
      24             : */
      25             : #include "bias/Bias.h"
      26             : #include "core/ActionRegister.h"
      27             : #include "core/PlumedMain.h"
      28             : #include "core/Value.h"
      29             : #include "tools/File.h"
      30             : #include "tools/Random.h"
      31             : #include "tools/Communicator.h"
      32             : #include <ctime>
      33             : 
      34             : namespace PLMD {
      35             : namespace isdb {
      36             : 
      37             : //+PLUMEDOC ISDB_BIAS RESCALE
      38             : /*
      39             : Scales the value of an another action, being a Collective Variable or a Bias.
      40             : 
      41             : The rescaling factor is determined by a parameter defined on a logarithmic grid of dimension NBIN in the range
      42             : from 1 to MAX_RESCALE. The current value of the rescaling parameter is stored and shared across
      43             : other actions using a [SELECTOR](SELECTOR.md). A Monte Carlo procedure is used to update the value
      44             : of the rescaling factor every MC_STRIDE steps of molecular dynamics. Well-tempered metadynamics, defined by the
      45             : parameters W0 and BIASFACTOR, is used to enhance the sampling in the space of the rescaling factor.
      46             : The well-tempered metadynamics bias potential is written to the file BFILE every BSTRIDE steps and read
      47             : when restarting the simulation using the directive [RESTART](RESTART.md).
      48             : 
      49             : !!! note "scaling arguments"
      50             : 
      51             :     Additional arguments not to be scaled, one for each bin in the rescaling parameter ladder, can be
      52             :     provided at the end of the ARG list. The number of such arguments is specified by the option NOT_RESCALED.
      53             :     These arguments will be not be scaled, but they will be
      54             :     considered as bias potentials and used in the computation of the Metropolis
      55             :     acceptance probability when proposing a move in the rescaling parameter. See example below.
      56             : 
      57             : !!! note "multiple replicas"
      58             : 
      59             :     If PLUMED is running in a multiple-replica framework (for example using the -multi option in GROMACS),
      60             :     the arguments will be summed across replicas, unless the NOT_SHARED option is used. Also, the value of the
      61             :     [SELECTOR](SELECTOR.md) will be shared and thus will be the same in all replicas.
      62             : 
      63             : ## Examples
      64             : 
      65             : In this example we use [RESCALE](RESCALE.md) to implement a simulated-tempering like approach.
      66             : The total potential energy of the system is scaled by a parameter defined on a logarithmic grid
      67             : of 5 bins in the range from 1 to 1.5.
      68             : A well-tempered metadynamics bias potential is used to ensure diffusion in the space of the rescaling
      69             : parameter.
      70             : 
      71             : ```plumed
      72             : ene: ENERGY
      73             : 
      74             : SELECTOR NAME=GAMMA VALUE=0
      75             : 
      76             : RESCALE ...
      77             : LABEL=res ARG=ene TEMP=300
      78             : SELECTOR=GAMMA MAX_RESCALE=1.5 NBIN=5
      79             : W0=1000 BIASFACTOR=100.0 BSTRIDE=2000 BFILE=bias.dat
      80             : ...
      81             : 
      82             : PRINT FILE=COLVAR ARG=* STRIDE=100
      83             : ```
      84             : 
      85             : In this second example, we add to the simulated-tempering approach introduced above
      86             : one Parallel Bias metadynamics simulation (see [PBMETAD](PBMETAD.md)) for each value of the rescaling parameter.
      87             : At each moment of the simulation, only one of the [PBMETAD](PBMETAD.md)
      88             : actions is activated, based on the current value of the associated [SELECTOR](SELECTOR.md).
      89             : The [PBMETAD](PBMETAD.md) bias potentials are not scaled, but just used in the calculation of
      90             : the Metropolis acceptance probability when proposing a move in the rescaling parameter.
      91             : 
      92             : ```plumed
      93             : ene: ENERGY
      94             : d: DISTANCE ATOMS=1,2
      95             : 
      96             : SELECTOR NAME=GAMMA VALUE=0
      97             : 
      98             : pbmetad0: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=0 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.0
      99             : pbmetad1: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=1 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.1
     100             : pbmetad2: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=2 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.2
     101             : pbmetad3: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=3 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.3
     102             : pbmetad4: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=4 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.4
     103             : 
     104             : RESCALE ...
     105             : LABEL=res TEMP=300
     106             : ARG=ene,pbmetad0.bias,pbmetad1.bias,pbmetad2.bias,pbmetad3.bias,pbmetad4.bias
     107             : SELECTOR=GAMMA MAX_RESCALE=1.5 NOT_RESCALED=5 NBIN=5
     108             : W0=1000 BIASFACTOR=100.0 BSTRIDE=2000 BFILE=bias.dat
     109             : ...
     110             : 
     111             : PRINT FILE=COLVAR ARG=* STRIDE=100
     112             : ```
     113             : 
     114             : 
     115             : */
     116             : //+ENDPLUMEDOC
     117             : 
     118             : class Rescale : public bias::Bias {
     119             :   // gamma parameter
     120             :   std::vector<double> gamma_;
     121             :   double         w0_;
     122             :   double         biasf_;
     123             :   std::vector<double> bias_;
     124             :   std::vector<double> expo_;
     125             :   std::vector<unsigned> shared_;
     126             :   unsigned nores_;
     127             :   // bias
     128             :   unsigned int   Biasstride_;
     129             :   unsigned int   Biaspace_;
     130             :   std::string         Biasfilename_;
     131             :   bool           first_bias_;
     132             :   OFile          Biasfile_;
     133             :   // temperature in kbt
     134             :   double kbt_;
     135             :   // Monte Carlo stuff
     136             :   unsigned MCsteps_;
     137             :   unsigned MCstride_;
     138             :   long long int MCfirst_;
     139             :   long long unsigned MCaccgamma_;
     140             :   Random random_;
     141             :   // replica stuff
     142             :   unsigned nrep_;
     143             :   unsigned replica_;
     144             :   // selector
     145             :   std::string selector_;
     146             : 
     147             :   // Monte Carlo
     148             :   void doMonteCarlo(unsigned igamma, double oldE, const std::vector<double> & args, const std::vector<double> & bargs);
     149             :   unsigned proposeMove(unsigned x, unsigned xmin, unsigned xmax);
     150             :   // current value of the SELECTOR, checked against the number of bins
     151             :   unsigned getSelector();
     152             :   bool doAccept(double oldE, double newE);
     153             :   // read and print bias
     154             :   void read_bias();
     155             :   void print_bias(long long int step);
     156             : 
     157             : public:
     158             :   explicit Rescale(const ActionOptions&);
     159             :   ~Rescale();
     160             :   void calculate();
     161             :   static void registerKeywords(Keywords& keys);
     162             : };
     163             : 
     164             : 
     165             : PLUMED_REGISTER_ACTION(Rescale,"RESCALE")
     166             : 
     167           6 : void Rescale::registerKeywords(Keywords& keys) {
     168           6 :   Bias::registerKeywords(keys);
     169           6 :   keys.add("compulsory","TEMP","temperature");
     170           6 :   keys.add("compulsory","SELECTOR", "name of the SELECTOR used for rescaling");
     171           6 :   keys.add("compulsory","MAX_RESCALE","maximum values for rescaling");
     172           6 :   keys.add("compulsory","NBIN","number of bins for gamma grid");
     173           6 :   keys.add("compulsory","W0", "initial bias height");
     174           6 :   keys.add("compulsory","BIASFACTOR", "bias factor");
     175           6 :   keys.add("compulsory","BSTRIDE", "stride for writing bias");
     176           6 :   keys.add("compulsory","BFILE", "file name for bias");
     177           6 :   keys.add("optional","NOT_SHARED",   "list of arguments (from 1 to N) not summed across replicas");
     178           6 :   keys.add("optional","NOT_RESCALED", "these last N arguments will not be scaled");
     179           6 :   keys.add("optional","MC_STEPS","number of MC steps");
     180           6 :   keys.add("optional","MC_STRIDE","MC stride");
     181           6 :   keys.add("optional","PACE", "Pace for adding bias, in MC stride unit");
     182           6 :   keys.add("optional","SEED","seed of the random number generator used by the Monte Carlo sampling (by default it is taken from the clock at every run)");
     183          12 :   keys.addOutputComponent("igamma",  "default","scalar","gamma parameter");
     184          12 :   keys.addOutputComponent("accgamma","default","scalar","MC acceptance for gamma");
     185          12 :   keys.addOutputComponent("wtbias",  "default","scalar","well-tempered bias");
     186           6 : }
     187             : 
     188           2 : Rescale::Rescale(const ActionOptions&ao):
     189             :   PLUMED_BIAS_INIT(ao),
     190           2 :   nores_(0), Biaspace_(1), first_bias_(true),
     191           2 :   MCsteps_(1), MCstride_(1), MCfirst_(-1), MCaccgamma_(0) {
     192             :   // set up replica stuff
     193           2 :   nrep_    = getNumberOfReplicas();
     194           2 :   replica_ = getReplicaIndex();
     195             : 
     196             :   // wt-parameters
     197           2 :   parse("W0", w0_);
     198           2 :   parse("BIASFACTOR", biasf_);
     199             : 
     200             :   // selector name
     201           2 :   parse("SELECTOR", selector_);
     202             : 
     203             :   // number of bins for gamma ladder
     204             :   unsigned nbin;
     205           2 :   parse("NBIN", nbin);
     206             : 
     207             :   // number of bias
     208           2 :   parse("NOT_RESCALED", nores_);
     209           2 :   if(nores_>0 && nores_!=nbin) {
     210           0 :     error("The number of non scaled arguments must be equal to either 0 or the number of bins");
     211             :   }
     212             : 
     213             :   // maximum value of rescale
     214           2 :   std::vector<double> max_rescale;
     215           4 :   parseVector("MAX_RESCALE", max_rescale);
     216             :   // check dimension of max_rescale
     217           2 :   if(max_rescale.size()!=(getNumberOfArguments()-nores_)) {
     218           0 :     error("Size of MAX_RESCALE array must be equal to the number of arguments that will to be scaled");
     219             :   }
     220             : 
     221             :   // calculate exponents
     222           2 :   double igamma_max = static_cast<double>(nbin);
     223           6 :   for(unsigned i=0; i<max_rescale.size(); ++i) {
     224           4 :     expo_.push_back(std::log(max_rescale[i])/std::log(igamma_max));
     225             :   }
     226             : 
     227             :   // allocate gamma grid and set bias to zero
     228          10 :   for(unsigned i=0; i<nbin; ++i) {
     229             :     // bias grid
     230           8 :     bias_.push_back(0.0);
     231             :     // gamma ladder
     232           8 :     double gamma = std::exp( static_cast<double>(i) / static_cast<double>(nbin-1) * std::log(igamma_max) );
     233           8 :     gamma_.push_back(gamma);
     234             :   }
     235             :   // print bias to file
     236           2 :   parse("BSTRIDE", Biasstride_);
     237           2 :   parse("BFILE",   Biasfilename_);
     238             : 
     239             :   // create vectors of shared arguments
     240             :   // by default they are all shared
     241           6 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
     242           4 :     shared_.push_back(1);
     243             :   }
     244             :   // share across replicas or not
     245           2 :   std::vector<unsigned> not_shared;
     246           2 :   parseVector("NOT_SHARED", not_shared);
     247             :   // and change the non-shared
     248           2 :   for(unsigned i=0; i<not_shared.size(); ++i) {
     249           0 :     if((not_shared[i]-1)>=(getNumberOfArguments()-nores_) && nrep_>1) {
     250           0 :       error("NOT_RESCALED args must always be shared when using multiple replicas");
     251             :     }
     252           0 :     if((not_shared[i]-1)>=getNumberOfArguments()) {
     253           0 :       error("NOT_SHARED args should be lower than total number of arguments");
     254             :     }
     255           0 :     shared_[not_shared[i]-1] = 0;
     256             :   }
     257             : 
     258             :   // monte carlo stuff
     259           2 :   parse("MC_STEPS",MCsteps_);
     260           2 :   parse("MC_STRIDE",MCstride_);
     261             :   // adjust for multiple-time steps
     262           2 :   MCstride_ *= getStride();
     263             :   // read bias deposition pace
     264           2 :   parse("PACE", Biaspace_);
     265           2 :   int seed=-1;
     266           2 :   parse("SEED",seed);
     267           2 :   if(seed<-1) {
     268           0 :     error("SEED must be a non-negative integer");
     269             :   }
     270             :   // multiply by MCstride
     271           2 :   Biaspace_ *= MCstride_;
     272             : 
     273             :   // get temperature
     274           2 :   kbt_=getkBT();
     275             : 
     276           2 :   checkRead();
     277             : 
     278           2 :   log.printf("  temperature of the system in energy unit %f\n",kbt_);
     279           2 :   log.printf("  name of the SELECTOR use for this action %s\n",selector_.c_str());
     280           2 :   log.printf("  number of bins in grid %u\n",nbin);
     281           2 :   log.printf("  number of arguments that will not be scaled %u\n",nores_);
     282           2 :   if(nrep_>1) {
     283           2 :     log<<"  number of arguments that will not be summed across replicas "<<not_shared.size()<<"\n";
     284             :   }
     285           2 :   log.printf("  biasfactor %f\n",biasf_);
     286           2 :   log.printf("  initial hills height %f\n",w0_);
     287           2 :   log.printf("  stride to write bias to file %u\n",Biasstride_);
     288           2 :   log.printf("  write bias to file : %s\n",Biasfilename_.c_str());
     289           2 :   log.printf("  number of replicas %u\n",nrep_);
     290           2 :   log.printf("  number of MC steps %d\n",MCsteps_);
     291           2 :   log.printf("  do MC every %d steps\n", MCstride_);
     292           2 :   log.printf("\n");
     293             : 
     294           2 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
     295             : 
     296             : 
     297             :   // add components
     298           4 :   addComponent("igamma");
     299           4 :   componentIsNotPeriodic("igamma");
     300           4 :   addComponent("accgamma");
     301           4 :   componentIsNotPeriodic("accgamma");
     302           4 :   addComponent("wtbias");
     303           2 :   componentIsNotPeriodic("wtbias");
     304             : 
     305             :   // initialize random seed
     306             :   // each replica gets its own stream, between 1 and 2^31-1
     307             :   unsigned iseed;
     308           2 :   if(seed>=0) {
     309           2 :     iseed = static_cast<unsigned>(1 + (static_cast<unsigned long long>(seed)*nrep_+replica_) % 2147483646ULL);
     310             :   } else {
     311           0 :     iseed = static_cast<unsigned>(time(NULL))+replica_;
     312             :   }
     313           2 :   random_.setSeed(-static_cast<int>(iseed));
     314             : 
     315             :   // read bias if restarting
     316           2 :   if(getRestart()) {
     317           0 :     read_bias();
     318             :   }
     319           4 : }
     320             : 
     321           4 : Rescale::~Rescale() {
     322           2 :   Biasfile_.close();
     323           8 : }
     324             : 
     325           0 : void Rescale::read_bias() {
     326             : // open file
     327             :   auto ifile=Tools::make_unique<IFile>();
     328           0 :   ifile->link(*this);
     329           0 :   if(ifile->FileExist(Biasfilename_)) {
     330           0 :     ifile->open(Biasfilename_);
     331             :     // read all the lines, store last value of bias
     332             :     double MDtime;
     333           0 :     while(ifile->scanField("MD_time",MDtime)) {
     334           0 :       for(unsigned i=0; i<bias_.size(); ++i) {
     335             :         // convert i to string
     336           0 :         std::stringstream ss;
     337             :         ss << i;
     338             :         // label
     339           0 :         std::string label = "b" + ss.str();
     340             :         // read entry
     341           0 :         ifile->scanField(label, bias_[i]);
     342           0 :       }
     343             :       // new line
     344           0 :       ifile->scanField();
     345             :     }
     346           0 :     ifile->close();
     347             :   } else {
     348           0 :     error("Cannot find bias file "+Biasfilename_+"\n");
     349             :   }
     350           0 : }
     351             : 
     352          24 : unsigned Rescale::getSelector() {
     353          24 :   const auto it = plumed.passMap.find(selector_);
     354          24 :   if(it==plumed.passMap.end()) {
     355           0 :     error("SELECTOR "+selector_+" is not defined");
     356             :   }
     357          24 :   if(!(it->second>=0.0) || it->second>=static_cast<double>(gamma_.size())) {
     358           0 :     error("the value of SELECTOR "+selector_+" must be between 0 and NBIN-1");
     359             :   }
     360          24 :   return static_cast<unsigned>(it->second);
     361             : }
     362             : 
     363          60 : unsigned Rescale::proposeMove(unsigned x, unsigned xmin, unsigned xmax) {
     364          60 :   int xmin_i = static_cast<int>(xmin);
     365          60 :   int xmax_i = static_cast<int>(xmax);
     366             :   int dx;
     367          60 :   if( random_.RandU01() < 0.5 ) {
     368             :     dx = +1;
     369             :   } else {
     370             :     dx = -1;
     371             :   }
     372             : // new index, integer
     373          60 :   int x_new = static_cast<int>(x) + dx;
     374             : // check boundaries
     375          60 :   if(x_new >= xmax_i) {
     376          22 :     x_new = xmax_i-1;
     377             :   }
     378          60 :   if(x_new <  xmin_i) {
     379             :     x_new = xmin_i;
     380             :   }
     381          60 :   return static_cast<unsigned>(x_new);
     382             : }
     383             : 
     384          60 : bool Rescale::doAccept(double oldE, double newE) {
     385             :   bool accept = false;
     386             :   // calculate delta energy
     387          60 :   double delta = ( newE - oldE ) / kbt_;
     388             :   // if delta is negative always accept move
     389          60 :   if( delta < 0.0 ) {
     390             :     accept = true;
     391             :   } else {
     392             :     // otherwise extract random number
     393          53 :     double s = random_.RandU01();
     394          53 :     if( s < std::exp(-delta) ) {
     395             :       accept = true;
     396             :     }
     397             :   }
     398          60 :   return accept;
     399             : }
     400             : 
     401          12 : void Rescale::doMonteCarlo(unsigned igamma, double oldE,
     402             :                            const std::vector<double> & args, const std::vector<double> & bargs) {
     403             :   double oldB, newB;
     404             : 
     405             : // cycle on MC steps
     406          72 :   for(unsigned i=0; i<MCsteps_; ++i) {
     407             :     // propose move in igamma
     408          60 :     unsigned new_igamma = proposeMove(igamma, 0, gamma_.size());
     409             :     // calculate new energy
     410             :     double newE = 0.0;
     411         180 :     for(unsigned j=0; j<args.size(); ++j) {
     412             :       // calculate energy term
     413         120 :       double fact = 1.0/pow(gamma_[new_igamma], expo_[j]) - 1.0;
     414         120 :       newE += args[j] * fact;
     415             :     }
     416             :     // calculate contributions from non-rescaled terms
     417          60 :     if(bargs.size()>0) {
     418           0 :       oldB = bias_[igamma]+bargs[igamma];
     419           0 :       newB = bias_[new_igamma]+bargs[new_igamma];
     420             :     } else {
     421          60 :       oldB = bias_[igamma];
     422          60 :       newB = bias_[new_igamma];
     423             :     }
     424             :     // accept or reject
     425          60 :     bool accept = doAccept(oldE+oldB, newE+newB);
     426          60 :     if(accept) {
     427          29 :       igamma = new_igamma;
     428             :       oldE = newE;
     429          29 :       MCaccgamma_++;
     430             :     }
     431             :   }
     432             : // send values of gamma to all replicas
     433          12 :   if(comm.Get_rank()==0) {
     434          12 :     if(multi_sim_comm.Get_rank()!=0) {
     435           6 :       igamma = 0;
     436             :     }
     437          12 :     multi_sim_comm.Sum(&igamma, 1);
     438             :   } else {
     439           0 :     igamma = 0;
     440             :   }
     441             : // local communication
     442          12 :   comm.Sum(&igamma, 1);
     443             : 
     444             : // set the value of gamma into passMap
     445          12 :   plumed.passMap[selector_]=static_cast<double>(igamma);
     446          12 : }
     447             : 
     448          12 : void Rescale::print_bias(long long int step) {
     449             : // if first time open the file
     450          12 :   if(first_bias_) {
     451           2 :     first_bias_ = false;
     452           2 :     Biasfile_.link(*this);
     453           2 :     Biasfile_.open(Biasfilename_);
     454             :     Biasfile_.setHeavyFlush();
     455           4 :     Biasfile_.fmtField("%30.5f");
     456             :   }
     457             : 
     458             : // write fields
     459          12 :   double MDtime = static_cast<double>(step)*getTimeStep();
     460          12 :   Biasfile_.printField("MD_time", MDtime);
     461          60 :   for(unsigned i=0; i<bias_.size(); ++i) {
     462             :     // convert i to string
     463          48 :     std::stringstream ss;
     464             :     ss << i;
     465             :     // label
     466          96 :     std::string label = "b" + ss.str();
     467             :     // print entry
     468          48 :     Biasfile_.printField(label, bias_[i]);
     469          48 :   }
     470          12 :   Biasfile_.printField();
     471          12 : }
     472             : 
     473          12 : void Rescale::calculate() {
     474             :   // get the current value of the selector
     475          12 :   const unsigned igamma = getSelector();
     476             : 
     477             :   // collect data from other replicas
     478          12 :   std::vector<double> all_args(getNumberOfArguments(), 0.0);
     479             :   // first calculate arguments
     480          36 :   for(unsigned i=0; i<all_args.size(); ++i) {
     481          24 :     double arg = getArgument(i);
     482             :     // sum shared arguments across replicas
     483          24 :     if(shared_[i]==1) {
     484          24 :       if(comm.Get_rank()==0) {
     485          24 :         multi_sim_comm.Sum(arg);
     486             :       } else {
     487           0 :         arg = 0.0;
     488             :       }
     489          24 :       if(comm.Get_size()>1) {
     490           0 :         comm.Sum(arg);
     491             :       }
     492             :     }
     493             :     // put into all_args
     494          24 :     all_args[i] = arg;
     495             :   }
     496             : 
     497             :   // now separate terms that should be rescaled
     498          12 :   std::vector<double> args;
     499          12 :   if(getNumberOfArguments()>nores_) {
     500          12 :     args.resize(getNumberOfArguments()-nores_);
     501             :   }
     502          36 :   for(unsigned i=0; i<args.size(); ++i) {
     503          24 :     args[i]  = all_args[i];
     504             :   }
     505             :   // and terms that should not
     506          12 :   std::vector<double> bargs;
     507          12 :   if(nores_>0) {
     508           0 :     bargs.resize(nores_);
     509             :   }
     510          12 :   for(unsigned i=0; i<bargs.size(); ++i) {
     511           0 :     bargs[i] = all_args[i+args.size()];
     512             :   }
     513             : 
     514             :   // calculate energy and forces, only on rescaled terms
     515             :   double ene = 0.0;
     516          36 :   for(unsigned i=0; i<args.size(); ++i) {
     517             :     // calculate energy term
     518          24 :     double fact = 1.0/pow(gamma_[igamma], expo_[i]) - 1.0;
     519          24 :     ene += args[i] * fact;
     520             :     // add force
     521          24 :     setOutputForce(i, -fact);
     522             :   }
     523             : 
     524             :   // set to zero on the others
     525          12 :   for(unsigned i=0; i<bargs.size(); ++i) {
     526           0 :     setOutputForce(i+args.size(), 0.0);
     527             :   }
     528             : 
     529             :   // set value of the bias
     530          12 :   setBias(ene);
     531             :   // set value of the wt-bias
     532          12 :   getPntrToComponent("wtbias")->set(bias_[igamma]);
     533             :   // set values of gamma
     534          12 :   getPntrToComponent("igamma")->set(igamma);
     535             :   // get time step
     536          12 :   long long int step = getStep();
     537          12 :   if(MCfirst_==-1) {
     538           2 :     MCfirst_=step;
     539             :   }
     540             :   // calculate gamma acceptance
     541          12 :   double MCtrials = std::floor(static_cast<double>(step-MCfirst_) / static_cast<double>(MCstride_))+1.0;
     542          12 :   double accgamma = static_cast<double>(MCaccgamma_) / static_cast<double>(MCsteps_) / MCtrials;
     543          12 :   getPntrToComponent("accgamma")->set(accgamma);
     544             : 
     545             :   // do MC at the right time step
     546          12 :   if(step%MCstride_==0&&!getExchangeStep()) {
     547          12 :     doMonteCarlo(igamma, ene, args, bargs);
     548             :   }
     549             : 
     550             :   // add well-tempered like bias
     551          12 :   if(step%Biaspace_==0) {
     552             :     // get updated igamma
     553          12 :     const unsigned newigamma = getSelector();
     554             :     // add "Gaussian"
     555          12 :     double kbDT = kbt_ * ( biasf_ - 1.0 );
     556          12 :     bias_[newigamma] += w0_ * std::exp(-bias_[newigamma] / kbDT);
     557             :   }
     558             : 
     559             :   // print bias
     560          12 :   if(step%Biasstride_==0) {
     561          12 :     print_bias(step);
     562             :   }
     563             : 
     564          12 : }
     565             : 
     566             : 
     567             : }
     568             : }
     569             : 

Generated by: LCOV version 1.16