void BridgeVessel::completeNumericalDerivatives(){ unsigned nextra = myOutputAction->getNumberOfDerivatives() - getAction()->getNumberOfDerivatives(); Matrix<double> tmpder( myOutputValues->getNumberOfComponents(), nextra ); ActionWithVessel* vval=dynamic_cast<ActionWithVessel*>( myOutputAction ); for(unsigned i=0;i<nextra;++i){ vval->bridgeVariable=i; getAction()->calculate(); for(int j=0;j<myOutputValues->getNumberOfComponents();++j) tmpder(j,i) = myOutputValues->getOutputQuantity(j); } vval->bridgeVariable=nextra; getAction()->calculate(); plumed_assert( inum==mynumerical_values.size() ); inum=0; // Reset inum now that we have finished calling calculate std::vector<double> base( myOutputValues->getNumberOfComponents() ); for(int j=0;j<myOutputValues->getNumberOfComponents();++j) base[j] = myOutputValues->getOutputQuantity(j); const double delta=sqrt(epsilon); ActionAtomistic* aa=dynamic_cast<ActionAtomistic*>( getAction() ); unsigned nvals=myOutputValues->getNumberOfComponents(); for(unsigned j=0;j<nvals;++j) ( myOutputValues->copyOutput(j) )->clearDerivatives(); if( aa ){ ActionWithArguments* aarg=dynamic_cast<ActionWithArguments*>( getAction() ); plumed_assert( !aarg ); Tensor box=aa->getBox(); unsigned natoms=aa->getNumberOfAtoms(); for(unsigned j=0;j<nvals;++j){ double ref=( myOutputValues->copyOutput(j) )->get(); if( ( myOutputValues->copyOutput(j) )->getNumberOfDerivatives()>0 ){ for(unsigned i=0;i<3*natoms;++i){ double d=( mynumerical_values[i*nvals+j] - ref)/delta; ( myOutputValues->copyOutput(j) )->addDerivative(i,d); } Tensor virial; for(int i=0;i<3;i++) for(int k=0;k<3;k++){ virial(i,k)=( mynumerical_values[ nvals*(3*natoms + 3*i + k) + j ]-ref)/delta; } virial=-matmul(box.transpose(),virial); for(int i=0;i<3;i++) for(int k=0;k<3;k++) ( myOutputValues->copyOutput(j) )->addDerivative(3*natoms+3*k+i,virial(k,i)); } } } else { plumed_merror("not implemented or tested yet"); // unsigned nder=myOutputAction->getNumberOfDerivatives(); // for(unsigned j=0;j<nvals;++j){ // double ref=( myOutputValues->copyOutput(j) )->get(); // for(unsigned i=0;i<nder;++i){ // double d=( mynumerical_values[i*nvals+j] - ref)/delta; // ( myOutputValues->copyOutput(j) )->addDerivative(i,d); // } // } // } } // Add the derivatives wrt to the local quantities we are working with for(unsigned j=0;j<nvals;++j){ unsigned k=0; for(unsigned i=getAction()->getNumberOfDerivatives();i<myOutputAction->getNumberOfDerivatives();++i){ ( myOutputValues->copyOutput(j) )->addDerivative( i, (tmpder(j,k)-base[j])/sqrt(epsilon) ); k++; } } }
void Molecular_system::locDerivative(int ion, Sample_point * sample, Force_fitter & fitter, Array1 <doublevar> & der) { sample->updateEIDist(); der.Resize(3); der=0; Array1 <doublevar> R(5); int ne=sample->electronSize(); Array1 <doublevar> tmpder(3), tmpder_fit(3); for(int e=0; e< ne; e++) { sample->getEIDist(e,ion, R); for(int d=0; d< 3; d++) //der(d)-=sample->getIonCharge(ion)*R(d+2)/(R(1)*R(0)); tmpder(d)=-sample->getIonCharge(ion)*R(d+2)/(R(1)*R(0)); fitter.fit_force(R,tmpder, tmpder_fit); for(int d=0; d< 3; d++) der(d)+=tmpder_fit(d); } Array1 <doublevar> vec(3); Array1 <doublevar> r_ion(3); sample->getIonPos(ion, r_ion); int nIon=sample->ionSize(); for(int j=0; j< nIon; j++) { if(j!=ion) { sample->getIonPos(j,R); doublevar r2=0; for(int d=0; d <3; d++) vec(d)=r_ion(d)-R(d); for(int d=0; d< 3; d++) r2+=vec(d)*vec(d); doublevar r=sqrt(r2); for(int d=0; d< 3; d++) der(d)-=sample->getIonCharge(ion)*sample->getIonCharge(j)*vec(d)/(r2*r); } } }
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); } } } }