示例#1
0
void ActionWithVessel::getIndexList( const unsigned& ntotal, const unsigned& jstore, const unsigned& maxder, std::vector<unsigned>& indices ){
  indices[jstore]=getNumberOfDerivatives();
  if( indices[jstore]>maxder ) error("too many derivatives to store. Run with LOWMEM");

  unsigned kder = ntotal + jstore*getNumberOfDerivatives();
  for(unsigned jder=0;jder<getNumberOfDerivatives();++jder){ indices[ kder ] = jder; kder++; }
}
示例#2
0
void VectorMultiColvar::addForcesOnAtoms( const std::vector<double>& inforces ){
  plumed_dbg_assert( inforces.size()==getNumberOfDerivatives() );
  std::vector<double> oldforces( getNumberOfDerivatives() ); 
  getForcesFromVessels( oldforces ); 
  for(unsigned i=0;i<getNumberOfDerivatives();++i) oldforces[i]+=inforces[i];
  setForcesOnAtoms( oldforces );
}
示例#3
0
void ActionWithVessel::readVesselKeywords(){
  // Set maxderivatives if it is too big
  if( maxderivatives>getNumberOfDerivatives() ) maxderivatives=getNumberOfDerivatives();

  // Loop over all keywords find the vessels and create appropriate functions
  for(unsigned i=0;i<keywords.size();++i){
      std::string thiskey,input; thiskey=keywords.getKeyword(i);
      // Check if this is a key for a vessel
      if( vesselRegister().check(thiskey) ){
          plumed_assert( keywords.style(thiskey,"vessel") );
          bool dothis=false; parseFlag(thiskey,dothis);
          if(dothis) addVessel( thiskey, input );

          parse(thiskey,input);
          if(input.size()!=0){ 
                addVessel( thiskey, input );
          } else {
             for(unsigned i=1;;++i){
                if( !parseNumbered(thiskey,i,input) ) break;
                std::string ss; Tools::convert(i,ss);
                addVessel( thiskey, input, i ); 
                input.clear();
             } 
          }
      }
  }

  // Make sure all vessels have had been resized at start
  if( functions.size()>0 ) resizeFunctions();
}
void BridgedMultiColvarFunction::clearDerivativesAfterTask( const unsigned& ider ){
  unsigned vstart=getNumberOfDerivatives()*ider;
  if( derivativesAreRequired() ){
     // Clear atom derivatives
     for(unsigned i=0;i<atoms_with_derivatives.getNumberActive();++i){
        unsigned iatom=vstart+3*atoms_with_derivatives[i];
        setElementDerivative( iatom, 0.0 ); iatom++;
        setElementDerivative( iatom, 0.0 ); iatom++;
        setElementDerivative( iatom, 0.0 );
     }
     // Clear virial contribution
     unsigned nvir=vstart+3*mycolv->getNumberOfAtoms();
     for(unsigned j=0;j<9;++j){
        setElementDerivative( nvir, 0.0 ); nvir++;
     }
     // Clear derivatives of local atoms
     for(unsigned j=0;j<getNumberOfAtoms();++j){
        setElementDerivative( nvir, 0.0 ); nvir++;
        setElementDerivative( nvir, 0.0 ); nvir++;
        setElementDerivative( nvir, 0.0 ); nvir++;
     }
     plumed_dbg_assert( (nvir-vstart)==getNumberOfDerivatives() );
  }
  // Clear values
  thisval_wasset[ider]=false; setElementValue( ider, 0.0 ); thisval_wasset[ider]=false;
}
示例#5
0
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() );
}
示例#6
0
void ActionWithVessel::chainRuleForElementDerivatives( const unsigned& iout, const unsigned& ider, const unsigned& stride, 
                                                       const unsigned& off, const double& df, Vessel* valout ){
  plumed_dbg_assert( off<stride );
  current_buffer_stride=stride;
  current_buffer_start=valout->bufstart + stride*(getNumberOfDerivatives()+1)*iout + stride + off;
  mergeDerivatives( ider, df );
}
Vector BridgedMultiColvarFunction::retrieveCentralAtomPos(){
  if( atomsWithCatomDer.getNumberActive()==0 ){
      Vector cvec = mycolv->retrieveCentralAtomPos();

      // Copy the value and derivatives from the MultiColvar
      atomsWithCatomDer.emptyActiveMembers();
      for(unsigned i=0;i<3;++i){
         setElementValue( getCentralAtomElementIndex() + i, mycolv->getElementValue( mycolv->getCentralAtomElementIndex() + i ) );
         unsigned nbase = ( getCentralAtomElementIndex() + i)*getNumberOfDerivatives();
         unsigned nbas2 = ( mycolv->getCentralAtomElementIndex() + i )*mycolv->getNumberOfDerivatives();
         for(unsigned j=0;j<mycolv->atomsWithCatomDer.getNumberActive();++j){
             unsigned n=mycolv->atomsWithCatomDer[j], nx=3*n; atomsWithCatomDer.activate(n);
             addElementDerivative(nbase + nx + 0, mycolv->getElementDerivative(nbas2 + nx + 0) );
             addElementDerivative(nbase + nx + 1, mycolv->getElementDerivative(nbas2 + nx + 1) );
             addElementDerivative(nbase + nx + 2, mycolv->getElementDerivative(nbas2 + nx + 2) ); 
         } 
      }
      for(unsigned j=0;j<mycolv->atomsWithCatomDer.getNumberActive();++j) atomsWithCatomDer.updateIndex( mycolv->atomsWithCatomDer[j] );
      atomsWithCatomDer.sortActiveList();
      return cvec;
  }
  Vector cvec;
  for(unsigned i=0;i<3;++i) cvec[i]=getElementValue(1+i);
  return cvec;
}
示例#8
0
void Histogram::apply() {
  if( !myhist->wasForced() ) return ;
  in_apply=true;
  // Run the loop to calculate the forces
  runAllTasks(); finishAveraging();
  // We now need to retrieve the buffer and set the forces on the atoms
  myhist->applyForce( forcesToApply );
  // Now make the forces make sense for the virial
  unsigned fbase=0, tbase=0, vbase = getNumberOfDerivatives() - myvessels.size()*9;
  for(unsigned i=vbase; i<vbase+9; ++i) finalForces[i]=0.0;
  for(unsigned i=0; i<myvessels.size(); ++i) {
    for(unsigned j=0; j<myvessels[i]->getNumberOfDerivatives()-9; ++j) {
      finalForces[fbase + j] = forcesToApply[tbase + j];
    }
    unsigned k=0;
    for(unsigned j=myvessels[i]->getNumberOfDerivatives()-9; j<myvessels[i]->getNumberOfDerivatives(); ++j) {
      finalForces[vbase + k] += forcesToApply[tbase + j]; k++;
    }
    fbase += myvessels[i]->getNumberOfDerivatives() - 9;
    tbase += myvessels[i]->getNumberOfDerivatives();
  }
  // And set the final forces on the atoms
  setForcesOnAtoms( finalForces );
  // Reset everything for next regular loop
  in_apply=false;
}
void SecondaryStructureRMSD::readBackboneAtoms( const std::string& moltype, std::vector<unsigned>& chain_lengths ){
  std::vector<SetupMolInfo*> moldat=plumed.getActionSet().select<SetupMolInfo*>();
  if( moldat.size()==0 ) error("Unable to find MOLINFO in input");

  std::vector<std::string> resstrings; parseVector( "RESIDUES", resstrings );
  if( !verbose_output ){
      if(resstrings[0]=="all"){
         log.printf("  examining all possible secondary structure combinations\n");
      } else {
         log.printf("  examining secondary struture in residue poritions : %s \n",resstrings[0].c_str() );
         for(unsigned i=1;i<resstrings.size();++i) log.printf(", %s",resstrings[i].c_str() );
         log.printf("\n");
      }
  }
  std::vector< std::vector<AtomNumber> > backatoms;
  moldat[0]->getBackbone( resstrings, moltype, backatoms );

  chain_lengths.resize( backatoms.size() );
  for(unsigned i=0;i<backatoms.size();++i){
     chain_lengths[i]=backatoms[i].size();
     for(unsigned j=0;j<backatoms[i].size();++j) all_atoms.push_back( backatoms[i][j] );
  }
  ActionAtomistic::requestAtoms( all_atoms );
  forcesToApply.resize( getNumberOfDerivatives() );
}
示例#10
0
void MultiColvarBase::quotientRule( const unsigned& uder, const unsigned& vder, const unsigned& iout ){
  unsigned ustart=uder*getNumberOfDerivatives();
  unsigned vstart=vder*getNumberOfDerivatives();
  unsigned istart=iout*getNumberOfDerivatives();
  double weight = getElementValue( vder ), pref = getElementValue( uder ) / (weight*weight);
  if( !doNotCalculateDerivatives() ){
      for(unsigned i=0;i<atoms_with_derivatives.getNumberActive();++i){
          unsigned n=3*atoms_with_derivatives[i], nx=n, ny=n+1, nz=n+2;
          setElementDerivative( istart + nx, getElementDerivative(ustart+nx) / weight - pref*getElementDerivative(vstart+nx) );
          setElementDerivative( istart + ny, getElementDerivative(ustart+ny) / weight - pref*getElementDerivative(vstart+ny) );
          setElementDerivative( istart + nz, getElementDerivative(ustart+nz) / weight - pref*getElementDerivative(vstart+nz) );
      }
      unsigned vbase=3*getNumberOfAtoms();
      for(unsigned i=0;i<9;++i){ 
          setElementDerivative( istart + vbase + i, getElementDerivative(ustart+vbase+i) / weight - pref*getElementDerivative(vstart+vbase+i) );
      }
  }
  thisval_wasset[iout]=false; setElementValue( iout, getElementValue(uder) / weight );
}
示例#11
0
void ActionWithValue::turnOnDerivatives() {
  // Turn on the derivatives
  noderiv=false;
  // Resize the derivatives
  for(unsigned i=0; i<values.size(); ++i) values[i]->resizeDerivatives( getNumberOfDerivatives() );
  // And turn on the derivatives in all actions on which we are dependent
  for(unsigned i=0; i<getDependencies().size(); ++i) {
    ActionWithValue* vv=dynamic_cast<ActionWithValue*>( getDependencies()[i] );
    if(vv) vv->turnOnDerivatives();
  }
}
示例#12
0
bool ActionWithVessel::getForcesFromVessels( std::vector<double>& forcesToApply ){
  plumed_dbg_assert( forcesToApply.size()==getNumberOfDerivatives() );
  forcesToApply.assign( forcesToApply.size(),0.0 );
  bool wasforced=false;
  for(unsigned i=0;i<getNumberOfVessels();++i){
    if( (functions[i]->applyForce( tmpforces )) ){
       wasforced=true;
       for(unsigned j=0;j<forcesToApply.size();++j) forcesToApply[j]+=tmpforces[j];
    }
  }
  return wasforced;
}
示例#13
0
void MultiColvarBase::mergeDerivatives( const unsigned& ider, const double& df ){
  unsigned vstart=getNumberOfDerivatives()*ider;
  for(unsigned i=0;i<atoms_with_derivatives.getNumberActive();++i){
     unsigned iatom=3*atoms_with_derivatives[i];
     accumulateDerivative( iatom, df*getElementDerivative(vstart+iatom) ); iatom++;
     accumulateDerivative( iatom, df*getElementDerivative(vstart+iatom) ); iatom++;
     accumulateDerivative( iatom, df*getElementDerivative(vstart+iatom) );
  }
  unsigned nvir=3*getNumberOfAtoms();
  for(unsigned j=0;j<9;++j){
     accumulateDerivative( nvir, df*getElementDerivative(vstart+nvir) ); nvir++;
  }
}
void StoreCentralAtomsVessel::addAtomsDerivatives( const unsigned& iatom, const unsigned& jout, const unsigned& base_cv_no, 
                                                   const Vector& df, MultiColvarFunction* funcout ){
  plumed_dbg_assert( mycolv->derivativesAreRequired() );

  for(unsigned ider=0;ider<getNumberOfDerivatives(iatom);ider+=3){
     for(unsigned i=0;i<3;++i) tmpdf[i]=df[0];
     funcout->addStoredDerivative( jout, base_cv_no, getStoredIndex( iatom, ider+0 ), chainRule(iatom, ider+0, tmpdf)  ); 
     for(unsigned i=0;i<3;++i) tmpdf[i]=df[1];
     funcout->addStoredDerivative( jout, base_cv_no, getStoredIndex( iatom, ider+1 ), chainRule(iatom, ider+1, tmpdf)  );
     for(unsigned i=0;i<3;++i) tmpdf[i]=df[2];
     funcout->addStoredDerivative( jout, base_cv_no, getStoredIndex( iatom, ider+2 ), chainRule(iatom, ider+2, tmpdf)  );
  }
}
void BridgedMultiColvarFunction::mergeDerivatives( const unsigned& ider, const double& df ){
  unsigned vstart=getNumberOfDerivatives()*ider;
  // Merge atom derivatives
  for(unsigned i=0;i<atoms_with_derivatives.getNumberActive();++i){
     unsigned iatom=3*atoms_with_derivatives[i];
     accumulateDerivative( iatom, df*getElementDerivative(vstart+iatom) ); iatom++;
     accumulateDerivative( iatom, df*getElementDerivative(vstart+iatom) ); iatom++;
     accumulateDerivative( iatom, df*getElementDerivative(vstart+iatom) );
  }
  // Merge virial derivatives
  unsigned nvir=3*mycolv->getNumberOfAtoms();
  for(unsigned j=0;j<9;++j){
     accumulateDerivative( nvir, df*getElementDerivative(vstart+nvir) ); nvir++;
  }
  // Merge local atom derivatives
  for(unsigned j=0;j<getNumberOfAtoms();++j){
     accumulateDerivative( nvir, df*getElementDerivative(vstart+nvir) ); nvir++;
     accumulateDerivative( nvir, df*getElementDerivative(vstart+nvir) ); nvir++;
     accumulateDerivative( nvir, df*getElementDerivative(vstart+nvir) ); nvir++;
  }
  plumed_dbg_assert( nvir==getNumberOfDerivatives() );
}
示例#16
0
double OrientationSphere::compute(){
   // Make sure derivatives for central atom are only calculated once
   VectorMultiColvar* vv = dynamic_cast<VectorMultiColvar*>( getBaseMultiColvar(0) );
   vv->firstcall=true;

   weightHasDerivatives=true;   // The weight has no derivatives really
   double sw, value=0, denom=0, dot, f_dot, dot_df, dfunc; Vector distance;

   getVectorForBaseTask(0, catom_orient );
   for(unsigned i=1;i<getNAtoms();++i){
      distance=getSeparation( getPositionOfCentralAtom(0), getPositionOfCentralAtom(i) );
      sw = switchingFunction.calculateSqr( distance.modulo2(), dfunc );
      if( sw>=getTolerance() ){    
         getVectorForBaseTask( i, this_orient );
         // Calculate the dot product wrt to this position 
         dot=0; for(unsigned k=0;k<catom_orient.size();++k) dot+=catom_orient[k]*this_orient[k];  
         f_dot = transformDotProduct( dot, dot_df ); 
         // N.B. We are assuming here that the imaginary part of the dot product is zero
         for(unsigned k=0;k<catom_orient.size();++k){
            this_orient[k]*=sw*dot_df; catom_der[k]=sw*dot_df*catom_orient[k];
         }  

         // Set the derivatives wrt of the numerator
         addOrientationDerivatives( 0, this_orient ); 
         addOrientationDerivatives( i, catom_der );  
         addCentralAtomsDerivatives( 0, 0, f_dot*(-dfunc)*distance );
         addCentralAtomsDerivatives( i, 0, f_dot*(dfunc)*distance );
         addBoxDerivatives( f_dot*(-dfunc)*Tensor(distance,distance) );
         value += sw*f_dot;
         // Set the derivatives wrt to the numerator
         addCentralAtomsDerivatives( 0, 1, (-dfunc)*distance );
         addCentralAtomsDerivatives( i, 1, (dfunc)*distance );
         addBoxDerivativesOfWeight( (-dfunc)*Tensor(distance,distance) );
         denom += sw;
      }
   }
   
   // Now divide everything
   unsigned nder = getNumberOfDerivatives();
   for(unsigned i=0;i<nder;++i){
      setElementDerivative( i, getElementDerivative(i)/denom - (value*getElementDerivative(nder+i))/(denom*denom) );  
      setElementDerivative( nder + i, 0.0 );
   }
   weightHasDerivatives=false;   // Weight has no derivatives we just use the holder for weight to store some stuff
   return value / denom;
}
示例#17
0
void MultiColvarBase::clearDerivativesAfterTask( const unsigned& ider ){
  unsigned vstart=getNumberOfDerivatives()*ider;
  thisval_wasset[ider]=false; setElementValue( ider, 0.0 );
  thisval_wasset[ider]=false;
  if( ider>1 && ider<5 && derivativesAreRequired() ){
     for(unsigned i=0;i<atomsWithCatomDer.getNumberActive();++i){
        unsigned iatom=vstart+3*atomsWithCatomDer[i];
        setElementDerivative( iatom, 0.0 ); iatom++;
        setElementDerivative( iatom, 0.0 ); iatom++;
        setElementDerivative( iatom, 0.0 );
     }  
  } else if( derivativesAreRequired() ) {
     for(unsigned i=0;i<atoms_with_derivatives.getNumberActive();++i){
        unsigned iatom=vstart+3*atoms_with_derivatives[i];
        setElementDerivative( iatom, 0.0 ); iatom++;
        setElementDerivative( iatom, 0.0 ); iatom++;
        setElementDerivative( iatom, 0.0 );
     }   
     unsigned nvir=vstart+3*getNumberOfAtoms();
     for(unsigned j=0;j<9;++j){
        setElementDerivative( nvir, 0.0 ); nvir++;
     }
  }
}
示例#18
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");
}
示例#19
0
void ActionWithVessel::clearDerivativesAfterTask( const unsigned& ider ){
  unsigned kstart=ider*getNumberOfDerivatives();
  thisval[ider]=0.0; thisval_wasset[ider]=false;
  for(unsigned j=0;j<getNumberOfDerivatives();++j) derivatives[ kstart+j ]=0.0;
}
示例#20
0
void MultiColvarBase::turnOnDerivatives(){
  ActionWithValue::turnOnDerivatives();
  needsDerivatives(); 
  forcesToApply.resize( getNumberOfDerivatives() );
} 
示例#21
0
void ActionWithVessel::chainRuleForElementDerivatives( const unsigned& iout, const unsigned& ider, const double& df, Vessel* valout ){
  current_buffer_stride=1;
  current_buffer_start=valout->bufstart + (getNumberOfDerivatives()+1)*iout + 1;
  mergeDerivatives( ider, df );
} 
示例#22
0
void ActionWithVessel::mergeDerivatives( const unsigned& ider, const double& df ){
  unsigned nder=getNumberOfDerivatives(), vstart=nder*ider; 
  for(unsigned i=0;i<getNumberOfDerivatives();++i){
     accumulateDerivative( i, df*derivatives[vstart+i] ); 
  }
}