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