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

Generated by: LCOV version 1.16