LCOV - code coverage report
Current view: top level - core - Action.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 113 147 76.9 %
Date: 2020-11-18 11:20:57 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        1613 : Keywords ActionOptions::emptyKeys;
      34             : 
      35        5280 : ActionOptions::ActionOptions(PlumedMain&p,const std::vector<std::string>&l):
      36             :   plumed(p),
      37             :   line(l),
      38        5280 :   keys(emptyKeys)
      39             : {
      40        5280 : }
      41             : 
      42        5278 : ActionOptions::ActionOptions(const ActionOptions&ao,const Keywords&keys):
      43        5278 :   plumed(ao.plumed),
      44             :   line(ao.line),
      45        5278 :   keys(keys)
      46             : {
      47        5278 : }
      48             : 
      49        5497 : void Action::registerKeywords( Keywords& keys ) {
      50        5497 :   plumed_assert( keys.size()==0 );
      51       21988 :   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       21988 :   keys.reserve("optional","UPDATE_FROM","Only update this action from this time");
      53       21988 :   keys.reserve("optional","UPDATE_UNTIL","Only update this action until this time");
      54       21988 :   keys.reserve("optional","RESTART","allows per-action setting of restart (YES/NO/AUTO)");
      55        5497 : }
      56             : 
      57        5278 : 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        5278 :   restart(ao.plumed.getRestart()),
      64        5278 :   doCheckPoint(ao.plumed.getCPT()),
      65        5278 :   plumed(ao.plumed),
      66        5278 :   log(plumed.getLog()),
      67        5278 :   comm(plumed.comm),
      68        5278 :   multi_sim_comm(plumed.multi_sim_comm),
      69       52781 :   keywords(ao.keys)
      70             : {
      71             :   line.erase(line.begin());
      72       10556 :   log.printf("Action %s\n",name.c_str());
      73             : 
      74        5278 :   if(comm.Get_rank()==0) {
      75        4283 :     replica_index=multi_sim_comm.Get_rank();
      76             :   }
      77        5278 :   comm.Bcast(replica_index,0);
      78             : 
      79       15707 :   if ( keywords.exists("LABEL") ) { parse("LABEL",label); }
      80             : 
      81        5278 :   if(label.length()==0) {
      82        3404 :     std::string s; Tools::convert(plumed.getActionSet().size(),s);
      83        3404 :     label="@"+s;
      84             :   }
      85       10557 :   if( plumed.getActionSet().selectWithLabel<Action*>(label) ) error("label " + label + " has been already used");
      86       10556 :   log.printf("  with label %s\n",label.c_str());
      87       11735 :   if ( keywords.exists("UPDATE_FROM") ) parse("UPDATE_FROM",update_from);
      88        5278 :   if(update_from!=std::numeric_limits<double>::max()) log.printf("  only update from time %f\n",update_from);
      89       11735 :   if ( keywords.exists("UPDATE_UNTIL") ) parse("UPDATE_UNTIL",update_until);
      90        5278 :   if(update_until!=std::numeric_limits<double>::max()) log.printf("  only update until time %f\n",update_until);
      91       10556 :   if ( keywords.exists("RESTART") ) {
      92        1263 :     std::string srestart="AUTO";
      93        2524 :     parse("RESTART",srestart);
      94        1262 :     if(srestart=="YES") restart=true;
      95        1223 :     else if(srestart=="NO")  restart=false;
      96        1221 :     else if(srestart=="AUTO") {}
      97           2 :     else error("RESTART should be either YES, NO, or AUTO");
      98             :   }
      99        5277 : }
     100             : 
     101       15831 : Action::~Action() {
     102        5277 :   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        5277 : }
     106             : 
     107          39 : FILE* Action::fopen(const char *path, const char *mode) {
     108             :   bool write(false);
     109          78 :   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             :   files.insert(fp);
     114          39 :   return fp;
     115             : }
     116             : 
     117          39 : int Action::fclose(FILE*fp) {
     118             :   files.erase(fp);
     119          39 :   return plumed.fclose(fp);
     120             : }
     121             : 
     122        7070 : void Action::fflush() {
     123        7070 :   for(const auto & p : files) {
     124           0 :     std::fflush(p);
     125             :   }
     126        7070 : }
     127             : 
     128          30 : std::string Action::getKeyword(const std::string& key) {
     129             :   // Check keyword has been registered
     130          30 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
     131             : 
     132             :   std::string outkey;
     133          30 :   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       14045 : void Action::parseFlag(const std::string&key,bool & t) {
     147             :   // Check keyword has been registered
     148       14045 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
     149             :   // Check keyword is a flag
     150       28090 :   if(!keywords.style(key,"nohtml")) {
     151       56180 :     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       14045 :   if(!Tools::parseFlag(line,key,t)) {
     156       39393 :     if( keywords.style(key,"nohtml") || keywords.style(key,"vessel") ) {
     157        2399 :       t=false;
     158       32196 :     } 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       14045 : }
     164             : 
     165       24102 : void Action::addDependency(Action*action) {
     166       24102 :   after.push_back(action);
     167       24102 : }
     168             : 
     169      378518 : 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      378518 :   if(!active) {
     175      190276 :     this->unlockRequests();
     176      190276 :     prepare();
     177      190276 :     this->lockRequests();
     178             :   } else return;
     179      495048 :   for(const auto & p : after) p->activate();
     180      190276 :   active=true;
     181             : }
     182             : 
     183         267 : void Action::setOption(const std::string &s) {
     184             : // This overloads the action and activate some options
     185             :   options.insert(s);
     186         448 :   for(const auto & p : after) p->setOption(s);
     187         267 : }
     188             : 
     189           0 : void Action::clearOptions() {
     190             : // This overloads the action and activate some options
     191             :   options.clear();
     192           0 : }
     193             : 
     194             : 
     195        5290 : void Action::clearDependencies() {
     196             :   after.clear();
     197        5290 : }
     198             : 
     199           0 : std::string Action::getDocumentation()const {
     200           0 :   return std::string("UNDOCUMENTED ACTION");
     201             : }
     202             : 
     203       10069 : void Action::checkRead() {
     204       10069 :   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       10069 : }
     213             : 
     214     1145151 : long int Action::getStep()const {
     215     2290302 :   return plumed.getStep();
     216             : }
     217             : 
     218      930728 : double Action::getTime()const {
     219     1861456 :   return plumed.getAtoms().getTimeStep()*getStep();
     220             : }
     221             : 
     222        4996 : double Action::getTimeStep()const {
     223        9992 :   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      154069 : void Action::prepare() {
     237      154069 :   return;
     238             : }
     239             : 
     240          30 : void Action::error( const std::string & msg ) const {
     241          60 :   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         238 : void Action::warning( const std::string & msg ) {
     246         476 :   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       27436 :   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      187132 : bool Action::checkUpdate()const {
     271      187132 :   double t=getTime();
     272      187132 :   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        1544 :   return plumed.getCPT();
     278             : }
     279             : 
     280        4839 : }
     281             : 

Generated by: LCOV version 1.13