LCOV - code coverage report
Current view: top level - generic - UpdateIf.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 43 43 100.0 %
Date: 2020-11-18 11:20:57 Functions: 13 15 86.7 %

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

Generated by: LCOV version 1.13