LCOV - code coverage report
Current view: top level - multicolvar - FilterLessThan.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 22 27 81.5 %
Date: 2024-10-11 08:09:47 Functions: 8 10 80.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2014-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             : #include "core/ActionRegister.h"
      23             : #include "tools/SwitchingFunction.h"
      24             : #include "MultiColvarFilter.h"
      25             : 
      26             : //+PLUMEDOC MTRANSFORMS MTRANSFORM_LESS
      27             : /*
      28             : This action can be used to transform the colvar values calculated by a \ref mcolv using a \ref switchingfunction
      29             : 
      30             : In this action each colvar, \f$s_i\f$, calculated by \ref mcolv is transformed by a \ref switchingfunction function that
      31             : is equal to one if the colvar is less than a certain target value and which is equal to zero otherwise.
      32             : It is important to understand the distinction between what is done here and what is done by \ref MFILTER_LESS.
      33             : In \ref MFILTER_LESS a weight, \f$w_i\f$ for the colvar is calculated using the \ref switchingfunction.  If one calculates the
      34             : MEAN for \ref MFILTER_LESS one is thus calculating:
      35             : 
      36             : \f[
      37             : \mu = \frac{ \sum_i \sigma(s_i) s_i }{\sum_i \simga(s_i) }
      38             : \f]
      39             : 
      40             : where \f$\sigma\f$ is the \ref switchingfunction.  In this action by contrast the colvar is being transformed by
      41             : the \ref switchingfunction.  If one thus calculates a MEAN for this action one computes:
      42             : 
      43             : \f[
      44             : \mu = \frac{ \sum_{i=1}^N \simga(s_i) }{ N }
      45             : \f]
      46             : 
      47             : In other words, you are calculating the mean for the transformed colvar.
      48             : 
      49             : \par Examples
      50             : 
      51             : The following input gives an example of how a MTRANSFORM_LESS action can be used to duplicate
      52             : functionality that is elsewhere in PLUMED.
      53             : 
      54             : \plumedfile
      55             : DISTANCES ...
      56             :  GROUPA=1-10 GROUPB=11-20
      57             :  LABEL=d1
      58             : ... DISTANCES
      59             : MTRANSFORM_LESS DATA=d1 SWITCH={GAUSSIAN D_0=1.5 R_0=0.00001}
      60             : \endplumedfile
      61             : 
      62             : In this case you can achieve the same result by using:
      63             : 
      64             : \plumedfile
      65             : DISTANCES ...
      66             :  GROUPA=1-10 GROUPB=11-20
      67             :  LESS_THAN={GAUSSIAN D_0=1.5 R_0=0.00001}
      68             : ... DISTANCES
      69             : \endplumedfile
      70             : (see \ref DISTANCES)
      71             : 
      72             : The advantage of MTRANSFORM_LESS comes, however, if you want to use transformed colvars as input
      73             : for \ref MULTICOLVARDENS
      74             : 
      75             : */
      76             : //+ENDPLUMEDOC
      77             : 
      78             : //+PLUMEDOC MFILTERS MFILTER_LESS
      79             : /*
      80             : This action can be used to filter the distribution of colvar values in a \ref mcolv
      81             : so that one can compute the mean and so on for only those multicolvars less than a tolerance.
      82             : 
      83             : This action can be used to create a dynamic group of atom based on the value of a multicolvar.
      84             : In this action a multicolvar is within the dynamic group if its value is less than a target.
      85             : In actuality a weight, \f$w_i\f$ is ascribed to each colvar, \f$s_i\f$ calculated by a multicolvar
      86             : and this weight measures the degree to which a colvar is a member of the group.  This weight is a number
      87             : between 0 and 1 that is calculated using a \ref switchingfunction , \f$\sigma\f$.
      88             : If one calculates a function of the set of multicolvars
      89             : these weights are included in the calculation.  As such if one calculates the MEAN, \f$\mu\f$ of a filtered
      90             : multicolvar what is computed is the following:
      91             : 
      92             : \f[
      93             : \mu = \frac{ \sum_i w_i s_i }{ \sum_i w_i}
      94             : \f]
      95             : 
      96             : One is thus calculating the mean for those colvars that are less than the target.
      97             : 
      98             : \par Examples
      99             : 
     100             : The example shown below calculates the mean for those distances that less than 1.5 nm in length
     101             : 
     102             : \plumedfile
     103             : DISTANCES GROUPA=1 GROUPB=2-50 MEAN LABEL=d1
     104             : MFILTER_LESS DATA=d1 SWITCH={GAUSSIAN D_0=1.5 R_0=0.00001} MEAN LABEL=d4
     105             : \endplumedfile
     106             : 
     107             : */
     108             : //+ENDPLUMEDOC
     109             : 
     110             : namespace PLMD {
     111             : namespace multicolvar {
     112             : 
     113             : class FilterLess : public MultiColvarFilter {
     114             : private:
     115             :   SwitchingFunction sf;
     116             : public:
     117             :   static void registerKeywords( Keywords& keys );
     118             :   explicit FilterLess(const ActionOptions& ao);
     119             :   double applyFilter( const double& val, double& df ) const override;
     120             : };
     121             : 
     122       10427 : PLUMED_REGISTER_ACTION(FilterLess,"MFILTER_LESS")
     123       10419 : PLUMED_REGISTER_ACTION(FilterLess,"MTRANSFORM_LESS")
     124             : 
     125           6 : void FilterLess::registerKeywords( Keywords& keys ) {
     126           6 :   MultiColvarFilter::registerKeywords( keys );
     127          12 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
     128          12 :   keys.add("compulsory","MM","0","The m parameter of the switching function ");
     129          12 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
     130          12 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
     131          12 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
     132             :            "The following provides information on the \\ref switchingfunction that are available. "
     133             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
     134           6 : }
     135             : 
     136           4 : FilterLess::FilterLess(const ActionOptions& ao):
     137             :   Action(ao),
     138           4 :   MultiColvarFilter(ao)
     139             : {
     140             :   // Read in the switching function
     141           8 :   std::string sw, errors; parse("SWITCH",sw);
     142           4 :   if(sw.length()>0) {
     143           4 :     sf.set(sw,errors);
     144           4 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
     145             :   } else {
     146           0 :     double r_0=-1.0, d_0; int nn, mm;
     147           0 :     parse("NN",nn); parse("MM",mm);
     148           0 :     parse("R_0",r_0); parse("D_0",d_0);
     149           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
     150           0 :     sf.set(nn,mm,r_0,d_0);
     151             :   }
     152           4 :   log.printf("  filtering colvar values and focussing only on those less than %s\n",( sf.description() ).c_str() );
     153             : 
     154           4 :   checkRead();
     155           4 : }
     156             : 
     157        2486 : double FilterLess::applyFilter( const double& val, double& df ) const {
     158        2486 :   double f = sf.calculate( val, df ); df*=val;
     159        2486 :   return f;
     160             : }
     161             : 
     162             : }
     163             : }

Generated by: LCOV version 1.15