All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Value.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 "Value.h"
23 #include "ActionWithValue.h"
24 #include "ActionAtomistic.h"
25 #include "ActionWithArguments.h"
26 #include "ActionWithVirtualAtom.h"
27 #include "tools/Exception.h"
28 #include "Atoms.h"
29 #include "PlumedMain.h"
30 
31 namespace PLMD{
32 
34  action(NULL),
35  value_set(false),
36  value(0.0),
37  inputForce(0.0),
38  hasForce(false),
39  hasDeriv(true),
40  periodicity(unset),
41  min(0.0),
42  max(0.0),
43  max_minus_min(0.0),
44  inv_max_minus_min(0.0)
45 {
46 }
47 
48 Value::Value(ActionWithValue* av, const std::string& name, const bool withderiv):
49  action(av),
50  value_set(false),
51  value(0.0),
52  inputForce(0.0),
53  hasForce(false),
54  name(name),
55  hasDeriv(withderiv),
56  periodicity(unset),
57  min(0.0),
58  max(0.0),
59  max_minus_min(0.0),
60  inv_max_minus_min(0.0)
61 {
62 }
63 
65  if( min==0 && max==0 ){
67  } else {
70  plumed_massert(max_minus_min>0, "your function has a very strange domain?");
72  }
73 }
74 
75 bool Value::isPeriodic()const{
76  plumed_massert(periodicity!=unset,"periodicity should be set");
77  return periodicity==periodic;
78 }
79 
80 bool Value::applyForce(std::vector<double>& forces ) const {
81  plumed_massert( derivatives.size()==forces.size()," forces array has wrong size" );
82  if( !hasForce ) return false;
83  for(unsigned i=0;i<derivatives.size();++i) forces[i]=inputForce*derivatives[i];
84  return true;
85 }
86 
89 }
90 
91 void Value::setDomain(const std::string& pmin,const std::string& pmax){
92  str_min=pmin;
93  if( !Tools::convert(str_min,min) ) action->error("could not convert period string " + str_min + " to real");
94  str_max=pmax;
95  if( !Tools::convert(str_max,max) ) action->error("could not convert period string " + str_max + " to read");
97 }
98 
99 void Value::getDomain(std::string&minout,std::string&maxout) const {
100  plumed_massert(periodicity==periodic,"function should be periodic");
101  minout=str_min;
102  maxout=str_max;
103 }
104 
105 void Value::getDomain(double&minout,double&maxout) const {
106  plumed_massert(periodicity==periodic,"function should be periodic");
107  minout=min;
108  maxout=max;
109 }
110 
112  gradients.clear();
113  ActionAtomistic*aa=dynamic_cast<ActionAtomistic*>(action);
115  if(aa){
116  Atoms&atoms((aa->plumed).getAtoms());
117  for(unsigned j=0;j<aa->getNumberOfAtoms();++j){
118  AtomNumber an=aa->getAbsoluteIndex(j);
119  if(atoms.isVirtualAtom(an)){
120  const ActionWithVirtualAtom* a=atoms.getVirtualAtomsAction(an);
121  for(std::map<AtomNumber,Tensor>::const_iterator p=a->getGradients().begin();p!=a->getGradients().end();++p){
122 // controllare l'ordine del matmul:
123  gradients[(*p).first]+=matmul(Vector(derivatives[3*j],derivatives[3*j+1],derivatives[3*j+2]),(*p).second);
124  }
125  } else {
126  for(unsigned i=0;i<3;i++) gradients[an][i]+=derivatives[3*j+i];
127  }
128  }
129  } else if(aw){
130  std::vector<Value*> values=aw->getArguments();
131  for(unsigned j=0;j<derivatives.size();j++){
132  for(std::map<AtomNumber,Vector>::const_iterator p=values[j]->gradients.begin();p!=values[j]->gradients.end();++p){
133  AtomNumber iatom=(*p).first;
134  gradients[iatom]+=(*p).second*derivatives[j];
135  }
136  }
137  } else plumed_error();
138 }
139 
140 double Value::projection(const Value& v1,const Value&v2){
141  double proj=0.0;
142  const std::map<AtomNumber,Vector> & grad1(v1.gradients);
143  const std::map<AtomNumber,Vector> & grad2(v2.gradients);
144  for(std::map<AtomNumber,Vector>::const_iterator p1=grad1.begin();p1!=grad1.end();++p1){
145  AtomNumber a=(*p1).first;
146  std::map<AtomNumber,Vector>::const_iterator p2=grad2.find(a);
147  if(p2!=grad2.end()){
148  proj+=dotProduct((*p1).second,(*p2).second);
149  }
150  }
151  return proj;
152 }
153 
155  plumed_assert( action!=NULL );
156  return action;
157 }
158 
159 void copy( const Value& val1, Value& val2 ){
160  unsigned nder=val1.getNumberOfDerivatives();
161  if( nder!=val2.getNumberOfDerivatives() ){ val2.resizeDerivatives( nder ); }
162  val2.clearDerivatives();
163  for(unsigned i=0;i<val1.getNumberOfDerivatives();++i) val2.addDerivative( i, val1.getDerivative(i) );
164  val2.set( val1.get() );
165 }
166 
167 void copy( const Value& val1, Value* val2 ){
168  unsigned nder=val1.getNumberOfDerivatives();
169  if( nder!=val2->getNumberOfDerivatives() ){ val2->resizeDerivatives( nder ); }
170  val2->clearDerivatives();
171  for(unsigned i=0;i<val1.getNumberOfDerivatives();++i) val2->addDerivative( i, val1.getDerivative(i) );
172  val2->set( val1.get() );
173 }
174 
175 void add( const Value& val1, Value* val2 ){
176  plumed_assert( val1.getNumberOfDerivatives()==val2->getNumberOfDerivatives() );
177  for(unsigned i=0;i<val1.getNumberOfDerivatives();++i) val2->addDerivative( i, val1.getDerivative(i) );
178  val2->set( val1.get() + val2->get() );
179 }
180 
181 }
182 
183 
184 
185 
186 
187 
188 
ActionWithValue * action
The action in which this quantity is calculated.
Definition: Value.h:60
Simple class to store the index of an atom.
Definition: AtomNumber.h:39
Value()
A constructor that can be used to make Vectors of values.
Definition: Value.cpp:33
void add(const Value &val1, Value *val2)
Definition: Value.cpp:175
void copy(const Value &val1, Value &val2)
Definition: Value.cpp:159
bool applyForce(std::vector< double > &forces) const
Apply the forces to the derivatives using the chain rule (if there are no forces this routine returns...
Definition: Value.cpp:80
double get() const
Get the value of the function.
Definition: Value.h:186
double inputForce
The force acting on this quantity.
Definition: Value.h:66
TensorGeneric< n, l > matmul(const TensorGeneric< n, m > &a, const TensorGeneric< m, l > &b)
Definition: Tensor.h:343
A class for holding the value of a function together with its derivatives.
Definition: Value.h:46
AtomNumber getAbsoluteIndex(int i) const
Get the absolute index of an atom.
static bool convert(const std::string &str, double &t)
Convert a string to a double, reading it.
Definition: Tools.cpp:74
void error(const std::string &msg) const
Crash calculation and print documentation.
Definition: Action.cpp:195
unsigned getNumberOfDerivatives() const
Get the number of derivatives that this particular value has.
Definition: Value.h:201
void clearDerivatives()
Set all the derivatives to zero.
Definition: Value.h:241
double max_minus_min
Definition: Value.h:81
Class containing atom related quantities from the MD code.
Definition: Atoms.h:45
This is used to create PLMD::Action objects that take the output from some other Action as input...
double inv_max_minus_min
Definition: Value.h:82
void setGradients()
This sets up the gradients.
Definition: Value.cpp:111
double max
Definition: Value.h:80
bool hasForce
A flag telling us we have a force acting on this quantity.
Definition: Value.h:68
const std::map< AtomNumber, Tensor > & getGradients() const
void set(double)
Set the value of the function.
Definition: Value.h:174
Used to create a PLMD::Action that has some scalar or vectorial output that may or may not have some ...
void getDomain(std::string &, std::string &) const
Get the domain of the quantity.
Definition: Value.cpp:99
void setNotPeriodic()
Set the function not periodic.
Definition: Value.cpp:87
Action used to create objects that access the positions of the atoms from the MD code.
std::vector< Value * > & getArguments()
Returns an array of pointers to the arguments.
double min
Definition: Value.h:80
Inherit from here if you are calculating the position of a virtual atom (eg a center of mass) ...
T dotProduct(const std::vector< T > &A, const std::vector< T > &B)
Calculate the dot product between two vectors.
Definition: Matrix.h:54
static double projection(const Value &, const Value &)
Definition: Value.cpp:140
void resizeDerivatives(int n)
Set the number of derivatives.
Definition: Value.h:218
PlumedMain & plumed
Reference to main plumed object.
Definition: Action.h:90
ActionWithValue * getPntrToAction()
This returns the pointer to the action where this value is calculated.
Definition: Value.cpp:154
std::vector< double > derivatives
The derivatives of the quantity stored in value.
Definition: Value.h:70
enum PLMD::Value::@1 periodicity
Is this quantity periodic.
void setupPeriodicity()
Complete the setup of the periodicity.
Definition: Value.cpp:64
std::string str_max
Definition: Value.h:79
bool isPeriodic() const
Check if the value is periodic.
Definition: Value.cpp:75
unsigned getNumberOfAtoms() const
Get number of available atoms.
std::string str_min
Various quantities that describe the domain of this value.
Definition: Value.h:79
void const char const char int double * a
Definition: Matrix.h:42
std::map< AtomNumber, Vector > gradients
Definition: Value.h:71
Vector3d Vector
Alias for three dimensional vectors.
Definition: Vector.h:351
void addDerivative(unsigned i, double d)
Add some derivative to the ith component of the derivatives array.
Definition: Value.h:224
double getDerivative(const unsigned n) const
Get the derivative with respect to component n.
Definition: Value.h:207
void setDomain(const std::string &, const std::string &)
Set the domain of the function.
Definition: Value.cpp:91