LCOV - code coverage report
Current view: top level - gridtools - EvaluateFunctionOnGrid.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 35 39 89.7 %
Date: 2026-11-05 10:19:04 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2016-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 "core/ActionRegister.h"
      23             : #include "function/FunctionShortcut.h"
      24             : #include "function/FunctionOfScalar.h"
      25             : #include "function/FunctionOfVector.h"
      26             : #include "EvaluateGridFunction.h"
      27             : #include "ActionWithGrid.h"
      28             : 
      29             : //+PLUMEDOC GRIDANALYSIS EVALUATE_FUNCTION_FROM_GRID
      30             : /*
      31             : Calculate the function stored on the input grid at an arbitrary point
      32             : 
      33             : This action can be used to evaluate a function that is stored on a grid at an arbitrary point in space via interpolation. For example, the
      34             : following input illustrates how you can use this action to evaulate the square of the distance between atom 1 and atom 2
      35             : 
      36             : ```plumed
      37             : d2: REFERENCE_GRID GRID_MIN=0 GRID_MAX=10 GRID_BIN=20 FUNC=d1*d1 VAR=d1 PERIODIC=NO
      38             : d1: DISTANCE ATOMS=1,2
      39             : ff: EVALUATE_FUNCTION_FROM_GRID GRID=d2
      40             : PRINT ARG=d1,ff FILE=colvar
      41             : ```
      42             : 
      43             : You can perform the same calculation using [CUSTOM](CUSTOM.md), which will do the calculation exactly and not perform any interpolation. However,
      44             : if for some reason you only have the values of the function at a grid of point EVALUATE_FUNCTION_FROM_GRID may be a useful alternative as you can
      45             : use [REFERENCE_GRID](REFERENCE_GRID.md) to read in the values of the function at your grid of point from a file as shown below:
      46             : 
      47             : ```plumed
      48             : #SETTINGS INPUTFILES=regtest/gridtools/rt-weights-integral/kde.grid
      49             : 
      50             : ff: REFERENCE_GRID FILE=regtest/gridtools/rt-weights-integral/kde.grid VALUE=h
      51             : aa: ANGLE ATOMS=1,2,3
      52             : tt: TORSION ATOMS=1,2,3,4
      53             : val: EVALUATE_FUNCTION_FROM_GRID ...
      54             :   GRID=ff INTERPOLATION_TYPE=spline
      55             :   ZERO_OUTSIDE_GRID_RANGE
      56             : ...
      57             : PRINT ARG=aa,tt,val FILE=colvar
      58             : ```
      59             : 
      60             : Notice that the ARG command does not need to be used with the EVALUATE_FUNCTION_FROM_GRID command to specify the labels of the input arguments at which you
      61             : would like the function to be evaluated.  Instead, you only specify the GRID that is being used as input for the interpolation.  The reason that it is not
      62             : necessary to specify the arguments is that PLUMED stores labels for each coordinate axis of a grid.  These labels appear at the top of the
      63             : columns that contain the grid points when you output grids using [DUMPGRID](DUMPGRID.md). Furthermore, in the first of the inputs above the labels of these
      64             : input arguments are specified using the VAR option for [REFERENCE_GRID](REFERENCE_GRID.md). Meanwhile, for the second  the titles of the columsn are
      65             : read in from the input file.  Consequently, PLUMED searches for a value named `d1` when evaluating `ff` in the first input.  For the second input it searches
      66             : for values labelled `aa` and `tt` and evaluates `val` from them.  You can, however, also use an ARG keyword in the input file as illustrated below if this helps
      67             : you to remember what precisely is being evluated:
      68             : 
      69             : ```plumed
      70             : d2: REFERENCE_GRID GRID_MIN=0 GRID_MAX=10 GRID_BIN=20 FUNC=d1*d1 VAR=d1 PERIODIC=NO
      71             : d1: DISTANCE ATOMS=1,2
      72             : ff: EVALUATE_FUNCTION_FROM_GRID GRID=d2 ARG=d1
      73             : PRINT ARG=d1,ff FILE=colvar
      74             : ```
      75             : 
      76             : Notice that input the inputs above the input values are scalars.  The output from EVALUATE_FUNCTION_FROM_GRID is thus also a scalar.  If, however, one uses an
      77             : input such as the one shown below:
      78             : 
      79             : ```plumed
      80             : #SETTINGS INPUTFILES=regtest/gridtools/rt-weights-integral/kde.grid
      81             : 
      82             : ff: REFERENCE_GRID FILE=regtest/gridtools/rt-weights-integral/kde.grid VALUE=h
      83             : aa: ANGLE ATOMS1=1,2,3 ATOMS2=4,5,6 ATOMS3=7,8,9
      84             : tt: TORSION ATOMS1=1,2,3,4 ATOMS2=5,6,7,8 ATOMS3=9,10,11,12
      85             : val: EVALUATE_FUNCTION_FROM_GRID GRID=ff
      86             : PRINT ARG=aa,tt,val FILE=colvar
      87             : ```
      88             : 
      89             : The value, `val`, that is output by the EVALUATE_FUNCTION_FROM_GRID action will be a vector.  In other words, in the same way you can use scalars, vectors, matrices and even
      90             : functions on grids in the input to the [CUSTOM](CUSTOM.md) command you can also use scalars, vectors, matrices and functions on grid in the input to the EVALUATE_FUNCTION_FROM_GRID
      91             : command.
      92             : 
      93             : ## The MASK keyword
      94             : 
      95             : If the input to this action is a vector you can use the MASK keyword as illustrated below:
      96             : 
      97             : ```plumed
      98             : #SETTINGS INPUTFILES=regtest/gridtools/rt-weights-integral/kde.grid
      99             : 
     100             : ff: REFERENCE_GRID FILE=regtest/gridtools/rt-weights-integral/kde.grid VALUE=h
     101             : d: DISTANCE ATOMS1=1,2 ATOMS2=4,5 ATOMS3=7,8
     102             : m: LESS_THAN ARG=d SWITCH={CUSTOM R_0=1 FUNC=step(0.1-x)}
     103             : aa: ANGLE ATOMS1=1,2,3 ATOMS2=4,5,6 ATOMS3=7,8,9
     104             : tt: TORSION ATOMS1=1,2,3,4 ATOMS2=5,6,7,8 ATOMS3=9,10,11,12
     105             : val: EVALUATE_FUNCTION_FROM_GRID GRID=ff MASK=m
     106             : prod: CUSTOM ARG=m,val FUNC=x*y PERIODIC=NO
     107             : sum: SUM ARG=prod PERIODIC=NO
     108             : PRINT ARG=sum FILE=colvar
     109             : ```
     110             : 
     111             : This input calculates the function of the angles and torsions that is provided in the input grid file for the three pairs of input angles and torsions.  The sum of these quantities
     112             : is then computed.  Importantly, however, each of the evaluated values of the function is only added to the final sum if the corresponding distance that is calculated by the [DISTANCE](DISTANCE.md)
     113             : action with label `d` is less than 0.1 nm.
     114             : 
     115             : */
     116             : //+ENDPLUMEDOC
     117             : 
     118             : namespace PLMD {
     119             : namespace gridtools {
     120             : 
     121             : class EvaluateFunctionOnGrid : public ActionShortcut {
     122             : public:
     123             :   static void registerKeywords(Keywords&);
     124             :   explicit EvaluateFunctionOnGrid(const ActionOptions&);
     125             : };
     126             : 
     127             : PLUMED_REGISTER_ACTION(EvaluateFunctionOnGrid,"EVALUATE_FUNCTION_FROM_GRID")
     128             : typedef function::FunctionOfScalar<EvaluateGridFunction> ScalarEvalGrid;
     129             : PLUMED_REGISTER_ACTION(ScalarEvalGrid,"EVALUATE_FUNCTION_FROM_GRID_SCALAR")
     130             : typedef function::FunctionOfVector<EvaluateGridFunction> VectorEvalGrid;
     131             : PLUMED_REGISTER_ACTION(VectorEvalGrid,"EVALUATE_FUNCTION_FROM_GRID_VECTOR")
     132             : 
     133          10 : void EvaluateFunctionOnGrid::registerKeywords(Keywords& keys ) {
     134          10 :   ActionShortcut::registerKeywords( keys );
     135          20 :   keys.addInputKeyword("compulsory","GRID","grid","the name of the grid that we are using to evaluate the function");
     136          20 :   keys.addInputKeyword("optional","ARG","scalar/vector","the arguments that you would like to use when evaluating the function.  If not specified these are determined from the names of the grid dimensions");
     137          10 :   keys.reserve("compulsory","PERIODIC","if the output of your function is periodic then you should specify the periodicity of the function.  If the output is not periodic you must state this using PERIODIC=NO");
     138          20 :   keys.addInputKeyword("optional","MASK","vector/matrix","the label for a sparse vector/matrix that should be used to determine which elements of the vector/matrix should be computed");
     139             :   EvaluateGridFunction ii;
     140          10 :   ii.registerKeywords( keys );
     141          10 :   keys.addActionNameSuffix("_SCALAR");
     142          20 :   keys.addActionNameSuffix("_VECTOR");
     143          10 : }
     144             : 
     145           6 : EvaluateFunctionOnGrid::EvaluateFunctionOnGrid(const ActionOptions&ao):
     146             :   Action(ao),
     147           6 :   ActionShortcut(ao) {
     148             :   // Get the grid that we are evaluating here
     149           6 :   std::vector<std::string> gridn(1);
     150           6 :   parse("GRID",gridn[0]);
     151           6 :   std::vector<Value*> gridv;
     152           6 :   ActionWithArguments::interpretArgumentList( gridn, plumed.getActionSet(), this, gridv );
     153             :   // Read the input arguments from the input file
     154           6 :   std::vector<std::string> argn;
     155          12 :   parseVector("ARG",argn);
     156             :   // Now get the arguments
     157           6 :   ActionWithGrid* ag = dynamic_cast<ActionWithGrid*>( gridv[0]->getPntrToAction() );
     158           6 :   if( !ag ) {
     159           0 :     error("argument to GRID argument is not a grid");
     160             :   }
     161           6 :   if( argn.size()==0 ) {
     162           3 :     std::vector<std::string> argn2( ag->getGridCoordinateNames() );
     163           3 :     argn.resize( argn2.size() );
     164           7 :     for(unsigned i=0; i<argn2.size(); ++i) {
     165             :       argn[i]=argn2[i];
     166             :     }
     167           3 :   }
     168           6 :   if( argn.size()!=gridv[0]->getRank() ) {
     169           0 :     error("found wrong number of arguments in Evaluate function on grid");
     170             :   }
     171             :   // Now use this information to create a gridobject
     172           6 :   if( ag->getGridCoordinatesObject().getGridType()=="fibonacci" ) {
     173           0 :     error("cannot interpolate on fibonacci sphere");
     174             :   }
     175             :   // Now get the actual values we are using
     176           6 :   std::vector<Value*> vals;
     177           6 :   ActionWithArguments::interpretArgumentList( argn, plumed.getActionSet(), this, vals );
     178           6 :   if( vals.size()==0 ) {
     179           0 :     error("found no input arguments to function");
     180             :   }
     181           6 :   std::string allargs = gridn[0];
     182          16 :   for(unsigned i=0; i<argn.size(); ++i) {
     183          20 :     allargs += "," + argn[i];
     184             :   }
     185           6 :   function::FunctionShortcut<int>::createAction( this, vals, allargs );
     186          12 : }
     187             : 
     188             : 
     189             : }
     190             : }

Generated by: LCOV version 1.16