Esempio n. 1
0
void Mapping::mergeDerivatives( const unsigned& ider, const double& df ){
  unsigned cur = getCurrentTask(), frameno=ider*getNumberOfReferencePoints() + cur;
  for(unsigned i=0;i<getNumberOfArguments();++i){
      accumulateDerivative( i, df*dfframes[frameno]*mymap->getArgumentDerivative(cur,i) );
  }
  if( getNumberOfAtoms()>0 ){
      Vector ader; Tensor tmpvir; tmpvir.zero();
      unsigned n=getNumberOfArguments(); 
      for(unsigned i=0;i<getNumberOfAtoms();++i){
          ader=mymap->getAtomDerivatives( cur, i );            
          accumulateDerivative( n, df*dfframes[frameno]*ader[0] ); n++;
          accumulateDerivative( n, df*dfframes[frameno]*ader[1] ); n++;
          accumulateDerivative( n, df*dfframes[frameno]*ader[2] ); n++;
          tmpvir += -1.0*Tensor( getPosition(i), ader );
      }
      Tensor vir; 
      if( !mymap->getVirial( cur, vir ) ) vir=tmpvir;
      accumulateDerivative( n, df*dfframes[frameno]*vir(0,0) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(0,1) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(0,2) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(1,0) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(1,1) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(1,2) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(2,0) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(2,1) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(2,2) ); 
  }
}
Esempio n. 2
0
void Sprint::apply() {
  std::vector<Vector>&   f(modifyForces());
  Tensor&           v(modifyVirial());
  unsigned          nat=getNumberOfAtoms();

  std::vector<double> forces( 3*getNumberOfAtoms() + 9 );
  for(int i=0; i<getNumberOfComponents(); ++i) {
    if( getPntrToComponent(i)->applyForce( forces ) ) {
      for(unsigned j=0; j<nat; ++j) {
        f[j][0]+=forces[3*j+0];
        f[j][1]+=forces[3*j+1];
        f[j][2]+=forces[3*j+2];
      }
      v(0,0)+=forces[3*nat+0];
      v(0,1)+=forces[3*nat+1];
      v(0,2)+=forces[3*nat+2];
      v(1,0)+=forces[3*nat+3];
      v(1,1)+=forces[3*nat+4];
      v(1,2)+=forces[3*nat+5];
      v(2,0)+=forces[3*nat+6];
      v(2,1)+=forces[3*nat+7];
      v(2,2)+=forces[3*nat+8];
    }
  }
}
Esempio n. 3
0
void MultiDomainRMSD::setupPCAStorage( ReferenceValuePack& mypack ) {
  plumed_dbg_assert( pcaIsEnabledForThisReference() );
  mypack.switchOnPCAOption();
  mypack.displacement.resize( getNumberOfAtoms() );
  mypack.centeredpos.resize( getNumberOfAtoms() );
  mypack.DRotDPos.resize(3,3); mypack.rot.resize( domains.size() );
  for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) mypack.DRotDPos(i,j).resize( getNumberOfAtoms() );
}
void BridgedMultiColvarFunction::applyBridgeForces( const std::vector<double>& bb ){
  if( getNumberOfAtoms()==0 ) return ;

  std::vector<Vector>& f( modifyForces() );
  for(unsigned i=0;i<getNumberOfAtoms();++i){
    f[i][0]+=bb[3*i+0]; f[i][1]+=bb[3*i+1]; f[i][2]+=bb[3*i+2];
  } 
}
Esempio n. 5
0
void MultiColvarBase::addCentralAtomDerivatives( const unsigned& iatom, const Tensor& der ){
  plumed_dbg_assert( iatom<getNumberOfAtoms() );
  atomsWithCatomDer.activate(iatom);
  unsigned nder = 3*getNumberOfAtoms() + 9;
  for(unsigned i=0;i<3;++i){ 
    for(unsigned j=0;j<3;++j){
        addElementDerivative( (getCentralAtomElementIndex()+j)*nder + 3*iatom + i, der(j,i) );
     }
  }
}
Esempio n. 6
0
void Mapping::calculateNumericalDerivatives( ActionWithValue* a ){
  if( getNumberOfAtoms()>0 ){
     ActionWithArguments::calculateNumericalDerivatives( a );
  }
  if( getNumberOfAtoms()>0 ){
     Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
     for(unsigned j=0;j<getNumberOfComponents();++j){
        for(unsigned i=0;i<getNumberOfArguments();++i) save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
     }
     calculateAtomicNumericalDerivatives( a, getNumberOfArguments() ); 
     for(unsigned j=0;j<getNumberOfComponents();++j){ 
        for(unsigned i=0;i<getNumberOfArguments();++i) getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
     }
  }
}
Esempio n. 7
0
double MultiDomainRMSD::projectAtomicDisplacementOnVector( const bool& normalized, const std::vector<Vector>& vecs, ReferenceValuePack& mypack ) const {
  double totd=0.; std::vector<Vector> tvecs; mypack.clear();
  MultiValue tvals( 1, mypack.getNumberOfDerivatives() ); ReferenceValuePack tder( 0, getNumberOfAtoms(), tvals );
  for(unsigned i=0; i<domains.size(); ++i) {
    // Must extract appropriate positions here
    tvecs.resize( blocks[i+1] - blocks[i] ); domains[i]->setupPCAStorage( tder );
    if( tder.centeredpos.size()>0 ) {
      for(unsigned p=0; p<3; ++p) for(unsigned q=0; q<3; ++q) tder.DRotDPos(p,q).resize( tvecs.size() );
    }
    // Extract information from storage pack and put in local pack
    if( tder.centeredpos.size()>0 ) tder.rot[0]=mypack.rot[i];
    unsigned n=0;
    for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) {
      tder.setAtomIndex(n,j); tvecs[n] = vecs[j]; tder.displacement[n]=mypack.displacement[j] / weights[i];
      if( tder.centeredpos.size()>0 ) {
        tder.centeredpos[n]=mypack.centeredpos[j];
        for(unsigned p=0; p<3; ++p) for(unsigned q=0; q<3; ++q) tder.DRotDPos(p,q)[n]=mypack.DRotDPos(p,q)[j];
      }
      n++;
    }
    for(unsigned k=n; k<getNumberOfAtoms(); ++k) tder.setAtomIndex(k,3*vecs.size()+10);

    // Do the calculations
    totd += weights[i]*domains[i]->projectAtomicDisplacementOnVector( normalized, tvecs, tder );

    // And derivatives
    mypack.copyScaledDerivatives( 0, weights[i], tvals );
  }
  if( !mypack.updateComplete() ) mypack.updateDynamicLists();

  return totd;
}
Esempio n. 8
0
double DistanceFromContour::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
  Vector distance = getSeparation( getPosition(getNumberOfAtoms()-1), myatoms.getPosition(0) );
  std::vector<double> pp(3), der(3,0); for(unsigned j=0;j<3;++j) pp[j] = distance[j]; 

  // Now create the kernel and evaluate
  KernelFunctions kernel( pp, bw, kerneltype, false, 1.0, true );
  double newval = kernel.evaluate( pval, der, true );

  if( mybasemulticolvars[0]->isDensity() ){ 
      if( !doNotCalculateDerivatives() && derivTime ){
          MultiValue& myvals=myatoms.getUnderlyingMultiValue();
          Vector vder; unsigned basen=myvals.getNumberOfDerivatives() - 12;
          for(unsigned i=0;i<3;++i){ 
              vder[i]=der[i]; myvals.addDerivative( 1, basen+i, vder[i] ); 
          }
          myatoms.setValue( 2, der[dir] );
          addAtomDerivatives( 1, 0, -vder, myatoms );
          myatoms.addBoxDerivatives( 1, Tensor(vder,distance) );
      }
      myatoms.setValue( 0, 1.0 ); return newval; 
  }

  // This does the stuff for averaging
  myatoms.setValue( 0, newval );

  // This gets the average if we are using a phase field
  std::vector<double> cvals( mybasemulticolvars[0]->getNumberOfQuantities() );
  mybasedata[0]->retrieveValueWithIndex( tindex, false, cvals );
  return newval*cvals[0]*cvals[1]; 
}
Esempio n. 9
0
double MultiColvarBase::getCentralAtomDerivative( const unsigned& iatom, const unsigned& jcomp, const Vector& df ){
  plumed_dbg_assert( atomsWithCatomDer.isActive(iatom) && jcomp<3 );
  unsigned nder = 3*getNumberOfAtoms() + 9;
  return df[0]*getElementDerivative( (getCentralAtomElementIndex()+0)*nder + 3*iatom + jcomp ) +
         df[1]*getElementDerivative( (getCentralAtomElementIndex()+1)*nder + 3*iatom + jcomp ) +
         df[2]*getElementDerivative( (getCentralAtomElementIndex()+2)*nder + 3*iatom + jcomp ); 
}
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;
}
Esempio n. 11
0
bool ActionVolume::inVolumeOfInterest( const unsigned& curr ) const {
  Vector catom_pos=getPntrToMultiColvar()->getCentralAtomPos( curr );
  Vector wdf; Tensor vir; std::vector<Vector> refders( getNumberOfAtoms() );
  double weight=calculateNumberInside( catom_pos, wdf, vir, refders );
  if( not_in ) weight = 1.0 - weight;
  if( weight<getTolerance() ) return false;
  return true;
}
Esempio n. 12
0
double Direction::calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& args, 
                        ReferenceValuePack& myder, const bool& squared ) const {
  plumed_assert( squared );
  for(unsigned i=0;i<getNumberOfReferenceArguments();++i) myder.addArgumentDerivatives( i, -2.*getReferenceArgument(i) );
  for(unsigned i=0;i<getNumberOfAtoms();++i) myder.getAtomsDisplacementVector()[i]=getReferencePosition(i);
  
  return 0.0;
}
Esempio n. 13
0
void Colvar::requestAtoms(const vector<AtomNumber> & a){
  plumed_massert(!isEnergy,"request atoms should not be called if this is energy");
// Tell actionAtomistic what atoms we are getting
  ActionAtomistic::requestAtoms(a);
// Resize the derivatives of all atoms
  for(int i=0;i<getNumberOfComponents();++i) getPntrToComponent(i)->resizeDerivatives(3*a.size()+9);
// Set the size of the forces array
  forces.resize(3*getNumberOfAtoms()+9);
}
Esempio n. 14
0
void Colvar::setBoxDerivativesNoPbc(Value* v){
  Tensor virial;
  unsigned nat=getNumberOfAtoms();
  for(unsigned i=0;i<nat;i++) virial-=Tensor(getPosition(i),
    Vector(v->getDerivative(3*i+0),
           v->getDerivative(3*i+1),
           v->getDerivative(3*i+2)));
  setBoxDerivatives(v,virial);
}
Esempio n. 15
0
// 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);

}
Esempio n. 16
0
void ActionVolume::calculateAllVolumes( const unsigned& curr, MultiValue& outvals ) const {
  Vector catom_pos=getPntrToMultiColvar()->getCentralAtomPos( curr );

  double weight; Vector wdf; Tensor vir; std::vector<Vector> refders( getNumberOfAtoms() );
  weight=calculateNumberInside( catom_pos, wdf, vir, refders );
  if( not_in ) {
    weight = 1.0 - weight; wdf *= -1.; vir *=-1;
    for(unsigned i=0; i<refders.size(); ++i) refders[i]*=-1;
  }
  setNumberInVolume( 0, curr, weight, wdf, vir, refders, outvals );
}
Esempio n. 17
0
void ActionAtomistic::calculateAtomicNumericalDerivatives( ActionWithValue* a, const unsigned& startnum ){
  if(!a){
    a=dynamic_cast<ActionWithValue*>(this);
    plumed_massert(a,"only Actions with a value can be differentiated");
  }

  const int nval=a->getNumberOfComponents();
  const int natoms=getNumberOfAtoms();
  std::vector<Vector> value(nval*natoms);
  std::vector<Tensor> valuebox(nval);
  std::vector<Vector> savedPositions(natoms);
  const double delta=sqrt(epsilon);

  for(int i=0;i<natoms;i++) for(int k=0;k<3;k++){
    savedPositions[i][k]=positions[i][k];
    positions[i][k]=positions[i][k]+delta;
    a->calculate();
    positions[i][k]=savedPositions[i][k];
    for(int j=0;j<nval;j++){
      value[j*natoms+i][k]=a->getOutputQuantity(j);
    }
  }
 Tensor box(pbc.getBox());
 for(int i=0;i<3;i++) for(int k=0;k<3;k++){
   double arg0=box(i,k);
   for(int j=0;j<natoms;j++) positions[j]=pbc.realToScaled(positions[j]);
   box(i,k)=box(i,k)+delta;
   pbc.setBox(box);
   for(int j=0;j<natoms;j++) positions[j]=pbc.scaledToReal(positions[j]);
   a->calculate();
   box(i,k)=arg0;
   pbc.setBox(box);
   for(int j=0;j<natoms;j++) positions[j]=savedPositions[j];
   for(int j=0;j<nval;j++) valuebox[j](i,k)=a->getOutputQuantity(j);
 }

  a->calculate();
  a->clearDerivatives();
  for(int j=0;j<nval;j++){
    Value* v=a->copyOutput(j);
    double ref=v->get();
    if(v->hasDerivatives()){
      for(int i=0;i<natoms;i++) for(int k=0;k<3;k++) {
        double d=(value[j*natoms+i][k]-ref)/delta;
        v->addDerivative(startnum+3*i+k,d);
      }
      Tensor virial;
      for(int i=0;i<3;i++) for(int k=0;k<3;k++)virial(i,k)= (valuebox[j](i,k)-ref)/delta;
// BE CAREFUL WITH NON ORTHOROMBIC CELL
      virial=-matmul(box.transpose(),virial);
      for(int i=0;i<3;i++) for(int k=0;k<3;k++) v->addDerivative(startnum+3*natoms+3*k+i,virial(k,i));
    }
  }
}
Esempio n. 18
0
double OptimalRMSD::projectAtomicDisplacementOnVector( const bool& normalized, const std::vector<Vector>& vecs, ReferenceValuePack& mypack ) const {
  plumed_dbg_assert( mypack.calcUsingPCAOption() );

  double proj=0.0; mypack.clear();
  for(unsigned i=0; i<vecs.size(); ++i) {
    proj += dotProduct( mypack.getAtomsDisplacementVector()[i], vecs[i] );
  }
  for(unsigned a=0; a<3; a++) {
    for(unsigned b=0; b<3; b++) {
      for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) {
        double tmp1=0.;
        for(unsigned n=0; n<getNumberOfAtoms(); n++) tmp1+=mypack.centeredpos[n][b]*vecs[n][a];
        if( normalized ) mypack.addAtomDerivatives( iat, getDisplace()[iat]*mypack.DRotDPos[a][b][iat]*tmp1 );
        else mypack.addAtomDerivatives( iat, mypack.DRotDPos[a][b][iat]*tmp1 );
      }
    }
  }
  Tensor trot=mypack.rot[0].transpose();
  Vector v1; v1.zero(); double prefactor = 1. / static_cast<double>( getNumberOfAtoms() );
  for(unsigned n=0; n<getNumberOfAtoms(); n++) v1+=prefactor*matmul(trot,vecs[n]);
  if( normalized ) {
    for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) mypack.addAtomDerivatives( iat, getDisplace()[iat]*(matmul(trot,vecs[iat]) - v1) );
  } else {
    for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) mypack.addAtomDerivatives( iat, (matmul(trot,vecs[iat]) - v1) );
  }
  if( !mypack.updateComplete() ) mypack.updateDynamicLists();

  return proj;
}
Esempio n. 19
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++;
  }
}
Esempio n. 20
0
void MultiColvarBase::getIndexList( const unsigned& ntotal, const unsigned& jstore, const unsigned& maxder, std::vector<unsigned>& indices ){
  plumed_dbg_assert( !doNotCalculateDerivatives() );
  indices[jstore]=3*atoms_with_derivatives.getNumberActive() + 9;
  if( indices[jstore]>maxder ) error("too many derivatives to store. Run with LOWMEM");

  unsigned kder = ntotal + jstore*maxder;
  for(unsigned jder=0;jder<atoms_with_derivatives.getNumberActive();++jder){
     unsigned iatom = 3*atoms_with_derivatives[jder];
     for(unsigned icomp=0;icomp<3;++icomp){ indices[ kder ] = iatom+icomp; kder++; }
  }
  unsigned nbase = 3*getNumberOfAtoms(); 
  for(unsigned icomp=0;icomp<9;++icomp){ indices[ kder ] = nbase + icomp; kder++; }   
}   
Esempio n. 21
0
double MultiDomainRMSD::calculate( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
  double totd=0.; Tensor tvirial; std::vector<Vector> mypos; MultiValue tvals( 1, 3*pos.size()+9 );
  ReferenceValuePack tder( 0, getNumberOfAtoms(), tvals ); myder.clear();

  for(unsigned i=0; i<domains.size(); ++i) {
    // Must extract appropriate positions here
    mypos.resize( blocks[i+1] - blocks[i] );
    if( myder.calcUsingPCAOption() ) domains[i]->setupPCAStorage( tder );
    unsigned n=0; for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) { tder.setAtomIndex(n,j); mypos[n]=pos[j]; n++; }
    for(unsigned k=n; k<getNumberOfAtoms(); ++k) tder.setAtomIndex(k,3*pos.size()+10);
    // This actually does the calculation
    totd += weights[i]*domains[i]->calculate( mypos, pbc, tder, true );
    // Now merge the derivative
    myder.copyScaledDerivatives( 0, weights[i], tvals );
    // If PCA copy PCA stuff
    if( myder.calcUsingPCAOption() ) {
      unsigned n=0;
      if( tder.centeredpos.size()>0 ) myder.rot[i]=tder.rot[0];
      for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) {
        myder.displacement[j]=weights[i]*tder.displacement[n];  // Multiplication by weights here ensures that normalisation is done correctly
        if( tder.centeredpos.size()>0 ) {
          myder.centeredpos[j]=tder.centeredpos[n];
          for(unsigned p=0; p<3; ++p) for(unsigned q=0; q<3; ++q) myder.DRotDPos(p,q)[j]=tder.DRotDPos(p,q)[n];
        }
        n++;
      }
    }
    // Make sure virial status is set correctly in output derivative pack
    // This is only done here so I do this by using class friendship
    if( tder.virialWasSet() ) myder.boxWasSet=true;
  }
  if( !myder.updateComplete() ) myder.updateDynamicLists();

  if( !squared ) {
    totd=sqrt(totd); double xx=0.5/totd;
    myder.scaleAllDerivatives( xx );
  }
  return totd;
}
Esempio n. 22
0
void MultiColvarBase::copyElementsToBridgedColvar( BridgedMultiColvarFunction* func ){
  func->setElementValue( 0, getElementValue(0) ); 
  for(unsigned i=0;i<atoms_with_derivatives.getNumberActive();++i){
     unsigned n=atoms_with_derivatives[i], nx=3*n;
     func->atoms_with_derivatives.activate(n);
     func->addElementDerivative( nx+0, getElementDerivative(nx+0) );
     func->addElementDerivative( nx+1, getElementDerivative(nx+1) );
     func->addElementDerivative( nx+2, getElementDerivative(nx+2) ); 
  }
  unsigned nvir=3*getNumberOfAtoms();
  for(unsigned i=0;i<9;++i){ 
     func->addElementDerivative( nvir, getElementDerivative(nvir) ); nvir++;
  }
}
Esempio n. 23
0
double OptimalRMSD::calc( const std::vector<Vector>& pos, ReferenceValuePack& myder, const bool& squared ) const {
  double d;
  if( myder.calcUsingPCAOption() ) {
    std::vector<Vector> centeredreference( getNumberOfAtoms () );
    d=myrmsd.calc_PCAelements(pos,myder.getAtomVector(),myder.rot[0],myder.DRotDPos,myder.getAtomsDisplacementVector(),myder.centeredpos,centeredreference,squared);
    unsigned nat = pos.size();
    for(unsigned i=0; i<nat; ++i) { myder.getAtomsDisplacementVector()[i] -= getReferencePosition(i); myder.getAtomsDisplacementVector()[i] *= getDisplace()[i]; }
  } else if( fast ) {
    if( getAlign()==getDisplace() ) d=myrmsd.optimalAlignment<false,true>(getAlign(),getDisplace(),pos,getReferencePositions(),myder.getAtomVector(),squared);
    else d=myrmsd.optimalAlignment<false,false>(getAlign(),getDisplace(),pos,getReferencePositions(),myder.getAtomVector(),squared);
  } else {
    if( getAlign()==getDisplace() ) d=myrmsd.optimalAlignment<true,true>(getAlign(),getDisplace(),pos,getReferencePositions(),myder.getAtomVector(),squared);
    else d=myrmsd.optimalAlignment<true,false>(getAlign(),getDisplace(),pos,getReferencePositions(),myder.getAtomVector(),squared);
  }
  myder.clear(); for(unsigned i=0; i<pos.size(); ++i) myder.setAtomDerivatives( i, myder.getAtomVector()[i] );
  if( !myder.updateComplete() ) myder.updateDynamicLists();
  return d;
}
Esempio n. 24
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 );
}
Esempio n. 25
0
void Mapping::prepare(){
  if( mymap->mappingNeedsSetup() ){
      // Get the arguments and atoms that are required
      std::vector<AtomNumber> atoms; std::vector<std::string> args;
      mymap->getAtomAndArgumentRequirements( atoms, args );
      requestAtoms( atoms ); std::vector<Value*> req_args; 
      interpretArgumentList( args, req_args ); requestArguments( req_args );
      // Duplicate all frames (duplicates are used by sketch-map)
      mymap->duplicateFrameList();
      // Get the number of frames in the path
      unsigned nfram=getNumberOfReferencePoints();
      fframes.resize( 2*nfram, 0.0 ); dfframes.resize( 2*nfram, 0.0 ); 
      plumed_assert( !mymap->mappingNeedsSetup() );
      // Resize all derivative arrays
      mymap->setNumberOfAtomsAndArguments( atoms.size(), args.size() );
      // Resize forces array
      forcesToApply.resize( 3*getNumberOfAtoms() + 9 + getNumberOfArguments() );
  }
}
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() );
}
Esempio n. 27
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;
}
Esempio n. 28
0
void Colvar::apply(){
  vector<Vector>&   f(modifyForces());
  Tensor&           v(modifyVirial());
  unsigned          nat=getNumberOfAtoms();

  for(unsigned i=0;i<f.size();i++){
    f[i][0]=0.0;
    f[i][1]=0.0;
    f[i][2]=0.0;
  }
  v.zero();

  if(!isEnergy){
    for(int i=0;i<getNumberOfComponents();++i){
      if( getPntrToComponent(i)->applyForce( forces ) ){
       for(unsigned j=0;j<nat;++j){
          f[j][0]+=forces[3*j+0];
          f[j][1]+=forces[3*j+1];
          f[j][2]+=forces[3*j+2];
       }
       v(0,0)+=forces[3*nat+0];
       v(0,1)+=forces[3*nat+1];
       v(0,2)+=forces[3*nat+2];
       v(1,0)+=forces[3*nat+3];
       v(1,1)+=forces[3*nat+4];
       v(1,2)+=forces[3*nat+5];
       v(2,0)+=forces[3*nat+6];
       v(2,1)+=forces[3*nat+7];
       v(2,2)+=forces[3*nat+8];
    }
   }
  } else if( isEnergy ){
     forces.resize(1);
     if( getPntrToComponent(0)->applyForce( forces ) ) modifyForceOnEnergy()+=forces[0];
  }
}
Esempio n. 29
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++;
     }
  }
}
Esempio n. 30
0
void SimpleRMSD::extractAtomicDisplacement( const std::vector<Vector>& pos, const bool& anflag, std::vector<Vector>& direction ) const {
  std::vector<Vector> tder( getNumberOfAtoms() );
  double d=myrmsd.simpleAlignment( getAlign(), getDisplace(), pos, getReferencePositions(), tder, direction, true );
  double scale=1.0; if( anflag ) scale = 1.0 / static_cast<double>( pos.size() );
  for(unsigned i=0;i<pos.size();++i) direction[i] = scale*direction[i];
}