// calculator void CoordinationBase::calculate() { double ncoord=0.; Tensor virial; vector<Vector> deriv(getNumberOfAtoms()); // deriv.resize(getPositions().size()); if(nl->getStride()>0 && invalidateList){ nl->update(getPositions()); } unsigned stride=comm.Get_size(); unsigned rank=comm.Get_rank(); if(serial){ stride=1; rank=0; }else{ stride=comm.Get_size(); rank=comm.Get_rank(); } for(unsigned int i=rank;i<nl->size();i+=stride) { // sum over close pairs Vector distance; unsigned i0=nl->getClosePair(i).first; unsigned i1=nl->getClosePair(i).second; if(getAbsoluteIndex(i0)==getAbsoluteIndex(i1)) continue; if(pbc){ distance=pbcDistance(getPosition(i0),getPosition(i1)); } else { distance=delta(getPosition(i0),getPosition(i1)); } double dfunc=0.; ncoord += pairing(distance.modulo2(), dfunc,i0,i1); deriv[i0] = deriv[i0] + (-dfunc)*distance ; deriv[i1] = deriv[i1] + dfunc*distance ; virial=virial+(-dfunc)*Tensor(distance,distance); } if(!serial){ comm.Sum(ncoord); if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size()); comm.Sum(virial); } for(unsigned i=0;i<deriv.size();++i) setAtomsDerivatives(i,deriv[i]); setValue (ncoord); setBoxDerivatives (virial); }
// calculator void CoordinationBase::calculate() { double ncoord=0.; Tensor virial; vector<Vector> deriv(getNumberOfAtoms()); // deriv.resize(getPositions().size()); if(nl->getStride()>0 && invalidateList) { nl->update(getPositions()); } unsigned stride=comm.Get_size(); unsigned rank=comm.Get_rank(); if(serial) { stride=1; rank=0; } else { stride=comm.Get_size(); rank=comm.Get_rank(); } unsigned nt=OpenMP::getNumThreads(); const unsigned nn=nl->size(); if(nt*stride*10>nn) nt=nn/stride/10; if(nt==0)nt=1; #pragma omp parallel num_threads(nt) { std::vector<Vector> omp_deriv(getPositions().size()); Tensor omp_virial; #pragma omp for reduction(+:ncoord) nowait for(unsigned int i=rank; i<nn; i+=stride) { Vector distance; unsigned i0=nl->getClosePair(i).first; unsigned i1=nl->getClosePair(i).second; if(getAbsoluteIndex(i0)==getAbsoluteIndex(i1)) continue; if(pbc) { distance=pbcDistance(getPosition(i0),getPosition(i1)); } else { distance=delta(getPosition(i0),getPosition(i1)); } double dfunc=0.; ncoord += pairing(distance.modulo2(), dfunc,i0,i1); Vector dd(dfunc*distance); Tensor vv(dd,distance); if(nt>1) { omp_deriv[i0]-=dd; omp_deriv[i1]+=dd; omp_virial-=vv; } else { deriv[i0]-=dd; deriv[i1]+=dd; virial-=vv; } } #pragma omp critical if(nt>1) { for(int i=0; i<getPositions().size(); i++) deriv[i]+=omp_deriv[i]; virial+=omp_virial; } } if(!serial) { comm.Sum(ncoord); if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size()); comm.Sum(virial); } for(unsigned i=0; i<deriv.size(); ++i) setAtomsDerivatives(i,deriv[i]); setValue (ncoord); setBoxDerivatives (virial); }
void PathMSDBase::calculate(){ if(neigh_size>0 && getExchangeStep()) error("Neighbor lists for this collective variable are not compatible with replica exchange, sorry for that!"); //log.printf("NOW CALCULATE! \n"); // resize the list to full if(imgVec.empty()){ // this is the signal that means: recalculate all imgVec.resize(nframes); for(unsigned i=0;i<nframes;i++){ imgVec[i].property=indexvec[i]; imgVec[i].index=i; } } // THIS IS THE HEAVY PART (RMSD STUFF) unsigned stride=comm.Get_size(); unsigned rank=comm.Get_rank(); unsigned nat=pdbv[0].size(); plumed_assert(nat>0); plumed_assert(nframes>0); plumed_assert(imgVec.size()>0); std::vector<double> tmp_distances(imgVec.size(),0.0); std::vector<Vector> tmp_derivs; // this array is a merge of all tmp_derivs, so as to allow a single comm.Sum below std::vector<Vector> tmp_derivs2(imgVec.size()*nat); // if imgVec.size() is less than nframes, it means that only some msd will be calculated for(unsigned i=rank;i<imgVec.size();i+=stride){ // store temporary local results tmp_distances[i]=msdv[imgVec[i].index].calculate(getPositions(),tmp_derivs,true); plumed_assert(tmp_derivs.size()==nat); for(unsigned j=0;j<nat;j++) tmp_derivs2[i*nat+j]=tmp_derivs[j]; } // reduce over all processors comm.Sum(tmp_distances); comm.Sum(tmp_derivs2); // assign imgVec[i].distance and imgVec[i].distder for(unsigned i=0;i<imgVec.size();i++){ imgVec[i].distance=tmp_distances[i]; imgVec[i].distder.assign(&tmp_derivs2[i*nat],nat+&tmp_derivs2[i*nat]); } // END OF THE HEAVY PART vector<Value*> val_s_path; if(labels.size()>0){ for(unsigned i=0;i<labels.size();i++){ val_s_path.push_back(getPntrToComponent(labels[i].c_str()));} }else{ val_s_path.push_back(getPntrToComponent("sss")); } Value* val_z_path=getPntrToComponent("zzz"); vector<double> s_path(val_s_path.size());for(unsigned i=0;i<s_path.size();i++)s_path[i]=0.; double partition=0.; double tmp; // clean vector for(unsigned i=0;i< derivs_z.size();i++){derivs_z[i].zero();} typedef vector< class ImagePath >::iterator imgiter; for(imgiter it=imgVec.begin();it!=imgVec.end();++it){ (*it).similarity=exp(-lambda*((*it).distance)); //log<<"DISTANCE "<<(*it).distance<<"\n"; for(unsigned i=0;i<s_path.size();i++){ s_path[i]+=((*it).property[i])*(*it).similarity; } partition+=(*it).similarity; } for(unsigned i=0;i<s_path.size();i++){ s_path[i]/=partition; val_s_path[i]->set(s_path[i]) ;} val_z_path->set(-(1./lambda)*std::log(partition)); for(unsigned j=0;j<s_path.size();j++){ // clean up for(unsigned i=0;i< derivs_s.size();i++){derivs_s[i].zero();} // do the derivative for(imgiter it=imgVec.begin();it!=imgVec.end();++it){ double expval=(*it).similarity; tmp=lambda*expval*(s_path[j]-(*it).property[j])/partition; for(unsigned i=0;i< derivs_s.size();i++){ derivs_s[i]+=tmp*(*it).distder[i] ;} if(j==0){for(unsigned i=0;i< derivs_z.size();i++){ derivs_z[i]+=(*it).distder[i]*expval/partition;}} } for(unsigned i=0;i< derivs_s.size();i++){ setAtomsDerivatives (val_s_path[j],i,derivs_s[i]); if(j==0){setAtomsDerivatives (val_z_path,i,derivs_z[i]);} } } for(unsigned i=0;i<val_s_path.size();++i) setBoxDerivativesNoPbc(val_s_path[i]); setBoxDerivativesNoPbc(val_z_path); // // here set next round neighbors // if (neigh_size>0){ //if( int(getStep())%int(neigh_stride/getTimeStep())==0 ){ // enforce consistency: the stride is in time steps if( int(getStep())%int(neigh_stride)==0 ){ // next round do it all:empty the vector imgVec.clear(); } // time to analyze the results: if(imgVec.size()==nframes){ //sort by msd sort(imgVec.begin(), imgVec.end(), imgOrderByDist()); //resize imgVec.resize(neigh_size); } } //log.printf("CALCULATION DONE! \n"); }