Esempio n. 1
0
void MultiColvarBase::setupLinkCells(){
  if( !linkcells.enabled() ) return ;

  unsigned iblock, jblock;
  if( usespecies ){
      iblock=0; 
  } else if( current_atoms.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( ablocks[iblock][i] ) ) nactive_atoms++;
  }

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

  nactive_atoms=0;
  if( usespecies ){
     ltmp_pos.resize( ablocks[0].size() ); ltmp_ind.resize( ablocks[0].size() );
     for(unsigned i=0;i<ablocks[0].size();++i){
        if( !isCurrentlyActive( ablocks[0][i] ) ) continue; 
        ltmp_ind[nactive_atoms]=ablocks[0][i];
        ltmp_pos[nactive_atoms]=getPositionOfAtomForLinkCells( ltmp_ind[nactive_atoms] );
        nactive_atoms++;
     }
  } else {
     ltmp_pos.resize( ablocks[1].size() ); ltmp_ind.resize( ablocks[1].size() ); 
     for(unsigned i=0;i<ablocks[1].size();++i){
        if( !isCurrentlyActive( 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( ablocks[0][i] ) ) continue;
         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;
  }
}
Esempio n. 2
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;
     }
  }

}