LCOV - code coverage report
Current view: top level - gridtools - HistogramOnGrid.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 74 76 97.4 %
Date: 2018-12-19 07:49:13 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2015-2018 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #include "HistogramOnGrid.h"
      23             : #include "tools/KernelFunctions.h"
      24             : 
      25             : namespace PLMD {
      26             : namespace gridtools {
      27             : 
      28          36 : void HistogramOnGrid::registerKeywords( Keywords& keys ) {
      29          36 :   GridVessel::registerKeywords( keys );
      30          36 :   keys.add("compulsory","KERNEL","the type of kernel to use");
      31          36 :   keys.add("compulsory","BANDWIDTH","the bandwidths");
      32          36 : }
      33             : 
      34          28 : HistogramOnGrid::HistogramOnGrid( const vesselbase::VesselOptions& da ):
      35             :   GridVessel(da),
      36             :   neigh_tot(0),
      37             :   addOneKernelAtATime(false),
      38             :   bandwidths(dimension),
      39          28 :   discrete(false)
      40             : {
      41          28 :   parse("KERNEL",kerneltype);
      42          28 :   if( kerneltype=="discrete" || kerneltype=="DISCRETE" ) {
      43           4 :     discrete=true; setNoDerivatives();
      44             :   } else {
      45          24 :     parseVector("BANDWIDTH",bandwidths);
      46             :   }
      47          28 : }
      48             : 
      49          16 : bool HistogramOnGrid::noDiscreteKernels() const {
      50          16 :   return !discrete;
      51             : }
      52             : 
      53          32 : void HistogramOnGrid::setBounds( const std::vector<std::string>& smin, const std::vector<std::string>& smax,
      54             :                                  const std::vector<unsigned>& nbins, const std::vector<double>& spacing ) {
      55          32 :   GridVessel::setBounds( smin, smax, nbins, spacing );
      56          32 :   if( !discrete ) {
      57          28 :     std::vector<double> point(dimension,0);
      58          56 :     KernelFunctions kernel( point, bandwidths, kerneltype, false, 1.0, true ); neigh_tot=1;
      59          56 :     nneigh=kernel.getSupport( dx ); std::vector<double> support( kernel.getContinuousSupport() );
      60          72 :     for(unsigned i=0; i<dimension; ++i) {
      61          44 :       if( pbc[i] && 2*support[i]>getGridExtent(i) ) error("bandwidth is too large for periodic grid");
      62          44 :       neigh_tot *= (2*nneigh[i]+1);
      63          28 :     }
      64             :   }
      65          32 : }
      66             : 
      67       16002 : KernelFunctions* HistogramOnGrid::getKernelAndNeighbors( std::vector<double>& point, unsigned& num_neigh, std::vector<unsigned>& neighbors ) const {
      68       16002 :   if( discrete ) {
      69           5 :     num_neigh=1; for(unsigned i=0; i<dimension; ++i) point[i] += 0.5*dx[i];
      70           5 :     neighbors[0] = getIndex( point ); return NULL;
      71             :   } else {
      72       15997 :     KernelFunctions* kernel = new KernelFunctions( point, bandwidths, kerneltype, false, 1.0, true );
      73       15993 :     getNeighbors( kernel->getCenter(), nneigh, num_neigh, neighbors );
      74       15998 :     return kernel;
      75             :   }
      76             : }
      77             : 
      78       27019 : std::vector<Value*> HistogramOnGrid::getVectorOfValues() const {
      79       27019 :   std::vector<Value*> vv;
      80      107201 :   for(unsigned i=0; i<dimension; ++i) {
      81       80188 :     vv.push_back(new Value());
      82       80190 :     if( pbc[i] ) vv[i]->setDomain( str_min[i], str_max[i] );
      83       42713 :     else vv[i]->setNotPeriodic();
      84             :   }
      85       27013 :   return vv;
      86             : }
      87             : 
      88       27018 : void HistogramOnGrid::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
      89       27018 :   if( addOneKernelAtATime ) {
      90             :     plumed_dbg_assert( myvals.getNumberOfValues()==2 );
      91       11046 :     std::vector<double> der( dimension );
      92       11061 :     for(unsigned i=0; i<dimension; ++i) der[i]=myvals.getDerivative( 1, i );
      93       11044 :     accumulate( getAction()->getPositionInCurrentTaskList(current), myvals.get(0), myvals.get(1), der, buffer );
      94             :   } else {
      95             :     plumed_dbg_assert( myvals.getNumberOfValues()==dimension+2 );
      96       15972 :     std::vector<double> point( dimension ); double weight=myvals.get(0)*myvals.get( 1+dimension );
      97       15971 :     for(unsigned i=0; i<dimension; ++i) point[i]=myvals.get( 1+i );
      98             : 
      99             :     // Get the kernel
     100       31947 :     unsigned num_neigh; std::vector<unsigned> neighbors;
     101       31947 :     std::vector<double> der( dimension );
     102       15974 :     KernelFunctions* kernel=getKernelAndNeighbors( point, num_neigh, neighbors );
     103             : 
     104       15974 :     if( !kernel ) {
     105           0 :       plumed_dbg_assert( num_neigh==1 ); der.resize(0);
     106           0 :       accumulate( neighbors[0], weight, 1.0, der, buffer );
     107             :     } else {
     108       15974 :       std::vector<Value*> vv( getVectorOfValues() );
     109             : 
     110       31947 :       double newval; std::vector<double> xx( dimension );
     111    15011275 :       for(unsigned i=0; i<num_neigh; ++i) {
     112    14995302 :         unsigned ineigh=neighbors[i];
     113    14995474 :         if( inactive( ineigh ) ) continue ;
     114    10640267 :         getGridPointCoordinates( ineigh, xx );
     115    10631690 :         for(unsigned j=0; j<dimension; ++j) vv[j]->set(xx[j]);
     116    10640227 :         newval = kernel->evaluate( vv, der, true );
     117    10640490 :         accumulate( ineigh, weight, newval, der, buffer );
     118             :       }
     119       15973 :       delete kernel;
     120       31948 :       for(unsigned i=0; i<dimension; ++i) delete vv[i];
     121       15974 :     }
     122             :   }
     123       27022 : }
     124             : 
     125       11268 : void HistogramOnGrid::accumulate( const unsigned& ipoint, const double& weight, const double& dens, const std::vector<double>& der, std::vector<double>& buffer ) const {
     126       11268 :   buffer[bufstart+nper*ipoint] += weight*dens;
     127       11272 :   if( der.size()>0 ) for(unsigned j=0; j<dimension; ++j) buffer[bufstart+nper*ipoint + 1 + j] += weight*der[j];
     128       11261 : }
     129             : 
     130          51 : void HistogramOnGrid::finish( const std::vector<double>& buffer ) {
     131          51 :   if( addOneKernelAtATime ) {
     132       11072 :     for(unsigned i=0; i<getAction()->getCurrentNumberOfActiveTasks(); ++i) {
     133       11048 :       for(unsigned j=0; j<nper; ++j) addDataElement( nper*getAction()->getActiveTask(i)+j, buffer[bufstart+i*nper+j] );
     134             :     }
     135             :   } else {
     136          27 :     GridVessel::finish( buffer );
     137             :   }
     138          51 : }
     139             : 
     140             : }
     141        2523 : }

Generated by: LCOV version 1.13