LCOV - code coverage report
Current view: top level - core - ActionWithValue.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 119 134 88.8 %
Date: 2018-12-19 07:49:13 Functions: 28 33 84.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 "ActionWithValue.h"
      23             : #include "tools/Exception.h"
      24             : #include "tools/OpenMP.h"
      25             : 
      26             : using namespace std;
      27             : namespace PLMD {
      28             : 
      29        1594 : void ActionWithValue::registerKeywords(Keywords& keys) {
      30             :   keys.setComponentsIntroduction("By default the value of the calculated quantity can be referenced elsewhere in the "
      31             :                                  "input file by using the label of the action.  Alternatively this Action can be used "
      32             :                                  "to calculate the following quantities by employing the keywords listed "
      33             :                                  "below.  These quanties can be referenced elsewhere in the input by using this Action's "
      34        1594 :                                  "label followed by a dot and the name of the quantity required from the list below.");
      35        1594 :   keys.addFlag("NUMERICAL_DERIVATIVES", false, "calculate the derivatives for these quantities numerically");
      36        1594 : }
      37             : 
      38           0 : void ActionWithValue::noAnalyticalDerivatives(Keywords& keys) {
      39           0 :   keys.remove("NUMERICAL_DERIVATIVES");
      40           0 :   keys.addFlag("NUMERICAL_DERIVATIVES",true,"analytical derivatives are not implemented for this keyword so numerical derivatives are always used");
      41           0 : }
      42             : 
      43         353 : void ActionWithValue::componentsAreNotOptional(Keywords& keys) {
      44             :   keys.setComponentsIntroduction("By default this Action calculates the following quantities. These quanties can "
      45             :                                  "be referenced elsewhere in the input by using this Action's label followed by a "
      46         353 :                                  "dot and the name of the quantity required from the list below.");
      47         353 : }
      48             : 
      49         137 : void ActionWithValue::useCustomisableComponents(Keywords& keys) {
      50             :   keys.setComponentsIntroduction("The names of the components in this action can be customized by the user in the "
      51             :                                  "actions input file.  However, in addition to these customizable components the "
      52         137 :                                  "following quantities will always be output");
      53         137 : }
      54             : 
      55        1473 : ActionWithValue::ActionWithValue(const ActionOptions&ao):
      56             :   Action(ao),
      57             :   noderiv(true),
      58        1473 :   numericalDerivatives(false)
      59             : {
      60        1473 :   if( keywords.exists("NUMERICAL_DERIVATIVES") ) parseFlag("NUMERICAL_DERIVATIVES",numericalDerivatives);
      61        1473 :   if(numericalDerivatives) log.printf("  using numerical derivatives\n");
      62        1473 : }
      63             : 
      64        2946 : ActionWithValue::~ActionWithValue() {
      65        1473 :   for(unsigned i=0; i<values.size(); ++i)delete values[i];
      66        1473 : }
      67             : 
      68       77878 : void ActionWithValue::clearInputForces() {
      69       77878 :   for(unsigned i=0; i<values.size(); i++) values[i]->clearInputForce();
      70       77878 : }
      71             : 
      72       80521 : void ActionWithValue::clearDerivatives() {
      73       80521 :   unsigned nt = OpenMP::getNumThreads();
      74      239822 :   #pragma omp parallel num_threads(nt)
      75             :   {
      76      160517 :     #pragma omp for
      77      318168 :     for(unsigned i=0; i<values.size(); i++) values[i]->clearDerivatives();
      78             :   }
      79       80521 : }
      80             : 
      81             : // -- These are the routine for copying the value pointers to other classes -- //
      82             : 
      83      113785 : bool ActionWithValue::exists( const std::string& name ) const {
      84    20569371 :   for(unsigned i=0; i<values.size(); ++i) {
      85    20472454 :     if (values[i]->name==name) return true;
      86             :   }
      87       96917 :   return false;
      88             : }
      89             : 
      90       16880 : Value* ActionWithValue::copyOutput( const std::string& name ) const {
      91     7988991 :   for(unsigned i=0; i<values.size(); ++i) {
      92     7988991 :     if (values[i]->name==name) return values[i];
      93             :   }
      94           0 :   plumed_merror("there is no pointer with name " + name);
      95             :   return NULL;
      96             : }
      97             : 
      98        7541 : Value* ActionWithValue::copyOutput( const unsigned& n ) const {
      99        7541 :   plumed_massert(n<values.size(),"you have requested a pointer that is out of bounds");
     100        7541 :   return values[n];
     101             : }
     102             : 
     103             : // -- HERE WE HAVE THE STUFF FOR THE DEFAULT VALUE -- //
     104             : 
     105          17 : void ActionWithValue::addValue() {
     106          17 :   plumed_massert(values.empty(),"You have already added the default value for this action");
     107          17 :   values.push_back(new Value(this,getLabel(), false ) );
     108          17 : }
     109             : 
     110         722 : void ActionWithValue::addValueWithDerivatives() {
     111         722 :   plumed_massert(values.empty(),"You have already added the default value for this action");
     112         722 :   values.push_back(new Value(this,getLabel(), true ) );
     113         722 : }
     114             : 
     115         651 : void ActionWithValue::setNotPeriodic() {
     116         651 :   plumed_massert(values.size()==1,"The number of components is not equal to one");
     117         651 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
     118         651 :   values[0]->min=0; values[0]->max=0;
     119         651 :   values[0]->setupPeriodicity();
     120         651 : }
     121             : 
     122          88 : void ActionWithValue::setPeriodic( const std::string& min, const std::string& max ) {
     123          88 :   plumed_massert(values.size()==1,"The number of components is not equal to one");
     124          88 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
     125          88 :   values[0]->setDomain( min, max );
     126          88 : }
     127             : 
     128    14957279 : Value* ActionWithValue::getPntrToValue() {
     129             :   plumed_dbg_massert(values.size()==1,"The number of components is not equal to one");
     130             :   plumed_dbg_massert(values[0]->name==getLabel(), "The value you are trying to retrieve is not the default");
     131    14957279 :   return values[0];
     132             : }
     133             : 
     134             : // -- HERE WE HAVE THE STUFF FOR NAMED VALUES / COMPONENTS -- //
     135             : 
     136        3251 : void ActionWithValue::addComponent( const std::string& name ) {
     137        3251 :   if( !keywords.outputComponentExists(name,true) ) {
     138           0 :     warning("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
     139           0 :             "registerKeywords as described in the developer docs.");
     140             :   }
     141        3251 :   std::string thename; thename=getLabel() + "." + name;
     142     2604187 :   for(unsigned i=0; i<values.size(); ++i) {
     143     2600936 :     plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
     144     2600936 :     plumed_massert(values[i]->name!=thename&&name!="bias","Since PLUMED 2.3 the component 'bias' is automatically added to all biases by the general constructor!\n"
     145           0 :                    "Remove the line addComponent(\"bias\") from your bias.");
     146     2600936 :     plumed_massert(values[i]->name!=thename,"there is already a value with this name");
     147             :   }
     148        3251 :   values.push_back(new Value(this,thename, false ) );
     149        6502 :   std::string msg="  added component to this action:  "+thename+" \n";
     150        6502 :   log.printf(msg.c_str());
     151        3251 : }
     152             : 
     153        7053 : void ActionWithValue::addComponentWithDerivatives( const std::string& name ) {
     154        7053 :   if( !keywords.outputComponentExists(name,true) ) {
     155           2 :     warning("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
     156           1 :             "registerKeywords as described in the developer doc.");
     157             :   }
     158        7053 :   std::string thename; thename=getLabel() + "." + name;
     159     1740563 :   for(unsigned i=0; i<values.size(); ++i) {
     160     1733510 :     plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
     161     1733510 :     plumed_massert(values[i]->name!=thename&&name!="bias","Since PLUMED 2.3 the component 'bias' is automatically added to all biases by the general constructor!\n"
     162           0 :                    "Remove the line addComponentWithDerivatives(\"bias\") from your bias.");
     163     1733510 :     plumed_massert(values[i]->name!=thename,"there is already a value with this name");
     164             :   }
     165        7053 :   values.push_back(new Value(this,thename, true ) );
     166       14106 :   std::string msg="  added component to this action:  "+thename+" \n";
     167       14106 :   log.printf(msg.c_str());
     168        7053 : }
     169             : 
     170       90143 : int ActionWithValue::getComponent( const std::string& name ) const {
     171       90143 :   plumed_massert( !exists( getLabel() ), "You should not be calling this routine if you are using a value");
     172       90143 :   std::string thename; thename=getLabel() + "." + name;
     173     8290767 :   for(unsigned i=0; i<values.size(); ++i) {
     174     8290767 :     if (values[i]->name==thename) return i;
     175             :   }
     176           0 :   plumed_merror("there is no component with name " + name);
     177       90143 :   return -1;
     178             : }
     179             : 
     180           0 : std::string ActionWithValue::getComponentsList( ) const {
     181           0 :   std::string complist;
     182           0 :   for(unsigned i=0; i<values.size(); ++i) {
     183           0 :     complist+=values[i]->name+" ";
     184             :   }
     185           0 :   return complist;
     186             : }
     187             : 
     188         485 : std::vector<std::string> ActionWithValue::getComponentsVector( ) const {
     189         485 :   std::vector<std::string> complist;
     190      173218 :   for(unsigned i=0; i<values.size(); ++i) {
     191      172733 :     complist.push_back(values[i]->name);
     192             :   }
     193         485 :   return complist;
     194             : }
     195             : 
     196        7244 : void ActionWithValue::componentIsNotPeriodic( const std::string& name ) {
     197        7244 :   int kk=getComponent(name);
     198        7244 :   values[kk]->min=0; values[kk]->max=0;
     199        7244 :   values[kk]->setupPeriodicity();
     200        7244 : }
     201             : 
     202          38 : void ActionWithValue::componentIsPeriodic( const std::string& name, const std::string& min, const std::string& max ) {
     203          38 :   int kk=getComponent(name);
     204          38 :   values[kk]->setDomain(min,max);
     205          38 : }
     206             : 
     207       77878 : void ActionWithValue::setGradientsIfNeeded() {
     208       77878 :   if(isOptionOn("GRADIENTS")) {
     209         402 :     for(unsigned i=0; i<values.size(); i++) values[i]->setGradients();
     210             :   }
     211       77878 : }
     212             : 
     213     3483411 : void ActionWithValue::turnOnDerivatives() {
     214             :   // Turn on the derivatives
     215     3483411 :   noderiv=false;
     216             :   // Resize the derivatives
     217     3483411 :   for(unsigned i=0; i<values.size(); ++i) values[i]->resizeDerivatives( getNumberOfDerivatives() );
     218             :   // And turn on the derivatives in all actions on which we are dependent
     219     6965796 :   for(unsigned i=0; i<getDependencies().size(); ++i) {
     220     3482385 :     ActionWithValue* vv=dynamic_cast<ActionWithValue*>( getDependencies()[i] );
     221     3482385 :     if(vv) vv->turnOnDerivatives();
     222             :   }
     223     3483411 : }
     224             : 
     225       82861 : Value* ActionWithValue::getPntrToComponent( const std::string& name ) {
     226       82861 :   int kk=getComponent(name);
     227       82861 :   return values[kk];
     228             : }
     229             : 
     230      190228 : Value* ActionWithValue::getPntrToComponent( int n ) {
     231             :   plumed_dbg_massert(n<values.size(),"you have requested a pointer that is out of bounds");
     232      190228 :   return values[n];
     233             : }
     234             : 
     235        2523 : }

Generated by: LCOV version 1.13