コード例 #1
0
double ContactAlignedMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
  double f_dot, dot_df; 

  std::vector<double> orient0(ncomp), orient1(ncomp);
  getOrientationVector( myatoms.getIndex(0), true, orient0 );
  getOrientationVector( myatoms.getIndex(1), true, orient1 );
  double dot=0; for(unsigned k=2;k<orient0.size();++k) dot+=orient0[k]*orient1[k];
  f_dot=0.5*( 1 + dot ); dot_df=0.5; 

  // Retrieve the weight of the connection
  double weight = myatoms.getValue(0); myatoms.setValue(0,1.0); 

  if( !doNotCalculateDerivatives() ){
      Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
      double dfunc, sw = switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( distance.modulo(), dfunc );
      addAtomDerivatives( 1, 0, (-dfunc)*f_dot*distance, myatoms );
      addAtomDerivatives( 1, 1, (+dfunc)*f_dot*distance, myatoms ); 
      myatoms.addBoxDerivatives( 1, (-dfunc)*f_dot*Tensor(distance,distance) ); 

      // Add derivatives of orientation 
      for(unsigned k=2;k<orient0.size();++k){ orient0[k]*=sw*dot_df; orient1[k]*=sw*dot_df; }
      addOrientationDerivatives( 1, 0, orient1, myatoms );
      addOrientationDerivatives( 1, 1, orient0, myatoms );
  }
  return weight*f_dot;
}
コード例 #2
0
ファイル: NumberOfLinks.cpp プロジェクト: juvejones/plumed2
double NumberOfLinks::compute(){
   getValueForBaseTask( 0, orient0 ); 
   getValueForBaseTask( 1, orient1 );

   double dot=0;
   for(unsigned k=0;k<orient0.size();++k){
       dot+=orient0[k]*orient1[k];
   }
//   for(unsigned k=0;k<orient0.size();++k){
//      orient0[k]*=dot_df; orient1[k]*=dot_df;
//   }
   addOrientationDerivatives( 0, orient1 );
   addOrientationDerivatives( 1, orient0 );

   return dot;
}
コード例 #3
0
double OrientationSphere::compute(){
   // Make sure derivatives for central atom are only calculated once
   VectorMultiColvar* vv = dynamic_cast<VectorMultiColvar*>( getBaseMultiColvar(0) );
   vv->firstcall=true;

   weightHasDerivatives=true;   // The weight has no derivatives really
   double sw, value=0, denom=0, dot, f_dot, dot_df, dfunc; Vector distance;

   getVectorForBaseTask(0, catom_orient );
   for(unsigned i=1;i<getNAtoms();++i){
      distance=getSeparation( getPositionOfCentralAtom(0), getPositionOfCentralAtom(i) );
      sw = switchingFunction.calculateSqr( distance.modulo2(), dfunc );
      if( sw>=getTolerance() ){    
         getVectorForBaseTask( i, this_orient );
         // Calculate the dot product wrt to this position 
         dot=0; for(unsigned k=0;k<catom_orient.size();++k) dot+=catom_orient[k]*this_orient[k];  
         f_dot = transformDotProduct( dot, dot_df ); 
         // N.B. We are assuming here that the imaginary part of the dot product is zero
         for(unsigned k=0;k<catom_orient.size();++k){
            this_orient[k]*=sw*dot_df; catom_der[k]=sw*dot_df*catom_orient[k];
         }  

         // Set the derivatives wrt of the numerator
         addOrientationDerivatives( 0, this_orient ); 
         addOrientationDerivatives( i, catom_der );  
         addCentralAtomsDerivatives( 0, 0, f_dot*(-dfunc)*distance );
         addCentralAtomsDerivatives( i, 0, f_dot*(dfunc)*distance );
         addBoxDerivatives( f_dot*(-dfunc)*Tensor(distance,distance) );
         value += sw*f_dot;
         // Set the derivatives wrt to the numerator
         addCentralAtomsDerivatives( 0, 1, (-dfunc)*distance );
         addCentralAtomsDerivatives( i, 1, (dfunc)*distance );
         addBoxDerivativesOfWeight( (-dfunc)*Tensor(distance,distance) );
         denom += sw;
      }
   }
   
   // Now divide everything
   unsigned nder = getNumberOfDerivatives();
   for(unsigned i=0;i<nder;++i){
      setElementDerivative( i, getElementDerivative(i)/denom - (value*getElementDerivative(nder+i))/(denom*denom) );  
      setElementDerivative( nder + i, 0.0 );
   }
   weightHasDerivatives=false;   // Weight has no derivatives we just use the holder for weight to store some stuff
   return value / denom;
}