LCOV - code coverage report
Current view: top level - core - Action.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 113 152 74.3 %
Date: 2018-12-19 07:49:13 Functions: 26 33 78.8 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-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 "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         841 : Keywords ActionOptions::emptyKeys;
      34             : 
      35        2347 : ActionOptions::ActionOptions(PlumedMain&p,const std::vector<std::string>&l):
      36             :   plumed(p),
      37             :   line(l),
      38        2347 :   keys(emptyKeys)
      39             : {
      40        2347 : }
      41             : 
      42        2347 : ActionOptions::ActionOptions(const ActionOptions&ao,const Keywords&keys):
      43             :   plumed(ao.plumed),
      44             :   line(ao.line),
      45        2347 :   keys(keys)
      46             : {
      47        2347 : }
      48             : 
      49        2507 : void Action::registerKeywords( Keywords& keys ) {
      50        2507 :   plumed_assert( keys.size()==0 );
      51        2507 :   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        2507 :   keys.reserve("optional","UPDATE_FROM","Only update this action from this time");
      53        2507 :   keys.reserve("optional","UPDATE_UNTIL","Only update this action until this time");
      54        2507 :   keys.reserve("optional","RESTART","allows per-action setting of restart (YES/NO/AUTO)");
      55        2507 : }
      56             : 
      57        2347 : Action::Action(const ActionOptions&ao):
      58        2347 :   name(ao.line[0]),
      59             :   line(ao.line),
      60        2347 :   update_from(std::numeric_limits<double>::max()),
      61        2347 :   update_until(std::numeric_limits<double>::max()),
      62             :   active(false),
      63        2347 :   restart(ao.plumed.getRestart()),
      64        2347 :   doCheckPoint(ao.plumed.getCPT()),
      65             :   plumed(ao.plumed),
      66        2347 :   log(plumed.getLog()),
      67             :   comm(plumed.comm),
      68             :   multi_sim_comm(plumed.multi_sim_comm),
      69       16429 :   keywords(ao.keys)
      70             : {
      71        2347 :   line.erase(line.begin());
      72        2347 :   log.printf("Action %s\n",name.c_str());
      73             : 
      74        2347 :   if ( keywords.exists("LABEL") ) { parse("LABEL",label); }
      75             : 
      76        2347 :   if(label.length()==0) {
      77         843 :     std::string s; Tools::convert(plumed.getActionSet().size(),s);
      78         843 :     label="@"+s;
      79             :   }
      80        2347 :   if( plumed.getActionSet().selectWithLabel<Action*>(label) ) error("label " + label + " has been already used");
      81        2347 :   log.printf("  with label %s\n",label.c_str());
      82        2347 :   if ( keywords.exists("UPDATE_FROM") ) parse("UPDATE_FROM",update_from);
      83        2347 :   if(update_from!=std::numeric_limits<double>::max()) log.printf("  only update from time %f\n",update_from);
      84        2347 :   if ( keywords.exists("UPDATE_UNTIL") ) parse("UPDATE_UNTIL",update_until);
      85        2347 :   if(update_until!=std::numeric_limits<double>::max()) log.printf("  only update until time %f\n",update_until);
      86        2347 :   if ( keywords.exists("RESTART") ) {
      87         649 :     std::string srestart="AUTO";
      88         649 :     parse("RESTART",srestart);
      89         649 :     if(srestart=="YES") restart=true;
      90         612 :     else if(srestart=="NO")  restart=false;
      91         610 :     else if(srestart=="AUTO") {}
      92           0 :     else error("RESTART should be either YES, NO, or AUTO");
      93             :   }
      94        2347 : }
      95             : 
      96        4694 : Action::~Action() {
      97        2347 :   if(files.size()!=0) {
      98           0 :     std::cerr<<"WARNING: some files open in action "+getLabel()+" where not properly closed. This could lead to data loss!!\n";
      99             :   }
     100        2347 : }
     101             : 
     102          34 : FILE* Action::fopen(const char *path, const char *mode) {
     103          34 :   bool write(false);
     104          34 :   for(const char*p=mode; *p; p++) if(*p=='w' || *p=='a' || *p=='+') write=true;
     105             :   FILE* fp;
     106          34 :   if(write && comm.Get_rank()!=0) fp=plumed.fopen("/dev/null",mode);
     107          34 :   else      fp=plumed.fopen(path,mode);
     108          34 :   files.insert(fp);
     109          34 :   return fp;
     110             : }
     111             : 
     112          34 : int Action::fclose(FILE*fp) {
     113          34 :   files.erase(fp);
     114          34 :   return plumed.fclose(fp);
     115             : }
     116             : 
     117        3803 : void Action::fflush() {
     118        3803 :   for(files_iterator p=files.begin(); p!=files.end(); ++p) {
     119           0 :     std::fflush((*p));
     120             :   }
     121        3803 : }
     122             : 
     123          24 : std::string Action::getKeyword(const std::string& key) {
     124             :   // Check keyword has been registered
     125          24 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
     126             : 
     127          24 :   std::string outkey;
     128          24 :   if( Tools::getKey(line,key,outkey ) ) return key + outkey;
     129             : 
     130           0 :   if( keywords.style(key,"compulsory") ) {
     131           0 :     if( keywords.getDefaultValue(key,outkey) ) {
     132           0 :       if( outkey.length()==0 ) error("keyword " + key + " has weird default value");
     133           0 :       return key + "=" +  outkey;
     134             :     } else {
     135           0 :       error("keyword " + key + " is compulsory for this action");
     136             :     }
     137             :   }
     138           0 :   return "";
     139             : }
     140             : 
     141        7664 : void Action::parseFlag(const std::string&key,bool & t) {
     142             :   // Check keyword has been registered
     143        7664 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
     144             :   // Check keyword is a flag
     145        7664 :   if(!keywords.style(key,"nohtml")) {
     146        7664 :     plumed_massert( keywords.style(key,"vessel") || keywords.style(key,"flag") || keywords.style(key,"hidden"), "keyword " + key + " is not a flag");
     147             :   }
     148             : 
     149             :   // Read in the flag otherwise get the default value from the keywords object
     150        7664 :   if(!Tools::parseFlag(line,key,t)) {
     151        7272 :     if( keywords.style(key,"nohtml") || keywords.style(key,"vessel") ) {
     152        2037 :       t=false;
     153        5235 :     } else if ( !keywords.getLogicalDefault(key,t) ) {
     154           0 :       log.printf("ERROR in action %s with label %s : flag %s has no default",name.c_str(),label.c_str(),key.c_str() );
     155           0 :       plumed_error();
     156             :     }
     157             :   }
     158        7664 : }
     159             : 
     160       18947 : void Action::addDependency(Action*action) {
     161       18947 :   after.push_back(action);
     162       18947 : }
     163             : 
     164      239064 : void Action::activate() {
     165             : // preparation step is called only the first time an Action is activated.
     166             : // since it could change its dependences (e.g. in an ActionAtomistic which is
     167             : // accessing to a virtual atom), this is done just before dependencies are
     168             : // activated
     169      239064 :   if(!active) {
     170      108738 :     this->unlockRequests();
     171      108738 :     prepare();
     172      108738 :     this->lockRequests();
     173      369390 :   } else return;
     174      108738 :   for(Dependencies::iterator p=after.begin(); p!=after.end(); ++p) (*p)->activate();
     175      108738 :   active=true;
     176             : }
     177             : 
     178         594 : void Action::setOption(const std::string &s) {
     179             : // This overloads the action and activate some options
     180         594 :   options.insert(s);
     181         594 :   for(Dependencies::iterator p=after.begin(); p!=after.end(); ++p) (*p)->setOption(s);
     182         594 : }
     183             : 
     184           0 : void Action::clearOptions() {
     185             : // This overloads the action and activate some options
     186           0 :   options.clear();
     187           0 : }
     188             : 
     189             : 
     190        3355 : void Action::clearDependencies() {
     191        3355 :   after.clear();
     192        3355 : }
     193             : 
     194           0 : std::string Action::getDocumentation()const {
     195           0 :   return std::string("UNDOCUMENTED ACTION");
     196             : }
     197             : 
     198        4456 : void Action::checkRead() {
     199        4456 :   if(!line.empty()) {
     200           0 :     std::string msg="cannot understand the following words from the input line : ";
     201           0 :     for(unsigned i=0; i<line.size(); i++) {
     202           0 :       if(i>0) msg = msg + ", ";
     203           0 :       msg = msg + line[i];
     204             :     }
     205           0 :     error(msg);
     206             :   }
     207        4456 : }
     208             : 
     209      784942 : long int Action::getStep()const {
     210      784942 :   return plumed.getStep();
     211             : }
     212             : 
     213      671951 : double Action::getTime()const {
     214      671951 :   return plumed.getAtoms().getTimeStep()*getStep();
     215             : }
     216             : 
     217        3143 : double Action::getTimeStep()const {
     218        3143 :   return plumed.getAtoms().getTimeStep();
     219             : }
     220             : 
     221             : 
     222             : 
     223           0 : void Action::exit(int c) {
     224           0 :   plumed.exit(c);
     225           0 : }
     226             : 
     227           0 : void Action::calculateNumericalDerivatives( ActionWithValue* a ) {
     228           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");
     229             : }
     230             : 
     231       85388 : void Action::prepare() {
     232       85388 :   return;
     233             : }
     234             : 
     235           0 : void Action::error( const std::string & msg ) const {
     236           0 :   log.printf("ERROR in input to action %s with label %s : %s \n \n", name.c_str(), label.c_str(), msg.c_str() );
     237           0 :   plumed_merror("ERROR in input to action " + name + " with label " + label + " : " + msg );
     238             : }
     239             : 
     240           1 : void Action::warning( const std::string & msg ) {
     241           1 :   log.printf("WARNING for action %s with label %s : %s \n", name.c_str(), label.c_str(), msg.c_str() );
     242           1 : }
     243             : 
     244           0 : void Action::calculateFromPDB( const PDB& pdb ) {
     245           0 :   activate();
     246           0 :   for(Dependencies::iterator p=after.begin(); p!=after.end(); ++p) {
     247           0 :     ActionWithValue*av=dynamic_cast<ActionWithValue*>(*p);
     248           0 :     if(av) { av->clearInputForces(); av->clearDerivatives(); }
     249           0 :     (*p)->readAtomsFromPDB( pdb );
     250           0 :     (*p)->calculate();
     251             :   }
     252           0 :   readAtomsFromPDB( pdb );
     253           0 :   calculate();
     254           0 : }
     255             : 
     256        7892 : bool Action::getExchangeStep()const {
     257        7892 :   return plumed.getExchangeStep();
     258             : }
     259             : 
     260           3 : std::string Action::cite(const std::string&s) {
     261           3 :   return plumed.cite(s);
     262             : }
     263             : 
     264             : /// Check if action should be updated.
     265      107502 : bool Action::checkUpdate()const {
     266      107502 :   double t=getTime();
     267      107502 :   if(t<update_until && (update_from==std::numeric_limits<double>::max() || t>=update_from)) return true;
     268         510 :   else return false;
     269             : }
     270             : 
     271          80 : bool Action::getCPT()const {
     272          80 :   return plumed.getCPT();
     273             : }
     274             : 
     275             : 
     276             : 
     277        2523 : }
     278             : 

Generated by: LCOV version 1.13