コード例 #1
0
void VectorMultiColvar::addWeightedValueDerivatives( const unsigned& iatom, const unsigned& base_cv_no, const double& weight, multicolvar::MultiColvarFunction* func ){
  if( usingLowMem() ){
     vecs->recompute( iatom, 1 ); 
     for(unsigned j=0;j<getNumberOfQuantities()-5;++j) vecs->chainRuleForComponent( 1, j, 5+j, base_cv_no, weight, func );
  } else {
     for(unsigned j=0;j<getNumberOfQuantities()-5;++j) vecs->chainRuleForComponent( iatom, j, 5+j, base_cv_no, weight, func );
  }
}
コード例 #2
0
ファイル: ActionWithVessel.cpp プロジェクト: apoma/plumed2
void ActionWithVessel::resizeFunctions(){
  unsigned bufsize=0; 
  for(unsigned i=0;i<functions.size();++i){
     functions[i]->bufstart=bufsize;
     functions[i]->resize();
     bufsize+=functions[i]->bufsize;
  }
  thisval.resize( getNumberOfQuantities() ); thisval_wasset.resize( getNumberOfQuantities(), false );
  derivatives.resize( getNumberOfQuantities()*getNumberOfDerivatives(), 0.0 );
  buffer.resize( bufsize );
  tmpforces.resize( getNumberOfDerivatives() );
}
コード例 #3
0
ファイル: HistogramOnGrid.cpp プロジェクト: plumed/plumed2
void HistogramOnGrid::getFinalForces( const std::vector<double>& buffer, std::vector<double>& finalForces ) {
    if( finalForces.size()!=getAction()->getNumberOfDerivatives() ) finalForces.resize( getAction()->getNumberOfDerivatives() );
    // And the final force
    unsigned nder = getAction()->getNumberOfDerivatives();
    // Derivatives due to normalization
    unsigned gridbuf = getNumberOfBufferPoints()*getNumberOfQuantities();
    for(unsigned i=0; i<finalForces.size(); ++i) finalForces[i] = buffer[ bufstart + gridbuf + i ];
    // Derivatives due to normalization
    if( !noAverage() ) {
        unsigned wderstart = bufstart + gridbuf + nder;
        double pref=0;
        for(unsigned ipoint=0; ipoint<getNumberOfPoints(); ++ipoint) {
            pref += forces[ipoint]*buffer[ bufstart + ipoint*nper ] / buffer[wderstart];
        }
        for(unsigned j=0; j<finalForces.size(); ++j) finalForces[j] -= pref*buffer[ wderstart + 1 + j ];
    }
}
コード例 #4
0
void ActionWithVessel::runAllTasks(){
  if( getExchangeStep() && nactive_tasks!=fullTaskList.size()  ) error("contributors must be unlocked during exchange steps");
  plumed_massert( functions.size()>0, "you must have a call to readVesselKeywords somewhere" );
  unsigned stride=comm.Get_size();
  unsigned rank=comm.Get_rank();
  if(serial){ stride=1; rank=0; }

  // Make sure jobs are done
  if(timers) stopwatch.start("1 Prepare Tasks");
  doJobsRequiredBeforeTaskList();
  if(timers) stopwatch.stop("1 Prepare Tasks");

  // Get number of threads for OpenMP
  unsigned nt=OpenMP::getNumThreads();
  if( nt*stride*10>nactive_tasks) nt=nactive_tasks/stride/10;
  if( nt==0 ) nt=1;

  // Get size for buffer
  unsigned bsize=0, bufsize=getSizeOfBuffer( bsize ); 
  // Clear buffer
  buffer.assign( buffer.size(), 0.0 );
  // Switch off calculation of derivatives in main loop
  if( dertime_can_be_off ) dertime=false;

  // std::vector<unsigned> der_list;
  // if( mydata ) der_list.resize( mydata->getSizeOfDerivativeList(), 0 ); 

  // Build storage stuff for loop
  // std::vector<double> buffer( bufsize, 0.0 );

  if(timers) stopwatch.start("2 Loop over tasks");
#pragma omp parallel num_threads(nt)
{
  std::vector<double> omp_buffer;
  if( nt>1 ) omp_buffer.resize( bufsize, 0.0 );
  MultiValue myvals( getNumberOfQuantities(), getNumberOfDerivatives() );
  MultiValue bvals( getNumberOfQuantities(), getNumberOfDerivatives() );
  myvals.clearAll(); bvals.clearAll();
 
#pragma omp for nowait
  for(unsigned i=rank;i<nactive_tasks;i+=stride){
      // Calculate the stuff in the loop for this action
      performTask( indexOfTaskInFullList[i], partialTaskList[i], myvals );
      // Weight should be between zero and one
      plumed_dbg_assert( myvals.get(0)>=0 && myvals.get(0)<=1.0 );

      // Check for conditions that allow us to just to skip the calculation
      // the condition is that the weight of the contribution is low 
      // N.B. Here weights are assumed to be between zero and one
      if( myvals.get(0)<tolerance ){
         // Deactivate task if it is less than the neighbor list tolerance
         if( myvals.get(0)<nl_tolerance && contributorsAreUnlocked ) deactivate_task( indexOfTaskInFullList[i] );
         // Clear the derivatives
         myvals.clearAll();
         continue;
      }

      // Now calculate all the functions
      // If the contribution of this quantity is very small at neighbour list time ignore it
      // untill next neighbour list time
      if( nt>1 ){
          if( !calculateAllVessels( indexOfTaskInFullList[i], myvals, bvals, omp_buffer, der_list ) && contributorsAreUnlocked ) deactivate_task( indexOfTaskInFullList[i] );
      } else {
          if( !calculateAllVessels( indexOfTaskInFullList[i], myvals, bvals, buffer, der_list ) && contributorsAreUnlocked ) deactivate_task( indexOfTaskInFullList[i] );
      }

      // Clear the value
      myvals.clearAll();
  }
#pragma omp critical
  if(nt>1) for(unsigned i=0;i<bufsize;++i) buffer[i]+=omp_buffer[i];
}
  if(timers) stopwatch.stop("2 Loop over tasks");
  // Turn back on derivative calculation
  dertime=true;

  if(timers) stopwatch.start("3 MPI gather");
  // MPI Gather everything
  if( !serial && buffer.size()>0 ) comm.Sum( buffer );
  // MPI Gather index stores
  if( mydata && !lowmem && !noderiv ){ 
     comm.Sum( der_list ); mydata->setActiveValsAndDerivatives( der_list ); 
  }
  // Update the elements that are makign contributions to the sum here
  // this causes problems if we do it in prepare
  if( !serial && contributorsAreUnlocked ) comm.Sum( taskFlags );
  if(timers) stopwatch.stop("3 MPI gather");

  if(timers) stopwatch.start("4 Finishing computations");
  finishComputations( buffer );
  if(timers) stopwatch.stop("4 Finishing computations");
}
コード例 #5
0
ファイル: HistogramOnGrid.cpp プロジェクト: plumed/plumed2
void HistogramOnGrid::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
    if( addOneKernelAtATime ) {
        plumed_dbg_assert( myvals.getNumberOfValues()==2 && !wasforced );
        std::vector<double> der( dimension );
        for(unsigned i=0; i<dimension; ++i) der[i]=myvals.getDerivative( 1, i );
        accumulate( getAction()->getPositionInCurrentTaskList(current), myvals.get(0), myvals.get(1), der, buffer );
    } else {
        plumed_dbg_assert( myvals.getNumberOfValues()==dimension+2 );
        std::vector<double> point( dimension );
        double weight=myvals.get(0)*myvals.get( 1+dimension );
        for(unsigned i=0; i<dimension; ++i) point[i]=myvals.get( 1+i );

        // Get the kernel
        unsigned num_neigh;
        std::vector<unsigned> neighbors;
        std::vector<double> der( dimension );
        KernelFunctions* kernel=getKernelAndNeighbors( point, num_neigh, neighbors );
        // If no kernel normalize the vector so von misses distribution is calculated correctly
        if( !kernel ) {
            double norm=0;
            for(unsigned j=0; j<dimension; ++j) norm += point[j]*point[j];
            norm=sqrt( norm );
            for(unsigned j=0; j<dimension; ++j) point[j] = point[j] / norm;
        }

        if( !kernel && getType()=="flat" ) {
            plumed_dbg_assert( num_neigh==1 );
            accumulate( neighbors[0], weight, 1.0, der, buffer );
        } else {
            double totwforce=0.0;
            std::vector<double> intforce( 2*dimension, 0.0 );
            std::vector<Value*> vv( getVectorOfValues() );

            double newval;
            std::vector<double> xx( dimension );
            for(unsigned i=0; i<num_neigh; ++i) {
                unsigned ineigh=neighbors[i];
                if( inactive( ineigh ) ) continue ;
                getGridPointCoordinates( ineigh, xx );
                for(unsigned j=0; j<dimension; ++j) vv[j]->set(xx[j]);
                if( kernel ) {
                    newval = kernel->evaluate( vv, der, true );
                } else {
                    // Evalulate dot product
                    double dot=0;
                    for(unsigned j=0; j<dimension; ++j) {
                        dot+=xx[j]*point[j];
                        der[j]=xx[j];
                    }
                    // Von misses distribution for concentration parameter
                    newval = von_misses_norm*exp( von_misses_concentration*dot );
                    // And final derivatives
                    for(unsigned j=0; j<dimension; ++j) der[j] *= von_misses_concentration*newval;
                }
                accumulate( ineigh, weight, newval, der, buffer );
                if( wasForced() ) {
                    accumulateForce( ineigh, weight, der, intforce );
                    totwforce += myvals.get( 1+dimension )*newval*forces[ineigh];
                }
            }
            if( wasForced() ) {
                unsigned nder = getAction()->getNumberOfDerivatives();
                unsigned gridbuf = getNumberOfBufferPoints()*getNumberOfQuantities();
                for(unsigned j=0; j<dimension; ++j) {
                    for(unsigned k=0; k<myvals.getNumberActive(); ++k) {
                        // Minus sign here as we are taking derivative with respect to position of center of kernel NOT derivative wrt to
                        // grid point
                        unsigned kder=myvals.getActiveIndex(k);
                        buffer[ bufstart + gridbuf + kder ] -= intforce[j]*myvals.getDerivative( j+1, kder );
                    }
                }
                // Accumulate the sum of all the weights
                buffer[ bufstart + gridbuf + nder ] += myvals.get(0);
                // Add the derivatives of the weights into the force -- this is separate loop as weights of all parts are considered together
                for(unsigned k=0; k<myvals.getNumberActive(); ++k) {
                    unsigned kder=myvals.getActiveIndex(k);
                    buffer[ bufstart + gridbuf + kder ] += totwforce*myvals.getDerivative( 0, kder );
                    buffer[ bufstart + gridbuf + nder + 1 + kder ] += myvals.getDerivative( 0, kder );
                }
            }
            delete kernel;
            for(unsigned i=0; i<dimension; ++i) delete vv[i];
        }
    }
}