예제 #1
0
void ReferenceValuePack::copyScaledDerivatives( const unsigned& from, const double& scalef, const MultiValue& tvals ){
  plumed_dbg_assert( tvals.getNumberOfDerivatives()==myvals.getNumberOfDerivatives() );
  for(unsigned i=0;i<tvals.getNumberActive();++i){
      unsigned ider=tvals.getActiveIndex(i);
      myvals.addDerivative( oind, ider, scalef*tvals.getDerivative( from, ider ) );
  }
}
void MultiColvarDensity::compute( const unsigned& current, MultiValue& myvals ) const {
  std::vector<double> cvals( mycolv->getNumberOfQuantities() ); stash->retrieveSequentialValue( current, false, cvals );
  Vector fpos, apos = pbcDistance( origin, mycolv->getCentralAtomPos( mycolv->getPositionInFullTaskList(current) ) );
  if( fractional ) { fpos = getPbc().realToScaled( apos ); } else { fpos=apos; }

  myvals.setValue( 0, cweight*cvals[0] ); for(unsigned j=0; j<directions.size(); ++j) myvals.setValue( 1+j, fpos[ directions[j] ] );
  myvals.setValue( 1+directions.size(), cvals[1] );
}
void VolumeGradientBase::completeTask( const unsigned& curr, MultiValue& invals, MultiValue& outvals ) const {
  if( getPntrToMultiColvar()->isDensity() ) {
    outvals.setValue(0, 1.0); outvals.setValue(1, 1.0);
  } else {
    // Copy derivatives of the colvar and the value of the colvar
    invals.copyValues( outvals );
    if( derivativesAreRequired() ) invals.copyDerivatives( outvals );
  }
  calculateAllVolumes( curr, outvals );
}
예제 #4
0
void SpathVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_index ) const {
  double pp=mymap->getPropertyValue( current, getLabel() ), weight=myvals.get(0);
  if( weight<getTolerance() ) return;
  unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
  buffer[bufstart] += weight*pp; buffer[bufstart+1+nderivatives] += weight;
  if( getAction()->derivativesAreRequired() ) {
    myvals.chainRule( 0, 0, 1, 0, pp, bufstart, buffer );
    myvals.chainRule( 0, 1, 1, 0, 1.0, bufstart, buffer );
  }
}
예제 #5
0
bool ActionWithVessel::calculateAllVessels( const unsigned& taskCode, MultiValue& myvals, MultiValue& bvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ){
  bool keep=false; 
  for(unsigned j=0;j<functions.size();++j){
      // Calculate returns a bool that tells us if this particular
      // quantity is contributing more than the tolerance
      if( functions[j]->calculate( taskCode, functions[j]->transformDerivatives(taskCode, myvals, bvals), buffer, der_list ) ) keep=true;
      if( !actionIsBridged && bvals.getNumberActive()>0 ) bvals.clearAll(); 
  }
  return keep;
}
예제 #6
0
void ActionWithInputMatrix::addConnectionDerivatives( const unsigned& i, const unsigned& j, MultiValue& myvals, MultiValue& myvout ) const {
  if( !mymatrix->matrixElementIsActive( i, j ) ) return;
  unsigned myelem = mymatrix->getStoreIndexFromMatrixIndices( i, j );
  // Get derivatives and add
  mymatrix->retrieveDerivatives( myelem, false, myvals );
  for(unsigned jd=0; jd<myvals.getNumberActive(); ++jd) {
    unsigned ider=myvals.getActiveIndex(jd);
    myvout.addDerivative( 1, ider, myvals.getDerivative( 1, ider ) );
  }
}
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;
}
예제 #8
0
AtomValuePack::AtomValuePack( MultiValue& vals, MultiColvarBase const * mcolv ):
myvals(vals),
mycolv(mcolv),
natoms(0),
indices( vals.getIndices() ),
sort_vector( vals.getSortIndices() ),
myatoms( vals.getAtomVector() )
{
  if( indices.size()!=mcolv->getNumberOfAtoms() ){ 
    indices.resize( mcolv->getNumberOfAtoms() ); 
    sort_vector.resize( mcolv->getNumberOfAtoms() ); 
    myatoms.resize( mcolv->getNumberOfAtoms() );
  }
}
예제 #9
0
void StoreDataVessel::storeDerivatives( const unsigned& myelem, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
  plumed_dbg_assert( vecsize>0 && getAction()->derivativesAreRequired() && myelem<getAction()->getFullNumberOfTasks() );
  unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem );

  if( getAction()->getFullNumberOfTasks()==getNumberOfStoredValues() ){
      der_list[jelem]=myvals.getNumberActive();
      unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
      for(unsigned j=0;j<myvals.getNumberActive();++j){ der_list[kder] = myvals.getActiveIndex(j); kder++; }
  } else {
      // This ensures that active indices are gathered correctly if 
      // we have multiple tasks contributing to a stored quantity 
      unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
      for(unsigned j=0;j<myvals.getNumberActive();++j){
          bool found=false; unsigned jder = myvals.getActiveIndex(j);
          for(unsigned k=0;k<der_list[jelem];++k){
              if( der_list[kder+k]==jder ){ found=true; break; }
          }
          if(!found){ der_list[kder+der_list[jelem]]=jder; der_list[jelem]++; }
      }
  }

  // Store the values of the components and the derivatives 
  for(unsigned icomp=0;icomp<vecsize;++icomp){
     unsigned ibuf = bufstart + jelem * ( vecsize*nspace ) + icomp*nspace + 1;
     for(unsigned j=0;j<myvals.getNumberActive();++j){
        unsigned jder=myvals.getActiveIndex(j);
        buffer[ibuf] += myvals.getDerivative( icomp, jder ); ibuf++;   
     }
  }
}
예제 #10
0
void StoreDataVessel::storeValues( const unsigned& myelem, MultiValue& myvals, std::vector<double>& buffer ) const {
  plumed_dbg_assert( vecsize>0 );
  unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem ); plumed_dbg_assert( jelem<getNumberOfStoredValues() );
  unsigned ibuf = bufstart + jelem * vecsize * nspace; 
  for(unsigned icomp=0;icomp<vecsize;++icomp){
      buffer[ibuf] += myvals.get(icomp); ibuf+=nspace;
  }
}
예제 #11
0
void StoreDataVessel::retrieveDerivatives( const unsigned& myelem, const bool& normed, MultiValue& myvals ){
  plumed_dbg_assert( myvals.getNumberOfValues()==vecsize && myvals.getNumberOfDerivatives()==getAction()->getNumberOfDerivatives() );

  myvals.clearAll();
  if( getAction()->lowmem ){
      recalculateStoredQuantity( myelem, myvals );
      if( normed ) getAction()->normalizeVectorDerivatives( myvals );
  } else {
      unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem );
      // Retrieve the derivatives for elements 0 and 1 - weight and norm
      for(unsigned icomp=0;icomp<vecsize;++icomp){
          unsigned ibuf = jelem * ( vecsize*nspace ) + icomp*nspace + 1;
          unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
          for(unsigned j=0;j<active_der[jelem];++j){
              myvals.addDerivative( icomp, active_der[kder], local_buffer[ibuf] );
              kder++; ibuf++;
          }
      }
      if( normed ) getAction()->normalizeVectorDerivatives( myvals );
      // Now ensure appropriate parts of list are activated
      myvals.emptyActiveMembers();
      unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
      for(unsigned j=0;j<active_der[jelem];++j){ myvals.putIndexInActiveArray( active_der[kder] ); kder++; }
      myvals.sortActiveList();
  } 
}
예제 #12
0
void MultiValue::copyDerivatives( MultiValue& outvals ) {
  plumed_dbg_assert( values.size()<=outvals.getNumberOfValues() && nderivatives<=outvals.getNumberOfDerivatives() );
  if( !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();

  outvals.atLeastOneSet=true; unsigned ndert=hasDerivatives.getNumberActive();
  for(unsigned j=0; j<ndert; ++j) {
    unsigned jder=hasDerivatives[j]; outvals.hasDerivatives.activate(jder);
  }

  unsigned base=0, obase=0;
  for(unsigned i=0; i<values.size(); ++i) {
    for(unsigned j=0; j<ndert; ++j) {
      unsigned jder=hasDerivatives[j];
      outvals.derivatives[obase+jder] += derivatives[base+jder];
    }
    obase+=outvals.nderivatives; base+=nderivatives;
  }
}
예제 #13
0
void StoreDataVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {

  if( myvals.get(0)>epsilon ){
     storeValues( current, myvals, buffer );
     if( !(getAction()->lowmem) && getAction()->derivativesAreRequired() ) storeDerivatives( current, myvals, buffer, der_list );
  } 

  return;
}
예제 #14
0
ReferenceValuePack::ReferenceValuePack( const unsigned& nargs, const unsigned& natoms, MultiValue& vals ):
boxWasSet(false),
numberOfArgs(nargs),
oind_set(false),
myvals(vals),
atom_indices(myvals.getIndices()),
pca(false)
{
  if( atom_indices.size()!=natoms ){ atom_indices.resize( natoms ); myvals.getAtomVector().resize( natoms ); }
  if( vals.getNumberOfValues()==1 ){ oind=0; oind_set=true; }
}
예제 #15
0
void VectorMultiColvar::normalizeVectorDerivatives( MultiValue& myvals ) const {
  double v = myvals.get(1), weight = 1.0 / v,  wdf = 1.0 / ( v*v*v );
  for(unsigned j=0;j<myvals.getNumberActive();++j){
      double comp2=0.0; unsigned jder=myvals.getActiveIndex(j);
      for(unsigned jcomp=2;jcomp<myvals.getNumberOfValues();++jcomp) comp2 += myvals.get(jcomp)*myvals.getDerivative( jcomp, jder );
      for(unsigned jcomp=2;jcomp<myvals.getNumberOfValues();++jcomp){
          myvals.setDerivative( jcomp, jder, weight*myvals.getDerivative( jcomp, jder ) - wdf*comp2*myvals.get(jcomp) );
      }
  }
}
예제 #16
0
 bool operator== (const MultiValue &rhs) const {
     if (n_ == rhs.size()) {
         for (int i = 0; i < n_; i++) {
             if (v_[i] != rhs[i]) {
                 return false;
             }
         }
         return true;
     } else {
         return false;
     }
 }
void FindContourSurface::compute( const unsigned& current, MultiValue& myvals ) const {
  std::vector<unsigned> neighbours; unsigned num_neighbours; unsigned nfound=0; double minp=0;
  std::vector<unsigned> bins_n( ingrid->getNbin() ); unsigned shiftn=current;
  std::vector<unsigned> ind( ingrid->getDimension() ); std::vector<double> point( ingrid->getDimension() );
#ifndef DNDEBUG
  std::vector<unsigned> oind( mygrid->getDimension() ); mygrid->getIndices( current, oind );
#endif
  for(unsigned i=0; i<bins_n[dir_n]; ++i) {
#ifndef DNDEBUG
    std::vector<unsigned> base_ind( ingrid->getDimension() ); ingrid->getIndices( shiftn, base_ind );
    for(unsigned j=0; j<gdirs.size(); ++j) plumed_dbg_assert( base_ind[gdirs[j]]==oind[j] );
#endif
    // Ensure inactive grid points are ignored
    if( ingrid->inactive( shiftn ) ) { shiftn += ingrid->getStride()[dir_n]; continue; }
    // Get the index of the current grid point
    ingrid->getIndices( shiftn, ind );
    // Exit if we are at the edge of the grid
    if( !ingrid->isPeriodic(dir_n) && (ind[dir_n]+1)==bins_n[dir_n] ) {
      shiftn += ingrid->getStride()[dir_n]; continue;
    }

    // Ensure points with inactive neighbours are ignored
    ingrid->getNeighbors( ind, ones, num_neighbours, neighbours );
    bool cycle=false;
    for(unsigned j=0; j<num_neighbours; ++j) {
      if( ingrid->inactive( neighbours[j]) ) { cycle=true; break; }
    }
    if( cycle ) { shiftn += ingrid->getStride()[dir_n]; continue; }

    // Now get the function value at two points
    double val1=getFunctionValue( shiftn ) - contour; double val2;
    if( (ind[dir_n]+1)==bins_n[dir_n] ) val2 = getFunctionValue( current ) - contour;
    else val2=getFunctionValue( shiftn + ingrid->getStride()[dir_n] ) - contour;

    // Check if the minimum is bracketed
    if( val1*val2<0 ) {
      ingrid->getGridPointCoordinates( shiftn, point ); findContour( direction, point );
      minp=point[dir_n]; nfound++; break;
    }


    // This moves us on to the next point
    shiftn += ingrid->getStride()[dir_n];
  }
  if( nfound==0 ) {
    std::string num; Tools::convert( getStep(), num );
    error("On step " + num + " failed to find required grid point");
  }
  myvals.setValue( 1, minp );
}
예제 #18
0
void FunctionVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
  unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
  double weight=myvals.get(0); 
  plumed_dbg_assert( weight>=getTolerance() );  

  // This deals with the value
  double dval, f=calcTransform( myvals.get(mycomp), dval );

  if( norm ){
     if( usetol && weight<getTolerance() ) return;
     buffer[bufstart+1+nderivatives] += weight;
     if( diffweight ) myvals.chainRule( 0, 1, 1, 0, 1.0, bufstart, buffer );
  }

  double contr=weight*f;
  if( usetol && contr<getTolerance() ) return;
  buffer[bufstart] += contr;

  if( diffweight ) myvals.chainRule( 0, 0, 1, 0, f, bufstart, buffer ); 
  if( getAction()->derivativesAreRequired() && fabs(dval)>0.0 ) myvals.chainRule( mycomp, 0, 1, 0, weight*dval, bufstart, buffer );

  return;
}
예제 #19
0
 bool operator< (const cell_locator &rhs) const {
     int i = tbl_name.compare(rhs.tbl_name);
     if (i < 0) {
         return true;
     } else if (i > 0) {
         return false;
     } else {
         if (col_id < rhs.col_id) {
             return true;
         } else if (col_id > rhs.col_id) {
             return false;
         } else {
             return primary_key.compare(rhs.primary_key) < 0;
         }
     }
 }
예제 #20
0
 size_t operator() (const MultiValue& key) const {
     size_t ret = 0;
     for (int i = 0; i < key.size(); i++) {
         const Value &v = key[i];
         switch (v.get_kind()) {
             case Value::I32:
                 ret ^= std::hash<int32_t>() (v.get_i32());
                 break;
             case Value::I64:
                 ret ^= std::hash<int64_t>() (v.get_i64());
                 break;
             case Value::DOUBLE:
                 ret ^= std::hash<double>() (v.get_double());
                 break;
             case Value::STR:
                 ret ^= std::hash<std::string>() (v.get_str());
                 break;
             default:
                 verify(0);
         }
     }
     return ret;
 }
예제 #21
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) );
      }
  }
}
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] );
}
예제 #23
0
void ClusterDiameter::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const { 
  unsigned iatom=std::floor(current/getNumberOfNodes()), jatom = current - iatom*getNumberOfNodes();
  Vector distance=getSeparation( getPosition(iatom), getPosition(jatom) );
  double dd = distance.modulo();
  myvals.setValue( 0, 1.0 ); myvals.setValue( 1, dd ); 
}
예제 #24
0
void ManyRestraintsBase::transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const {
    outvals.setValue( 0, invals.get(0) );

    // Get the potential
    double dval=0, val=calcPotential( invals.get(1), dval );

    outvals.setValue( 1, val );
    for(unsigned i=0; i<invals.getNumberActive(); ++i) {
        unsigned jder=invals.getActiveIndex(i);
        outvals.addDerivative( 1, jder, dval*invals.getDerivative( 1, jder ) );
    }

    // Now update the outvals derivatives lists
    outvals.emptyActiveMembers();
    for(unsigned j=0; j<invals.getNumberActive(); ++j) outvals.updateIndex( invals.getActiveIndex(j) );
    outvals.completeUpdate();
    return;
}
예제 #25
0
void HistogramOnGrid::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
    if( addOneKernelAtATime ) {
        plumed_dbg_assert( myvals.getNumberOfValues()==2 && !wasforced );
        std::vector<double> der( dimension );
        for(unsigned i=0; i<dimension; ++i) der[i]=myvals.getDerivative( 1, i );
        accumulate( getAction()->getPositionInCurrentTaskList(current), myvals.get(0), myvals.get(1), der, buffer );
    } else {
        plumed_dbg_assert( myvals.getNumberOfValues()==dimension+2 );
        std::vector<double> point( dimension );
        double weight=myvals.get(0)*myvals.get( 1+dimension );
        for(unsigned i=0; i<dimension; ++i) point[i]=myvals.get( 1+i );

        // Get the kernel
        unsigned num_neigh;
        std::vector<unsigned> neighbors;
        std::vector<double> der( dimension );
        KernelFunctions* kernel=getKernelAndNeighbors( point, num_neigh, neighbors );
        // If no kernel normalize the vector so von misses distribution is calculated correctly
        if( !kernel ) {
            double norm=0;
            for(unsigned j=0; j<dimension; ++j) norm += point[j]*point[j];
            norm=sqrt( norm );
            for(unsigned j=0; j<dimension; ++j) point[j] = point[j] / norm;
        }

        if( !kernel && getType()=="flat" ) {
            plumed_dbg_assert( num_neigh==1 );
            accumulate( neighbors[0], weight, 1.0, der, buffer );
        } else {
            double totwforce=0.0;
            std::vector<double> intforce( 2*dimension, 0.0 );
            std::vector<Value*> vv( getVectorOfValues() );

            double newval;
            std::vector<double> xx( dimension );
            for(unsigned i=0; i<num_neigh; ++i) {
                unsigned ineigh=neighbors[i];
                if( inactive( ineigh ) ) continue ;
                getGridPointCoordinates( ineigh, xx );
                for(unsigned j=0; j<dimension; ++j) vv[j]->set(xx[j]);
                if( kernel ) {
                    newval = kernel->evaluate( vv, der, true );
                } else {
                    // Evalulate dot product
                    double dot=0;
                    for(unsigned j=0; j<dimension; ++j) {
                        dot+=xx[j]*point[j];
                        der[j]=xx[j];
                    }
                    // Von misses distribution for concentration parameter
                    newval = von_misses_norm*exp( von_misses_concentration*dot );
                    // And final derivatives
                    for(unsigned j=0; j<dimension; ++j) der[j] *= von_misses_concentration*newval;
                }
                accumulate( ineigh, weight, newval, der, buffer );
                if( wasForced() ) {
                    accumulateForce( ineigh, weight, der, intforce );
                    totwforce += myvals.get( 1+dimension )*newval*forces[ineigh];
                }
            }
            if( wasForced() ) {
                unsigned nder = getAction()->getNumberOfDerivatives();
                unsigned gridbuf = getNumberOfBufferPoints()*getNumberOfQuantities();
                for(unsigned j=0; j<dimension; ++j) {
                    for(unsigned k=0; k<myvals.getNumberActive(); ++k) {
                        // Minus sign here as we are taking derivative with respect to position of center of kernel NOT derivative wrt to
                        // grid point
                        unsigned kder=myvals.getActiveIndex(k);
                        buffer[ bufstart + gridbuf + kder ] -= intforce[j]*myvals.getDerivative( j+1, kder );
                    }
                }
                // Accumulate the sum of all the weights
                buffer[ bufstart + gridbuf + nder ] += myvals.get(0);
                // Add the derivatives of the weights into the force -- this is separate loop as weights of all parts are considered together
                for(unsigned k=0; k<myvals.getNumberActive(); ++k) {
                    unsigned kder=myvals.getActiveIndex(k);
                    buffer[ bufstart + gridbuf + kder ] += totwforce*myvals.getDerivative( 0, kder );
                    buffer[ bufstart + gridbuf + nder + 1 + kder ] += myvals.getDerivative( 0, kder );
                }
            }
            delete kernel;
            for(unsigned i=0; i<dimension; ++i) delete vv[i];
        }
    }
}
예제 #26
0
inline bool operator <(const MultiValue& mv1, const MultiValue& mv2) {
    return mv1.compare(mv2) == -1;
}
void VolumeGradientBase::setNumberInVolume( const unsigned& ivol, const unsigned& curr, const double& weight,
    const Vector& wdf, const Tensor& virial, const std::vector<Vector>& refders,
    MultiValue& outvals ) const {
  MultiColvarBase* mcolv=getPntrToMultiColvar();
  if( !mcolv->weightHasDerivatives ) {
    outvals.setValue(ivol, weight );
    if( derivativesAreRequired() ) {
      CatomPack catom; mcolv->getCentralAtomPack( 0, curr, catom );
      for(unsigned i=0; i<catom.getNumberOfAtomsWithDerivatives(); ++i) {
        unsigned jatom=3*catom.getIndex(i);
        outvals.addDerivative( ivol, jatom+0, catom.getDerivative(i,0,wdf) );
        outvals.addDerivative( ivol, jatom+1, catom.getDerivative(i,1,wdf) );
        outvals.addDerivative( ivol, jatom+2, catom.getDerivative(i,2,wdf) );
      }
      unsigned nmder=getPntrToMultiColvar()->getNumberOfDerivatives();
      for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) outvals.addDerivative( ivol, nmder-9+3*i+j, virial(i,j) );
      for(unsigned i=0; i<refders.size(); ++i) {
        unsigned iatom=nmder+3*i;

        outvals.addDerivative( ivol, iatom+0, refders[i][0] );
        outvals.addDerivative( ivol, iatom+1, refders[i][1] );
        outvals.addDerivative( ivol, iatom+2, refders[i][2] );
      }
    }
  } else if(ivol==0) {
    double ww=outvals.get(0); outvals.setValue(ivol,ww*weight);
    if( derivativesAreRequired() ) {
      plumed_merror("This needs testing");
      CatomPack catom; mcolv->getCentralAtomPack( 0, curr, catom );
      for(unsigned i=0; i<catom.getNumberOfAtomsWithDerivatives(); ++i) {
        unsigned jatom=3*catom.getIndex(i);
        outvals.addDerivative( ivol, jatom+0, weight*outvals.getDerivative(ivol,jatom+0) + ww*catom.getDerivative(i,0,wdf) );
        outvals.addDerivative( ivol, jatom+1, weight*outvals.getDerivative(ivol,jatom+1) + ww*catom.getDerivative(i,1,wdf) );
        outvals.addDerivative( ivol, jatom+2, weight*outvals.getDerivative(ivol,jatom+2) + ww*catom.getDerivative(i,2,wdf) );
      }
      unsigned nmder=getPntrToMultiColvar()->getNumberOfDerivatives();
      for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) outvals.addDerivative( ivol, nmder-9+3*i+j, ww*virial(i,j) );
      for(unsigned i=0; i<refders.size(); ++i) {
        unsigned iatom=nmder+3*i;
        outvals.addDerivative( ivol, iatom+0, ww*refders[i][0] );
        outvals.addDerivative( ivol, iatom+1, ww*refders[i][1] );
        outvals.addDerivative( ivol, iatom+2, ww*refders[i][2] );
      }
    }
  } else {
    double ww=outvals.get(0); outvals.setValue(ivol,ww*weight);
    if( derivativesAreRequired() ) {
      plumed_merror("This needs testing");
      CatomPack catom; mcolv->getCentralAtomPack( 0, curr, catom );
      for(unsigned i=0; i<catom.getNumberOfAtomsWithDerivatives(); ++i) {
        unsigned jatom=3*catom.getIndex(i);
        outvals.addDerivative( ivol, jatom+0, ww*catom.getDerivative(i,0,wdf) );
        outvals.addDerivative( ivol, jatom+1, ww*catom.getDerivative(i,1,wdf) );
        outvals.addDerivative( ivol, jatom+2, ww*catom.getDerivative(i,2,wdf) );
      }
      unsigned nmder=getPntrToMultiColvar()->getNumberOfDerivatives();
      for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) outvals.addDerivative( ivol, nmder-9+3*i+j, ww*virial(i,j) );
      for(unsigned i=0; i<refders.size(); ++i) {
        unsigned iatom=nmder+3*i;
        outvals.addDerivative( ivol, iatom+0, ww*refders[i][0] );
        outvals.addDerivative( ivol, iatom+1, ww*refders[i][1] );
        outvals.addDerivative( ivol, iatom+2, ww*refders[i][2] );
      }
    }
  }
}
예제 #28
0
void Histogram::compute( const unsigned& current, MultiValue& myvals ) const {
  if( mvectors ) {
    std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() );
    stashes[0]->retrieveSequentialValue( current, true, cvals );
    for(unsigned i=2; i<myvessels[0]->getNumberOfQuantities(); ++i) myvals.setValue( i-1, cvals[i] );
    myvals.setValue( 0, cvals[0] ); myvals.setValue( myvessels[0]->getNumberOfQuantities() - 1, ww );
    if( in_apply ) {
      MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0);
      if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() ||
          tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() )
        tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() );
      stashes[0]->retrieveDerivatives( stashes[0]->getTrueIndex(current), true, tmpval );
      for(unsigned j=0; j<tmpval.getNumberActive(); ++j) {
        unsigned jder=tmpval.getActiveIndex(j); myvals.addDerivative( 0, jder, tmpval.getDerivative(0, jder) );
        for(unsigned i=2; i<myvessels[0]->getNumberOfQuantities(); ++i) myvals.addDerivative( i-1, jder, tmpval.getDerivative(i, jder) );
      }
      myvals.updateDynamicList();
    }
  } else if( myvessels.size()>0 ) {
    std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() );
    stashes[0]->retrieveSequentialValue( current, false, cvals );
    unsigned derbase; double totweight=cvals[0], tnorm = cvals[0]; myvals.setValue( 1, cvals[1] );
    // Get the derivatives as well if we are in apply
    if( in_apply ) {
      // This bit gets the total weight
      double weight0 = cvals[0];  // Store the current weight
      for(unsigned j=1; j<myvessels.size(); ++j) {
        stashes[j]->retrieveSequentialValue( current, false, cvals ); totweight *= cvals[0];
      }
      // And this bit the derivatives
      MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0);
      if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() ||
          tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() )
        tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() );
      stashes[0]->retrieveDerivatives( stashes[0]->getTrueIndex(current), false, tmpval );
      for(unsigned j=0; j<tmpval.getNumberActive(); ++j) {
        unsigned jder=tmpval.getActiveIndex(j);
        myvals.addDerivative( 1, jder, tmpval.getDerivative(1,jder) );
        myvals.addDerivative( 0, jder, (totweight/weight0)*tmpval.getDerivative(0,jder) );
      }
      derbase = myvessels[0]->getNumberOfDerivatives();
    }
    for(unsigned i=1; i<myvessels.size(); ++i) {
      if( cvals.size()!=myvessels[i]->getNumberOfQuantities() ) cvals.resize( myvessels[i]->getNumberOfQuantities() );
      stashes[i]->retrieveSequentialValue( current, false, cvals );
      tnorm *= cvals[0]; myvals.setValue( 1+i, cvals[1] );
      // Get the derivatives as well if we are in apply
      if( in_apply ) {
        MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0);
        if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() ||
            tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() )
          tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() );
        stashes[i]->retrieveDerivatives( stashes[i]->getTrueIndex(current), false, tmpval );
        for(unsigned j=0; j<tmpval.getNumberActive(); ++j) {
          unsigned jder=tmpval.getActiveIndex(j);
          myvals.addDerivative( 1+i, derbase+jder, tmpval.getDerivative(1,jder) );
          myvals.addDerivative( 0, derbase+jder, (totweight/cvals[0])*tmpval.getDerivative(0,jder) );
        }
        derbase += myvessels[i]->getNumberOfDerivatives();
      }
    }
    myvals.setValue( 0, tnorm ); myvals.setValue( 1+myvessels.size(), ww );
    if( in_apply ) myvals.updateDynamicList();
  } else {
    plumed_assert( !in_apply );
    std::vector<Value*> vv( myhist->getVectorOfValues() );
    std::vector<double> val( getNumberOfArguments() ), der( getNumberOfArguments() );
    // Retrieve the location of the grid point at which we are evaluating the kernel
    mygrid->getGridPointCoordinates( current, val );
    if( kernel ) {
      for(unsigned i=0; i<getNumberOfArguments(); ++i) vv[i]->set( val[i] );
      // Evaluate the histogram at the relevant grid point and set the values
      double vvh = kernel->evaluate( vv, der,true); myvals.setValue( 1, vvh );
    } else {
      plumed_merror("normalisation of vectors does not work with arguments and spherical grids");
      // Evalulate dot product
      double dot=0; for(unsigned j=0; j<getNumberOfArguments(); ++j) { dot+=val[j]*getArgument(j); der[j]=val[j]; }
      // Von misses distribution for concentration parameter
      double newval = (myhist->von_misses_norm)*exp( (myhist->von_misses_concentration)*dot ); myvals.setValue( 1, newval );
      // And final derivatives
      for(unsigned j=0; j<getNumberOfArguments(); ++j) der[j] *= (myhist->von_misses_concentration)*newval;
    }
    // Set the derivatives and delete the vector of values
    for(unsigned i=0; i<getNumberOfArguments(); ++i) { myvals.setDerivative( 1, i, der[i] ); delete vv[i]; }
  }
}
예제 #29
0
void MultiValue::copyValues( MultiValue& outvals ) const {
  plumed_dbg_assert( values.size()<=outvals.getNumberOfValues() );
  for(unsigned i=0; i<values.size(); ++i) outvals.setValue( i, values[i] );

}
예제 #30
0
void MultiColvarFilter::completeTask( const unsigned& curr, MultiValue& invals, MultiValue& outvals ) const {
  invals.copyValues( outvals );
  if( derivativesAreRequired() ) invals.copyDerivatives( outvals );
 
  // Retrive the value of the multicolvar and apply filter
  double val=invals.get(1), df, weight=applyFilter( val, df );

  // Now propegate derivatives
  if( !getPntrToMultiColvar()->weightHasDerivatives ){
     outvals.setValue( 0, weight );
     if( derivativesAreRequired() ){
         for(unsigned i=0;i<invals.getNumberActive();++i){
             unsigned jder=invals.getActiveIndex(i);
             outvals.addDerivative( 0, jder, df*invals.getDerivative(1, jder ) );
         }
     }
  } else {
     double ww=outvals.get(0); outvals.setValue( 0, ww*weight );
     if( derivativesAreRequired() ){
         for(unsigned i=0;i<outvals.getNumberActive();++i){
             unsigned ider=outvals.getActiveIndex(i);
             outvals.setDerivative( 0, ider, weight*outvals.getDerivative(1,ider) + ww*df*outvals.getDerivative(0,ider) );
         }
     }
  }
}