LCOV - code coverage report
Current view: top level - generic - UpdateIf.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 42 42 100.0 %
Date: 2024-10-18 13:59:31 Functions: 8 10 80.0 %

          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             : #include "core/ActionPilot.h"
      23             : #include "core/ActionWithArguments.h"
      24             : #include "core/ActionRegister.h"
      25             : #include "core/PlumedMain.h"
      26             : 
      27             : namespace PLMD {
      28             : namespace generic {
      29             : 
      30             : //+PLUMEDOC PRINTANALYSIS UPDATE_IF
      31             : /*
      32             : Conditional update of other actions.
      33             : 
      34             : 
      35             : This action can be used to enable and disable the update step for the following actions
      36             : depending on the value of its arguments. This allows for example to extract snapshots
      37             : with value of some CVs in a given range.
      38             : 
      39             : When called with MORE_THAN and/or LESS_THAN keywords, this action starts an if block.
      40             : The block is executed if all the arguments are less than all the respective values
      41             : in the LESS_THAN keyword (if present) and all the arguments are more than all the
      42             : respective values
      43             : in the MORE_THAN keyword (if present).
      44             : 
      45             : When called with the END flag, this action ends the corresponding IF block.
      46             : Notice that in this case one should also provide the ARG keyword. It is recommended to
      47             : use the same ARG keyword that was used to begin the block, so as to make the input more readable.
      48             : 
      49             : Of course, blocks can be nested at will.
      50             : 
      51             : There are many potential usages for this keyword. One might e.g. decide to analyze some variable
      52             : only when another variable is within a given range.
      53             : 
      54             : \warning
      55             : Notice that not all the possible usage make
      56             : particular sense. For example, conditionally updating a \ref METAD keyword
      57             : (that is: adding hills only if a variable is within a given range)
      58             : can lead to unexpected results.
      59             : 
      60             : \par Examples
      61             : 
      62             : The following input instructs plumed dump all the snapshots where an atom is in touch with
      63             : the solute.
      64             : \plumedfile
      65             : solute: GROUP ATOMS=1-124
      66             : coord: COORDINATION GROUPA=solute GROUPB=500 R_0=0.5
      67             : 
      68             : # A coordination number higher than 0.5 indicate that there is at least one
      69             : # atom of group `solute` at less than 5 A from atom number 500
      70             : 
      71             : UPDATE_IF ARG=coord MORE_THAN=0.5
      72             : DUMPATOMS ATOMS=solute,500 FILE=output.xyz
      73             : UPDATE_IF ARG=coord END
      74             : \endplumedfile
      75             : 
      76             : */
      77             : //+ENDPLUMEDOC
      78             : 
      79             : class UpdateIf:
      80             :   public ActionPilot,
      81             :   public ActionWithArguments
      82             : {
      83             :   std::vector<double> lower;
      84             :   std::vector<double> upper;
      85             :   bool on;
      86             :   bool end;
      87             : public:
      88             :   void prepare() override;
      89             :   void calculate() override;
      90             :   void beforeUpdate() override;
      91             :   explicit UpdateIf(const ActionOptions&);
      92             :   static void registerKeywords(Keywords& keys);
      93          28 :   void apply() override {}
      94             :   ~UpdateIf();
      95             : };
      96             : 
      97             : PLUMED_REGISTER_ACTION(UpdateIf,"UPDATE_IF")
      98             : 
      99           9 : void UpdateIf::registerKeywords(Keywords& keys) {
     100           9 :   Action::registerKeywords(keys);
     101           9 :   ActionPilot::registerKeywords(keys);
     102           9 :   ActionWithArguments::registerKeywords(keys);
     103          18 :   keys.addInputKeyword("compulsory","ARG","scalar","the labels of values that should be used to make the decision on whether to update or not");
     104          18 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
     105          18 :   keys.addFlag("END",false,"end");
     106          18 :   keys.add("optional","LESS_THAN","upper bound");
     107          18 :   keys.add("optional","MORE_THAN","lower bound");
     108           9 : }
     109             : 
     110           7 : UpdateIf::UpdateIf(const ActionOptions&ao):
     111             :   Action(ao),
     112             :   ActionPilot(ao),
     113             :   ActionWithArguments(ao),
     114           7 :   on(false),
     115           7 :   end(false)
     116             : {
     117           7 :   parseFlag("END",end);
     118           7 :   parseVector("LESS_THAN",upper);
     119           7 :   parseVector("MORE_THAN",lower);
     120           7 :   if(end && upper.size()!=0) error("END and LESS_THAN are not compatible");
     121           7 :   if(end && lower.size()!=0) error("END and MORE_THAN are not compatible");
     122           7 :   if(upper.size()==0) upper.assign(getNumberOfArguments(),+std::numeric_limits<double>::max());
     123           7 :   if(lower.size()==0) lower.assign(getNumberOfArguments(),-std::numeric_limits<double>::max());
     124           7 :   if(upper.size()!=getNumberOfArguments()) error("LESS_THAN should have the same size as ARG");
     125           7 :   if(lower.size()!=getNumberOfArguments()) error("MORE_THAN should have the same size as ARG");
     126          15 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
     127           8 :     log<<"  boundaries for argument "<<i<<"    "<<lower[i]<<" "<<upper[i]<<"\n";
     128             :   }
     129           7 :   checkRead();
     130           7 : }
     131             : 
     132          28 : void UpdateIf::prepare() {
     133          28 :   on=false;
     134          28 : }
     135             : 
     136          28 : void UpdateIf::calculate() {
     137          28 :   on=true;
     138          60 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
     139          32 :     if(getArgument(i)>=upper[i] || getArgument(i)<=lower[i]) on=false;
     140             :   }
     141          28 : }
     142             : 
     143          28 : void UpdateIf::beforeUpdate() {
     144          28 :   if(end) plumed.updateFlagsPop();
     145             :   else {
     146          23 :     if(on) plumed.updateFlagsPush(plumed.updateFlagsTop());
     147           9 :     else   plumed.updateFlagsPush(false);
     148             :   }
     149          28 : }
     150             : 
     151             : 
     152          14 : UpdateIf::~UpdateIf() {
     153          14 : }
     154             : 
     155             : }
     156             : 
     157             : 
     158             : }

Generated by: LCOV version 1.16