All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
BiasRepresentation.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 "core/Value.h"
23 #include "Communicator.h"
24 #include "BiasRepresentation.h"
25 #include <iostream>
26 
27 namespace PLMD {
28 
29 //+PLUMEDOC INTERNAL BiasRepresentation
30 /*
31 An internal tool in plumed that is used to represent a bias
32 
33 */
34 //+ENDPLUMEDOC
35 
36 /// the constructor here
37 BiasRepresentation::BiasRepresentation(vector<Value*> tmpvalues, Communicator &cc ):hasgrid(false),mycomm(cc),BiasGrid_(NULL){
38  ndim=tmpvalues.size();
39  for(int i=0;i<ndim;i++){
40  values.push_back(tmpvalues[i]);
41  names.push_back(values[i]->getName());
42  }
43 }
44 /// overload the constructor: add the sigma at constructor time
45 BiasRepresentation::BiasRepresentation(vector<Value*> tmpvalues, Communicator &cc, vector<double> sigma ):hasgrid(false),histosigma(sigma),mycomm(cc),BiasGrid_(NULL){
46  ndim=tmpvalues.size();
47  for(int i=0;i<ndim;i++){
48  values.push_back(tmpvalues[i]);
49  names.push_back(values[i]->getName());
50  }
51 }
52 /// overload the constructor: add the grid at constructor time
53 BiasRepresentation::BiasRepresentation(vector<Value*> tmpvalues, Communicator &cc , vector<string> gmin, vector<string> gmax, vector<unsigned> nbin ):hasgrid(false), rescaledToBias(false), mycomm(cc), BiasGrid_(NULL){
54  ndim=tmpvalues.size();
55  for(int i=0;i<ndim;i++){
56  values.push_back(tmpvalues[i]);
57  names.push_back(values[i]->getName());
58  }
59  // initialize the grid
60  addGrid(gmin,gmax,nbin);
61 }
62 /// overload the constructor with some external sigmas: needed for histogram
63 BiasRepresentation::BiasRepresentation(vector<Value*> tmpvalues, Communicator &cc , vector<string> gmin, vector<string> gmax, vector<unsigned> nbin , vector<double> sigma):hasgrid(false), rescaledToBias(false),histosigma(sigma),mycomm(cc),BiasGrid_(NULL){
64  ndim=tmpvalues.size();
65  for(int i=0;i<ndim;i++){
66  values.push_back(tmpvalues[i]);
67  names.push_back(values[i]->getName());
68  }
69  // initialize the grid
70  addGrid(gmin,gmax,nbin);
71 }
72 
74  if(BiasGrid_) delete BiasGrid_;
75  for(unsigned i=0;i<hills.size();i++) delete hills[i];
76 }
77 
78 void BiasRepresentation::addGrid( vector<string> gmin, vector<string> gmax, vector<unsigned> nbin ){
79  plumed_massert(hills.size()==0,"you can set the grid before loading the hills");
80  plumed_massert(hasgrid==false,"to build the grid you should not having the grid in this bias representation");
81  string ss; ss="file.free";
82  vector<Value*> vv;for(unsigned i=0;i<values.size();i++)vv.push_back(values[i]);
83  //cerr<<" initializing grid "<<endl;
84  BiasGrid_=new Grid(ss,vv,gmin,gmax,nbin,false,true);
85  hasgrid=true;
86 }
88  if(histosigma.size()==0){return false;}else{return true;}
89 }
91  plumed_massert(hills.size()==0,"you can set the rescaling function only before loading hills");
92  rescaledToBias=rescaled;
93 }
95  return rescaledToBias;
96 }
97 
99  return values.size();
100 }
102  return names;
103 }
104 const string & BiasRepresentation::getName(unsigned i){
105  return names[i];
106 }
107 
108 const vector<Value*>& BiasRepresentation::getPtrToValues(){
109  return values;
110 }
112  return values[i];
113 }
114 
116  vector<double> cc( names.size() );
117  for(unsigned i=0;i<names.size();++i){
118  ifile->scanField(names[i],cc[i]);
119  }
120  double h=1.0;
121  return new KernelFunctions(cc,histosigma,"gaussian",false,h,false);
122 }
124  KernelFunctions *kk=NULL;
125  // here below the reading of the kernel is completely hidden
126  if(histosigma.size()==0){
127  ifile->allowIgnoredFields();
128  kk=KernelFunctions::read(ifile,names) ;
129  }else{
130  // when doing histogram assume gaussian with a given diagonal sigma
131  // and neglect all the rest
132  kk=readFromPoint(ifile) ;
133  }
134  hills.push_back(kk);
135  // the bias factor is not something about the kernels but
136  // must be stored to keep the bias/free energy duality
137  string dummy; double dummyd;
138  if(ifile->FieldExist("biasf")){
139  ifile->scanField("biasf",dummy);
140  Tools::convert(dummy,dummyd);
141  }else{dummyd=1.0;}
142  biasf.push_back(dummyd);
143  // the domain does not pertain to the kernel but to the values here defined
144  string mins,maxs,minv,maxv,mini,maxi;mins="min_";maxs="max_";
145  for(unsigned i=0 ; i<ndim; i++){
146  if(values[i]->isPeriodic()){
147  ifile->scanField(mins+names[i],minv);
148  ifile->scanField(maxs+names[i],maxv);
149  // verify that the domain is correct
150  values[i]->getDomain(mini,maxi);
151  plumed_massert(mini==minv,"the input periodicity in hills and in value definition does not match" );
152  plumed_massert(maxi==maxv,"the input periodicity in hills and in value definition does not match" );
153  }
154  }
155  // if grid is defined then it should be added on the grid
156  //cerr<<"now with "<<hills.size()<<endl;
157  if(hasgrid){
158  vector<unsigned> nneighb=kk->getSupport(BiasGrid_->getDx());
159  vector<unsigned> neighbors=BiasGrid_->getNeighbors(kk->getCenter(),nneighb);
160  vector<double> der(ndim);
161  vector<double> xx(ndim);
162  if(mycomm.Get_size()==1){
163  for(int i=0;i<neighbors.size();++i){
164  unsigned ineigh=neighbors[i];
165  for(int j=0;j<ndim;++j){der[j]=0.0;}
166  BiasGrid_->getPoint(ineigh,xx);
167  // assign xx to a new vector of values
168  for(int j=0;j<ndim;++j){values[j]->set(xx[j]);}
169  double bias=kk->evaluate(values,der,true);
170  if(rescaledToBias){
171  double f=(biasf.back()-1.)/(biasf.back());
172  bias*=f;
173  for(int j=0;j<ndim;++j){der[j]*=f;}
174  }
175  BiasGrid_->addValueAndDerivatives(ineigh,bias,der);
176  }
177  } else {
178  unsigned stride=mycomm.Get_size();
179  unsigned rank=mycomm.Get_rank();
180  vector<double> allder(ndim*neighbors.size(),0.0);
181  vector<double> allbias(neighbors.size(),0.0);
182  vector<double> tmpder(ndim);
183  for(unsigned i=rank;i<neighbors.size();i+=stride){
184  unsigned ineigh=neighbors[i];
185  BiasGrid_->getPoint(ineigh,xx);
186  for(int j=0;j<ndim;++j){values[j]->set(xx[j]);}
187  allbias[i]=kk->evaluate(values,tmpder,true);
188  if(rescaledToBias){
189  double f=(biasf.back()-1.)/(biasf.back());
190  allbias[i]*=f;
191  for(int j=0;j<ndim;++j){tmpder[j]*=f;}
192  }
193  // this solution with the temporary vector is rather bad, probably better to take
194  // a pointer of double as it was in old gaussian
195  for(int j=0;j<ndim;++j){ allder[ndim*i+j]=tmpder[j];tmpder[j]=0.;}
196  }
197  mycomm.Sum(&allbias[0],allbias.size());
198  mycomm.Sum(&allder[0],allder.size());
199  for(unsigned i=0;i<neighbors.size();++i){
200  unsigned ineigh=neighbors[i];
201  for(unsigned j=0;j<ndim;++j){der[j]=allder[ndim*i+j];}
202  BiasGrid_->addValueAndDerivatives(ineigh,allbias[i],der);
203  }
204  }
205  }
206 }
208  return hills.size();
209 }
211  plumed_massert(hasgrid,"if you want the grid pointer then you should have defined a grid before");
212  return BiasGrid_;
213 }
214 void BiasRepresentation::getMinMaxBin(vector<double> &vmin, vector<double> &vmax, vector<unsigned> &vbin){
215  vector<double> ss,cc,binsize;
216  vmin.clear();vmin.resize(ndim,10.e20);
217  vmax.clear();vmax.resize(ndim,-10.e20);
218  vbin.clear();vbin.resize(ndim);
219  binsize.clear();binsize.resize(ndim,10.e20);
220  int ndiv=10; // adjustable parameter: division per support
221  for(unsigned i=0;i<hills.size();i++){
222  if(histosigma.size()!=0){
223  ss=histosigma;
224  }else{
225  ss=hills[i]->getContinuousSupport();
226  }
227  cc=hills[i]->getCenter();
228  for(unsigned j=0;j<ndim;j++){
229  double dmin=cc[j]-ss[j];
230  double dmax=cc[j]+ss[j];
231  double ddiv=ss[j]/double(ndiv);
232  if(dmin<vmin[j])vmin[j]=dmin;
233  if(dmax>vmax[j])vmax[j]=dmax;
234  if(ddiv<binsize[j])binsize[j]=ddiv;
235  }
236  }
237  for(unsigned j=0;j<ndim;j++){
238  // reset to periodicity
239  if(values[j]->isPeriodic()){
240  double minv,maxv;
241  values[j]->getDomain(minv,maxv);
242  if(minv>vmin[j])vmin[j]=minv;
243  if(maxv<vmax[j])vmax[j]=maxv;
244  }
245  vbin[j]=static_cast<unsigned>(ceil((vmax[j]-vmin[j])/binsize[j]) );
246  }
247 }
249  // clear the hills
250  for(vector<KernelFunctions*>::const_iterator it = hills.begin(); it != hills.end(); ++it)
251  {
252  delete *it;
253  }
254  hills.clear();
255  // clear the grid
256  if(hasgrid){
257  BiasGrid_->clear();
258  }
259 }
260 
261 
262 }
bool FieldExist(const std::string &s)
Check if a field exist.
Definition: IFile.cpp:104
std::vector< unsigned > getSupport(const std::vector< double > &dx) const
Get the support.
std::vector< double > getCenter() const
Get the position of the center.
static KernelFunctions * read(IFile *ifile, const std::vector< std::string > &valnames)
Read a kernel function from a file.
double evaluate(const std::vector< Value * > &pos, std::vector< double > &derivatives, bool usederiv=true) const
Evaluate the kernel function.
void pushKernel(IFile *ff)
push a kernel on the representation (includes widths and height)
bool hasSigmaInInput()
check if the sigma values are already provided (in case of a histogram representation with input sigm...
Value * getPtrToValue(unsigned i)
get a pointer to a specific value
Grid * getGridPtr()
get the pointer to the grid
void getMinMaxBin(vector< double > &vmin, vector< double > &vmax, vector< unsigned > &vbin)
get an automatic min/max from the set so to know how to configure the grid
A class for holding the value of a function together with its derivatives.
Definition: Value.h:46
virtual void clear()
clear grid
Definition: Grid.cpp:116
static bool convert(const std::string &str, double &t)
Convert a string to a double, reading it.
Definition: Tools.cpp:74
unsigned getNumberOfDimensions()
retrieve the number of dimension of the representation
Class containing wrappers to MPI.
Definition: Communicator.h:44
int getNumberOfKernels()
get the number of kernels contained in the representation
void clear()
clear the representation (grid included)
int Get_rank() const
Obtain the rank of the present process.
std::vector< double > getDx() const
get bin size
Definition: Grid.cpp:136
KernelFunctions * readFromPoint(IFile *ifile)
get a new histogram point from a file
virtual void addValueAndDerivatives(unsigned index, double value, std::vector< double > &der)
add to grid value and derivatives
Definition: Grid.cpp:489
void addGrid(vector< string > gmin, vector< string > gmax, vector< unsigned > nbin)
add the grid to the representation
BiasRepresentation(vector< Value * > tmpvalues, Communicator &cc)
create a bias representation from a list of pointer to values
Class for input files.
Definition: IFile.h:40
vector< KernelFunctions * > hills
void setRescaledToBias(bool rescaled)
set the flag that rescales the free energy to the bias
static int dummy
Definition: Plumed.c:80
IFile & scanField(const std::string &, double &)
Read a double field.
Definition: IFile.cpp:121
const vector< Value * > & getPtrToValues()
get the pointer to the values
vector< string > getNames()
get the names of the variables
std::vector< double > getPoint(unsigned index) const
Definition: Grid.cpp:222
int Get_size() const
Obtain the number of processes.
std::vector< unsigned > getNeighbors(unsigned index, const std::vector< unsigned > &neigh) const
get neighbors
Definition: Grid.cpp:300
void Sum(T *, int)
Wrapper for MPI_Allreduce with MPI_SUM.
Definition: Communicator.h:124
const string & getName(unsigned i)
get the name of the i-th value
void allowIgnoredFields()
Allow some of the fields in the input to be ignored.
Definition: IFile.cpp:199
const bool & isRescaledToBias()
check if the representation is rescaled to the bias