void SecondaryStructureRMSD::setSecondaryStructure( std::vector<Vector>& structure, double bondlength, double units ){
  // If we are in natural units get conversion factor from nm into natural length units
  if( plumed.getAtoms().usingNaturalUnits() ){
      error("cannot use this collective variable when using natural units");
  }
  plumed_massert( !(align_strands && align_atom_1==0 && align_atom_2==0), "you must use setAtomsFromStrands with strands cutoff"); 

  // Convert into correct units
  for(unsigned i=0;i<structure.size();++i){
     structure[i][0]*=units; structure[i][1]*=units; structure[i][2]*=units;
  }

  if( references.size()==0 ){
     finishTaskListUpdate();

     readVesselKeywords();
     if( getNumberOfVessels()==0 ){
         double r0; parse("R_0",r0); double d0; parse("D_0",d0);
         int nn; parse("NN",nn); int mm; parse("MM",mm);
         std::ostringstream ostr;
         ostr<<"RATIONAL R_0="<<r0<<" D_0="<<d0<<" NN="<<nn<<" MM="<<mm;
         std::string input=ostr.str(); addVessel( "LESS_THAN", input, -1 ); // -1 here means that this value will be named getLabel()
         readVesselKeywords();  // This makes sure resizing is done
     } 
  }

  // Set the reference structure
  references.push_back( metricRegister().create<SingleDomainRMSD>( alignType ) ); 
  unsigned nn=references.size()-1;
  std::vector<double> align( structure.size(), 1.0 ), displace( structure.size(), 1.0 );
  references[nn]->setBoundsOnDistances( true , bondlength );  // We always use pbc
  references[nn]->setReferenceAtoms( structure, align, displace );
//  references[nn]->setNumberOfAtoms( structure.size() );
}
Пример #2
0
vesselbase::StoreDataVessel* MultiColvarBase::buildDataStashes( const bool& allow_wcutoff, const double& wtol ){
  // Check if vessels have already been setup
  for(unsigned i=0;i<getNumberOfVessels();++i){
     StoreColvarVessel* ssc=dynamic_cast<StoreColvarVessel*>( getPntrToVessel(i) );
     if(ssc){
        if( allow_wcutoff && !ssc->weightCutoffIsOn() ) error("Cannot have more than one data stash with different properties");
        if( !allow_wcutoff && ssc->weightCutoffIsOn() ) error("Cannot have more than one data stash with different properties");
        return ssc;
     }
  }
 
  // Setup central atoms
  vesselbase::VesselOptions da("","",0,"",this);
  mycatoms=new StoreCentralAtomsVessel(da);
  if( allow_wcutoff ) mycatoms->setHardCutoffOnWeight( wtol );
  addVessel(mycatoms); 

  // Setup store values vessel
  vesselbase::VesselOptions ta("","",0,"",this);
  myvalues=new StoreColvarVessel(ta);   
  if( allow_wcutoff ) myvalues->setHardCutoffOnWeight( wtol );
  addVessel(myvalues);

  // Make sure resizing of vessels is done
  resizeFunctions();
  return myvalues;
}
Пример #3
0
void ClusterAnalysisBase::turnOnDerivatives(){ 
  // Check for dubious vessels
  for(unsigned i=0;i<getNumberOfVessels();++i){
     if( getPntrToVessel(i)->getName()=="MEAN" ) error("MEAN of cluster is not differentiable");
     if( getPntrToVessel(i)->getName()=="VMEAN" ) error("VMEAN of cluster is not differentiable");  
  }
  MultiColvarBase::turnOnDerivatives();
}
Пример #4
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;
}
Пример #5
0
void MultiColvarBase::addTaskToList( const unsigned& taskCode ){
  plumed_assert( getNumberOfVessels()==0 );
  ActionWithVessel::addTaskToList( taskCode );
}
Пример #6
0
void MultiColvarBase::setupLinkCells(){
  if( !linkcells.enabled() ) return ;

  unsigned iblock;
  if( usespecies ){
      iblock=0; 
  } else if( ablocks.size()<4 ){ 
      iblock=1;  
  } else {
      plumed_error();
  }
 
  // Count number of currently active atoms
  unsigned nactive_atoms=0;
  for(unsigned i=0;i<ablocks[iblock].size();++i){
      if( isCurrentlyActive( iblock, ablocks[iblock][i] ) ) nactive_atoms++;
  }

  std::vector<Vector> ltmp_pos( nactive_atoms ); 
  std::vector<unsigned> ltmp_ind( nactive_atoms );

  nactive_atoms=0;
  if( usespecies ){
     for(unsigned i=0;i<ablocks[0].size();++i){
        if( !isCurrentlyActive( 0, ablocks[0][i] ) ) continue; 
        ltmp_ind[nactive_atoms]=ablocks[0][i];
        ltmp_pos[nactive_atoms]=getPositionOfAtomForLinkCells( ltmp_ind[nactive_atoms] );
        nactive_atoms++;
     }
  } else {
     for(unsigned i=0;i<ablocks[1].size();++i){
        if( !isCurrentlyActive( 1, ablocks[1][i] ) ) continue;
        ltmp_ind[nactive_atoms]=i; 
        ltmp_pos[nactive_atoms]=getPositionOfAtomForLinkCells( ablocks[1][i] );
        nactive_atoms++; 
     }
  }

  // Build the lists for the link cells
  linkcells.buildCellLists( ltmp_pos, ltmp_ind, getPbc() );

  if( !usespecies ){
     // Get some parallel info
     unsigned stride=comm.Get_size();
     unsigned rank=comm.Get_rank(); 
     if( serialCalculation() ){ stride=1; rank=0; }

     // Ensure we only do tasks where atoms are in appropriate link cells
     std::vector<unsigned> linked_atoms( 1+ablocks[1].size() );
     std::vector<unsigned>  active_tasks( getFullNumberOfTasks(), 0 );
     for(unsigned i=rank;i<ablocks[0].size();i+=stride){
         if( !isCurrentlyActive( 0, ablocks[0][i] ) ) continue;
         unsigned natomsper=1; linked_atoms[0]=ltmp_ind[0];  // Note we always check atom 0 because it is simpler than changing LinkCells.cpp
         linkcells.retrieveNeighboringAtoms( getPositionOfAtomForLinkCells( ablocks[0][i] ), natomsper, linked_atoms );
         for(unsigned j=0;j<natomsper;++j){
             for(unsigned k=bookeeping(i,linked_atoms[j]).first;k<bookeeping(i,linked_atoms[j]).second;++k) active_tasks[k]=1;
         }
     }
     if( !serialCalculation() ) comm.Sum( active_tasks ); 

     deactivateAllTasks(); 
     activateTheseTasks( active_tasks );
     contributorsAreUnlocked=false;
  } else {
     // Now check for calculating volumes (currently this is only done for usespecies style commands 
     // as it is difficult to do with things like DISTANCES or ANGLES and I think pointless
     bool justVolumes=true;
     for(unsigned i=0;i<getNumberOfVessels();++i){
         vesselbase::BridgeVessel* myb=dynamic_cast<vesselbase::BridgeVessel*>( getPntrToVessel(i) );
         if( !myb ){ justVolumes=false; break; }
         ActionVolume* myv=dynamic_cast<ActionVolume*>( myb->getOutputAction() ); 
         if( !myv ){ justVolumes=false; break; }
     }
     // Now ensure that we only do calculations for those atoms in the relevant volume
     if( justVolumes ){
         bool justVolumes=true;
         // Setup the regions in the action volume objects 
         for(unsigned i=0;i<getNumberOfVessels();++i){
             vesselbase::BridgeVessel* myb=dynamic_cast<vesselbase::BridgeVessel*>( getPntrToVessel(i) );
             ActionVolume* myv=dynamic_cast<ActionVolume*>( myb->getOutputAction() );
             myv->retrieveAtoms(); myv->setupRegions();
         } 

         unsigned stride=comm.Get_size();
         unsigned rank=comm.Get_rank();
         if( serialCalculation() ){ stride=1; rank=0; } 

         unsigned nactive=0;
         std::vector<unsigned>  active_tasks( getFullNumberOfTasks(), 0 );
         for(unsigned i=rank;i<getFullNumberOfTasks();i+=stride){
             bool invol=false;
             for(unsigned j=0;j<getNumberOfVessels();++j){
                 vesselbase::BridgeVessel* myb=dynamic_cast<vesselbase::BridgeVessel*>( getPntrToVessel(j) );
                 ActionVolume* myv=dynamic_cast<ActionVolume*>( myb->getOutputAction() );
                 if( myv->inVolumeOfInterest(i) ){ invol=true; }  
             }
             if( invol ){ nactive++; active_tasks[i]=1; }
         }

         if( !serialCalculation() ) comm.Sum( active_tasks );

         deactivateAllTasks();
         activateTheseTasks( active_tasks );
         contributorsAreUnlocked=false;
     }
  }

}