void ActionAtomistic::makeWhole(){ for(unsigned j=0;j<positions.size()-1;++j){ const Vector & first (positions[j]); Vector & second (positions[j+1]); second=first+pbcDistance(first,second); } }
// calculator void CoordinationBase::calculate() { double ncoord=0.; Tensor virial; vector<Vector> deriv(getNumberOfAtoms()); // deriv.resize(getPositions().size()); if(nl->getStride()>0 && invalidateList){ nl->update(getPositions()); } unsigned stride=comm.Get_size(); unsigned rank=comm.Get_rank(); if(serial){ stride=1; rank=0; }else{ stride=comm.Get_size(); rank=comm.Get_rank(); } for(unsigned int i=rank;i<nl->size();i+=stride) { // sum over close pairs Vector distance; unsigned i0=nl->getClosePair(i).first; unsigned i1=nl->getClosePair(i).second; if(getAbsoluteIndex(i0)==getAbsoluteIndex(i1)) continue; if(pbc){ distance=pbcDistance(getPosition(i0),getPosition(i1)); } else { distance=delta(getPosition(i0),getPosition(i1)); } double dfunc=0.; ncoord += pairing(distance.modulo2(), dfunc,i0,i1); deriv[i0] = deriv[i0] + (-dfunc)*distance ; deriv[i1] = deriv[i1] + dfunc*distance ; virial=virial+(-dfunc)*Tensor(distance,distance); } if(!serial){ comm.Sum(ncoord); if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size()); comm.Sum(virial); } for(unsigned i=0;i<deriv.size();++i) setAtomsDerivatives(i,deriv[i]); setValue (ncoord); setBoxDerivatives (virial); }
double VolumeTetrapore::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& rderiv ) const { // Setup the histogram bead HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( getKernelType() ); // Calculate distance of atom from origin of new coordinate frame Vector datom=pbcDistance( origin, cpos ); double ucontr, uder, vcontr, vder, wcontr, wder; // Calculate contribution from integral along bi bead.set( 0, len_bi, sigma ); double upos=dotProduct( datom, bi ); ucontr=bead.calculate( upos, uder ); double udlen=bead.uboundDerivative( upos ); double uder2 = bead.lboundDerivative( upos ) - udlen; // Calculate contribution from integral along cross bead.set( 0, len_cross, sigma ); double vpos=dotProduct( datom, cross ); vcontr=bead.calculate( vpos, vder ); double vdlen=bead.uboundDerivative( vpos ); double vder2 = bead.lboundDerivative( vpos ) - vdlen; // Calculate contribution from integral along perp bead.set( 0, len_perp, sigma ); double wpos=dotProduct( datom, perp ); wcontr=bead.calculate( wpos, wder ); double wdlen=bead.uboundDerivative( wpos ); double wder2 = bead.lboundDerivative( wpos ) - wdlen; Vector dfd; dfd[0]=uder*vcontr*wcontr; dfd[1]=ucontr*vder*wcontr; dfd[2]=ucontr*vcontr*wder; derivatives[0] = (dfd[0]*bi[0]+dfd[1]*cross[0]+dfd[2]*perp[0]); derivatives[1] = (dfd[0]*bi[1]+dfd[1]*cross[1]+dfd[2]*perp[1]); derivatives[2] = (dfd[0]*bi[2]+dfd[1]*cross[2]+dfd[2]*perp[2]); double tot = ucontr*vcontr*wcontr*jacob_det; // Add reference atom derivatives dfd[0]=uder2*vcontr*wcontr; dfd[1]=ucontr*vder2*wcontr; dfd[2]=ucontr*vcontr*wder2; Vector dfld; dfld[0]=udlen*vcontr*wcontr; dfld[1]=ucontr*vdlen*wcontr; dfld[2]=ucontr*vcontr*wdlen; rderiv[0] = dfd[0]*matmul(datom,dbi[0]) + dfd[1]*matmul(datom,dcross[0]) + dfd[2]*matmul(datom,dperp[0]) + dfld[0]*dlbi[0] + dfld[1]*dlcross[0] + dfld[2]*dlperp[0] - derivatives; rderiv[1] = dfd[0]*matmul(datom,dbi[1]) + dfd[1]*matmul(datom,dcross[1]) + dfd[2]*matmul(datom,dperp[1]) + dfld[0]*dlbi[1] + dfld[1]*dlcross[1] + dfld[2]*dlperp[1]; rderiv[2] = dfd[0]*matmul(datom,dbi[2]) + dfd[1]*matmul(datom,dcross[2]) + dfd[2]*matmul(datom,dperp[2]) + dfld[0]*dlbi[2] + dfld[1]*dlcross[2] + dfld[2]*dlperp[2]; rderiv[3] = dfld[0]*dlbi[3] + dfld[1]*dlcross[3] + dfld[2]*dlperp[3]; vir.zero(); vir-=Tensor( cpos,derivatives ); for(unsigned i=0;i<4;++i){ vir -= Tensor( getPosition(i), rderiv[i] ); } return tot; }
void SecondaryStructureRMSD::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const { // Retrieve the positions std::vector<Vector> pos( references[0]->getNumberOfAtoms() ); const unsigned n=pos.size(); for(unsigned i=0;i<n;++i) pos[i]=ActionAtomistic::getPosition( getAtomIndex(current,i) ); // This does strands cutoff Vector distance=pbcDistance( pos[align_atom_1],pos[align_atom_2] ); if( s_cutoff2>0 ){ if( distance.modulo2()>s_cutoff2 ){ myvals.setValue( 0, 0.0 ); return; } } // This aligns the two strands if this is required if( alignType!="DRMSD" && align_strands ){ Vector origin_old, origin_new; origin_old=pos[align_atom_2]; origin_new=pos[align_atom_1]+distance; for(unsigned i=15;i<30;++i){ pos[i]+=( origin_new - origin_old ); } } // Create a holder for the derivatives ReferenceValuePack mypack( 0, pos.size(), myvals ); mypack.setValIndex( 1 ); for(unsigned i=0;i<n;++i) mypack.setAtomIndex( i, getAtomIndex(current,i) ); // And now calculate the RMSD const Pbc& pbc=getPbc(); unsigned closest=0; double r = references[0]->calculate( pos, pbc, mypack, false ); const unsigned rs = references.size(); for(unsigned i=1;i<rs;++i){ mypack.setValIndex( i+1 ); double nr=references[i]->calculate( pos, pbc, mypack, false ); if( nr<r ){ closest=i; r=nr; } } // Transfer everything to the value myvals.setValue( 0, 1.0 ); myvals.setValue( 1, r ); if( closest>0 ) mypack.moveDerivatives( closest+1, 1 ); if( !mypack.virialWasSet() ){ Tensor vir; const unsigned cacs = colvar_atoms[current].size(); for(unsigned i=0;i<cacs;++i){ vir+=(-1.0*Tensor( pos[i], mypack.getAtomDerivative(i) )); } mypack.setValIndex(1); mypack.addBoxDerivatives( vir ); } return; }
void IMD::calculate(){ if(comm.Get_rank()==0 && connected && plumed.getStep()%transferRate==0 && vmdsock_selwrite(clientsock,0)) { double scale=10.0*plumed.getAtoms().getUnits().getLength(); Vector ref; for(int i=0;i<natoms;i++){ Vector pos=getPosition(i); if(wrap) pos=pbcDistance(ref,pos); coord[3*i+0]=static_cast<float>((pos[0]*scale)); coord[3*i+1]=static_cast<float>((pos[1]*scale)); coord[3*i+2]=static_cast<float>((pos[2]*scale)); } imd_send_fcoords(clientsock,natoms,&coord[0]); } }
Vector MultiColvarBase::getSeparation( const Vector& vec1, const Vector& vec2 ) const { if(usepbc){ return pbcDistance( vec1, vec2 ); } else{ return delta( vec1, vec2 ); } }
// calculator void CoordinationBase::calculate() { double ncoord=0.; Tensor virial; vector<Vector> deriv(getNumberOfAtoms()); // deriv.resize(getPositions().size()); if(nl->getStride()>0 && invalidateList) { nl->update(getPositions()); } unsigned stride=comm.Get_size(); unsigned rank=comm.Get_rank(); if(serial) { stride=1; rank=0; } else { stride=comm.Get_size(); rank=comm.Get_rank(); } unsigned nt=OpenMP::getNumThreads(); const unsigned nn=nl->size(); if(nt*stride*10>nn) nt=nn/stride/10; if(nt==0)nt=1; #pragma omp parallel num_threads(nt) { std::vector<Vector> omp_deriv(getPositions().size()); Tensor omp_virial; #pragma omp for reduction(+:ncoord) nowait for(unsigned int i=rank; i<nn; i+=stride) { Vector distance; unsigned i0=nl->getClosePair(i).first; unsigned i1=nl->getClosePair(i).second; if(getAbsoluteIndex(i0)==getAbsoluteIndex(i1)) continue; if(pbc) { distance=pbcDistance(getPosition(i0),getPosition(i1)); } else { distance=delta(getPosition(i0),getPosition(i1)); } double dfunc=0.; ncoord += pairing(distance.modulo2(), dfunc,i0,i1); Vector dd(dfunc*distance); Tensor vv(dd,distance); if(nt>1) { omp_deriv[i0]-=dd; omp_deriv[i1]+=dd; omp_virial-=vv; } else { deriv[i0]-=dd; deriv[i1]+=dd; virial-=vv; } } #pragma omp critical if(nt>1) { for(int i=0; i<getPositions().size(); i++) deriv[i]+=omp_deriv[i]; virial+=omp_virial; } } if(!serial) { comm.Sum(ncoord); if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size()); comm.Sum(virial); } for(unsigned i=0; i<deriv.size(); ++i) setAtomsDerivatives(i,deriv[i]); setValue (ncoord); setBoxDerivatives (virial); }