LCOV - code coverage report
Current view: top level - cltools - SwitchingPlotter.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 19 68 27.9 %
Date: 2024-10-18 14:00:25 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2024 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             : 
      23             : #include "CLTool.h"
      24             : #include "core/CLToolRegister.h"
      25             : #include "tools/Tools.h"
      26             : #include "tools/SwitchingFunction.h"
      27             : #include <string>
      28             : #include <iostream>
      29             : #include <iomanip>
      30             : #include <limits>
      31             : 
      32             : //+PLUMEDOC TOOLS plotswitch
      33             : /*
      34             : plotswitch is a tool that takes a the input of a switching function and tabulates the output on the terminal
      35             : 
      36             : The tabulated data is compatible with gnuplot and numpy.loadtxt
      37             : 
      38             : Without options plotswitch will tabulate 50 points between 0 and R_0, and then continue in tabulating points with the same step until 2*R_0 or if D_MAX is set, D_MAX
      39             : 
      40             : Without options plotswitch will tabulate data calling calculateSqr, since should be the most used option within the various colvars
      41             : 
      42             : Note that if R_0 happen to be between "from" and "to" the number of steps may not be exacly the number requested in order to force r0 to be computed.
      43             : 
      44             : The various --rational** options use the special set option for the rational, like in COORDINATION.
      45             : 
      46             : \par Examples
      47             : 
      48             : Without option will plot the NN=6 MM=12 rational
      49             : \verbatim
      50             : plumed plotswitch > plot.dat
      51             : \endverbatim
      52             : 
      53             : \verbatim
      54             : plumed plotswitch --switch="RATIONAL NN=5 MM=9 R_0=1.3" --from=1.29999 --to=1.30001 --steps=100> plot.dat
      55             : \endverbatim
      56             : If you use this with a older plumed version you will see the discontinuity in dfunc around 1.3
      57             : (i use gnuplot with "p 'plot.dat' u 1:3 w l t 'dfunc', 'plot.dat' u 1:2 w l axis x1y2 t 'res'")
      58             : */
      59             : //+ENDPLUMEDOC
      60             : 
      61             : namespace PLMD {
      62             : namespace cltools {
      63             : class SwitchingPlotter : public CLTool {
      64             : public:
      65             :   explicit SwitchingPlotter(const CLToolOptions&);
      66             :   static void registerKeywords( Keywords&  );
      67             : 
      68             :   int main( FILE*, FILE*, Communicator& ) override;
      69             : 
      70             : };
      71       15952 : PLUMED_REGISTER_CLTOOL(SwitchingPlotter,"plotswitch")
      72             : 
      73        5316 : void SwitchingPlotter::registerKeywords( Keywords& keys ) {
      74        5316 :   CLTool::registerKeywords( keys );
      75       10632 :   keys.add("compulsory","--switch",
      76             :            "RATIONAL NN=6 R_0=1.0","the input to pass to the switching function,"
      77             :            " please remeber the quotes");
      78       10632 :   keys.add("compulsory","--steps","50",
      79             :            "the number of steps between 0 and R_O, or in the specified interval");
      80       10632 :   keys.add("compulsory","--from","-1",
      81             :            "the start of the interval, if negative will be set to 0");
      82       10632 :   keys.add("compulsory","--to","-1",
      83             :            "the end of the interval, will be D_MAX or 2*R_0 if D_MAX is not set");
      84       10632 :   keys.add("compulsory","--plotprecision","8",
      85             :            "the precision to use for the tabulated results");
      86       10632 :   keys.add("compulsory","--rationalR_0","-1",
      87             :            "The r_0 parameter of the switching function, this will activate the "
      88             :            "--rational options, note that this will ignore the --switch option silently");
      89       10632 :   keys.add("compulsory","--rationalNN","6",
      90             :            "The n parameter of the switching function");
      91       10632 :   keys.add("compulsory","--rationalMM","0",
      92             :            "The m parameter of the switching function; 0 implies 2*NN");
      93       10632 :   keys.add("compulsory","--rationalD_0","0.0",
      94             :            "The d_0 parameter of the switching function");
      95       10632 :   keys.addFlag("--nosquare",false,"use calculate instead of calculateSqr");
      96       10632 :   keys.add("compulsory","--centerrange","-1",
      97             :            "centers the visualization in R_0 in a range given epsilons times r_0"
      98             :            ", note that specifying this will overide all the other range options");
      99        5316 : }
     100             : 
     101           4 : SwitchingPlotter::SwitchingPlotter(const CLToolOptions& co ):
     102           4 :   CLTool(co) {
     103           4 :   inputdata=commandline;
     104           4 : }
     105           0 : int SwitchingPlotter::main( FILE*, FILE*, Communicator& ) {
     106             :   //collecting options:
     107             :   std::string swInput;
     108           0 :   parse("--switch",swInput);
     109             :   bool dontOptimize;
     110           0 :   parseFlag("--nosquare",dontOptimize);
     111             :   int Nsteps;
     112           0 :   parse("--steps",Nsteps);
     113             :   double lowerLimit;
     114           0 :   parse("--from",lowerLimit);
     115             :   double upperLimit;
     116           0 :   parse("--to",upperLimit);
     117             :   unsigned plotPrecision;
     118           0 :   parse("--plotprecision",plotPrecision);
     119             :   int rationalNN;
     120           0 :   parse("--rationalNN",rationalNN);
     121             :   int rationalMM;
     122           0 :   parse("--rationalMM",rationalMM);
     123             :   double rationalD_0;
     124           0 :   parse("--rationalD_0",rationalD_0);
     125             :   double rationalR_0;
     126           0 :   parse("--rationalR_0",rationalR_0);
     127             :   //this works only because we use lepton to parse the numbers
     128             :   double centerrange;
     129           0 :   parse("--centerrange",centerrange);
     130             :   //setting up the switching function
     131           0 :   PLMD::SwitchingFunction switchingFunction;
     132           0 :   if (rationalR_0>0) {
     133           0 :     switchingFunction.set(rationalNN,rationalMM,rationalR_0,rationalD_0);
     134             :   } else {
     135             :     std::string errors;
     136           0 :     switchingFunction.set(swInput,errors);
     137           0 :     if( errors.length()!=0 ) {
     138           0 :       error("problem reading SWITCH keyword : " + errors );
     139             :     }
     140             :   }
     141             : 
     142             :   //setting up the limits:
     143           0 :   const double r0 = switchingFunction.get_r0();
     144           0 :   const double dmax = switchingFunction.get_dmax();
     145             : 
     146           0 :   if (lowerLimit <0) {
     147           0 :     lowerLimit=0.0;
     148             :   }
     149           0 :   if (upperLimit < 0) {
     150           0 :     upperLimit = dmax;
     151           0 :     if (! (upperLimit < std::numeric_limits<double>::max())) {
     152           0 :       upperLimit = 2*r0;
     153             :     }
     154             :   }
     155           0 :   if(centerrange>0) {
     156           0 :     upperLimit=(1.0+centerrange*PLMD::epsilon)*r0;
     157           0 :     lowerLimit=(1.0-centerrange*PLMD::epsilon)*r0;
     158             :   }
     159           0 :   const double step = [=]() {
     160           0 :     if(r0 > lowerLimit && r0< upperLimit) {
     161             :       //this will make the step pass trough r0
     162           0 :       double interval = (r0-lowerLimit)/(upperLimit-lowerLimit);
     163           0 :       return  (r0-lowerLimit)/(interval *Nsteps);
     164             :     }
     165           0 :     return (upperLimit-lowerLimit)/double(Nsteps);
     166           0 :   }();
     167           0 :   if (step <0.0) {
     168           0 :     error("I calculated a negative step");
     169             :   }
     170             : 
     171             :   //finally doing the job
     172             :   //descriptions starts with the values of "r_0"
     173           0 :   std::cout <<"#r val dfunc ( r_0="<<switchingFunction.description()<<")\n";
     174           0 :   double x=lowerLimit;
     175           0 :   while(x < upperLimit) {
     176           0 :     double dfunc=0.0;
     177             :     double res;
     178           0 :     if(dontOptimize) {
     179           0 :       res=switchingFunction.calculate(x,dfunc);
     180             :     } else {
     181           0 :       res=switchingFunction.calculateSqr(x*x,dfunc);
     182             :     }
     183           0 :     std::cout << std::setprecision(plotPrecision) << x << "\t"
     184           0 :               << std::setprecision(plotPrecision) << res << "\t"
     185           0 :               << std::setprecision(plotPrecision) << dfunc << '\n';
     186           0 :     x+=step;
     187             :   }
     188           0 :   return 0;
     189             : }
     190             : 
     191             : } //namespace cltools
     192             : } // namespace PLMD

Generated by: LCOV version 1.16