void AdaptivePath::update() { double weight2 = -1.*mypathv->dx; double weight1 = 1.0 + mypathv->dx; if( weight1>1.0 ) { weight1=1.0; weight2=0.0; } else if( weight2>1.0 ) { weight1=0.0; weight2=1.0; } // Add projections to dispalcement accumulators ReferenceConfiguration* myref = getReferenceConfiguration( mypathv->iclose1 ); myref->extractDisplacementVector( getPositions(), getArguments(), mypathv->cargs, false, displacement ); getReferenceConfiguration( mypathv->iclose2 )->extractDisplacementVector( myref->getReferencePositions(), getArguments(), myref->getReferenceArguments(), false, displacement2 ); displacement.addDirection( -mypathv->dx, displacement2 ); pdisplacements[mypathv->iclose1].addDirection( weight1, displacement ); pdisplacements[mypathv->iclose2].addDirection( weight2, displacement ); // Update weight accumulators wsum[mypathv->iclose1] *= fadefact; wsum[mypathv->iclose2] *= fadefact; wsum[mypathv->iclose1] += weight1; wsum[mypathv->iclose2] += weight2; // This does the update of the path if it is time to if( (getStep()>0) && (getStep()%update_str==0) ) { wsum[fixedn[0]]=wsum[fixedn[1]]=0.; for(unsigned inode=0; inode<getNumberOfReferencePoints(); ++inode) { if( wsum[inode]>0 ) { // First displace the node by the weighted direction getReferenceConfiguration( inode )->displaceReferenceConfiguration( 1./wsum[inode], pdisplacements[inode] ); // Reset the displacement pdisplacements[inode].zeroDirection(); } } // Now ensure all the nodes of the path are equally spaced PathReparameterization myspacings( getPbc(), getArguments(), getAllReferenceConfigurations() ); myspacings.reparameterize( fixedn[0], fixedn[1], tolerance ); } if( (getStep()>0) && (getStep()%wstride==0) ) { pathfile.printf("# PATH AT STEP %d TIME %f \n", getStep(), getTime() ); std::vector<std::unique_ptr<ReferenceConfiguration>>& myconfs=getAllReferenceConfigurations(); std::vector<SetupMolInfo*> moldat=plumed.getActionSet().select<SetupMolInfo*>(); if( moldat.size()>1 ) error("you should only have one MOLINFO action in your input file"); SetupMolInfo* mymoldat=NULL; if( moldat.size()==1 ) mymoldat=moldat[0]; std::vector<std::string> argument_names( getNumberOfArguments() ); for(unsigned i=0; i<getNumberOfArguments(); ++i) argument_names[i] = getPntrToArgument(i)->getName(); PDB mypdb; mypdb.setArgumentNames( argument_names ); for(unsigned i=0; i<myconfs.size(); ++i) { pathfile.printf("REMARK TYPE=%s\n", myconfs[i]->getName().c_str() ); mypdb.setAtomPositions( myconfs[i]->getReferencePositions() ); for(unsigned j=0; j<getNumberOfArguments(); ++j) mypdb.setArgumentValue( getPntrToArgument(j)->getName(), myconfs[i]->getReferenceArgument(j) ); mypdb.print( atoms.getUnits().getLength()/0.1, mymoldat, pathfile, ofmt ); } pathfile.flush(); } }
TrigonometricPathVessel::TrigonometricPathVessel( const vesselbase::VesselOptions& da ): StoreDataVessel(da), projdir(ReferenceConfigurationOptions("DIRECTION")), mydpack1( 1, getAction()->getNumberOfDerivatives() ), mydpack2( 1, getAction()->getNumberOfDerivatives() ), mydpack3( 1, getAction()->getNumberOfDerivatives() ), mypack1( 0, 0, mydpack1 ), mypack2( 0, 0, mydpack2 ), mypack3( 0, 0, mydpack3 ) { mymap=dynamic_cast<Mapping*>( getAction() ); plumed_massert( mymap, "Trigonometric path vessel can only be used with mappings"); // Retrieve the index of the property in the underlying mapping if( mymap->getNumberOfProperties()!=1 ) error("cannot use trigonometric paths when there are multiple properties"); for(unsigned i=0; i<mymap->getFullNumberOfTasks(); ++i) { if( mymap->getTaskCode(i)!=mymap->getPositionInFullTaskList(i) ) error("mismatched tasks and codes"); } mymap->addComponentWithDerivatives("gspath"); mymap->componentIsNotPeriodic("gspath"); sp=mymap->copyOutput( mymap->getNumberOfComponents()-1 ); sp->resizeDerivatives( mymap->getNumberOfDerivatives() ); mymap->addComponentWithDerivatives("gzpath"); mymap->componentIsNotPeriodic("gzpath"); zp=mymap->copyOutput( mymap->getNumberOfComponents()-1 ); zp->resizeDerivatives( mymap->getNumberOfDerivatives() ); // Check we have PCA ReferenceConfiguration* ref0=mymap->getReferenceConfiguration(0); for(unsigned i=0; i<mymap->getFullNumberOfTasks(); ++i) { if( !(mymap->getReferenceConfiguration(i))->pcaIsEnabledForThisReference() ) error("pca must be implemented in order to use trigometric path"); if( ref0->getName()!=(mymap->getReferenceConfiguration(i))->getName() ) error("cannot use mixed metrics"); if( mymap->getNumberOfAtoms()!=(mymap->getReferenceConfiguration(i))->getNumberOfReferencePositions() ) error("all frames must use the same set of atoms"); if( mymap->getNumberOfArguments()!=(mymap->getReferenceConfiguration(i))->getNumberOfReferenceArguments() ) error("all frames must use the same set of arguments"); } cargs.resize( mymap->getNumberOfArguments() ); std::vector<std::string> argument_names( mymap->getNumberOfArguments() ); for(unsigned i=0; i<mymap->getNumberOfArguments(); ++i) argument_names[i] = (mymap->getPntrToArgument(i))->getName(); PDB mypdb; mypdb.setAtomNumbers( mymap->getAbsoluteIndexes() ); mypdb.addBlockEnd( mymap->getAbsoluteIndexes().size() ); if( argument_names.size()>0 ) mypdb.setArgumentNames( argument_names ); projdir.read( mypdb ); mypack1.resize( mymap->getNumberOfArguments(), mymap->getNumberOfAtoms() ); ref0->setupPCAStorage( mypack1 ); mypack2.resize( mymap->getNumberOfArguments(), mymap->getNumberOfAtoms() ); ref0->setupPCAStorage( mypack2 ); mypack3.resize( mymap->getNumberOfArguments(), mymap->getNumberOfAtoms() ); for(unsigned i=0; i<mymap->getNumberOfAtoms(); ++i) { mypack1.setAtomIndex(i,i); mypack2.setAtomIndex(i,i); mypack3.setAtomIndex(i,i); } mypack1_stashd_atoms.resize( mymap->getNumberOfAtoms() ); mypack1_stashd_args.resize( mymap->getNumberOfArguments() ); }