예제 #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;
}
double InterMolecularTorsions::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
  Vector v1, v2, dv1, dv2, dconn, conn = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );

  // Retrieve vectors
  std::vector<double> orient0( 5 ), orient1( 5 );
  getInputData( 0, true, myatoms, orient0 );
  getInputData( 1, true, myatoms, orient1 );
  for(unsigned i=0; i<3; ++i) { v1[i]=orient0[2+i]; v2[i]=orient1[2+i]; }
  if( getBaseMultiColvar(0)->getNumberOfQuantities()<3 ) return 1.0;

  // Evaluate angle
  Torsion t; double angle = t.compute( v1, conn, v2, dv1, dconn, dv2 );
  for(unsigned i=0; i<3; ++i) { orient0[i+2]=dv1[i]; orient1[i+2]=dv2[i]; }

  // And accumulate derivatives
  if( !doNotCalculateDerivatives() ) {
    MultiValue& myder0=getInputDerivatives( 0, true, myatoms );
    mergeInputDerivatives( 1, 2, orient1.size(), 0, orient0, myder0, myatoms );
    MultiValue& myder1=getInputDerivatives( 1, true, myatoms );
    mergeInputDerivatives( 1, 2, orient0.size(), 1, orient1, myder1, myatoms );
    addAtomDerivatives( 1, 0, -dconn, myatoms ); addAtomDerivatives( 1, 1, dconn, myatoms );
    myatoms.addBoxDerivatives( 1, -extProduct( conn, dconn ) );
  }

  return angle;
}
예제 #3
0
double NumberOfLinks::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
   if( getBaseMultiColvar(0)->getNumberOfQuantities()<3 ) return 1.0; 

   unsigned ncomp=getBaseMultiColvar(0)->getNumberOfQuantities();

   std::vector<double> orient0( ncomp ), orient1( ncomp );
   getVectorForTask( myatoms.getIndex(0), true, orient0 ); 
   getVectorForTask( myatoms.getIndex(1), true, orient1 );

   double dot=0;
   for(unsigned k=2;k<orient0.size();++k){
       dot+=orient0[k]*orient1[k];
   }

   if( !doNotCalculateDerivatives() ){
     unsigned nder=myatoms.getNumberOfDerivatives();   //getNumberOfDerivatives();
     MultiValue myder0(ncomp,nder), myder1(ncomp,nder);
     getVectorDerivatives( myatoms.getIndex(0), true, myder0 );
     mergeVectorDerivatives( 1, 2, orient1.size(), myatoms.getIndex(0), orient1, myder0, myatoms );
     getVectorDerivatives( myatoms.getIndex(1), true, myder1 ); 
     mergeVectorDerivatives( 1, 2, orient0.size(), myatoms.getIndex(1), orient0, myder1, myatoms );
   }

   return dot;
}
예제 #4
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]; 
}
예제 #5
0
double ContactMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
  if( !doNotCalculateDerivatives() ){
      Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
      double dfunc, sw = switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) - ncol_t ).calculate( distance.modulo(), dfunc );
      addAtomDerivatives( 1, 0, (-dfunc)*distance, myatoms );
      addAtomDerivatives( 1, 1, (+dfunc)*distance, myatoms ); 
      myatoms.addBoxDerivatives( 1, (-dfunc)*Tensor(distance,distance) ); 
  }
  double val=myatoms.getValue(0); myatoms.setValue(0,1.0);
  return val;
}
예제 #6
0
void MultiColvarBase::getCentralAtomIndexList( const unsigned& ntotal, const unsigned& jstore, const unsigned& maxder, std::vector<unsigned>& indices ) const {
  plumed_dbg_assert( !doNotCalculateDerivatives() );

  indices[jstore]=3*atomsWithCatomDer.getNumberActive();
  if( indices[jstore]>maxder ) error("too many derivatives to store. Run with LOWMEM");

  unsigned kder  = ntotal + jstore*maxder;
  for(unsigned jder=0;jder<atomsWithCatomDer.getNumberActive();++jder){
     unsigned iatom = 3*atomsWithCatomDer[jder];
     for(unsigned icomp=0;icomp<3;++icomp){ indices[ kder ] = iatom+icomp; kder++; }
  }
}
예제 #7
0
double TopologyMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
  HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( kerneltype );

  // Initialise to zero density on all bins
  for(unsigned bin=0; bin<maxbins; ++bin) myatoms.setValue(bin+1,0);
  // Calculate whether or not atoms 1 and 2 are within cutoff (can use delta here as pbc are done in atom setup)
  Vector d1 = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) ); double d1_len = d1.modulo();
  d1 = d1 / d1_len;  // Convert vector into director
  AtomNumber a1 = myatoms.getAbsoluteIndex( 0 );
  AtomNumber a2 = myatoms.getAbsoluteIndex( 1 );
  for(unsigned i=2; i<myatoms.getNumberOfAtoms(); ++i) {
    AtomNumber a3 = myatoms.getAbsoluteIndex( i );
    if( a3!=a1 && a3!=a2 ) calculateForThreeAtoms( i, d1, d1_len, bead, myatoms );
  }
  // std::vector<double> binvals( 1+maxbins ); for(unsigned i=1;i<maxbins;++i) binvals[i]=myatoms.getValue(i);
  // unsigned ii; double fdf;
  //std::cout<<"HELLO DENSITY "<<myatoms.getIndex(0)<<" "<<myatoms.getIndex(1)<<" "<<transformStoredValues( binvals, ii, fdf )<<std::endl;

  // Now find the element for which the density is maximal
  unsigned vout=2; double max=myatoms.getValue( 2 );
  for(unsigned i=3; i<myatoms.getUnderlyingMultiValue().getNumberOfValues()-1; ++i) {
    if( myatoms.getValue(i)>max ) { max=myatoms.getValue(i); vout=i; }
  }
  // Calculate value and derivative of switching function between atoms 1 and 2
  double dfuncl, sw = switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ),
                                         getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( d1_len, dfuncl );
  // Transform the density
  double df, tsw = threshold_switch.calculate( max, df );
  if( !doNotCalculateDerivatives() ) {
    // Factor of d1_len is required here because d1 is normalized
    d1 *= d1_len;
    addAtomDerivatives( 2+maxbins, 0, -dfuncl*d1, myatoms );
    addAtomDerivatives( 2+maxbins, 1, dfuncl*d1, myatoms );
    myatoms.addBoxDerivatives( 2+maxbins, (-dfuncl)*Tensor(d1,d1) );
    // Update active atoms so that next bit works
    updateActiveAtoms( myatoms );
    // Now finish caclulation of derivatives
    MultiValue& myvals=myatoms.getUnderlyingMultiValue();
    for(unsigned jd=0; jd<myvals.getNumberActive(); ++jd) {
      unsigned ider=myvals.getActiveIndex(jd);
      myvals.addDerivative( 1, ider, sw*df*max*myvals.getDerivative( vout, ider ) + tsw*myvals.getDerivative( 2+maxbins, ider ) );
    }
  }
  return sw*tsw;
}
예제 #8
0
void DFSClusterDiameter::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const { 
  unsigned iatom=current/getNumberOfNodes(), jatom = current - iatom*getNumberOfNodes();
  Vector distance=getSeparation( getPosition(iatom), getPosition(jatom) );
  double dd = distance.modulo(), inv = 1.0/dd ; myvals.setValue( 1, dd ); 
  if( !doNotCalculateDerivatives() ){
      myvals.addDerivative( 1, 3*iatom + 0, -inv*distance[0] );
      myvals.addDerivative( 1, 3*iatom + 1, -inv*distance[1] );
      myvals.addDerivative( 1, 3*iatom + 2, -inv*distance[2] );
      myvals.addDerivative( 1, 3*jatom + 0, +inv*distance[0] );
      myvals.addDerivative( 1, 3*jatom + 1, +inv*distance[1] );
      myvals.addDerivative( 1, 3*jatom + 2, +inv*distance[2] );
      Tensor vir = -inv*Tensor(distance,distance);
      unsigned vbase = myvals.getNumberOfDerivatives() - 9;
      for(unsigned i=0;i<3;++i){
          for(unsigned j=0;j<3;++j) myvals.addDerivative( 1, vbase+3*i+j, vir(i,j) );
      }
  }
}
예제 #9
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 );
}
예제 #10
0
void ActionWithGrid::calculate(){
  // Do nothing if derivatives are not required
  if( doNotCalculateDerivatives() ) return;
  // Clear on every step
  if( mygrid ) clearAverage();
  // Should not be any reweighting so just set these accordingly
  lweight=0; cweight=1.0;
  // Prepare to do the averaging
  prepareForAveraging();
  // Run all the tasks (if required
  if( useRunAllTasks ) runAllTasks();
  // This the averaging if it is not done using task list
  else performOperations( true );
  // Update the norm
  if( mygrid ) mygrid->setNorm( cweight );
  // Finish the averaging
  finishAveraging();
  // And reset for next step
  if( mygrid ) mygrid->reset();
}
예제 #11
0
double VectorMultiColvar::doCalculation( const unsigned& taskIndex, multicolvar::AtomValuePack& myatoms ) const {
  // Now calculate the vector
  calculateVector( myatoms );
  // Sort out the active derivatives
  updateActiveAtoms( myatoms );

  // Now calculate the norm of the vector (this is what we return here)
  double norm=0; 
  for(unsigned i=0;i<ncomponents;++i) norm += myatoms.getValue(2+i)*myatoms.getValue(2+i); 
  norm=sqrt(norm);
 
  if( !doNotCalculateDerivatives() ){
      double inorm = 1.0 / norm; std::vector<double> dervec( ncomponents );
      for(unsigned i=0;i<ncomponents;++i) dervec[i] = inorm*myatoms.getValue(2+i);
 
      MultiValue& myvals=myatoms.getUnderlyingMultiValue();
      for(unsigned j=0;j<myvals.getNumberActive();++j){
          unsigned jder=myvals.getActiveIndex(j);
          for(unsigned i=0;i<ncomponents;++i) myvals.addDerivative( 1, jder, dervec[i]*myvals.getDerivative( 2+i, jder ) );
      }
  }
  
  return norm;
}
예제 #12
0
double OrientationSphere::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
   // Make sure derivatives for central atom are only calculated once
   VectorMultiColvar* vv = dynamic_cast<VectorMultiColvar*>( getBaseMultiColvar(0) );
   vv->firstcall=true;

   double d2, sw, value=0, denom=0, dot, f_dot, dot_df, dfunc; 
   unsigned ncomponents=getBaseMultiColvar(0)->getNumberOfQuantities();
   unsigned nder=myatoms.getNumberOfDerivatives();
   std::vector<double> catom_orient( ncomponents ), this_orient( ncomponents ), catom_der( ncomponents ); 

   Vector catom_pos = myatoms.getPosition(0);
   getVectorForTask( myatoms.getIndex(0), true, catom_orient );
   multicolvar::CatomPack atom0; MultiValue myder0(0,0), myder1(0,0); 
   if( !doNotCalculateDerivatives() ){
       myder0.resize( ncomponents,nder ); myder1.resize(ncomponents,nder); 
       atom0=getCentralAtomPackFromInput( myatoms.getIndex(0) );
       getVectorDerivatives( myatoms.getIndex(0), true, myder0 );
   }

   for(unsigned i=1;i<myatoms.getNumberOfAtoms();++i){
      Vector& distance=myatoms.getPosition(i);  
      if ( (d2=distance[0]*distance[0])<rcut2 &&
           (d2+=distance[1]*distance[1])<rcut2 &&
           (d2+=distance[2]*distance[2])<rcut2) {
 
         sw = switchingFunction.calculateSqr( d2, dfunc );  
 
         getVectorForTask( myatoms.getIndex(i), true, this_orient );
         // Calculate the dot product wrt to this position 
         dot=0; for(unsigned k=2;k<catom_orient.size();++k) dot+=catom_orient[k]*this_orient[k];  
         f_dot = transformDotProduct( dot, dot_df ); 

         if( !doNotCalculateDerivatives() ){
             // N.B. We are assuming here that the imaginary part of the dot product is zero
             for(unsigned k=2;k<catom_orient.size();++k){
                 this_orient[k]*=sw*dot_df; catom_der[k]=sw*dot_df*catom_orient[k];
             }
             getVectorDerivatives( myatoms.getIndex(i), true, myder1 );
             mergeVectorDerivatives( 1, 2, this_orient.size(), myatoms.getIndex(0), this_orient, myder0, myatoms );  
             mergeVectorDerivatives( 1, 2, catom_der.size(), myatoms.getIndex(i), catom_der, myder1, myatoms );
             myatoms.addComDerivatives( 1, f_dot*(-dfunc)*distance, atom0 );
             addAtomDerivatives( 1, i, f_dot*(dfunc)*distance, myatoms );
             myatoms.addBoxDerivatives( 1, (-dfunc)*f_dot*Tensor(distance,distance) );
             myder1.clearAll();
              
             myatoms.addComDerivatives( -1, (-dfunc)*distance, atom0 );
             addAtomDerivatives( -1, i, (dfunc)*distance, myatoms );
             myatoms.addTemporyBoxDerivatives( (-dfunc)*Tensor(distance,distance) );

         }
         value += sw*f_dot;
         denom += sw;
      }
   }
   double rdenom, df2, pref=calculateCoordinationPrefactor( denom, df2 );
   if( fabs(denom)>epsilon ){ rdenom = 1.0 / denom; }
   else { plumed_assert(fabs(value)<epsilon); rdenom=1.0; } 
  
   // Now divide everything
   double rdenom2=rdenom*rdenom;
   updateActiveAtoms( myatoms ); MultiValue& myvals=myatoms.getUnderlyingMultiValue();
   for(unsigned i=0;i<myvals.getNumberActive();++i){
       unsigned ider=myvals.getActiveIndex(i);
       double  dgd=myvals.getTemporyDerivative(ider);
       myvals.setDerivative( 1, ider, rdenom*(pref*myvals.getDerivative(1,ider)+value*df2*dgd) - (value*pref*dgd)*rdenom2 );
   } 

   return pref*rdenom*value;
}
void ClusterProperties::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
  std::vector<double> vals( myvals.getNumberOfValues() ); getPropertiesOfNode( current, vals );
  if( !doNotCalculateDerivatives() ) getNodePropertyDerivatives( current, myvals );
  for(unsigned k=0; k<vals.size(); ++k) myvals.setValue( k, vals[k] );
}
예제 #14
0
void TopologyMatrix::calculateForThreeAtoms( const unsigned& iat, const Vector& d1, const double& d1_len,
    HistogramBead& bead, multicolvar::AtomValuePack& myatoms ) const {
  // Calculate if there are atoms in the cylinder (can use delta here as pbc are done in atom setup)
  Vector d2 = getSeparation( myatoms.getPosition(0), myatoms.getPosition(iat) );
  // Now calculate projection of d2 on d1
  double proj=dotProduct(d2,d1);
  // This tells us if we are outside the end of the cylinder
  double excess = proj - d1_len;
  // Return if we are outside of the cylinder as calculated based on excess
  if( excess>low_sf( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).get_dmax() ) return;
  // Find the length of the cylinder
  double binw = binw_mat( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) );
  double lcylinder = (std::floor( d1_len / binw ) + 1)*binw;
  // Return if the projection is outside the length of interest
  if( proj<-bead.getCutoff() || proj>(lcylinder+bead.getCutoff()) ) return;

  // Calculate the excess swiching function
  double edf, eval = low_sf( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( excess, edf );
  // Calculate the projection on the perpendicular distance from the center of the tube
  double cm = d2.modulo2() - proj*proj;

  // Now calculate the density in the cylinder
  if( cm<cylinder_sw( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).get_dmax2() ) {
    double dfuncr, val = cylinder_sw( getBaseColvarNumber( myatoms.getIndex(0) ),
                                      getBaseColvarNumber( myatoms.getIndex(1) ) ).calculateSqr( cm, dfuncr );
    double cellv = cell_volume( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) );
    Vector dc1, dc2, dc3, dd1, dd2, dd3, de1, de2, de3;
    if( !doNotCalculateDerivatives() ) {
      Tensor d1_a1;
      // Derivative of director connecting atom1 - atom2 wrt the position of atom 1
      d1_a1(0,0) = ( -(d1[1]*d1[1]+d1[2]*d1[2])/d1_len );   // dx/dx
      d1_a1(0,1) = (  d1[0]*d1[1]/d1_len );                 // dx/dy
      d1_a1(0,2) = (  d1[0]*d1[2]/d1_len );                 // dx/dz
      d1_a1(1,0) = (  d1[1]*d1[0]/d1_len );                 // dy/dx
      d1_a1(1,1) = ( -(d1[0]*d1[0]+d1[2]*d1[2])/d1_len );   // dy/dy
      d1_a1(1,2) = (  d1[1]*d1[2]/d1_len );
      d1_a1(2,0) = (  d1[2]*d1[0]/d1_len );
      d1_a1(2,1) = (  d1[2]*d1[1]/d1_len );
      d1_a1(2,2) = ( -(d1[1]*d1[1]+d1[0]*d1[0])/d1_len );

      // Calculate derivatives of dot product
      dd1 = matmul(d2, d1_a1) - d1;
      dd2 = matmul(d2, -d1_a1);
      dd3 = d1;

      // Calculate derivatives of cross product
      dc1 = dfuncr*( -d2 - proj*dd1 );
      dc2 = dfuncr*( -proj*dd2 );
      dc3 = dfuncr*( d2 - proj*dd3 );

      // Calculate derivatives of excess
      de1 = edf*excess*( dd1 + d1 );
      de2 = edf*excess*( dd2 - d1 );
      de3 = edf*excess*dd3;
    }

    Vector pos1 = myatoms.getPosition(0) + d1_len*d1;
    Vector pos2 = myatoms.getPosition(0) + d2;
    Vector g1derivf,g2derivf,lderivf; Tensor vir;
    for(unsigned bin=0; bin<maxbins; ++bin) {
      bead.set( bin*binw, (bin+1)*binw, sigma );
      if( proj<(bin*binw-bead.getCutoff()) || proj>binw*(bin+1)+bead.getCutoff() ) continue;
      double der, contr=bead.calculateWithCutoff( proj, der ) / cellv; der /= cellv;
      myatoms.addValue( 2+bin, contr*val*eval );

      if( !doNotCalculateDerivatives() ) {
        g1derivf=contr*eval*dc1 + val*eval*der*dd1 + contr*val*de1;
        addAtomDerivatives( 2+bin, 0, g1derivf, myatoms );
        g2derivf=contr*eval*dc2 + val*eval*der*dd2 + contr*val*de2;
        addAtomDerivatives( 2+bin, 1, g2derivf, myatoms );
        lderivf=contr*eval*dc3 + val*eval*der*dd3 + contr*val*de3;
        addAtomDerivatives( 2+bin, iat, lderivf, myatoms );
        // Virial
        vir = -Tensor( myatoms.getPosition(0), g1derivf ) - Tensor( pos1, g2derivf ) - Tensor( pos2, lderivf );
        myatoms.addBoxDerivatives( 2+bin, vir );
      }
    }
  }
}
예제 #15
0
void DFSBasic::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
   std::vector<double> vals( myvals.getNumberOfValues() ); getVectorForTask( current, false, vals );
   if( !doNotCalculateDerivatives() ) getVectorDerivatives( current, false, myvals );
   for(unsigned k=0;k<vals.size();++k) myvals.setValue( k, vals[k] ); 
}