void SecondaryStructureRMSD::setSecondaryStructure( std::vector<Vector>& structure, double bondlength, double units ){ // If we are in natural units get conversion factor from nm into natural length units if( plumed.getAtoms().usingNaturalUnits() ){ error("cannot use this collective variable when using natural units"); } plumed_massert( !(align_strands && align_atom_1==0 && align_atom_2==0), "you must use setAtomsFromStrands with strands cutoff"); // Convert into correct units for(unsigned i=0;i<structure.size();++i){ structure[i][0]*=units; structure[i][1]*=units; structure[i][2]*=units; } if( references.size()==0 ){ finishTaskListUpdate(); readVesselKeywords(); if( getNumberOfVessels()==0 ){ double r0; parse("R_0",r0); double d0; parse("D_0",d0); int nn; parse("NN",nn); int mm; parse("MM",mm); std::ostringstream ostr; ostr<<"RATIONAL R_0="<<r0<<" D_0="<<d0<<" NN="<<nn<<" MM="<<mm; std::string input=ostr.str(); addVessel( "LESS_THAN", input, -1 ); // -1 here means that this value will be named getLabel() readVesselKeywords(); // This makes sure resizing is done } } // Set the reference structure references.push_back( metricRegister().create<SingleDomainRMSD>( alignType ) ); unsigned nn=references.size()-1; std::vector<double> align( structure.size(), 1.0 ), displace( structure.size(), 1.0 ); references[nn]->setBoundsOnDistances( true , bondlength ); // We always use pbc references[nn]->setReferenceAtoms( structure, align, displace ); // references[nn]->setNumberOfAtoms( structure.size() ); }
vesselbase::StoreDataVessel* MultiColvarBase::buildDataStashes( const bool& allow_wcutoff, const double& wtol ){ // Check if vessels have already been setup for(unsigned i=0;i<getNumberOfVessels();++i){ StoreColvarVessel* ssc=dynamic_cast<StoreColvarVessel*>( getPntrToVessel(i) ); if(ssc){ if( allow_wcutoff && !ssc->weightCutoffIsOn() ) error("Cannot have more than one data stash with different properties"); if( !allow_wcutoff && ssc->weightCutoffIsOn() ) error("Cannot have more than one data stash with different properties"); return ssc; } } // Setup central atoms vesselbase::VesselOptions da("","",0,"",this); mycatoms=new StoreCentralAtomsVessel(da); if( allow_wcutoff ) mycatoms->setHardCutoffOnWeight( wtol ); addVessel(mycatoms); // Setup store values vessel vesselbase::VesselOptions ta("","",0,"",this); myvalues=new StoreColvarVessel(ta); if( allow_wcutoff ) myvalues->setHardCutoffOnWeight( wtol ); addVessel(myvalues); // Make sure resizing of vessels is done resizeFunctions(); return myvalues; }
void ClusterAnalysisBase::turnOnDerivatives(){ // Check for dubious vessels for(unsigned i=0;i<getNumberOfVessels();++i){ if( getPntrToVessel(i)->getName()=="MEAN" ) error("MEAN of cluster is not differentiable"); if( getPntrToVessel(i)->getName()=="VMEAN" ) error("VMEAN of cluster is not differentiable"); } MultiColvarBase::turnOnDerivatives(); }
bool ActionWithVessel::getForcesFromVessels( std::vector<double>& forcesToApply ){ plumed_dbg_assert( forcesToApply.size()==getNumberOfDerivatives() ); forcesToApply.assign( forcesToApply.size(),0.0 ); bool wasforced=false; for(unsigned i=0;i<getNumberOfVessels();++i){ if( (functions[i]->applyForce( tmpforces )) ){ wasforced=true; for(unsigned j=0;j<forcesToApply.size();++j) forcesToApply[j]+=tmpforces[j]; } } return wasforced; }
void MultiColvarBase::addTaskToList( const unsigned& taskCode ){ plumed_assert( getNumberOfVessels()==0 ); ActionWithVessel::addTaskToList( taskCode ); }
void MultiColvarBase::setupLinkCells(){ if( !linkcells.enabled() ) return ; unsigned iblock; if( usespecies ){ iblock=0; } else if( ablocks.size()<4 ){ iblock=1; } else { plumed_error(); } // Count number of currently active atoms unsigned nactive_atoms=0; for(unsigned i=0;i<ablocks[iblock].size();++i){ if( isCurrentlyActive( iblock, ablocks[iblock][i] ) ) nactive_atoms++; } std::vector<Vector> ltmp_pos( nactive_atoms ); std::vector<unsigned> ltmp_ind( nactive_atoms ); nactive_atoms=0; if( usespecies ){ for(unsigned i=0;i<ablocks[0].size();++i){ if( !isCurrentlyActive( 0, ablocks[0][i] ) ) continue; ltmp_ind[nactive_atoms]=ablocks[0][i]; ltmp_pos[nactive_atoms]=getPositionOfAtomForLinkCells( ltmp_ind[nactive_atoms] ); nactive_atoms++; } } else { for(unsigned i=0;i<ablocks[1].size();++i){ if( !isCurrentlyActive( 1, ablocks[1][i] ) ) continue; ltmp_ind[nactive_atoms]=i; ltmp_pos[nactive_atoms]=getPositionOfAtomForLinkCells( ablocks[1][i] ); nactive_atoms++; } } // Build the lists for the link cells linkcells.buildCellLists( ltmp_pos, ltmp_ind, getPbc() ); if( !usespecies ){ // Get some parallel info unsigned stride=comm.Get_size(); unsigned rank=comm.Get_rank(); if( serialCalculation() ){ stride=1; rank=0; } // Ensure we only do tasks where atoms are in appropriate link cells std::vector<unsigned> linked_atoms( 1+ablocks[1].size() ); std::vector<unsigned> active_tasks( getFullNumberOfTasks(), 0 ); for(unsigned i=rank;i<ablocks[0].size();i+=stride){ if( !isCurrentlyActive( 0, ablocks[0][i] ) ) continue; unsigned natomsper=1; linked_atoms[0]=ltmp_ind[0]; // Note we always check atom 0 because it is simpler than changing LinkCells.cpp linkcells.retrieveNeighboringAtoms( getPositionOfAtomForLinkCells( ablocks[0][i] ), natomsper, linked_atoms ); for(unsigned j=0;j<natomsper;++j){ for(unsigned k=bookeeping(i,linked_atoms[j]).first;k<bookeeping(i,linked_atoms[j]).second;++k) active_tasks[k]=1; } } if( !serialCalculation() ) comm.Sum( active_tasks ); deactivateAllTasks(); activateTheseTasks( active_tasks ); contributorsAreUnlocked=false; } else { // Now check for calculating volumes (currently this is only done for usespecies style commands // as it is difficult to do with things like DISTANCES or ANGLES and I think pointless bool justVolumes=true; for(unsigned i=0;i<getNumberOfVessels();++i){ vesselbase::BridgeVessel* myb=dynamic_cast<vesselbase::BridgeVessel*>( getPntrToVessel(i) ); if( !myb ){ justVolumes=false; break; } ActionVolume* myv=dynamic_cast<ActionVolume*>( myb->getOutputAction() ); if( !myv ){ justVolumes=false; break; } } // Now ensure that we only do calculations for those atoms in the relevant volume if( justVolumes ){ bool justVolumes=true; // Setup the regions in the action volume objects for(unsigned i=0;i<getNumberOfVessels();++i){ vesselbase::BridgeVessel* myb=dynamic_cast<vesselbase::BridgeVessel*>( getPntrToVessel(i) ); ActionVolume* myv=dynamic_cast<ActionVolume*>( myb->getOutputAction() ); myv->retrieveAtoms(); myv->setupRegions(); } unsigned stride=comm.Get_size(); unsigned rank=comm.Get_rank(); if( serialCalculation() ){ stride=1; rank=0; } unsigned nactive=0; std::vector<unsigned> active_tasks( getFullNumberOfTasks(), 0 ); for(unsigned i=rank;i<getFullNumberOfTasks();i+=stride){ bool invol=false; for(unsigned j=0;j<getNumberOfVessels();++j){ vesselbase::BridgeVessel* myb=dynamic_cast<vesselbase::BridgeVessel*>( getPntrToVessel(j) ); ActionVolume* myv=dynamic_cast<ActionVolume*>( myb->getOutputAction() ); if( myv->inVolumeOfInterest(i) ){ invol=true; } } if( invol ){ nactive++; active_tasks[i]=1; } } if( !serialCalculation() ) comm.Sum( active_tasks ); deactivateAllTasks(); activateTheseTasks( active_tasks ); contributorsAreUnlocked=false; } } }