void VolumeGradientBase::requestAtoms( const std::vector<AtomNumber>& atoms ) { ActionAtomistic::requestAtoms(atoms); bridgeVariable=3*atoms.size(); std::map<std::string,bool> checklabs; for(const auto & p : getDependencies() ) checklabs.insert(std::pair<std::string,bool>(p->getLabel(),false)); for(const auto & p : plumed.getActionSet() ) { if( p->getLabel()==getPntrToMultiColvar()->getLabel() ) break; if( checklabs.count(p->getLabel()) ) checklabs[p->getLabel()]=true; } for(const auto & p : checklabs ) { if( !p.second ) error("the input for the virtual atoms used in the input for this action must appear in the input file before the input multicolvar"); } addDependency( getPntrToMultiColvar() ); tmpforces.resize( 3*atoms.size()+9 ); }
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) ); } } } }
MultiColvarFilter::MultiColvarFilter(const ActionOptions&ao): Action(ao), BridgedMultiColvarFunction(ao) { if( getPntrToMultiColvar()->isDensity() ) error("filtering density makes no sense"); readVesselKeywords(); }
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; }
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 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 ); }
MultiColvarFilter::MultiColvarFilter(const ActionOptions&ao): Action(ao), BridgedMultiColvarFunction(ao) { if( getPntrToMultiColvar()->isDensity() ) error("filtering/transforming density makes no sense"); if( getName().find("MFILTER")!=std::string::npos ) filter=true; else { plumed_assert( getName().find("MTRANSFORM")!=std::string::npos ); filter=false; } readVesselKeywords(); }
ActionVolume::ActionVolume(const ActionOptions&ao): Action(ao), VolumeGradientBase(ao) { // Find number of quantities if( getPntrToMultiColvar()->isDensity() ) nquantities=2; // Value + weight else if( getPntrToMultiColvar()->getNumberOfQuantities()==2 ) nquantities=2; // Value + weight else nquantities = 1 + getPntrToMultiColvar()->getNumberOfQuantities()-2 + 1; // Norm + vector + weight // Output some nice information std::string functype=getPntrToMultiColvar()->getName(); std::transform( functype.begin(), functype.end(), functype.begin(), tolower ); log.printf(" calculating %s inside region of insterest\n",functype.c_str() ); parseFlag("OUTSIDE",not_in); sigma=0.0; if( keywords.exists("SIGMA") ) parse("SIGMA",sigma); if( keywords.exists("KERNEL") ) parse("KERNEL",kerneltype); if( getPntrToMultiColvar()->isDensity() ) { std::string input; addVessel( "SUM", input, -1 ); // -1 here means that this value will be named getLabel() } readVesselKeywords(); }
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] ); } } } }