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: 2018-12-19 07:49:13 Functions: 13 15 86.7 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2015-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/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             : \verbatim
      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             : \endverbatim
      77             : (See also \ref GROUP, \ref COORDINATION, and \ref DUMPATOMS)
      78             : 
      79             : */
      80             : //+ENDPLUMEDOC
      81             : 
      82             : class UpdateIf:
      83             :   public ActionPilot,
      84             :   public ActionWithArguments
      85             : {
      86             :   std::vector<double> lower;
      87             :   std::vector<double> upper;
      88             :   bool on;
      89             :   bool end;
      90             : public:
      91             :   void prepare();
      92             :   void calculate();
      93             :   void beforeUpdate();
      94             :   explicit UpdateIf(const ActionOptions&);
      95             :   static void registerKeywords(Keywords& keys);
      96          28 :   void apply() {}
      97             :   ~UpdateIf();
      98             : };
      99             : 
     100        2530 : PLUMED_REGISTER_ACTION(UpdateIf,"UPDATE_IF")
     101             : 
     102           8 : void UpdateIf::registerKeywords(Keywords& keys) {
     103           8 :   Action::registerKeywords(keys);
     104           8 :   ActionPilot::registerKeywords(keys);
     105           8 :   ActionWithArguments::registerKeywords(keys);
     106           8 :   keys.use("ARG");
     107           8 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
     108           8 :   keys.addFlag("END",false,"end");
     109           8 :   keys.add("optional","LESS_THAN","upper bound");
     110           8 :   keys.add("optional","MORE_THAN","lower bound");
     111           8 : }
     112             : 
     113           7 : UpdateIf::UpdateIf(const ActionOptions&ao):
     114             :   Action(ao),
     115             :   ActionPilot(ao),
     116             :   ActionWithArguments(ao),
     117             :   on(false),
     118           7 :   end(false)
     119             : {
     120           7 :   parseFlag("END",end);
     121           7 :   parseVector("LESS_THAN",upper);
     122           7 :   parseVector("MORE_THAN",lower);
     123           7 :   if(end && upper.size()!=0) error("END and LESS_THAN are not compatible");
     124           7 :   if(end && lower.size()!=0) error("END and MORE_THAN are not compatible");
     125           7 :   if(upper.size()==0) upper.assign(getNumberOfArguments(),+std::numeric_limits<double>::max());
     126           7 :   if(lower.size()==0) lower.assign(getNumberOfArguments(),-std::numeric_limits<double>::max());
     127           7 :   if(upper.size()!=getNumberOfArguments()) error("LESS_THAN should have the same size as ARG");
     128           7 :   if(lower.size()!=getNumberOfArguments()) error("MORE_THAN should have the same size as ARG");
     129          15 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
     130           8 :     log<<"  boundaries for argument "<<i<<"    "<<lower[i]<<" "<<upper[i]<<"\n";
     131             :   }
     132           7 :   checkRead();
     133           7 : }
     134             : 
     135          28 : void UpdateIf::prepare() {
     136          28 :   on=false;
     137          28 : }
     138             : 
     139          28 : void UpdateIf::calculate() {
     140          28 :   on=true;
     141          60 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
     142          32 :     if(getArgument(i)>=upper[i] || getArgument(i)<=lower[i]) on=false;
     143             :   }
     144          28 : }
     145             : 
     146          28 : void UpdateIf::beforeUpdate() {
     147          28 :   if(end) plumed.updateFlagsPop();
     148             :   else {
     149          16 :     if(on) plumed.updateFlagsPush(plumed.updateFlagsTop());
     150           9 :     else   plumed.updateFlagsPush(false);
     151             :   }
     152          28 : }
     153             : 
     154             : 
     155          21 : UpdateIf::~UpdateIf() {
     156          21 : }
     157             : 
     158             : }
     159             : 
     160             : 
     161        2523 : }

Generated by: LCOV version 1.13