LCOV - code coverage report
Current view: top level - ves - LinearBasisSetExpansion.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 313 353 88.7 %
Date: 2024-10-18 14:00:25 Functions: 30 36 83.3 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2016-2021 The VES code team
       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
       4             : 
       5             :    See http://www.ves-code.org for more information.
       6             : 
       7             :    This file is part of VES code module.
       8             : 
       9             :    The VES code module 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             :    The VES code module 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 the VES code module.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : 
      23             : #include "LinearBasisSetExpansion.h"
      24             : #include "VesBias.h"
      25             : #include "CoeffsVector.h"
      26             : #include "VesTools.h"
      27             : #include "GridIntegrationWeights.h"
      28             : #include "BasisFunctions.h"
      29             : #include "TargetDistribution.h"
      30             : 
      31             : 
      32             : #include "tools/Keywords.h"
      33             : #include "tools/Grid.h"
      34             : #include "tools/Communicator.h"
      35             : 
      36             : #include "GridProjWeights.h"
      37             : 
      38             : #include <limits>
      39             : 
      40             : namespace PLMD {
      41             : namespace ves {
      42             : 
      43           0 : void LinearBasisSetExpansion::registerKeywords(Keywords& keys) {
      44           0 : }
      45             : 
      46             : 
      47         130 : LinearBasisSetExpansion::LinearBasisSetExpansion(
      48             :   const std::string& label,
      49             :   const double beta_in,
      50             :   Communicator& cc,
      51             :   const std::vector<Value*>& args_pntrs_in,
      52             :   std::vector<BasisFunctions*>& basisf_pntrs_in,
      53         130 :   CoeffsVector* bias_coeffs_pntr_in):
      54         130 :   label_(label),
      55         130 :   action_pntr_(NULL),
      56         130 :   vesbias_pntr_(NULL),
      57         130 :   mycomm_(cc),
      58         130 :   serial_(false),
      59         130 :   beta_(beta_in),
      60         130 :   kbt_(1.0/beta_),
      61         130 :   args_pntrs_(args_pntrs_in),
      62         130 :   nargs_(args_pntrs_.size()),
      63         130 :   basisf_pntrs_(basisf_pntrs_in),
      64         130 :   nbasisf_(basisf_pntrs_.size()),
      65         130 :   bias_coeffs_pntr_(bias_coeffs_pntr_in),
      66         130 :   ncoeffs_(0),
      67         130 :   grid_min_(nargs_),
      68         130 :   grid_max_(nargs_),
      69         130 :   grid_bins_(nargs_,100),
      70         130 :   targetdist_grid_label_("targetdist"),
      71         130 :   step_of_last_biasgrid_update(-1000),
      72         130 :   step_of_last_biaswithoutcutoffgrid_update(-1000),
      73         130 :   step_of_last_fesgrid_update(-1000),
      74         130 :   log_targetdist_grid_pntr_(NULL),
      75         130 :   targetdist_grid_pntr_(NULL),
      76         260 :   targetdist_pntr_(NULL)
      77             : {
      78         130 :   plumed_massert(args_pntrs_.size()==basisf_pntrs_.size(),"number of arguments and basis functions do not match");
      79         295 :   for(unsigned int k=0; k<nargs_; k++) {nbasisf_[k]=basisf_pntrs_[k]->getNumberOfBasisFunctions();}
      80             :   //
      81         130 :   if(bias_coeffs_pntr_==NULL) {
      82           0 :     bias_coeffs_pntr_ = new CoeffsVector(label_+".coeffs",args_pntrs_,basisf_pntrs_,mycomm_,true);
      83             :   }
      84         130 :   plumed_massert(bias_coeffs_pntr_->numberOfDimensions()==basisf_pntrs_.size(),"dimension of coeffs does not match with number of basis functions ");
      85             :   //
      86         130 :   ncoeffs_ = bias_coeffs_pntr_->numberOfCoeffs();
      87         130 :   targetdist_averages_pntr_ = Tools::make_unique<CoeffsVector>(*bias_coeffs_pntr_);
      88             : 
      89         130 :   std::string targetdist_averages_label = bias_coeffs_pntr_->getLabel();
      90         130 :   if(targetdist_averages_label.find("coeffs")!=std::string::npos) {
      91         260 :     targetdist_averages_label.replace(targetdist_averages_label.find("coeffs"), std::string("coeffs").length(), "targetdist_averages");
      92             :   }
      93             :   else {
      94             :     targetdist_averages_label += "_targetdist_averages";
      95             :   }
      96         130 :   targetdist_averages_pntr_->setLabels(targetdist_averages_label);
      97             :   //
      98         295 :   for(unsigned int k=0; k<nargs_; k++) {
      99         330 :     grid_min_[k] = basisf_pntrs_[k]->intervalMinStr();
     100         330 :     grid_max_[k] = basisf_pntrs_[k]->intervalMaxStr();
     101             :   }
     102         130 : }
     103             : 
     104         130 : LinearBasisSetExpansion::~LinearBasisSetExpansion() {
     105         390 : }
     106             : 
     107             : 
     108           0 : bool LinearBasisSetExpansion::isStaticTargetDistFileOutputActive() const {
     109             :   bool output_static_targetdist_files=true;
     110           0 :   if(vesbias_pntr_!=NULL) {
     111             :     output_static_targetdist_files = vesbias_pntr_->isStaticTargetDistFileOutputActive();
     112             :   }
     113           0 :   return output_static_targetdist_files;
     114             : }
     115             : 
     116             : 
     117          90 : void LinearBasisSetExpansion::linkVesBias(VesBias* vesbias_pntr_in) {
     118          90 :   vesbias_pntr_ = vesbias_pntr_in;
     119          90 :   action_pntr_ = static_cast<Action*>(vesbias_pntr_in);
     120             : 
     121          90 : }
     122             : 
     123             : 
     124           0 : void LinearBasisSetExpansion::linkAction(Action* action_pntr_in) {
     125           0 :   action_pntr_ = action_pntr_in;
     126           0 : }
     127             : 
     128             : 
     129         129 : void LinearBasisSetExpansion::setGridBins(const std::vector<unsigned int>& grid_bins_in) {
     130         129 :   plumed_massert(grid_bins_in.size()==nargs_,"the number of grid bins given doesn't match the number of arguments");
     131         129 :   plumed_massert(!bias_grid_pntr_,"setGridBins should be used before setting up the grids, otherwise it doesn't work");
     132         129 :   plumed_massert(!fes_grid_pntr_,"setGridBins should be used before setting up the grids, otherwise it doesn't work");
     133         129 :   grid_bins_=grid_bins_in;
     134         129 : }
     135             : 
     136             : 
     137          39 : void LinearBasisSetExpansion::setGridBins(const unsigned int nbins) {
     138          39 :   std::vector<unsigned int> grid_bins_in(nargs_,nbins);
     139          39 :   setGridBins(grid_bins_in);
     140          39 : }
     141             : 
     142             : 
     143         220 : std::unique_ptr<Grid> LinearBasisSetExpansion::setupGeneralGrid(const std::string& label_suffix, const bool usederiv) {
     144         220 :   bool use_spline = false;
     145         440 :   auto grid_pntr = Tools::make_unique<Grid>(label_+"."+label_suffix,args_pntrs_,grid_min_,grid_max_,grid_bins_,use_spline,usederiv);
     146         220 :   return grid_pntr;
     147             : }
     148             : 
     149             : 
     150         166 : void LinearBasisSetExpansion::setupBiasGrid(const bool usederiv) {
     151         166 :   if(bias_grid_pntr_) {return;}
     152         258 :   bias_grid_pntr_ = setupGeneralGrid("bias",usederiv);
     153         129 :   if(biasCutoffActive()) {
     154           6 :     bias_withoutcutoff_grid_pntr_ = setupGeneralGrid("bias_withoutcutoff",usederiv);
     155             :   }
     156             : }
     157             : 
     158             : 
     159         120 : void LinearBasisSetExpansion::setupFesGrid() {
     160         120 :   if(fes_grid_pntr_) {return;}
     161          88 :   if(!bias_grid_pntr_) {
     162          37 :     setupBiasGrid(true);
     163             :   }
     164         176 :   fes_grid_pntr_ = setupGeneralGrid("fes",false);
     165             : }
     166             : 
     167             : 
     168           8 : void LinearBasisSetExpansion::setupFesProjGrid() {
     169           8 :   if(!fes_grid_pntr_) {
     170           1 :     setupFesGrid();
     171             :   }
     172           8 : }
     173             : 
     174             : 
     175         829 : void LinearBasisSetExpansion::updateBiasGrid() {
     176         829 :   plumed_massert(bias_grid_pntr_,"the bias grid is not defined");
     177         829 :   if(action_pntr_!=NULL &&  getStepOfLastBiasGridUpdate()==action_pntr_->getStep()) {
     178             :     return;
     179             :   }
     180     1982290 :   for(Grid::index_t l=0; l<bias_grid_pntr_->getSize(); l++) {
     181     1981698 :     std::vector<double> forces(nargs_);
     182     1981698 :     std::vector<double> args = bias_grid_pntr_->getPoint(l);
     183     1981698 :     bool all_inside=true;
     184     1981698 :     double bias=getBiasAndForces(args,all_inside,forces);
     185             :     //
     186     1981698 :     if(biasCutoffActive()) {
     187         600 :       vesbias_pntr_->applyBiasCutoff(bias,forces);
     188             :     }
     189             :     //
     190     1981698 :     if(bias_grid_pntr_->hasDerivatives()) {
     191     1473981 :       bias_grid_pntr_->setValueAndDerivatives(l,bias,forces);
     192             :     }
     193             :     else {
     194      507717 :       bias_grid_pntr_->setValue(l,bias);
     195             :     }
     196             :     //
     197             :   }
     198         592 :   if(vesbias_pntr_!=NULL) {
     199         475 :     vesbias_pntr_->setCurrentBiasMaxValue(bias_grid_pntr_->getMaxValue());
     200             :   }
     201         592 :   if(action_pntr_!=NULL) {
     202         475 :     setStepOfLastBiasGridUpdate(action_pntr_->getStep());
     203             :   }
     204             : }
     205             : 
     206             : 
     207          27 : void LinearBasisSetExpansion::updateBiasWithoutCutoffGrid() {
     208          27 :   plumed_massert(bias_withoutcutoff_grid_pntr_,"the bias without cutoff grid is not defined");
     209          27 :   plumed_massert(biasCutoffActive(),"the bias cutoff has to be active");
     210          27 :   plumed_massert(vesbias_pntr_!=NULL,"has to be linked to a VesBias to work");
     211          27 :   if(action_pntr_!=NULL &&  getStepOfLastBiasWithoutCutoffGridUpdate()==action_pntr_->getStep()) {
     212             :     return;
     213             :   }
     214             :   //
     215        2423 :   for(Grid::index_t l=0; l<bias_withoutcutoff_grid_pntr_->getSize(); l++) {
     216        2400 :     std::vector<double> forces(nargs_);
     217        2400 :     std::vector<double> args = bias_withoutcutoff_grid_pntr_->getPoint(l);
     218        2400 :     bool all_inside=true;
     219        2400 :     double bias=getBiasAndForces(args,all_inside,forces);
     220        2400 :     if(bias_withoutcutoff_grid_pntr_->hasDerivatives()) {
     221        2400 :       bias_withoutcutoff_grid_pntr_->setValueAndDerivatives(l,bias,forces);
     222             :     }
     223             :     else {
     224           0 :       bias_withoutcutoff_grid_pntr_->setValue(l,bias);
     225             :     }
     226             :   }
     227             :   //
     228          23 :   double bias_max = bias_withoutcutoff_grid_pntr_->getMaxValue();
     229          23 :   double bias_min = bias_withoutcutoff_grid_pntr_->getMinValue();
     230             :   double shift = 0.0;
     231             :   bool bias_shifted=false;
     232          23 :   if(bias_min < 0.0) {
     233          22 :     shift += -bias_min;
     234             :     bias_shifted=true;
     235          22 :     BiasCoeffs()[0] -= bias_min;
     236          22 :     bias_max -= bias_min;
     237             :   }
     238          23 :   if(bias_max > vesbias_pntr_->getBiasCutoffValue()) {
     239          22 :     shift += -(bias_max-vesbias_pntr_->getBiasCutoffValue());
     240             :     bias_shifted=true;
     241          22 :     BiasCoeffs()[0] -= (bias_max-vesbias_pntr_->getBiasCutoffValue());
     242          22 :     bias_max -= (bias_max-vesbias_pntr_->getBiasCutoffValue());
     243             :   }
     244          23 :   if(bias_shifted) {
     245             :     // this should be done inside a grid function really,
     246             :     // need to define my grid class for that
     247        2322 :     for(Grid::index_t l=0; l<bias_withoutcutoff_grid_pntr_->getSize(); l++) {
     248        2300 :       if(bias_withoutcutoff_grid_pntr_->hasDerivatives()) {
     249        2300 :         std::vector<double> zeros(nargs_,0.0);
     250        2300 :         bias_withoutcutoff_grid_pntr_->addValueAndDerivatives(l,shift,zeros);
     251             :       }
     252             :       else {
     253           0 :         bias_withoutcutoff_grid_pntr_->addValue(l,shift);
     254             :       }
     255             :     }
     256             :   }
     257          23 :   if(vesbias_pntr_!=NULL) {
     258             :     vesbias_pntr_->setCurrentBiasMaxValue(bias_max);
     259             :   }
     260          23 :   if(action_pntr_!=NULL) {
     261          23 :     setStepOfLastBiasWithoutCutoffGridUpdate(action_pntr_->getStep());
     262             :   }
     263             : }
     264             : 
     265             : 
     266         539 : void LinearBasisSetExpansion::updateFesGrid() {
     267         539 :   plumed_massert(fes_grid_pntr_,"the FES grid is not defined");
     268         539 :   updateBiasGrid();
     269         539 :   if(action_pntr_!=NULL && getStepOfLastFesGridUpdate() == action_pntr_->getStep()) {
     270             :     return;
     271             :   }
     272             :   //
     273             :   double bias2fes_scalingf = -1.0;
     274     1474154 :   for(Grid::index_t l=0; l<fes_grid_pntr_->getSize(); l++) {
     275     1473681 :     double fes_value = bias2fes_scalingf*bias_grid_pntr_->getValue(l);
     276     1473681 :     if(log_targetdist_grid_pntr_!=NULL) {
     277     1224051 :       fes_value += kBT()*log_targetdist_grid_pntr_->getValue(l);
     278             :     }
     279     1473681 :     fes_grid_pntr_->setValue(l,fes_value);
     280             :   }
     281         473 :   fes_grid_pntr_->setMinToZero();
     282         473 :   if(action_pntr_!=NULL) {
     283         473 :     setStepOfLastFesGridUpdate(action_pntr_->getStep());
     284             :   }
     285             : }
     286             : 
     287             : 
     288         212 : void LinearBasisSetExpansion::writeBiasGridToFile(OFile& ofile, const bool append_file) const {
     289         212 :   plumed_massert(bias_grid_pntr_,"the bias grid is not defined");
     290         212 :   if(append_file) {ofile.enforceRestart();}
     291         212 :   bias_grid_pntr_->writeToFile(ofile);
     292         212 : }
     293             : 
     294             : 
     295           5 : void LinearBasisSetExpansion::writeBiasWithoutCutoffGridToFile(OFile& ofile, const bool append_file) const {
     296           5 :   plumed_massert(bias_withoutcutoff_grid_pntr_,"the bias without cutoff grid is not defined");
     297           5 :   if(append_file) {ofile.enforceRestart();}
     298           5 :   bias_withoutcutoff_grid_pntr_->writeToFile(ofile);
     299           5 : }
     300             : 
     301             : 
     302         169 : void LinearBasisSetExpansion::writeFesGridToFile(OFile& ofile, const bool append_file) const {
     303         169 :   plumed_massert(fes_grid_pntr_!=NULL,"the FES grid is not defined");
     304         169 :   if(append_file) {ofile.enforceRestart();}
     305         169 :   fes_grid_pntr_->writeToFile(ofile);
     306         169 : }
     307             : 
     308             : 
     309          36 : void LinearBasisSetExpansion::writeFesProjGridToFile(const std::vector<std::string>& proj_arg, OFile& ofile, const bool append_file) const {
     310          36 :   plumed_massert(fes_grid_pntr_,"the FES grid is not defined");
     311          36 :   auto Fw = Tools::make_unique<FesWeight>(beta_);
     312          36 :   Grid proj_grid = fes_grid_pntr_->project(proj_arg,Fw.get());
     313          36 :   proj_grid.setMinToZero();
     314          36 :   if(append_file) {ofile.enforceRestart();}
     315          36 :   proj_grid.writeToFile(ofile);
     316          36 : }
     317             : 
     318             : 
     319          82 : void LinearBasisSetExpansion::writeTargetDistGridToFile(OFile& ofile, const bool append_file) const {
     320          82 :   if(targetdist_grid_pntr_==NULL) {return;}
     321          82 :   if(append_file) {ofile.enforceRestart();}
     322          82 :   targetdist_grid_pntr_->writeToFile(ofile);
     323             : }
     324             : 
     325             : 
     326          82 : void LinearBasisSetExpansion::writeLogTargetDistGridToFile(OFile& ofile, const bool append_file) const {
     327          82 :   if(log_targetdist_grid_pntr_==NULL) {return;}
     328          82 :   if(append_file) {ofile.enforceRestart();}
     329          82 :   log_targetdist_grid_pntr_->writeToFile(ofile);
     330             : }
     331             : 
     332             : 
     333          20 : void LinearBasisSetExpansion::writeTargetDistProjGridToFile(const std::vector<std::string>& proj_arg, OFile& ofile, const bool append_file) const {
     334          20 :   if(targetdist_grid_pntr_==NULL) {return;}
     335          20 :   if(append_file) {ofile.enforceRestart();}
     336          20 :   Grid proj_grid = TargetDistribution::getMarginalDistributionGrid(targetdist_grid_pntr_,proj_arg);
     337          20 :   proj_grid.writeToFile(ofile);
     338          20 : }
     339             : 
     340             : 
     341           0 : void LinearBasisSetExpansion::writeTargetDistributionToFile(const std::string& filename) const {
     342           0 :   OFile of1; OFile of2;
     343           0 :   if(action_pntr_!=NULL) {
     344           0 :     of1.link(*action_pntr_); of2.link(*action_pntr_);
     345             :   }
     346           0 :   of1.enforceBackup(); of2.enforceBackup();
     347           0 :   of1.open(filename);
     348           0 :   of2.open(FileBase::appendSuffix(filename,".log"));
     349           0 :   writeTargetDistGridToFile(of1);
     350           0 :   writeLogTargetDistGridToFile(of2);
     351           0 :   of1.close(); of2.close();
     352           0 : }
     353             : 
     354             : 
     355     2011787 : double LinearBasisSetExpansion::getBiasAndForces(const std::vector<double>& args_values, bool& all_inside, std::vector<double>& forces, std::vector<double>& coeffsderivs_values, std::vector<BasisFunctions*>& basisf_pntrs_in, CoeffsVector* coeffs_pntr_in, Communicator* comm_in) {
     356     2011787 :   unsigned int nargs = args_values.size();
     357     2011787 :   plumed_assert(coeffs_pntr_in->numberOfDimensions()==nargs);
     358     2011787 :   plumed_assert(basisf_pntrs_in.size()==nargs);
     359     2011787 :   plumed_assert(forces.size()==nargs);
     360     2011787 :   plumed_assert(coeffsderivs_values.size()==coeffs_pntr_in->numberOfCoeffs());
     361             : 
     362     2011787 :   std::vector<double> args_values_trsfrm(nargs);
     363             :   // std::vector<bool>   inside_interval(nargs,true);
     364     2011787 :   all_inside = true;
     365             :   //
     366     2011787 :   std::vector< std::vector <double> > bf_values(nargs);
     367     2011787 :   std::vector< std::vector <double> > bf_derivs(nargs);
     368             :   //
     369     5966255 :   for(unsigned int k=0; k<nargs; k++) {
     370     3954468 :     bf_values[k].assign(basisf_pntrs_in[k]->getNumberOfBasisFunctions(),0.0);
     371     3954468 :     bf_derivs[k].assign(basisf_pntrs_in[k]->getNumberOfBasisFunctions(),0.0);
     372     3954468 :     bool curr_inside=true;
     373     3954468 :     basisf_pntrs_in[k]->getAllValues(args_values[k],args_values_trsfrm[k],curr_inside,bf_values[k],bf_derivs[k]);
     374             :     // inside_interval[k]=curr_inside;
     375     3954468 :     if(!curr_inside) {all_inside=false;}
     376     3954468 :     forces[k]=0.0;
     377             :   }
     378             :   //
     379             :   size_t stride=1;
     380             :   size_t rank=0;
     381     2011787 :   if(comm_in!=NULL)
     382             :   {
     383     2011787 :     stride=comm_in->Get_size();
     384     2011787 :     rank=comm_in->Get_rank();
     385             :   }
     386             :   // loop over coeffs
     387     2011787 :   double bias=0.0;
     388   144769949 :   for(size_t i=rank; i<coeffs_pntr_in->numberOfCoeffs(); i+=stride) {
     389   142758162 :     std::vector<unsigned int> indices=coeffs_pntr_in->getIndices(i);
     390             :     double coeff = coeffs_pntr_in->getValue(i);
     391             :     double bf_curr=1.0;
     392   435044808 :     for(unsigned int k=0; k<nargs; k++) {
     393   292286646 :       bf_curr*=bf_values[k][indices[k]];
     394             :     }
     395   142758162 :     bias+=coeff*bf_curr;
     396   142758162 :     coeffsderivs_values[i] = bf_curr;
     397   435044808 :     for(unsigned int k=0; k<nargs; k++) {
     398             :       double der = 1.0;
     399   898592256 :       for(unsigned int l=0; l<nargs; l++) {
     400   606305610 :         if(l!=k) {der*=bf_values[l][indices[l]];}
     401   292286646 :         else {der*=bf_derivs[l][indices[l]];}
     402             :       }
     403   292286646 :       forces[k]-=coeff*der;
     404             :       // maybe faster but dangerous
     405             :       // forces[k]-=coeff*bf_curr*(bf_derivs[k][indices[k]]/bf_values[k][indices[k]]);
     406             :     }
     407             :   }
     408             :   //
     409     2011787 :   if(comm_in!=NULL) {
     410             :     // coeffsderivs_values is not summed as the mpi Sum is done later on for the averages
     411     2011787 :     comm_in->Sum(bias);
     412     2011787 :     comm_in->Sum(forces);
     413             :   }
     414     2011787 :   return bias;
     415     2011787 : }
     416             : 
     417             : 
     418      862315 : void LinearBasisSetExpansion::getBasisSetValues(const std::vector<double>& args_values, std::vector<double>& basisset_values, std::vector<BasisFunctions*>& basisf_pntrs_in, CoeffsVector* coeffs_pntr_in, Communicator* comm_in) {
     419      862315 :   unsigned int nargs = args_values.size();
     420      862315 :   plumed_assert(coeffs_pntr_in->numberOfDimensions()==nargs);
     421      862315 :   plumed_assert(basisf_pntrs_in.size()==nargs);
     422             : 
     423      862315 :   std::vector<double> args_values_trsfrm(nargs);
     424             :   std::vector< std::vector <double> > bf_values;
     425             :   //
     426     2583312 :   for(unsigned int k=0; k<nargs; k++) {
     427     1720997 :     std::vector<double> tmp_val(basisf_pntrs_in[k]->getNumberOfBasisFunctions());
     428     1720997 :     std::vector<double> tmp_der(tmp_val.size());
     429     1720997 :     bool inside=true;
     430     1720997 :     basisf_pntrs_in[k]->getAllValues(args_values[k],args_values_trsfrm[k],inside,tmp_val,tmp_der);
     431     1720997 :     bf_values.push_back(tmp_val);
     432             :   }
     433             :   //
     434             :   size_t stride=1;
     435             :   size_t rank=0;
     436      862315 :   if(comm_in!=NULL)
     437             :   {
     438           0 :     stride=comm_in->Get_size();
     439           0 :     rank=comm_in->Get_rank();
     440             :   }
     441             :   // loop over basis set
     442    95955507 :   for(size_t i=rank; i<coeffs_pntr_in->numberOfCoeffs(); i+=stride) {
     443    95093192 :     std::vector<unsigned int> indices=coeffs_pntr_in->getIndices(i);
     444             :     double bf_curr=1.0;
     445   298507612 :     for(unsigned int k=0; k<nargs; k++) {
     446   203414420 :       bf_curr*=bf_values[k][indices[k]];
     447             :     }
     448    95093192 :     basisset_values[i] = bf_curr;
     449             :   }
     450             :   //
     451      862315 :   if(comm_in!=NULL) {
     452           0 :     comm_in->Sum(basisset_values);
     453             :   }
     454     1724630 : }
     455             : 
     456             : 
     457         408 : double LinearBasisSetExpansion::getBasisSetValue(const std::vector<double>& args_values, const size_t index, std::vector<BasisFunctions*>& basisf_pntrs_in, CoeffsVector* coeffs_pntr_in) {
     458         408 :   unsigned int nargs = args_values.size();
     459         408 :   plumed_assert(coeffs_pntr_in->numberOfDimensions()==nargs);
     460         408 :   plumed_assert(basisf_pntrs_in.size()==nargs);
     461             : 
     462         408 :   std::vector<double> args_values_trsfrm(nargs);
     463             :   std::vector< std::vector <double> > bf_values;
     464             :   //
     465         938 :   for(unsigned int k=0; k<nargs; k++) {
     466         530 :     std::vector<double> tmp_val(basisf_pntrs_in[k]->getNumberOfBasisFunctions());
     467         530 :     std::vector<double> tmp_der(tmp_val.size());
     468         530 :     bool inside=true;
     469         530 :     basisf_pntrs_in[k]->getAllValues(args_values[k],args_values_trsfrm[k],inside,tmp_val,tmp_der);
     470         530 :     bf_values.push_back(tmp_val);
     471             :   }
     472             :   //
     473         408 :   std::vector<unsigned int> indices=coeffs_pntr_in->getIndices(index);
     474             :   double bf_value=1.0;
     475         938 :   for(unsigned int k=0; k<nargs; k++) {
     476         530 :     bf_value*=bf_values[k][indices[k]];
     477             :   }
     478         408 :   return bf_value;
     479         408 : }
     480             : 
     481             : 
     482          45 : void LinearBasisSetExpansion::setupUniformTargetDistribution() {
     483          45 :   std::vector< std::vector <double> > bf_integrals(0);
     484          45 :   std::vector<double> targetdist_averages(ncoeffs_,0.0);
     485             :   //
     486         100 :   for(unsigned int k=0; k<nargs_; k++) {
     487         110 :     bf_integrals.push_back(basisf_pntrs_[k]->getUniformIntegrals());
     488             :   }
     489             :   //
     490        1672 :   for(size_t i=0; i<ncoeffs_; i++) {
     491        1627 :     std::vector<unsigned int> indices=bias_coeffs_pntr_->getIndices(i);
     492             :     double value = 1.0;
     493        4492 :     for(unsigned int k=0; k<nargs_; k++) {
     494        2865 :       value*=bf_integrals[k][indices[k]];
     495             :     }
     496        1627 :     targetdist_averages[i]=value;
     497             :   }
     498          45 :   TargetDistAverages() = targetdist_averages;
     499          45 : }
     500             : 
     501             : 
     502          45 : void LinearBasisSetExpansion::setupTargetDistribution(TargetDistribution* targetdist_pntr_in) {
     503          45 :   targetdist_pntr_ = targetdist_pntr_in;
     504             :   //
     505          45 :   targetdist_pntr_->setupGrids(args_pntrs_,grid_min_,grid_max_,grid_bins_);
     506          45 :   targetdist_grid_pntr_      = targetdist_pntr_->getTargetDistGridPntr();
     507          45 :   log_targetdist_grid_pntr_  = targetdist_pntr_->getLogTargetDistGridPntr();
     508             :   //
     509          45 :   if(targetdist_pntr_->isDynamic()) {
     510          39 :     vesbias_pntr_->enableDynamicTargetDistribution();
     511             :   }
     512             :   //
     513          45 :   if(targetdist_pntr_->biasGridNeeded()) {
     514           0 :     setupBiasGrid(true);
     515           0 :     targetdist_pntr_->linkBiasGrid(bias_grid_pntr_.get());
     516             :   }
     517          45 :   if(targetdist_pntr_->biasWithoutCutoffGridNeeded()) {
     518           3 :     setupBiasGrid(true);
     519           3 :     targetdist_pntr_->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_.get());
     520             :   }
     521          45 :   if(targetdist_pntr_->fesGridNeeded()) {
     522          36 :     setupFesGrid();
     523          36 :     targetdist_pntr_->linkFesGrid(fes_grid_pntr_.get());
     524             :   }
     525             :   //
     526          45 :   targetdist_pntr_->updateTargetDist();
     527          45 :   calculateTargetDistAveragesFromGrid(targetdist_grid_pntr_);
     528          45 : }
     529             : 
     530             : 
     531         355 : void LinearBasisSetExpansion::updateTargetDistribution() {
     532         355 :   plumed_massert(targetdist_pntr_!=NULL,"the target distribution hasn't been setup!");
     533         355 :   plumed_massert(targetdist_pntr_->isDynamic(),"this should only be used for dynamically updated target distributions!");
     534         355 :   if(targetdist_pntr_->biasGridNeeded()) {updateBiasGrid();}
     535         355 :   if(biasCutoffActive()) {updateBiasWithoutCutoffGrid();}
     536         355 :   if(targetdist_pntr_->fesGridNeeded()) {updateFesGrid();}
     537         355 :   targetdist_pntr_->updateTargetDist();
     538         355 :   calculateTargetDistAveragesFromGrid(targetdist_grid_pntr_);
     539         355 : }
     540             : 
     541             : 
     542           8 : void LinearBasisSetExpansion::readInRestartTargetDistribution(const std::string& grid_fname) {
     543           8 :   targetdist_pntr_->readInRestartTargetDistGrid(grid_fname);
     544           8 :   if(biasCutoffActive()) {targetdist_pntr_->clearLogTargetDistGrid();}
     545           8 : }
     546             : 
     547             : 
     548           8 : void LinearBasisSetExpansion::restartTargetDistribution() {
     549           8 :   plumed_massert(targetdist_pntr_!=NULL,"the target distribution hasn't been setup!");
     550           8 :   plumed_massert(targetdist_pntr_->isDynamic(),"this should only be used for dynamically updated target distributions!");
     551           8 :   if(biasCutoffActive()) {updateBiasWithoutCutoffGrid();}
     552           8 :   calculateTargetDistAveragesFromGrid(targetdist_grid_pntr_);
     553           8 : }
     554             : 
     555             : 
     556         408 : void LinearBasisSetExpansion::calculateTargetDistAveragesFromGrid(const Grid* targetdist_grid_pntr) {
     557         408 :   plumed_assert(targetdist_grid_pntr!=NULL);
     558         408 :   std::vector<double> targetdist_averages(ncoeffs_,0.0);
     559         816 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr);
     560         408 :   Grid::index_t stride=mycomm_.Get_size();
     561         408 :   Grid::index_t rank=mycomm_.Get_rank();
     562      862723 :   for(Grid::index_t l=rank; l<targetdist_grid_pntr->getSize(); l+=stride) {
     563      862315 :     std::vector<double> args_values = targetdist_grid_pntr->getPoint(l);
     564      862315 :     std::vector<double> basisset_values(ncoeffs_);
     565             :     // parallelization done over the grid -> should NOT use parallel in getBasisSetValues!!
     566      862315 :     getBasisSetValues(args_values,basisset_values,false);
     567      862315 :     double weight = integration_weights[l]*targetdist_grid_pntr->getValue(l);
     568    95955507 :     for(unsigned int i=0; i<ncoeffs_; i++) {
     569    95093192 :       targetdist_averages[i] += weight*basisset_values[i];
     570             :     }
     571             :   }
     572         408 :   mycomm_.Sum(targetdist_averages);
     573             :   // the overall constant;
     574         408 :   targetdist_averages[0] = getBasisSetConstant();
     575         408 :   TargetDistAverages() = targetdist_averages;
     576         408 : }
     577             : 
     578             : 
     579          39 : void LinearBasisSetExpansion::setBiasMinimumToZero() {
     580          39 :   plumed_massert(bias_grid_pntr_,"setBiasMinimumToZero can only be used if the bias grid is defined");
     581          39 :   updateBiasGrid();
     582          39 :   BiasCoeffs()[0]-=bias_grid_pntr_->getMinValue();
     583          39 : }
     584             : 
     585             : 
     586           0 : void LinearBasisSetExpansion::setBiasMaximumToZero() {
     587           0 :   plumed_massert(bias_grid_pntr_,"setBiasMaximumToZero can only be used if the bias grid is defined");
     588           0 :   updateBiasGrid();
     589           0 :   BiasCoeffs()[0]-=bias_grid_pntr_->getMaxValue();
     590           0 : }
     591             : 
     592             : 
     593     1982225 : bool LinearBasisSetExpansion::biasCutoffActive() const {
     594     1982225 :   if(vesbias_pntr_!=NULL) {return vesbias_pntr_->biasCutoffActive();}
     595             :   else {return false;}
     596             : }
     597             : 
     598             : 
     599           0 : double LinearBasisSetExpansion::calculateReweightFactor() const {
     600           0 :   plumed_massert(targetdist_grid_pntr_!=NULL,"calculateReweightFactor only be used if the target distribution grid is defined");
     601           0 :   plumed_massert(bias_grid_pntr_,"calculateReweightFactor only be used if the bias grid is defined");
     602             :   double sum = 0.0;
     603           0 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr_);
     604             :   //
     605           0 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++) {
     606           0 :     sum += integration_weights[l] * targetdist_grid_pntr_->getValue(l) * exp(+beta_*bias_grid_pntr_->getValue(l));
     607             :   }
     608           0 :   if(sum==0.0) sum=std::numeric_limits<double>::min();
     609           0 :   return (1.0/beta_)*std::log(sum);
     610             : }
     611             : 
     612             : 
     613             : 
     614             : 
     615             : }
     616             : 
     617             : }

Generated by: LCOV version 1.16