KernelFunctions* HistogramOnGrid::getKernelAndNeighbors( std::vector<double>& point, unsigned& num_neigh, std::vector<unsigned>& neighbors ) const { if( discrete ) { plumed_assert( getType()=="flat" ); num_neigh=1; for(unsigned i=0; i<dimension; ++i) point[i] += 0.5*dx[i]; neighbors[0] = getIndex( point ); return NULL; } else if( getType()=="flat" ) { KernelFunctions* kernel = new KernelFunctions( point, bandwidths, kerneltype, false, 1.0, true ); getNeighbors( kernel->getCenter(), nneigh, num_neigh, neighbors ); return kernel; } else { num_neigh = getNumberOfPoints(); if( neighbors.size()!=getNumberOfPoints() ) neighbors.resize( getNumberOfPoints() ); for(unsigned i=0; i<getNumberOfPoints(); ++i) neighbors[i]=i; } return NULL; }
void BiasRepresentation::pushKernel( IFile *ifile ){ KernelFunctions *kk; // here below the reading of the kernel is completely hidden if(histosigma.size()==0){ ifile->allowIgnoredFields(); kk=KernelFunctions::read(ifile,names) ; }else{ // when doing histogram assume gaussian with a given diagonal sigma // and neglect all the rest kk=readFromPoint(ifile) ; } hills.push_back(kk); // the bias factor is not something about the kernels but // must be stored to keep the bias/free energy duality string dummy; double dummyd; if(ifile->FieldExist("biasf")){ ifile->scanField("biasf",dummy); Tools::convert(dummy,dummyd); }else{dummyd=1.0;} biasf.push_back(dummyd); // the domain does not pertain to the kernel but to the values here defined string mins,maxs,minv,maxv,mini,maxi;mins="min_";maxs="max_"; for(int i=0 ; i<ndim; i++){ if(values[i]->isPeriodic()){ ifile->scanField(mins+names[i],minv); ifile->scanField(maxs+names[i],maxv); // verify that the domain is correct values[i]->getDomain(mini,maxi); plumed_massert(mini==minv,"the input periodicity in hills and in value definition does not match" ); plumed_massert(maxi==maxv,"the input periodicity in hills and in value definition does not match" ); } } // if grid is defined then it should be added on the grid //cerr<<"now with "<<hills.size()<<endl; if(hasgrid){ vector<unsigned> nneighb=kk->getSupport(BiasGrid_->getDx()); vector<unsigned> neighbors=BiasGrid_->getNeighbors(kk->getCenter(),nneighb); vector<double> der(ndim); vector<double> xx(ndim); if(mycomm.Get_size()==1){ for(unsigned i=0;i<neighbors.size();++i){ unsigned ineigh=neighbors[i]; for(int j=0;j<ndim;++j){der[j]=0.0;} BiasGrid_->getPoint(ineigh,xx); // assign xx to a new vector of values for(int j=0;j<ndim;++j){values[j]->set(xx[j]);} double bias=kk->evaluate(values,der,true); if(rescaledToBias){ double f=(biasf.back()-1.)/(biasf.back()); bias*=f; for(int j=0;j<ndim;++j){der[j]*=f;} } BiasGrid_->addValueAndDerivatives(ineigh,bias,der); } } else { unsigned stride=mycomm.Get_size(); unsigned rank=mycomm.Get_rank(); vector<double> allder(ndim*neighbors.size(),0.0); vector<double> allbias(neighbors.size(),0.0); vector<double> tmpder(ndim); for(unsigned i=rank;i<neighbors.size();i+=stride){ unsigned ineigh=neighbors[i]; BiasGrid_->getPoint(ineigh,xx); for(int j=0;j<ndim;++j){values[j]->set(xx[j]);} allbias[i]=kk->evaluate(values,tmpder,true); if(rescaledToBias){ double f=(biasf.back()-1.)/(biasf.back()); allbias[i]*=f; for(int j=0;j<ndim;++j){tmpder[j]*=f;} } // this solution with the temporary vector is rather bad, probably better to take // a pointer of double as it was in old gaussian for(int j=0;j<ndim;++j){ allder[ndim*i+j]=tmpder[j];tmpder[j]=0.;} } mycomm.Sum(allbias); mycomm.Sum(allder); for(unsigned i=0;i<neighbors.size();++i){ unsigned ineigh=neighbors[i]; for(int j=0;j<ndim;++j){der[j]=allder[ndim*i+j];} BiasGrid_->addValueAndDerivatives(ineigh,allbias[i],der); } } } }