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 ); }
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 ); } }
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; }
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; }
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() ); } }
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++; } } }
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; } }
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(); } }
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; } }
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; }
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; } }
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) ); } } }
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 ); }
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; }
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; } } }
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; }
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] ); }
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 ); }
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; }
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]; } } }
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] ); } } } }
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]; } } }
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] ); }
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) ); } } } }