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 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(); } }
PathBase::PathBase(const ActionOptions& ao): Action(ao), Mapping(ao) { bool noz; parseFlag("NOZPATH",noz); parse("LAMBDA",lambda); // Create the list of tasks for(unsigned i=0;i<getNumberOfReferencePoints();++i) addTaskToList( i ); std::string empty="LABEL=zpath"; if(!noz) addVessel("ZPATH",empty,0); }
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 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<ReferenceConfiguration*>& myconfs=getAllReferenceConfigurations(); for(unsigned i=0; i<myconfs.size(); ++i) myconfs[i]->print( pathfile, ofmt, atoms.getUnits().getLength()/0.1 ); pathfile.flush(); } }