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

Generated by: LCOV version 1.16