LCOV - code coverage report
Current view: top level - core - Action.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 111 145 76.6 %
Date: 2019-08-13 10:15:31 Functions: 27 33 81.8 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-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 "Action.h"
      23             : #include "ActionWithValue.h"
      24             : #include "PlumedMain.h"
      25             : #include "tools/Log.h"
      26             : #include "tools/Exception.h"
      27             : #include "Atoms.h"
      28             : #include "ActionSet.h"
      29             : #include <iostream>
      30             : 
      31             : namespace PLMD {
      32             : 
      33        1958 : Keywords ActionOptions::emptyKeys;
      34             : 
      35        6228 : ActionOptions::ActionOptions(PlumedMain&p,const std::vector<std::string>&l):
      36             :   plumed(p),
      37             :   line(l),
      38        6228 :   keys(emptyKeys)
      39             : {
      40        6228 : }
      41             : 
      42        6226 : ActionOptions::ActionOptions(const ActionOptions&ao,const Keywords&keys):
      43             :   plumed(ao.plumed),
      44             :   line(ao.line),
      45        6226 :   keys(keys)
      46             : {
      47        6226 : }
      48             : 
      49        6492 : void Action::registerKeywords( Keywords& keys ) {
      50        6492 :   plumed_assert( keys.size()==0 );
      51       25968 :   keys.add( "hidden", "LABEL", "a label for the action so that its output can be referenced in the input to other actions.  Actions with scalar output are referenced using their label only.  Actions with vector output must have a separate label for every component.  Individual componets are then refered to using label.component" );
      52       25968 :   keys.reserve("optional","UPDATE_FROM","Only update this action from this time");
      53       25968 :   keys.reserve("optional","UPDATE_UNTIL","Only update this action until this time");
      54       25968 :   keys.reserve("optional","RESTART","allows per-action setting of restart (YES/NO/AUTO)");
      55        6492 : }
      56             : 
      57        6226 : Action::Action(const ActionOptions&ao):
      58             :   name(ao.line[0]),
      59             :   line(ao.line),
      60             :   update_from(std::numeric_limits<double>::max()),
      61             :   update_until(std::numeric_limits<double>::max()),
      62             :   active(false),
      63        6226 :   restart(ao.plumed.getRestart()),
      64        6226 :   doCheckPoint(ao.plumed.getCPT()),
      65             :   plumed(ao.plumed),
      66        6226 :   log(plumed.getLog()),
      67             :   comm(plumed.comm),
      68             :   multi_sim_comm(plumed.multi_sim_comm),
      69       49809 :   keywords(ao.keys)
      70             : {
      71        6226 :   line.erase(line.begin());
      72        6226 :   log.printf("Action %s\n",name.c_str());
      73             : 
      74        6226 :   if(comm.Get_rank()==0) {
      75        5136 :     replica_index=multi_sim_comm.Get_rank();
      76             :   }
      77        6226 :   comm.Bcast(replica_index,0);
      78             : 
      79       18520 :   if ( keywords.exists("LABEL") ) { parse("LABEL",label); }
      80             : 
      81        6226 :   if(label.length()==0) {
      82        4042 :     std::string s; Tools::convert(plumed.getActionSet().size(),s);
      83        4042 :     label="@"+s;
      84             :   }
      85       12452 :   if( plumed.getActionSet().selectWithLabel<Action*>(label) ) error("label " + label + " has been already used");
      86        6226 :   log.printf("  with label %s\n",label.c_str());
      87       13858 :   if ( keywords.exists("UPDATE_FROM") ) parse("UPDATE_FROM",update_from);
      88        6226 :   if(update_from!=std::numeric_limits<double>::max()) log.printf("  only update from time %f\n",update_from);
      89       13858 :   if ( keywords.exists("UPDATE_UNTIL") ) parse("UPDATE_UNTIL",update_until);
      90        6226 :   if(update_until!=std::numeric_limits<double>::max()) log.printf("  only update until time %f\n",update_until);
      91       12453 :   if ( keywords.exists("RESTART") ) {
      92        1468 :     std::string srestart="AUTO";
      93        2935 :     parse("RESTART",srestart);
      94        1467 :     if(srestart=="YES") restart=true;
      95        1398 :     else if(srestart=="NO")  restart=false;
      96        1396 :     else if(srestart=="AUTO") {}
      97           2 :     else error("RESTART should be either YES, NO, or AUTO");
      98             :   }
      99        6225 : }
     100             : 
     101       12450 : Action::~Action() {
     102        6225 :   if(files.size()!=0) {
     103           0 :     std::cerr<<"WARNING: some files open in action "+getLabel()+" where not properly closed. This could lead to data loss!!\n";
     104             :   }
     105        6225 : }
     106             : 
     107          73 : FILE* Action::fopen(const char *path, const char *mode) {
     108             :   bool write(false);
     109          73 :   for(const char*p=mode; *p; p++) if(*p=='w' || *p=='a' || *p=='+') write=true;
     110             :   FILE* fp;
     111          73 :   if(write && comm.Get_rank()!=0) fp=plumed.fopen("/dev/null",mode);
     112          73 :   else      fp=plumed.fopen(path,mode);
     113             :   files.insert(fp);
     114          73 :   return fp;
     115             : }
     116             : 
     117          91 : int Action::fclose(FILE*fp) {
     118             :   files.erase(fp);
     119          91 :   return plumed.fclose(fp);
     120             : }
     121             : 
     122        9935 : void Action::fflush() {
     123       19870 :   for(const auto & p : files) {
     124           0 :     std::fflush(p);
     125             :   }
     126        9935 : }
     127             : 
     128          29 : std::string Action::getKeyword(const std::string& key) {
     129             :   // Check keyword has been registered
     130          29 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
     131             : 
     132             :   std::string outkey;
     133          29 :   if( Tools::getKey(line,key,outkey ) ) return key + outkey;
     134             : 
     135           0 :   if( keywords.style(key,"compulsory") ) {
     136           0 :     if( keywords.getDefaultValue(key,outkey) ) {
     137           0 :       if( outkey.length()==0 ) error("keyword " + key + " has weird default value");
     138           0 :       return key + "=" +  outkey;
     139             :     } else {
     140           0 :       error("keyword " + key + " is compulsory for this action");
     141             :     }
     142             :   }
     143           0 :   return "";
     144             : }
     145             : 
     146       17176 : void Action::parseFlag(const std::string&key,bool & t) {
     147             :   // Check keyword has been registered
     148       17176 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
     149             :   // Check keyword is a flag
     150       34352 :   if(!keywords.style(key,"nohtml")) {
     151       49006 :     plumed_massert( keywords.style(key,"vessel") || keywords.style(key,"flag") || keywords.style(key,"hidden"), "keyword " + key + " is not a flag");
     152             :   }
     153             : 
     154             :   // Read in the flag otherwise get the default value from the keywords object
     155       17176 :   if(!Tools::parseFlag(line,key,t)) {
     156       47850 :     if( keywords.style(key,"nohtml") || keywords.style(key,"vessel") ) {
     157        2522 :       t=false;
     158       26856 :     } else if ( !keywords.getLogicalDefault(key,t) ) {
     159           0 :       log.printf("ERROR in action %s with label %s : flag %s has no default",name.c_str(),label.c_str(),key.c_str() );
     160           0 :       plumed_error();
     161             :     }
     162             :   }
     163       17176 : }
     164             : 
     165       25790 : void Action::addDependency(Action*action) {
     166       25790 :   after.push_back(action);
     167       25790 : }
     168             : 
     169      815505 : void Action::activate() {
     170             : // preparation step is called only the first time an Action is activated.
     171             : // since it could change its dependences (e.g. in an ActionAtomistic which is
     172             : // accessing to a virtual atom), this is done just before dependencies are
     173             : // activated
     174      815505 :   if(!active) {
     175      456102 :     this->unlockRequests();
     176      456102 :     prepare();
     177      456102 :     this->lockRequests();
     178      815505 :   } else return;
     179     1434668 :   for(const auto & p : after) p->activate();
     180      456102 :   active=true;
     181             : }
     182             : 
     183         594 : void Action::setOption(const std::string &s) {
     184             : // This overloads the action and activate some options
     185             :   options.insert(s);
     186        1587 :   for(const auto & p : after) p->setOption(s);
     187         594 : }
     188             : 
     189           0 : void Action::clearOptions() {
     190             : // This overloads the action and activate some options
     191             :   options.clear();
     192           0 : }
     193             : 
     194             : 
     195        6201 : void Action::clearDependencies() {
     196             :   after.clear();
     197        6201 : }
     198             : 
     199           0 : std::string Action::getDocumentation()const {
     200           0 :   return std::string("UNDOCUMENTED ACTION");
     201             : }
     202             : 
     203       11778 : void Action::checkRead() {
     204       11778 :   if(!line.empty()) {
     205           0 :     std::string msg="cannot understand the following words from the input line : ";
     206           0 :     for(unsigned i=0; i<line.size(); i++) {
     207           0 :       if(i>0) msg = msg + ", ";
     208           0 :       msg = msg + line[i];
     209             :     }
     210           0 :     error(msg);
     211             :   }
     212       11778 : }
     213             : 
     214     1995619 : long int Action::getStep()const {
     215     3991238 :   return plumed.getStep();
     216             : }
     217             : 
     218     1370523 : double Action::getTime()const {
     219     2741046 :   return plumed.getAtoms().getTimeStep()*getStep();
     220             : }
     221             : 
     222       16159 : double Action::getTimeStep()const {
     223       32318 :   return plumed.getAtoms().getTimeStep();
     224             : }
     225             : 
     226             : 
     227             : 
     228           0 : void Action::exit(int c) {
     229           0 :   plumed.exit(c);
     230           0 : }
     231             : 
     232           0 : void Action::calculateNumericalDerivatives( ActionWithValue* a ) {
     233           0 :   plumed_merror("if you get here it means that you are trying to use numerical derivatives for a class that does not implement them");
     234             : }
     235             : 
     236      313565 : void Action::prepare() {
     237      313565 :   return;
     238             : }
     239             : 
     240          30 : void Action::error( const std::string & msg ) const {
     241          30 :   log.printf("ERROR in input to action %s with label %s : %s \n \n", name.c_str(), label.c_str(), msg.c_str() );
     242         240 :   plumed_merror("ERROR in input to action " + name + " with label " + label + " : " + msg );
     243             : }
     244             : 
     245         153 : void Action::warning( const std::string & msg ) {
     246         153 :   log.printf("WARNING for action %s with label %s : %s \n", name.c_str(), label.c_str(), msg.c_str() );
     247         153 : }
     248             : 
     249           0 : void Action::calculateFromPDB( const PDB& pdb ) {
     250           0 :   activate();
     251           0 :   for(const auto & p : after) {
     252           0 :     ActionWithValue*av=dynamic_cast<ActionWithValue*>(p);
     253           0 :     if(av) { av->clearInputForces(); av->clearDerivatives(); }
     254           0 :     p->readAtomsFromPDB( pdb );
     255           0 :     p->calculate();
     256             :   }
     257           0 :   readAtomsFromPDB( pdb );
     258           0 :   calculate();
     259           0 : }
     260             : 
     261       27689 : bool Action::getExchangeStep()const {
     262       55378 :   return plumed.getExchangeStep();
     263             : }
     264             : 
     265          24 : std::string Action::cite(const std::string&s) {
     266          24 :   return plumed.cite(s);
     267             : }
     268             : 
     269             : /// Check if action should be updated.
     270      448251 : bool Action::checkUpdate()const {
     271      448251 :   double t=getTime();
     272      448251 :   if(t<update_until && (update_from==std::numeric_limits<double>::max() || t>=update_from)) return true;
     273         510 :   else return false;
     274             : }
     275             : 
     276         976 : bool Action::getCPT()const {
     277        1952 :   return plumed.getCPT();
     278             : }
     279             : 
     280        5874 : }
     281             : 

Generated by: LCOV version 1.14