Exemplo n.º 1
0
void LinkCells::buildCellLists( const std::vector<Vector>& pos, const std::vector<unsigned>& indices, const Pbc& pbc ){
  plumed_assert( cutoffwasset && pos.size()==indices.size() );

  // Must be able to check that pbcs are not nonsensical in some way?? -- GAT

  // Setup the pbc object by copying it from action
  mypbc.setBox( pbc.getBox() );

  // Setup the lists
  if( pos.size()!=allcells.size() ){ 
    allcells.resize( pos.size() ); lcell_lists.resize( pos.size() ); 
  }

   {
// This is the reciprocal lattice
// notice that reciprocal.getRow(0) is a vector that is orthogonal to b and c
// This allows to use linked cells in non orthorhomic boxes
     Tensor reciprocal(transpose(mypbc.getInvBox()));
     ncells[0] = std::floor( 1.0/ reciprocal.getRow(0).modulo() / link_cutoff );
     if( ncells[0]==0 ) ncells[0]=1;
     ncells[1] = std::floor( 1.0/ reciprocal.getRow(1).modulo() / link_cutoff );
     if( ncells[1]==0 ) ncells[1]=1;
     ncells[2] = std::floor( 1.0/ reciprocal.getRow(2).modulo() / link_cutoff );
     if( ncells[2]==0 ) ncells[2]=1;
  }
  // Setup the strides
  nstride[0]=1; nstride[1]=ncells[0]; nstride[2]=ncells[0]*ncells[1];

  // Setup the storage for link cells
  unsigned ncellstot=ncells[0]*ncells[1]*ncells[2];
  if( lcell_tots.size()!=ncellstot ){
      lcell_tots.resize( ncellstot ); lcell_starts.resize( ncellstot );
  }
  // Clear nlcells
  for(unsigned i=0;i<ncellstot;++i) lcell_tots[i]=0;
  // Clear allcells
  allcells.assign( allcells.size(), 0 );

  // Find out what cell everyone is in
  unsigned rank=comm.Get_rank(), size=comm.Get_size();
  for(unsigned i=rank;i<pos.size();i+=size){
      allcells[i]=findCell( pos[i] );
      lcell_tots[allcells[i]]++;
  }
  // And gather all this information on every node
  comm.Sum( allcells ); comm.Sum( lcell_tots );

  // Now prepare the link cell lists
  unsigned tot=0;
  for(unsigned i=0;i<lcell_tots.size();++i){ lcell_starts[i]=tot; tot+=lcell_tots[i]; lcell_tots[i]=0; }
  plumed_assert( tot==pos.size() );

  // And setup the link cells properly
  for(unsigned j=0;j<pos.size();++j){
      unsigned myind = lcell_starts[ allcells[j] ] + lcell_tots[ allcells[j] ];
      lcell_lists[ myind ] = indices[j];
      lcell_tots[allcells[j]]++;
  }
}
Exemplo n.º 2
0
double DRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
  plumed_dbg_assert(!targets.empty());

  Vector distance; 
  myder.clear(); 
  double drmsd=0.; 
  for(std::map< std::pair <unsigned,unsigned> , double>::const_iterator it=targets.begin();it!=targets.end();++it){
      
      const unsigned i=getAtomIndex( it->first.first );
      const unsigned j=getAtomIndex( it->first.second );

      if(nopbc) distance=delta( pos[i] , pos[j] ); 
      else      distance=pbc.distance( pos[i] , pos[j] );

      const double len = distance.modulo();
      const double diff = len - it->second;
      const double der = diff / len; 

      drmsd += diff * diff;
      myder.addAtomDerivatives( i, -der * distance );
      myder.addAtomDerivatives( j,  der * distance );
      myder.addBoxDerivatives( - der * Tensor(distance,distance) );
  }

  const double inpairs = 1./static_cast<double>(targets.size());
  double idrmsd;

  if(squared){
     drmsd = drmsd * inpairs;
     idrmsd = 2.0 * inpairs;
  } else {
     drmsd = sqrt( drmsd * inpairs );
     idrmsd = inpairs / drmsd ;
  }

  myder.scaleAllDerivatives( idrmsd );

  return drmsd;
}
Exemplo n.º 3
0
double DRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, const bool& squared ){
  plumed_dbg_assert( !targets.empty() );

  Vector distance; 
  double drmsd=0.; 
  for(std::map< std::pair <unsigned,unsigned> , double>::const_iterator it=targets.begin();it!=targets.end();++it){
      
      unsigned i=getAtomIndex( it->first.first );
      unsigned j=getAtomIndex( it->first.second );

      if(nopbc){ distance=delta( pos[i] , pos[j] ); }
      else{ distance=pbc.distance( pos[i] , pos[j] ); }

      double len = distance.modulo();
      double diff = len - it->second;

      drmsd += diff * diff;
      addAtomicDerivatives( i, -( diff / len ) * distance );
      addAtomicDerivatives( j, ( diff / len ) * distance );
      addBoxDerivatives( -( diff / len ) * Tensor(distance,distance) );
  }

  double npairs = static_cast<double>(targets.size());
  double idrmsd;

  if(squared){
     drmsd = drmsd / npairs;
     idrmsd = 2.0 / npairs;
  } else {
     drmsd = sqrt( drmsd / npairs );
     idrmsd = 1.0/( drmsd * npairs );
  }

  virial *= idrmsd; 
  for(unsigned i=0;i<getNumberOfAtoms();++i){atom_ders[i] *= idrmsd;}

  return drmsd;
}
Exemplo n.º 4
0
void Pbc::test(){
  Random r;
  r.setSeed(-20);
  for(int i=0;i<1000;i++){
// random matrix with some zero element
    Tensor box;
    for(int j=0;j<3;j++) for(int k=0;k<3;k++) if(r.U01()>0.2){
      box[j][k]=2.0*r.U01()-1.0;
    }
    int boxtype=i%10;
    switch(boxtype){
    case 0:
// cubic
      for(int j=0;j<3;j++) for(int k=0;k<3;k++) if(j!=k) box[j][k]=0.0;
      for(int j=1;j<3;j++) box[j][j]=box[0][0];
      break;
    case 1:
// orthorombic
      for(int j=0;j<3;j++) for(int k=0;k<3;k++) if(j!=k) box[j][k]=0.0;
      break;
    case 2:
// hexagonal
      {
      int perm=r.U01()*100;
      Vector a;
      a(0)=r.U01()*2-2; a(1)=0.0;a(2)=0.0;
      double d=r.U01()*2-2;
      Vector b(0.0,d,0.0);
      Vector c(0.0,0.5*d,sqrt(3.0)*d*0.5);
      box.setRow((perm+0)%3,a);
      box.setRow((perm+1)%3,b);
      box.setRow((perm+2)%3,c);
      }
      break;
    case 3:
// bcc
      {
      int perm=r.U01()*100;
      double d=r.U01()*2-2;
      Vector a(d,d,d);
      Vector b(d,-d,d);
      Vector c(d,d,-d);
      box.setRow((perm+0)%3,a);
      box.setRow((perm+1)%3,b);
      box.setRow((perm+2)%3,c);
      }
      break;
    case 4:
// fcc
      {
      int perm=r.U01()*100;
      double d=r.U01()*2-2;
      Vector a(d,d,0);
      Vector b(d,0,d);
      Vector c(0,d,d);
      box.setRow((perm+0)%3,a);
      box.setRow((perm+1)%3,b);
      box.setRow((perm+2)%3,c);
      }
      break;
    default:
// triclinic
      break;
    }

    Pbc pbc;
    pbc.setBox(box);
    std::cerr<<"( "<<boxtype<<" )\n";
    std::cerr<<"Box:";
    for(int j=0;j<3;j++) for(int k=0;k<3;k++) std::cerr<<" "<<box[j][k];
    std::cerr<<"\n";
    std::cerr<<"Determinant: "<<determinant(box)<<"\n";
    std::cerr<<"Shifts:";
    for(int j=0;j<2;j++) for(int k=0;k<2;k++) for(int l=0;l<2;l++) std::cerr<<" "<<pbc.shifts[j][k][l].size();
    std::cerr<<"\n";
    int nshifts=0;
    int ntot=10000;
    for(int j=0;j<ntot;j++){
      Vector v(r.U01()-0.5,r.U01()-0.5,r.U01()-0.5);
      v*=5;
      for(int j=0;j<3;j++) if(r.U01()>0.2) v(j)=0.0;
      Vector full(v);
      Vector fast=pbc.distance(Vector(0,0,0),v,&nshifts);
      full=fast;

      pbc.fullSearch(full);
  
     if(modulo2(fast-full)>1e-10) {
        std::cerr<<"orig "<<v[0]<<" "<<v[1]<<" "<<v[2]<<"\n";
        std::cerr<<"fast "<<fast[0]<<" "<<fast[1]<<" "<<fast[2]<<"\n";
        std::cerr<<"full "<<full[0]<<" "<<full[1]<<" "<<full[2]<<"\n";
        std::cerr<<"diff "<<modulo2(fast)-modulo2(full)<<std::endl;
        if(std::fabs(modulo2(fast)-modulo2(full))>1e-15) plumed_error();
     }
    }
    std::cerr<<"Average number of shifts: "<<double(nshifts)/double(ntot)<<"\n";
  }
}