All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ActionWithValue.cpp
Go to the documentation of this file.
1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2  Copyright (c) 2013 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-code.org for more information.
6 
7  This file is part of plumed, version 2.0.
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 
25 using namespace std;
26 namespace PLMD{
27 
28 void ActionWithValue::registerKeywords(Keywords& keys){
29  keys.setComponentsIntroduction("By default the value of the calculated quantity can be referenced elsewhere in the "
30  "input file by using the label of the action. Alternatively this Action can be used "
31  "to be used to calculate the following quantities by employing the keywords listed "
32  "below. These quanties can be referenced elsewhere in the input by using this Action's "
33  "label followed by a dot and the name of the quantity required from the list below.");
34  keys.addFlag("NUMERICAL_DERIVATIVES", false, "calculate the derivatives for these quantities numerically");
35 }
36 
37 void ActionWithValue::noAnalyticalDerivatives(Keywords& keys){
38  keys.remove("NUMERICAL_DERIVATIVES");
39  keys.addFlag("NUMERICAL_DERIVATIVES",true,"analytical derivatives are not implemented for this keyword so numerical derivatives are always used");
40 }
41 
42 void ActionWithValue::componentsAreNotOptional(Keywords& keys){
43  keys.setComponentsIntroduction("By default this Action calculates the following quantities. These quanties can "
44  "be referenced elsewhere in the input by using this Action's label followed by a "
45  "dot and the name of the quantity required from the list below.");
46 }
47 
48 void ActionWithValue::useCustomisableComponents(Keywords& keys){
49  keys.setComponentsIntroduction("The names of the components in this action can be customized by the user in the "
50  "actions input file. However, in addition to these customizable components the "
51  "following quantities will always be output");
52 }
53 
54 ActionWithValue::ActionWithValue(const ActionOptions&ao):
55  Action(ao),
56  numericalDerivatives(false)
57 {
58  if( keywords.exists("NUMERICAL_DERIVATIVES") ) parseFlag("NUMERICAL_DERIVATIVES",numericalDerivatives);
59  if(numericalDerivatives) log.printf(" using numerical derivatives\n");
60 }
61 
63  for(unsigned i=0;i<values.size();++i)delete values[i];
64 }
65 
67  for(unsigned i=0;i<values.size();i++) values[i]->clearInputForce();
68 }
70  for(unsigned i=0;i<values.size();i++) values[i]->clearDerivatives();
71 }
72 
73 // -- These are the routine for copying the value pointers to other classes -- //
74 
75 bool ActionWithValue::exists( const std::string& name ) const {
76  for(unsigned i=0;i<values.size();++i){
77  if (values[i]->name==name) return true;
78  }
79  return false;
80 }
81 
82 Value* ActionWithValue::copyOutput( const std::string& name ) const {
83  for(unsigned i=0;i<values.size();++i){
84  if (values[i]->name==name) return values[i];
85  }
86  plumed_merror("there is no pointer with name " + name);
87  return NULL;
88 }
89 
90 Value* ActionWithValue::copyOutput( const unsigned& n ) const {
91  plumed_massert(n<values.size(),"you have requested a pointer that is out of bounds");
92  return values[n];
93 }
94 
95 // -- HERE WE HAVE THE STUFF FOR THE DEFAULT VALUE -- //
96 
98  plumed_massert(values.empty(),"You have already added the default value for this action");
99  values.push_back(new Value(this,getLabel(), false ) );
100 }
101 
103  plumed_massert(values.empty(),"You have already added the default value for this action");
104  values.push_back(new Value(this,getLabel(), true ) );
105 }
106 
108  plumed_massert(values.size()==1,"The number of components is not equal to one");
109  plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
110  values[0]->min=0; values[0]->max=0;
111  values[0]->setupPeriodicity();
112 }
113 
114 void ActionWithValue::setPeriodic( const std::string& min, const std::string& max ){
115  plumed_massert(values.size()==1,"The number of components is not equal to one");
116  plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
117  values[0]->setDomain( min, max );
118 }
119 
121  plumed_dbg_massert(values.size()==1,"The number of components is not equal to one");
122  plumed_dbg_massert(values[0]->name==getLabel(), "The value you are trying to retrieve is not the default");
123  return values[0];
124 }
125 
126 // -- HERE WE HAVE THE STUFF FOR NAMED VALUES / COMPONENTS -- //
127 
128 void ActionWithValue::addComponent( const std::string& name ){
129 // plumed_massert( keywords.outputComponentExists(name,true), "a description of component " + name + " has not been added to the manual");
130  if( !keywords.outputComponentExists(name,true) ){
131  warning("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
132  "registerKeywords as described in the developer docs. In version 2.2 this warning will turn into an error i.e. component registration will be compulsory");
133  }
134  std::string thename; thename=getLabel() + "." + name;
135  for(unsigned i=0;i<values.size();++i){
136  plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
137  plumed_massert(values[i]->name!=thename,"there is already a value with this name");
138  }
139  values.push_back(new Value(this,thename, false ) );
140  std::string msg=" added component to this action: "+thename+" \n";
141  log.printf(msg.c_str());
142 }
143 
144 void ActionWithValue::addComponentWithDerivatives( const std::string& name ){
145 // plumed_massert( keywords.outputComponentExists(name,true), "a description of component " + name + " has not been added to the manual");
146  if( !keywords.outputComponentExists(name,true) ){
147  warning("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
148  "registerKeywords as described in the developer doc. In version 2.2 this warning will turn into an error i.e. component registration will be compulsory");
149  }
150  std::string thename; thename=getLabel() + "." + name;
151  for(unsigned i=0;i<values.size();++i){
152  plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
153  plumed_massert(values[i]->name!=thename,"there is already a value with this name");
154  }
155  values.push_back(new Value(this,thename, true ) );
156  std::string msg=" added component to this action: "+thename+" \n";
157  log.printf(msg.c_str());
158 }
159 
160 int ActionWithValue::getComponent( const std::string& name ) const {
161  plumed_massert( !exists( getLabel() ), "You should not be calling this routine if you are using a value");
162  std::string thename; thename=getLabel() + "." + name;
163  for(unsigned i=0;i<values.size();++i){
164  if (values[i]->name==thename) return i;
165  }
166  plumed_merror("there is no component with name " + name);
167  return -1;
168 }
169 
171  std::string complist;
172  //plumed_massert( !exists( getLabel() ), "You should not be calling this routine if you are using a value");
173  for(unsigned i=0;i<values.size();++i){
174  complist+=values[i]->name+" ";
175  }
176  return complist;
177 }
178 
179 std::vector<std::string> ActionWithValue::getComponentsVector( ) const {
180  std::vector<std::string> complist;
181  //plumed_massert( !exists( getLabel() ), "You should not be calling this routine if you are using a value");
182  for(unsigned i=0;i<values.size();++i){
183  complist.push_back(values[i]->name);
184  }
185  return complist;
186 }
187 
188 void ActionWithValue::componentIsNotPeriodic( const std::string& name ){
189  int kk=getComponent(name);
190  values[kk]->min=0; values[kk]->max=0;
191  values[kk]->setupPeriodicity();
192 }
193 
195  if(isOptionOn("GRADIENTS")) {
196  for(unsigned i=0;i<values.size();i++) values[i]->setGradients();
197  }
198 }
199 
200 void ActionWithValue::componentIsPeriodic( const std::string& name, const std::string& min, const std::string& max ){
201  int kk=getComponent(name);
202  values[kk]->setDomain(min,max);
203 }
204 
205 Value* ActionWithValue::getPntrToComponent( const std::string& name ){
206  int kk=getComponent(name);
207  return values[kk];
208 }
209 
211  plumed_dbg_massert(n<values.size(),"you have requested a pointer that is out of bounds");
212  return values[n];
213 }
214 
215 void ActionWithValue::mergeFieldDerivatives( const std::vector<double>& derivatives, Value* val_out ){
216  plumed_assert( derivatives.size()==getNumberOfComponents() );
217  for(unsigned i=0;i<derivatives.size();++i){
218  for(unsigned j=0;j<getPntrToComponent(i)->getNumberOfDerivatives();++j){
219  val_out->addDerivative( j, derivatives[i]*getPntrToComponent(i)->getDerivative(j) );
220  }
221  }
222 }
223 }
void setComponentsIntroduction(const std::string &instr)
Set the text that introduces how the components for this action are introduced.
Definition: Keywords.cpp:561
void parseFlag(const std::string &key, bool &t)
Parse one keyword as boolean flag.
Definition: Action.cpp:104
void setNotPeriodic()
Set your default value to have no periodicity.
Log & log
Reference to the log stream.
Definition: Action.h:93
void componentIsNotPeriodic(const std::string &name)
Set your value component to have no periodicity.
void warning(const std::string &msg)
Issue a warning.
Definition: Action.cpp:201
int getComponent(const std::string &name) const
Return the index for the component named name.
A class for holding the value of a function together with its derivatives.
Definition: Value.h:46
std::vector< Value * > values
An array containing the values for this action.
unsigned getNumberOfDerivatives() const
Get the number of derivatives that this particular value has.
Definition: Value.h:201
Value * getPntrToValue()
Get a pointer to the default value.
const std::string & getLabel() const
Returns the label.
Definition: Action.h:263
STL namespace.
void addValueWithDerivatives()
Add a value with the name label that has derivatives.
void addComponent(const std::string &name)
Add a value with a name like label.name.
void const char const char int * n
Definition: Matrix.h:42
void setGradientsIfNeeded()
Calculate the gradients and store them for all the values (need for projections)
This class holds the keywords and their documentation.
Definition: Keywords.h:36
const std::string name
Name of the directive in the plumed.dat file.
Definition: Action.h:64
std::string getComponentsList() const
get a string that contains all the available components
bool exists(const std::string &name) const
Check if a value with a particular name is present.
This class is used to bring the relevant information to the Action constructor.
Definition: Action.h:41
void clearInputForces()
Clear the forces on the values.
void setPeriodic(const std::string &min, const std::string &max)
Set the value to be periodic with a particular domain.
int printf(const char *fmt,...)
Formatted output with explicit format - a la printf.
Definition: OFile.cpp:82
Base class for all the input Actions.
Definition: Action.h:60
Value * copyOutput(const std::string &name) const
Return a pointer to the value with name (this is used to retrieve values in other PLMD::Actions) You ...
bool isOptionOn(const std::string &s) const
Check if an option is on.
Definition: Action.h:380
void componentIsPeriodic(const std::string &name, const std::string &min, const std::string &max)
Set the value to be periodic with a particular domain.
std::vector< std::string > getComponentsVector() const
get a vector that contains the label for all the components
void remove(const std::string &k)
Remove the keyword with name k.
Definition: Keywords.cpp:204
virtual void mergeFieldDerivatives(const std::vector< double > &derivatives, Value *val_out)
bool exists(const std::string &k) const
Check if there is a keyword with name k.
Definition: Keywords.cpp:239
void addComponentWithDerivatives(const std::string &name)
Add a value with a name like label.name that has derivatives.
virtual void clearDerivatives()
Clear the derivatives of values wrt parameters.
int getNumberOfComponents() const
Returns the number of values defined.
void addValue()
Add a value with the name label.
Value * getPntrToComponent(int i)
Return a pointer to the component by index.
bool outputComponentExists(const std::string &name, const bool &custom) const
Has a component with this name been added?
Definition: Keywords.cpp:572
bool numericalDerivatives
Are we using numerical derivatives to differentiate.
const Keywords & keywords
Definition: Action.h:161
void addDerivative(unsigned i, double d)
Add some derivative to the ith component of the derivatives array.
Definition: Value.h:224
void addFlag(const std::string &k, const bool def, const std::string &d)
Add a falg with name k that is by default on if def is true and off if def is false. d should provide a description of the flag.
Definition: Keywords.cpp:193