SSAGES  0.1
A MetaDynamics Package
Public Member Functions | Static Public Member Functions | Protected Member Functions | List of all members
SSAGES::DirectForwardFlux Class Reference

ForwardFlux sampling method. More...

#include <DirectForwardFlux.h>

Inheritance diagram for SSAGES::DirectForwardFlux:
Inheritance graph
[legend]

Public Member Functions

 DirectForwardFlux (const MPI_Comm &world, const MPI_Comm &comm, double ninterfaces, std::vector< double > interfaces, unsigned int N0Target, std::vector< unsigned int > M, bool initialFluxFlag, bool saveTrajectories, unsigned int currentInterface, std::string output_directory, unsigned int frequency)
 Constructor. More...
 
void PostIntegration (Snapshot *snapshot, const class CVManager &cvmanager) override
 Post-integration hook. More...
 
- Public Member Functions inherited from SSAGES::ForwardFlux
 ForwardFlux (const MPI_Comm &world, const MPI_Comm &comm, double ninterfaces, std::vector< double > interfaces, unsigned int N0Target, std::vector< unsigned int > M, bool initialFluxFlag, bool saveTrajectories, unsigned int currentInterface, std::string output_directory, unsigned int frequency)
 Constructor. More...
 
void PreSimulation (Snapshot *snapshot, const class CVManager &cvmanager) override
 Pre-simulation hook. More...
 
void PostSimulation (Snapshot *snapshot, const class CVManager &cvmanager) override
 Post-simulation hook. More...
 
- Public Member Functions inherited from SSAGES::Method
 Method (uint frequency, const MPI_Comm &world, const MPI_Comm &comm)
 Constructor. More...
 
void SetCVMask (const std::vector< uint > &mask)
 Sets the collective variable mask.
 
virtual ~Method ()
 Destructor.
 
- Public Member Functions inherited from SSAGES::EventListener
 EventListener (uint frequency)
 Constructor. More...
 
uint GetFrequency () const
 Get frequency of event listener. More...
 
virtual ~EventListener ()
 Destructor.
 

Static Public Member Functions

static DirectForwardFluxBuild (const Json::Value &json, const MPI_Comm &world, const MPI_Comm &comm, const std::string &path)
 
- Static Public Member Functions inherited from SSAGES::ForwardFlux
static ForwardFluxBuild (const Json::Value &json, const MPI_Comm &world, const MPI_Comm &comm, const std::string &path)
 
- Static Public Member Functions inherited from SSAGES::Method
static MethodBuildMethod (const Json::Value &json, const MPI_Comm &world, const MPI_Comm &comm, const std::string &path)
 Build a derived method from JSON node. More...
 

Protected Member Functions

void CheckForInterfaceCrossings (Snapshot *, const class CVManager &) override
 Function that checks if interfaces have been crossed (different for each FFS flavor) More...
 
void InitializeQueue (Snapshot *, const CVList &) override
 Initialize the Queue.
 
- Protected Member Functions inherited from SSAGES::ForwardFlux
void CheckInitialStructure (const CVList &)
 Function that checks the initial structure that user provides.
 
void WriteInitialFlux ()
 Function to compute and write the initial flux.
 
void AddNewIDsToQueue ()
 
bool HasReturnedToA (double)
 Function checks if configuration has returned to A.
 
int HasCrossedInterface (double, double, unsigned int interface)
 Function checks if configuration has crossed interface specified since the last check. More...
 
void WriteFFSConfiguration (Snapshot *snapshot, FFSConfigID &ffsconfig, bool wassuccess)
 Write a file corresponding to FFSConfigID from current snapshot.
 
void ReadFFSConfiguration (Snapshot *, FFSConfigID &, bool)
 Read a file corresponding to a FFSConfigID into current snapshot.
 
void ComputeInitialFlux (Snapshot *, const CVList &)
 Compute Initial Flux.
 
void ComputeTransitionProbabilities ()
 Compute the probability of going from each lambda_i to lambda_{i+1}. More...
 
void PrintQueue ()
 Print the queue, useful for debugging.
 
void PopQueueMPI (Snapshot *, const CVList &, unsigned)
 Pop the queue, do MPI so that all procs maintain the same queue.
 
void FluxBruteForce (Snapshot *, const CVList &)
 Compute the flux via brute force. More...
 
void ReconstructTrajectories (Snapshot *)
 When simulation is finished, parse through the trajectories that reached B, and reconstruct the complete trajectory from where it started at A (lambda0)
 
void ComputeCommittorProbability (Snapshot *)
 When simulation is finished, recursively parse through the trajectories that reached B or failed back to A and calculate the Commitor Probability of that state going to B (_pB)
 
void AppendTrajectoryFile (Snapshot *, std::ofstream &)
 
void OpenTrajectoryFile (std::ofstream &)
 Take the current config in snapshot and append it to the provided ofstream.
 

Additional Inherited Members

- Protected Attributes inherited from SSAGES::ForwardFlux
double _ninterfaces
 
std::vector< double > _interfaces
 FFS Interfaces.
 
bool _interfaces_increase
 Interfaces must monotonically increase (or decrease), this determines whether going to the 'next' interface will be higher values of CV, or lower ones.
 
double _cvvalue_previous
 Previous cv position, used to determine if you've crossed an interface since last time.
 
double _cvvalue
 current cv position
 
double _rate
 rate constant
 
std::vector< FFSConfigIDLambda0ConfigLibrary
 Data structure that holds a Library N0 configurations at lambda0.
 
double _N0TotalSimTime
 Total Simulation Time spent in accumulating \ _N0.
 
unsigned int _N0Target
 Number of configurations to store at lambda0, target.
 
double _fluxA0
 Flux of trajectories out of state A. Denoted PhiA0 over h_A in Allen2009.
 
std::vector< unsigned int > _M
 
std::vector< unsigned int > _A
 Number of attempts from interface i.
 
std::vector< double > _P
 Flag to determine wheter fluxA0 should be calculated, seems not using this. More...
 
std::vector< unsigned int > _S
 
std::vector< unsigned int > _N
 
bool _pop_tried_but_empty_queue
 
bool _initialFluxFlag
 if 1 compute initial flux
 
bool initializeQueueFlag
 
FFSConfigID myFFSConfigID
 The current FFSConfigID of this MPI process.
 
bool _saveTrajectories
 should the FFS trajectories be saved
 
unsigned int _nfailure_total
 
std::vector< std::vector< double > > _pB
 
unsigned int _current_interface
 Current Interface.
 
std::default_random_engine _generator
 random number generator
 
std::deque< FFSConfigIDFFSConfigIDQueue
 
std::string _output_directory
 Directory of FFS output.
 
std::ofstream _trajectory_file
 file to which the current trajectory is written to
 
uint iteration_
 Method iteration counter/.
 
- Protected Attributes inherited from SSAGES::Method
mxx::comm world_
 Global MPI communicator.
 
mxx::comm comm_
 Local MPI communicator.
 
std::vector< uint > cvmask_
 Mask which identifies which CVs to act on.
 

Detailed Description

ForwardFlux sampling method.

The notation used here is drawn largely from Allen, Valeriani and Rein ten Wolde. J. Phys.: Condens. Matter (2009) 21:463102. We recommend referring to this review if the reader is unfamiliar with the method, or our variable naming conventions.

Definition at line 35 of file DirectForwardFlux.h.

Constructor & Destructor Documentation

SSAGES::DirectForwardFlux::DirectForwardFlux ( const MPI_Comm &  world,
const MPI_Comm &  comm,
double  ninterfaces,
std::vector< double >  interfaces,
unsigned int  N0Target,
std::vector< unsigned int >  M,
bool  initialFluxFlag,
bool  saveTrajectories,
unsigned int  currentInterface,
std::string  output_directory,
unsigned int  frequency 
)
inline

Constructor.

Parameters
worldMPI global communicator.
commMPI local communicator.
frequencyFrequency with which this method is invoked.

Create instance of Forward Flux

Definition at line 65 of file DirectForwardFlux.h.

References Build(), and PostIntegration().

71  : ForwardFlux(world, comm, ninterfaces, interfaces, N0Target, M,
72  initialFluxFlag, saveTrajectories, currentInterface, output_directory, frequency) {}
ForwardFlux(const MPI_Comm &world, const MPI_Comm &comm, double ninterfaces, std::vector< double > interfaces, unsigned int N0Target, std::vector< unsigned int > M, bool initialFluxFlag, bool saveTrajectories, unsigned int currentInterface, std::string output_directory, unsigned int frequency)
Constructor.
Definition: ForwardFlux.h:246

Here is the call graph for this function:

Member Function Documentation

static DirectForwardFlux* SSAGES::DirectForwardFlux::Build ( const Json::Value &  json,
const MPI_Comm &  world,
const MPI_Comm &  comm,
const std::string &  path 
)
static

Referenced by DirectForwardFlux().

Here is the caller graph for this function:

void SSAGES::DirectForwardFlux::CheckForInterfaceCrossings ( Snapshot ,
const class CVManager  
)
overrideprotectedvirtual

Function that checks if interfaces have been crossed (different for each FFS flavor)

Number of trials to attemt from each interface Note _M[0] sets the number of 'branches' for RBFFS and BGFFS?

Implements SSAGES::ForwardFlux.

Definition at line 67 of file DirectForwardFlux.cpp.

References SSAGES::ForwardFlux::_A, SSAGES::ForwardFlux::_current_interface, SSAGES::ForwardFlux::_cvvalue, SSAGES::ForwardFlux::_cvvalue_previous, SSAGES::ForwardFlux::_generator, SSAGES::ForwardFlux::_interfaces, SSAGES::ForwardFlux::_M, SSAGES::ForwardFlux::_N, SSAGES::ForwardFlux::_nfailure_total, SSAGES::ForwardFlux::_ninterfaces, SSAGES::ForwardFlux::_P, SSAGES::ForwardFlux::_pop_tried_but_empty_queue, SSAGES::ForwardFlux::_S, SSAGES::ForwardFlux::_saveTrajectories, SSAGES::ForwardFlux::_trajectory_file, SSAGES::ForwardFlux::FFSConfigID::a, SSAGES::ForwardFlux::AppendTrajectoryFile(), SSAGES::Method::cvmask_, SSAGES::ForwardFlux::FFSConfigIDQueue, SSAGES::CVManager::GetCVs(), SSAGES::ForwardFlux::HasCrossedInterface(), SSAGES::ForwardFlux::HasReturnedToA(), SSAGES::ForwardFlux::iteration_, SSAGES::ForwardFlux::FFSConfigID::l, SSAGES::ForwardFlux::myFFSConfigID, SSAGES::ForwardFlux::FFSConfigID::n, SSAGES::ForwardFlux::PopQueueMPI(), SSAGES::ForwardFlux::PostSimulation(), SSAGES::Method::world_, and SSAGES::ForwardFlux::WriteFFSConfiguration().

Referenced by PostIntegration().

68  {
69  //This is the main FFS method. The magic happens here!
70  auto cvs = cvmanager.GetCVs(cvmask_);
71 
72  //QUESTION: Whats the difference between world_ and _comm?
73  //For now I'll use world_ for everything. But if each driver uses multiple procs then I suspect that this will be wrong.
74  _cvvalue = cvs[0]->GetValue();
75 
77  //if ((myFFSConfigID.l == 2) && (myFFSConfigID.n == 20) && (myFFSConfigID.a ==1)){
78  // std::cout << "stop here\n";
79  //}
80  //if (myFFSConfigID.l != _current_interface){
81  // std::cout << "stop here\n";
82  //}
83 
84  //check if I've crossed the next interface
85  bool hasreturned = HasReturnedToA(_cvvalue);
87  unsigned int fail_local=false,success_local=false;
88  //std::vector<bool> in MPI were strange, ended up using std::vector<unsigned int>
89  std::vector<unsigned int> successes (world_.size());
90  std::vector<unsigned int> failures (world_.size());
91 
93  {
94  // make sure this isnt a zombie trajectory that previously failed or succeeded and is just waiting for the queue to get more jobs
95  if (hasreturned)
96  fail_local=true;
97  else if (hascrossed == 1)
98  success_local=true;
99  else if (hascrossed == -1)
100  {
101  //this should never happen if the interfaces are non-intersecting, it would be wise to throw an error here though
102  std::cerr << "Trajectory l"<<myFFSConfigID.l<<"-n"<<myFFSConfigID.n<<"-a"<<myFFSConfigID.a<<" crossed backwards! This shouldnt happen!" << std::endl;
103  //world_.abort(EXIT_FAILURE);
104  }
105  else
106  {
107  //not sure if anything should needs to be done here
108  }
109  }
110 
111  //for each traj that crossed to lambda+1 need to write it to disk (FFSConfigurationFile)
112  //MPIAllgather success_local into successes
113  MPI_Allgather(&success_local,1,MPI_UNSIGNED,successes.data(),1,MPI_UNSIGNED,world_);
114  MPI_Allgather(&fail_local,1,MPI_UNSIGNED,failures.data(),1,MPI_UNSIGNED,world_);
115 
116  int success_count = 0, fail_count = 0;
117  // I dont pass the queue information between procs but I do syncronize 'successes' and 'failures'
118  // as a reuslt all proc should have the same queue throughout the simulation
119  for (int i=0;i<world_.size();i++)
120  {
121  int l,n,a,lprev,nprev,aprev;
122  // write config to lambda+1
123  lprev = myFFSConfigID.l;
124  nprev = myFFSConfigID.n;
125  aprev = myFFSConfigID.a;
126 
127  if (successes[i] == true)
128  {
129  if (i == world_.rank())
130  {
131  //update ffsconfigid's l,n,a
132  l = _current_interface + 1;
133  n = _S[_current_interface] + success_count;
134  a = 0;
135  FFSConfigID newid = FFSConfigID(l,n,a,lprev,nprev,aprev);
136  WriteFFSConfiguration(snapshot,newid,1);
137  }
138  success_count++;
139  }
140  if (failures[i] == true)
141  {
142  if (i == world_.rank())
143  {
144  //update ffsconfigid's l,n,a
145  l = 0; //only fail at lambda 0,
146  n = _nfailure_total + fail_count;
147  a = 0;
148  FFSConfigID newid = FFSConfigID(l,n,a,lprev,nprev,aprev);
149  WriteFFSConfiguration(snapshot,newid,0);
150  }
151  fail_count++;
152  }
153  }
154 
155  //update trajectories
156  if (_saveTrajectories)
157  {
158  if (!_pop_tried_but_empty_queue) //dont update trajectory if zombie job
160  if (success_local || fail_local) //if finished then close it
161  _trajectory_file.close();
162  }
163 
164  //update the number of successes and attempts, same for all proc since Allgathered 'successes' and 'failures'
165  _S[_current_interface] += success_count;
166  _A[_current_interface] += success_count + fail_count;
167  // ^ I dont like storing attempts this way (as is its only when they finish). _A should also include jobs in progress (i.e. jobs currently running). THINK ABOUT THIS!.
168  _nfailure_total += fail_count;
169 
170  //------------------------------
171  //print info
172  if ((success_local) || (fail_local))
173  {
174  std::cout << "Iteration: "<< iteration_ << ", proc " << world_.rank() << "\n";
175  if (success_local)
176  {
177  std::cout << "Successful attempt from interface " << _current_interface
178  << " l"<<myFFSConfigID.l<<"-n"<<myFFSConfigID.n<<"-a"<<myFFSConfigID.a
179  << " (cvvalue_previous: " << _cvvalue_previous << " cvvalue " << _cvvalue << " interface["<<_current_interface+1<<"] = " << _interfaces[_current_interface+1] << "\n";
180  }
181  if (fail_local)
182  {
183  std::cout << "Failed attempt from interface " << _current_interface
184  << " l"<<myFFSConfigID.l<<"-n"<<myFFSConfigID.n<<"-a"<<myFFSConfigID.a
185  << " (cvvalue_previous: " << _cvvalue_previous << " cvvalue " << _cvvalue << " interface[0] = "<< _interfaces[0] << "\n"
186  << "nfailuretotal: " << _nfailure_total << "\n";
187  }
188 
189  std::cout << "A: ";
190  for (auto a : _A)
191  std::cout << a << " ";
192  std::cout << "\n";
193 
194  std::cout << "S: ";
195  for (auto s : _S)
196  std::cout << s << " ";
197  std::cout << "\n";
198 
199  std::cout << "M: ";
200  for (auto m : _M)
201  std::cout << m << " ";
202  std::cout << "\n";
203  }
204  //------------------------------
205 
206  //create new funciton here? (call it SetupNextInterface()
207  // Check if this interface is finished, if so add new tasks to queue, and increment _current_interface
209  {
210  //set N and P
211  _N[_current_interface+1] = _S[_current_interface];
212  _P[_current_interface] = (double) _S[_current_interface] / _A[_current_interface];
213 
214  if (_current_interface+2 < _ninterfaces)
215  {
216  _current_interface += 1;
217  //_N[_current_interface] = _S[_current_interface-1];
218 
219  if (_N[_current_interface] == 0)
220  {
221  std::cerr << "Error! No successes from interface " << _current_interface-1 << " to " << _current_interface <<"! Try turning up M["<<_current_interface-1<<"] or spacing interfaces closer together.\n";
222  MPI_Abort(world_, EXIT_FAILURE);
223  }
224 
225  //for DFFS
226  unsigned int npicks = _M[_current_interface];
227  std::vector<unsigned int> picks;
228  picks.resize(npicks);
229  if (world_.rank() == 0)
230  {
231  std::uniform_int_distribution<int> distribution(0,_N[_current_interface]-1);
232  for (unsigned int i=0; i < npicks ; i++)
233  picks[i] = distribution(_generator);
234  }
235  MPI_Bcast(picks.data(),npicks,MPI_UNSIGNED,0,world_);
236 
237  //each proc adds to the queue
238  //set correct attempt index if a given ID is picked twice
239  std::vector<unsigned int> attempt_count;
240  attempt_count.resize(_N[_current_interface],0);
241 
242  for (unsigned int i=0; i < npicks ; i++)
243  {
244  unsigned int mypick = picks[i];
245  int l,n,a,lprev,nprev,aprev;
246  lprev = myFFSConfigID.l;
247  nprev = myFFSConfigID.n;
248  aprev = myFFSConfigID.a;
249  //update ffsconfigid's l,n,a
250  l = _current_interface;
251  n = mypick;
252  a = attempt_count[mypick];
253  attempt_count[mypick]++; //this updates attempt number if same config is picked twice
254 
255  FFSConfigIDQueue.emplace_back(l,n,a,lprev,nprev,aprev);
256  }
257  }
258  else
259  {
260  std::cout << "DFFS should be finished here, do something special? like exit?\n";
261  //Hythem said this is "acceptable" until the code is changed
262  PostSimulation(snapshot, cvmanager);
263  }
264  }
265 
266  // if succeeded or failed (or zombie job), get a new config from the queue...but need to be careful that no two procs get the same config
267 
268  // Need to account for zombie jobs that are waiting for a new config
269  unsigned int shouldpop_local = false;
270  std::vector<unsigned int> shouldpop(world_.size(),0);
271 
272  if (success_local || fail_local || _pop_tried_but_empty_queue)
273  shouldpop_local = true;
274 
275  //Pop the queue
276  // Need to perform mpi call so that all proc pop the queue in the same way
277  PopQueueMPI(snapshot,cvs, shouldpop_local);
278 
279  //Anything else to update across mpi?
280  //clean up
282  iteration_++;
283  }
void PostSimulation(Snapshot *snapshot, const class CVManager &cvmanager) override
Post-simulation hook.
Definition: ForwardFlux.cpp:48
std::vector< unsigned int > _M
Definition: ForwardFlux.h:101
std::vector< unsigned int > _S
Definition: ForwardFlux.h:114
std::vector< unsigned int > _A
Number of attempts from interface i.
Definition: ForwardFlux.h:104
unsigned int _current_interface
Current Interface.
Definition: ForwardFlux.h:147
bool _pop_tried_but_empty_queue
Definition: ForwardFlux.h:124
std::vector< unsigned int > _N
Definition: ForwardFlux.h:119
void WriteFFSConfiguration(Snapshot *snapshot, FFSConfigID &ffsconfig, bool wassuccess)
Write a file corresponding to FFSConfigID from current snapshot.
double _cvvalue_previous
Previous cv position, used to determine if you&#39;ve crossed an interface since last time...
Definition: ForwardFlux.h:79
mxx::comm world_
Global MPI communicator.
Definition: Method.h:46
uint iteration_
Method iteration counter/.
Definition: ForwardFlux.h:166
double _cvvalue
current cv position
Definition: ForwardFlux.h:82
bool HasReturnedToA(double)
Function checks if configuration has returned to A.
unsigned int a
Attempt number.
Definition: ForwardFlux.h:47
std::deque< FFSConfigID > FFSConfigIDQueue
Definition: ForwardFlux.h:157
std::ofstream _trajectory_file
file to which the current trajectory is written to
Definition: ForwardFlux.h:163
int HasCrossedInterface(double, double, unsigned int interface)
Function checks if configuration has crossed interface specified since the last check.
Definition: ForwardFlux.cpp:79
void AppendTrajectoryFile(Snapshot *, std::ofstream &)
std::vector< double > _P
Flag to determine wheter fluxA0 should be calculated, seems not using this.
Definition: ForwardFlux.h:110
unsigned int _nfailure_total
Definition: ForwardFlux.h:140
std::vector< uint > cvmask_
Mask which identifies which CVs to act on.
Definition: Method.h:50
unsigned int n
Configuration Number.
Definition: ForwardFlux.h:46
bool _saveTrajectories
should the FFS trajectories be saved
Definition: ForwardFlux.h:135
std::default_random_engine _generator
random number generator
Definition: ForwardFlux.h:150
std::vector< double > _interfaces
FFS Interfaces.
Definition: ForwardFlux.h:73
FFSConfigID myFFSConfigID
The current FFSConfigID of this MPI process.
Definition: ForwardFlux.h:132
unsigned int l
Interface number.
Definition: ForwardFlux.h:45
void PopQueueMPI(Snapshot *, const CVList &, unsigned)
Pop the queue, do MPI so that all procs maintain the same queue.

Here is the call graph for this function:

Here is the caller graph for this function:

void SSAGES::DirectForwardFlux::PostIntegration ( Snapshot snapshot,
const class CVManager cvmanager 
)
overridevirtual

Post-integration hook.

Parameters
snapshotCurrent simulation snapshot.
cvmanagerCollective variable manager.

Implements SSAGES::ForwardFlux.

Definition at line 32 of file DirectForwardFlux.cpp.

References SSAGES::ForwardFlux::_initialFluxFlag, CheckForInterfaceCrossings(), SSAGES::ForwardFlux::CheckInitialStructure(), SSAGES::ForwardFlux::ComputeInitialFlux(), SSAGES::Method::cvmask_, SSAGES::CVManager::GetCVs(), InitializeQueue(), SSAGES::ForwardFlux::iteration_, and SSAGES::ForwardFlux::PrintQueue().

Referenced by DirectForwardFlux().

33  {
34  //check if we want to check FFS interfaces this timestep
35  //for now, do it every time step
36  if (iteration_ % 1 != 0) return;
37 
38  auto cvs = cvmanager.GetCVs(cvmask_);
39  // check the structure at the beginning of the simulation
40  if (iteration_ == 0)
42 
43  // if _computefluxA0
44  if (_initialFluxFlag)
45  {
46  ComputeInitialFlux(snapshot,cvs);
47  if (!_initialFluxFlag)
48  { //only enter here once
49  InitializeQueue(snapshot,cvs);
50  PrintQueue();
51  }
52  }
53  else if (initializeQueueFlag)
54  {
55  InitializeQueue(snapshot,cvs);
56  PrintQueue();
57  }
58  // Else check the FFS interfaces
59  else
60  {
61  CheckForInterfaceCrossings(snapshot, cvmanager);
62  //FluxBruteForce(snapshot,cvs);
63  }
64  // Other modes?
65  }
void CheckInitialStructure(const CVList &)
Function that checks the initial structure that user provides.
Definition: ForwardFlux.cpp:61
void CheckForInterfaceCrossings(Snapshot *, const class CVManager &) override
Function that checks if interfaces have been crossed (different for each FFS flavor) ...
uint iteration_
Method iteration counter/.
Definition: ForwardFlux.h:166
void ComputeInitialFlux(Snapshot *, const CVList &)
Compute Initial Flux.
bool _initialFluxFlag
if 1 compute initial flux
Definition: ForwardFlux.h:127
void PrintQueue()
Print the queue, useful for debugging.
std::vector< uint > cvmask_
Mask which identifies which CVs to act on.
Definition: Method.h:50
void InitializeQueue(Snapshot *, const CVList &) override
Initialize the Queue.

Here is the call graph for this function:

Here is the caller graph for this function:


The documentation for this class was generated from the following files: