LCOV - code coverage report
Current view: top level - core - Action.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 120 155 77.4 %
Date: 2019-08-13 10:39:37 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        1607 : Keywords ActionOptions::emptyKeys;
      34             : 
      35        5260 : ActionOptions::ActionOptions(PlumedMain&p,const std::vector<std::string>&l):
      36             :   plumed(p),
      37             :   line(l),
      38        5260 :   keys(emptyKeys)
      39             : {
      40        5260 : }
      41             : 
      42        5258 : ActionOptions::ActionOptions(const ActionOptions&ao,const Keywords&keys):
      43             :   plumed(ao.plumed),
      44             :   line(ao.line),
      45        5258 :   keys(keys)
      46             : {
      47        5258 : }
      48             : 
      49        5477 : void Action::registerKeywords( Keywords& keys ) {
      50        5477 :   plumed_assert( keys.size()==0 );
      51        5477 :   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        5477 :   keys.reserve("optional","UPDATE_FROM","Only update this action from this time");
      53        5477 :   keys.reserve("optional","UPDATE_UNTIL","Only update this action until this time");
      54        5477 :   keys.reserve("optional","RESTART","allows per-action setting of restart (YES/NO/AUTO)");
      55        5477 : }
      56             : 
      57        5258 : Action::Action(const ActionOptions&ao):
      58        5258 :   name(ao.line[0]),
      59             :   line(ao.line),
      60        5258 :   update_from(std::numeric_limits<double>::max()),
      61        5258 :   update_until(std::numeric_limits<double>::max()),
      62             :   active(false),
      63        5258 :   restart(ao.plumed.getRestart()),
      64        5258 :   doCheckPoint(ao.plumed.getCPT()),
      65             :   plumed(ao.plumed),
      66        5258 :   log(plumed.getLog()),
      67             :   comm(plumed.comm),
      68             :   multi_sim_comm(plumed.multi_sim_comm),
      69       36807 :   keywords(ao.keys)
      70             : {
      71        5258 :   line.erase(line.begin());
      72        5258 :   log.printf("Action %s\n",name.c_str());
      73             : 
      74        5258 :   if(comm.Get_rank()==0) {
      75        4263 :     replica_index=multi_sim_comm.Get_rank();
      76             :   }
      77        5258 :   comm.Bcast(replica_index,0);
      78             : 
      79        5258 :   if ( keywords.exists("LABEL") ) { parse("LABEL",label); }
      80             : 
      81        5258 :   if(label.length()==0) {
      82        1695 :     std::string s; Tools::convert(plumed.getActionSet().size(),s);
      83        1695 :     label="@"+s;
      84             :   }
      85        5258 :   if( plumed.getActionSet().selectWithLabel<Action*>(label) ) error("label " + label + " has been already used");
      86        5258 :   log.printf("  with label %s\n",label.c_str());
      87        5258 :   if ( keywords.exists("UPDATE_FROM") ) parse("UPDATE_FROM",update_from);
      88        5258 :   if(update_from!=std::numeric_limits<double>::max()) log.printf("  only update from time %f\n",update_from);
      89        5258 :   if ( keywords.exists("UPDATE_UNTIL") ) parse("UPDATE_UNTIL",update_until);
      90        5258 :   if(update_until!=std::numeric_limits<double>::max()) log.printf("  only update until time %f\n",update_until);
      91        5258 :   if ( keywords.exists("RESTART") ) {
      92        1260 :     std::string srestart="AUTO";
      93        1260 :     parse("RESTART",srestart);
      94        1260 :     if(srestart=="YES") restart=true;
      95        1221 :     else if(srestart=="NO")  restart=false;
      96        1219 :     else if(srestart=="AUTO") {}
      97           2 :     else error("RESTART should be either YES, NO, or AUTO");
      98             :   }
      99        5257 : }
     100             : 
     101       10514 : Action::~Action() {
     102        5257 :   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        5257 : }
     106             : 
     107          39 : FILE* Action::fopen(const char *path, const char *mode) {
     108          39 :   bool write(false);
     109          39 :   for(const char*p=mode; *p; p++) if(*p=='w' || *p=='a' || *p=='+') write=true;
     110             :   FILE* fp;
     111          39 :   if(write && comm.Get_rank()!=0) fp=plumed.fopen("/dev/null",mode);
     112          39 :   else      fp=plumed.fopen(path,mode);
     113          39 :   files.insert(fp);
     114          39 :   return fp;
     115             : }
     116             : 
     117          39 : int Action::fclose(FILE*fp) {
     118          39 :   files.erase(fp);
     119          39 :   return plumed.fclose(fp);
     120             : }
     121             : 
     122        7041 : void Action::fflush() {
     123        7041 :   for(const auto & p : files) {
     124           0 :     std::fflush(p);
     125             :   }
     126        7041 : }
     127             : 
     128          28 : std::string Action::getKeyword(const std::string& key) {
     129             :   // Check keyword has been registered
     130          28 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
     131             : 
     132          28 :   std::string outkey;
     133          28 :   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       14011 : void Action::parseFlag(const std::string&key,bool & t) {
     147             :   // Check keyword has been registered
     148       14011 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
     149             :   // Check keyword is a flag
     150       14011 :   if(!keywords.style(key,"nohtml")) {
     151       14011 :     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       14011 :   if(!Tools::parseFlag(line,key,t)) {
     156       13101 :     if( keywords.style(key,"nohtml") || keywords.style(key,"vessel") ) {
     157        2399 :       t=false;
     158       10702 :     } 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       14011 : }
     164             : 
     165       24088 : void Action::addDependency(Action*action) {
     166       24088 :   after.push_back(action);
     167       24088 : }
     168             : 
     169      378255 : 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      378255 :   if(!active) {
     175      190097 :     this->unlockRequests();
     176      190097 :     prepare();
     177      190097 :     this->lockRequests();
     178      566413 :   } else return;
     179      190097 :   for(const auto & p : after) p->activate();
     180      190097 :   active=true;
     181             : }
     182             : 
     183         594 : void Action::setOption(const std::string &s) {
     184             : // This overloads the action and activate some options
     185         594 :   options.insert(s);
     186         594 :   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           0 :   options.clear();
     192           0 : }
     193             : 
     194             : 
     195        5280 : void Action::clearDependencies() {
     196        5280 :   after.clear();
     197        5280 : }
     198             : 
     199           0 : std::string Action::getDocumentation()const {
     200           0 :   return std::string("UNDOCUMENTED ACTION");
     201             : }
     202             : 
     203       10031 : void Action::checkRead() {
     204       10031 :   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       10031 : }
     213             : 
     214     1144455 : long int Action::getStep()const {
     215     1144455 :   return plumed.getStep();
     216             : }
     217             : 
     218      930502 : double Action::getTime()const {
     219      930502 :   return plumed.getAtoms().getTimeStep()*getStep();
     220             : }
     221             : 
     222        4996 : double Action::getTimeStep()const {
     223        4996 :   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      153911 : void Action::prepare() {
     237      153911 :   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          30 :   plumed_merror("ERROR in input to action " + name + " with label " + label + " : " + msg );
     243             : }
     244             : 
     245         238 : void Action::warning( const std::string & msg ) {
     246         238 :   log.printf("WARNING for action %s with label %s : %s \n", name.c_str(), label.c_str(), msg.c_str() );
     247         238 : }
     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       13718 : bool Action::getExchangeStep()const {
     262       13718 :   return plumed.getExchangeStep();
     263             : }
     264             : 
     265          12 : std::string Action::cite(const std::string&s) {
     266          12 :   return plumed.cite(s);
     267             : }
     268             : 
     269             : /// Check if action should be updated.
     270      186953 : bool Action::checkUpdate()const {
     271      186953 :   double t=getTime();
     272      186953 :   if(t<update_until && (update_from==std::numeric_limits<double>::max() || t>=update_from)) return true;
     273         510 :   else return false;
     274             : }
     275             : 
     276         772 : bool Action::getCPT()const {
     277         772 :   return plumed.getCPT();
     278             : }
     279             : 
     280        4821 : }
     281             : 

Generated by: LCOV version 1.13