LCOV - code coverage report
Current view: top level - gridtools - SumOfKernels.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 56 57 98.2 %
Date: 2025-12-04 11:19:34 Functions: 16 23 69.6 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2015-2023 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #ifndef __PLUMED_gridtools_SumOfKernels_h
      23             : #define __PLUMED_gridtools_SumOfKernels_h
      24             : 
      25             : #include "function/FunctionSetup.h"
      26             : #include "tools/SwitchingFunction.h"
      27             : #include "tools/HistogramBead.h"
      28             : #include "tools/Matrix.h"
      29             : 
      30             : namespace PLMD {
      31             : namespace gridtools {
      32             : 
      33             : template <class K>
      34             : class RegularKernel;
      35             : 
      36      178360 : class DiagonalKernelParams {
      37             : public:
      38             :   std::vector<double> at;
      39             :   std::vector<double> sigma;
      40             :   double height;
      41             :   static bool bandwidthIsConstant( std::size_t ndim, const std::vector<Value*>& args );
      42             :   static bool bandwidthsAllSame( std::size_t ndim, const std::vector<Value*>& args );
      43             :   static bool setKernelAndCheckHeight( DiagonalKernelParams& kp, std::size_t ndim, const std::vector<double>& args );
      44             :   static std::size_t getNumberOfParameters( const DiagonalKernelParams& kp );
      45             :   static void getSigmaProjections( const DiagonalKernelParams& kp, std::vector<double>& support );
      46             :   static double evaluateR2( const RegularKernel<DiagonalKernelParams>& p, const DiagonalKernelParams& kp, View<const double> x, View<double> paramderivs );
      47             : };
      48             : 
      49             : class NonDiagonalKernelParams {
      50             : public:
      51             :   std::vector<double> at;
      52             :   Matrix<double> sigma, metric;
      53             :   double height;
      54             :   static bool bandwidthIsConstant( std::size_t ndim, const std::vector<Value*>& args );
      55             :   static bool bandwidthsAllSame( std::size_t ndim, const std::vector<Value*>& args );
      56             :   static bool setKernelAndCheckHeight( NonDiagonalKernelParams& kp, std::size_t ndim, const std::vector<double>& args );
      57             :   static std::size_t getNumberOfParameters( const NonDiagonalKernelParams& kp );
      58             :   static void getSigmaProjections( const NonDiagonalKernelParams& kp, std::vector<double>& support );
      59             :   static double evaluateR2( const RegularKernel<NonDiagonalKernelParams>& p, const NonDiagonalKernelParams& kp, View<const double> x, View<double> paramderivs );
      60             : };
      61             : 
      62             : class DiscreteKernel {
      63             : public:
      64             :   static void registerKeywords( Keywords& keys ) {}
      65             :   static void read( DiscreteKernel& p, ActionWithArguments* action, const std::vector<Value*>& args ) {}
      66             :   static void setArgumentDomain( const unsigned& i, DiscreteKernel& params, const double& spacing, const bool isp, const std::string& min1, const std::string& max1 ) {}
      67             :   static void getSupport( DiscreteKernel& params, const DiagonalKernelParams& kp, double dp2cutoff, std::vector<double>& support ) {}
      68             :   static double calc( const DiscreteKernel& params, const DiagonalKernelParams& kp, View<const double> x, View<double> der, View<double> paramderivs );
      69             : };
      70             : 
      71             : class HistogramBeadKernel {
      72             : public:
      73             :   std::vector<HistogramBead> beads;
      74             :   std::vector<double> gridspacing;
      75             :   static void registerKeywords( Keywords& keys );
      76             :   static void read( HistogramBeadKernel& p, ActionWithArguments* action, const std::vector<Value*>& args );
      77             :   static void setArgumentDomain( const unsigned& i, HistogramBeadKernel& params, const double& spacing, const bool isp, const std::string& min1, const std::string& max1 );
      78             :   static void getSupport( HistogramBeadKernel& params, const DiagonalKernelParams& kp, double dp2cutoff, std::vector<double>& support );
      79             :   static double calc( const HistogramBeadKernel& params, const DiagonalKernelParams& kp, View<const double> x, View<double> der, View<double> paramderivs );
      80             : };
      81             : 
      82             : template <class K>
      83             : class RegularKernel {
      84             : public:
      85             :   bool canusevol;
      86             :   SwitchingFunction switchingFunction;
      87             :   std::vector<bool> periodic;
      88             :   std::vector<double> max_minus_min, inv_max_minus_min;
      89             :   static void registerKeywords( Keywords& keys );
      90             :   static void read( RegularKernel& p, ActionWithArguments* action, const std::vector<Value*>& args );
      91             :   static void setArgumentDomain( const unsigned& i, RegularKernel& params, const double& spacing, const bool isp, const std::string& min1, const std::string& max1 );
      92             :   static double difference( const RegularKernel& params, unsigned i, const double& val1, const double& val2 );
      93             :   static void getSupport( const RegularKernel& params, const K& kp, double dp2cutoff, std::vector<double>& support );
      94             :   static double calc( const RegularKernel& params, const K& kp, View<const double> x, View<double> der, View<double> paramderivs );
      95             : };
      96             : 
      97             : template <class K>
      98         244 : void RegularKernel<K>::registerKeywords( Keywords& keys ) {
      99         244 :   keys.add("compulsory","KERNEL","GAUSSIAN","the kernel function you are using.");
     100         244 : }
     101             : 
     102             : template <class K>
     103          48 : void RegularKernel<K>::read( RegularKernel& p, ActionWithArguments* action, const std::vector<Value*>& args ) {
     104             :   std::string kerneltype;
     105          96 :   action->parse("KERNEL",kerneltype);
     106             :   std::string errors;
     107         432 :   for(auto & c: kerneltype) {
     108         384 :     c = std::toupper(c);
     109             :   }
     110          48 :   p.canusevol = (kerneltype=="GAUSSIAN");
     111          96 :   p.switchingFunction.set( kerneltype + " R_0=1.0 NOSTRETCH", errors );
     112          48 :   if( errors.length()!=0 ) {
     113           0 :     action->error("problem reading switching function description " + errors);
     114             :   }
     115          48 :   p.periodic.resize( args.size() );
     116          48 :   p.max_minus_min.resize( args.size() );
     117          48 :   p.inv_max_minus_min.resize( args.size() );
     118          48 : }
     119             : 
     120             : template <class K>
     121          74 : void RegularKernel<K>::setArgumentDomain( const unsigned& i, RegularKernel& params, const double& spacing, const bool isp, const std::string& min1, const std::string& max1 ) {
     122          74 :   params.periodic[i] = isp;
     123          74 :   if( params.periodic[i] ) {
     124             :     double min, max;
     125          35 :     Tools::convert( min1, min );
     126          35 :     Tools::convert( max1, max );
     127          35 :     params.max_minus_min[i]=max-min;
     128          35 :     params.inv_max_minus_min[i]=1.0/params.max_minus_min[i];
     129             :   }
     130          74 : }
     131             : 
     132             : template <class K>
     133   113633781 : double RegularKernel<K>::difference( const RegularKernel<K>& params, unsigned i, const double& val1, const double& val2 ) {
     134   113633781 :   if( !params.periodic[i] ) {
     135    22673791 :     return val1 - val2;
     136             :   }
     137    90959990 :   return params.max_minus_min[i]*Tools::pbc( params.inv_max_minus_min[i]*( val1 - val2 ) );
     138             : }
     139             : 
     140             : template <class K>
     141          46 : void RegularKernel<K>::getSupport( const RegularKernel<K>& params, const K& kp, double dp2cutoff, std::vector<double>& support ) {
     142          46 :   K::getSigmaProjections( kp, support );
     143         120 :   for(unsigned i=0; i<support.size(); ++i) {
     144          74 :     support[i] = sqrt(2.0*dp2cutoff)*support[i];
     145             :   }
     146          46 : }
     147             : 
     148             : template <class K>
     149    38366411 : double RegularKernel<K>::calc( const RegularKernel<K>& params, const K& kp, View<const double> x, View<double> der, View<double> paramderivs ) {
     150    38366411 :   double r2 = K::evaluateR2( params, kp, x, paramderivs );
     151    38366411 :   double dval, val = kp.height*params.switchingFunction.calculateSqr( r2, dval );
     152    38366411 :   dval *= kp.height;
     153   152000192 :   for(unsigned i=0; i<der.size(); ++i) {
     154   113633781 :     der[i] += dval*paramderivs[i];
     155   113633781 :     paramderivs[i] = -dval*paramderivs[i];
     156             :   }
     157    38366411 :   paramderivs[2*kp.at.size()] = val / kp.height;
     158    38366411 :   return val;
     159             : }
     160             : 
     161      108263 : class VonMissesKernelParams {
     162             : public:
     163             :   std::vector<double> at;
     164             :   double concentration;
     165             :   double norm;
     166             :   double height;
     167             :   static bool bandwidthIsConstant( std::size_t ndim, const std::vector<Value*>& args );
     168             :   static bool bandwidthsAllSame( std::size_t ndim, const std::vector<Value*>& args );
     169             :   static bool setKernelAndCheckHeight( VonMissesKernelParams& kp, std::size_t ndim, const std::vector<double>& argval );
     170             :   static std::size_t getNumberOfParameters( const VonMissesKernelParams& kp );
     171             : };
     172             : 
     173             : class UniversalVonMisses {
     174             : public:
     175             :   std::string kerneltype;
     176             :   SwitchingFunction switchingFunction;
     177             :   static void registerKeywords( Keywords& keys ) {}
     178             :   static void read( UniversalVonMisses& p, ActionWithArguments* action, const std::vector<Value*>& args ) {}
     179             :   static void setArgumentDomain( const unsigned& i, UniversalVonMisses& params, const double& spacing, const bool isp, const std::string& min1, const std::string& max1 ) {}
     180             :   static double calc( const UniversalVonMisses& params, const VonMissesKernelParams& kp, View<const double> x, View<double> der, View<double> paramderivs );
     181             : };
     182             : 
     183             : template <class K, class P>
     184             : class SumOfKernels {
     185             : public:
     186             :   P params;
     187             :   std::vector<K> kernelParams;
     188             : /// This is used to setup the input gridobject's bounds with the grid data from values
     189             :   static void registerKeywords( Keywords& keys );
     190             :   static void read( SumOfKernels<K,P>& func, ActionWithArguments* action, const std::vector<Value*>& args, function::FunctionOptions& options );
     191             :   static void calc( View<const std::size_t> klist, const SumOfKernels<K,P>& func, View<const double> args, View<double> values, View<double> der, View<double> paramderivs );
     192             : };
     193             : 
     194             : template <class K, class P>
     195         282 : void SumOfKernels<K,P>::registerKeywords( Keywords& keys ) {
     196         282 :   P::registerKeywords( keys );
     197         282 : }
     198             : 
     199             : template <class K, class P>
     200          66 : void SumOfKernels<K,P>::read( SumOfKernels<K,P>& func, ActionWithArguments* action, const std::vector<Value*>& args, function::FunctionOptions& options ) {
     201             : // Read the universal parameters for the kernel
     202          66 :   P::read( func.params, action, args );
     203          66 : }
     204             : 
     205             : template <class K, class P>
     206      183915 : void SumOfKernels<K,P>::calc( View<const std::size_t> klist, const SumOfKernels<K,P>& func, View<const double> args, View<double> values, View<double> der, View<double> paramderivs ) {
     207      183915 :   values[0] = 0;
     208      657974 :   for(unsigned i=0; i<der.size(); ++i) {
     209      474059 :     der[i] = 0;
     210             :   }
     211      183915 :   std::size_t nparams = K::getNumberOfParameters( func.kernelParams[0] );
     212    65166809 :   for(unsigned i=0; i<klist.size(); ++i) {
     213    64982894 :     values[0] += P::calc( func.params, func.kernelParams[klist[i]], args, der, View<double>( paramderivs.data() + i*nparams, nparams ) );
     214             :   }
     215      183915 : }
     216             : 
     217             : }
     218             : }
     219             : #endif

Generated by: LCOV version 1.16