SSAGES  0.1
A MetaDynamics Package
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Groups Pages
Swarm.cpp
1 
20 #include "Swarm.h"
21 #include "CVs/CVManager.h"
22 #include "Snapshot.h"
23 #include "spline.h"
24 #include <cmath>
25 #include <iostream>
26 #include <iomanip>
27 #include <string>
28 #include <sstream>
29 #include <algorithm>
30 
31 namespace SSAGES
32 {
33 
34  //Helper function to check if CVs are initialized correctly
35  bool Swarm::CVInitialized(const CVList& cvs)
36  {
37  double threshold = 0.2;
38  const double eps = 0.0000000001;
39  double diff;
40 
41  //On the first iteration, check that the CVs are within (threshold*100)% of the center value they're associated to
42  for(size_t i = 0; i < cvs.size(); i++)
43  {
44  if(centers_[i] <= eps)
45  {//e.g. if centers_[i] = 0
46  diff = std::abs((cvs[i]->GetValue() - (centers_[i]+eps)) / ((cvs[i]->GetValue() + (eps + centers_[i]))/2.0));
47  }
48  else
49  {
50  diff = std::abs((cvs[i]->GetValue() - (centers_[i])) / ((cvs[i]->GetValue() + (centers_[i]))/2.0));
51  }
52  if(diff >= threshold)
53  {
54  return false; //proceed to initialize again
55  }
56  }
57  return true; //OK to move on to regular sampling
58  }
59 
60  void Swarm::PostIntegration(Snapshot* snapshot, const CVManager& cvmanager)
61  {
62  auto cvs = cvmanager.GetCVs(cvmask_);
63  auto& forces = snapshot->GetForces();
64  auto& positions = snapshot->GetPositions();
65  auto& velocities = snapshot->GetVelocities();
66  auto& atomids = snapshot->GetAtomIDs();
67 
68  if(snapshot_stored)
69  {
70  initialized = true;
71  }
72  else
73  {
74  initialized = CVInitialized(cvs); //Whether to initialize or not
75  }
76 
78 
80  {
81  if(!snapshot_stored)
82  {
85  prev_IDs_[index_] = snapshot->SerializeIDs();
86  snapshot_stored = true;
87  }
88  }
89  MPI_Allreduce(MPI_IN_PLACE, &initialized, 1, MPI_INT, MPI_LAND, world_);
91  {//Ensure CVs are initialized well
92  //Do restrained sampling, and do not harvest trajectories
94  {
95  for(size_t i = 0; i < cvs.size(); i++)
96  {
97  //Get current CV and gradient
98  auto& cv = cvs[i];
99  auto& grad = cv->GetGradient();
100 
101  //Compute dV/dCV
102  auto D = cvspring_[i]*(cv->GetDifference(centers_[i]));
103 
104  //Update forces
105  for(size_t j = 0; j < forces.size(); j++)
106  {
107  for(int k = 0; k < forces[j].size(); k++)
108  {
109  forces[j][k] -= (double)D*grad[j][k];
110  }
111  }
112  }
113  }
114  else
115  {
116  //Reset positions and forces, keeping them at their initialized value
117  index_ = 0;
118  for(auto& force: forces)
119  force.setZero();
120 
121  for(size_t i = 0; i < prev_IDs_[index_].size(); i++)
122  {
123  auto localindex = snapshot->GetLocalIndex(prev_IDs_[index_][i]);
124  if(localindex!= -1)
125  {
126  positions[localindex][0] = prev_positions_[index_][i*3];
127  positions[localindex][1] = prev_positions_[index_][i*3 + 1];
128  positions[localindex][2] = prev_positions_[index_][i*3 + 2];
129 
130  velocities[localindex][0] = prev_velocities_[index_][i*3];
131  velocities[localindex][1] = prev_velocities_[index_][i*3 + 1];
132  velocities[localindex][2] = prev_velocities_[index_][i*3 + 2];
133 
134  }
135  }
136  }
137  }
138  else
139  {
140  if(!sampling_started)
141  {
142  sampling_started = true; //Flag to prevent unneeded umbrella sampling
143  }
145  {
146  //Do restrained sampling, and do harvest trajectories
147  for(size_t i = 0; i < cvs.size(); i++)
148  {
149  if(iterator_ == 0)
150  {
151  index_ = 0; //Reset index when starting
152  }
153  //Get current CV and gradient
154  auto& cv = cvs[i];
155  auto& grad = cv->GetGradient();
156 
157  //Compute dV/dCV
158  auto D = cvspring_[i]*(cv->GetDifference(centers_[i]));
159 
160  //Update forces
161  for(size_t j = 0; j < forces.size(); j++)
162  {
163  for(int k = 0; k < forces[j].size(); k++)
164  {
165  forces[j][k] -= (double)D*grad[j][k];
166  }
167  }
168  }
170  {
171  //Harvest a trajectory every harvest_length_ steps
172  if(iterator_ % harvest_length_ == 0)
173  {
176  prev_IDs_[index_] = snapshot->SerializeIDs();
177  index_++;
178  }
179  }
181  {
182  //Reset positions and forces before first call to unrestrained sampling
183  index_ = 0;
184  for(auto& force: forces)
185  force.setZero();
186 
187  for(size_t i = 0; i < prev_IDs_[index_].size(); i++)
188  {
189  auto localindex = snapshot->GetLocalIndex(prev_IDs_[index_][i]);
190  if(localindex!= -1)
191  {
192  positions[localindex][0] = prev_positions_[index_][i*3];
193  positions[localindex][1] = prev_positions_[index_][i*3 + 1];
194  positions[localindex][2] = prev_positions_[index_][i*3 + 2];
195 
196  velocities[localindex][0] = prev_velocities_[index_][i*3];
197  velocities[localindex][1] = prev_velocities_[index_][i*3 + 1];
198  velocities[localindex][2] = prev_velocities_[index_][i*3 + 2];
199 
200  }
201  }
202  }
203  iterator_++;
204  }
206  {
207  //Launch unrestrained trajectories
209  {
210  //End of trajectory, harvest drift
211  for(size_t i = 0; i < cv_drift_.size(); i++)
212  {
213  cv_drift_[i] = (cv_drift_[i]*index_ + cvs[i]->GetMinimumImage(centers_[i]) - centers_[i]) / (index_+1); //Calculate running average of drifts
214  }
215  //Set up for next trajectory
216  index_++;
217 
219  {
220  for(auto& force: forces)
221  force.setZero();
222 
223  for(size_t i = 0; i < prev_IDs_[index_].size(); i++)
224  {
225  auto localindex = snapshot->GetLocalIndex(prev_IDs_[index_][i]);
226  if(localindex!= -1)
227  {
228  positions[localindex][0] = prev_positions_[index_][i*3];
229  positions[localindex][1] = prev_positions_[index_][i*3 + 1];
230  positions[localindex][2] = prev_positions_[index_][i*3 + 2];
231 
232  velocities[localindex][0] = prev_velocities_[index_][i*3];
233  velocities[localindex][1] = prev_velocities_[index_][i*3 + 1];
234  velocities[localindex][2] = prev_velocities_[index_][i*3 + 2];
235 
236  }
237  }
238  }
239  }
240  iterator_++;
241  }
242  else
243  {
244  //Evolve CVs, reparametrize, and reset vectors
245  iteration_++;
246 
247  MPI_Barrier(world_);
248  StringUpdate();
249  CheckEnd(cvs);
250  MPI_Barrier(world_);
251  UpdateWorldString(cvs);
252  PrintString(cvs);
253 
254  iterator_ = 0;
255  index_ = 0;
256  snapshot_stored = false;
257 
258  for(size_t i = 0; i < cv_drift_.size(); i++)
259  {
260  cv_drift_[i] = 0;
261  }
262  }
263  }
264  }
265 
267  {
268  // Update node locations toward running averages:
269  for(size_t i = 0; i < centers_.size(); i++)
270  {
271 
272  centers_[i] = centers_[i] + cv_drift_[i];
273  }
274 
275  std::vector<double> lcv0, ucv0;
276  lcv0.resize(centers_.size(), 0);
277  ucv0.resize(centers_.size(), 0);
278 
279  GatherNeighbors(&lcv0, &ucv0);
280 
281  double alphastar = distance(centers_, lcv0);
282 
283  StringReparam(alphastar);
284 
285  }
286 }
287 
double distance(const std::vector< double > &x, const std::vector< double > &y) const
Helper function for calculating distances.
Definition: StringMethod.h:102
Collective variable manager.
Definition: CVManager.h:40
unsigned int initialize_steps_
Total number of MD steps for initialization for one iteration.
Definition: Swarm.h:40
bool original_initialized
Flag for whether a system was initialized before it checked whether other systems were...
Definition: Swarm.h:79
bool CVInitialized(const CVList &cvs)
Helper function check if CVs are initialized correctly.
Definition: Swarm.cpp:35
std::vector< CollectiveVariable * > CVList
List of Collective Variables.
Definition: types.h:51
std::vector< std::vector< double > > prev_velocities_
Store velocities for starting trajectories.
Definition: StringMethod.h:88
int initialized
Flag for whether a system is initialized at a given iteration.
Definition: Swarm.h:76
Class containing a snapshot of the current simulation in time.
Definition: Snapshot.h:43
void GatherNeighbors(std::vector< double > *lcv0, std::vector< double > *ucv0)
Gather neighbors over MPI.
std::vector< double > centers_
CV starting location values.
Definition: StringMethod.h:43
uint iteration_
The global method iteration.
Definition: StringMethod.h:73
std::vector< double > cv_drift_
Drift of CVs for one iteration.
Definition: Swarm.h:37
unsigned int swarm_length_
Length of unrestrained trajectories.
Definition: Swarm.h:52
bool sampling_started
Flag for determing whether to perform initialization or not.
Definition: Swarm.h:70
std::vector< double > SerializePositions()
Return the serialized positions across all local cores.
Definition: Snapshot.h:648
void PostIntegration(Snapshot *snapshot, const class CVManager &cvmanager) override
Post-integration hook.
Definition: Swarm.cpp:60
mxx::comm world_
Global MPI communicator.
Definition: Method.h:46
bool CheckEnd(const CVList &CV)
Check if method reached one of the exit criteria.
bool snapshot_stored
Flag for whether a snapshot was stored in the umbrella sampling.
Definition: Swarm.h:73
std::vector< int > SerializeIDs()
Return the serialized positions across all local cores.
Definition: Snapshot.h:713
int GetLocalIndex(int id) const
Gets the local atom index corresponding to an atom ID.
Definition: Snapshot.h:555
std::vector< std::vector< int > > prev_IDs_
Store atom IDs for starting trajectories.
Definition: StringMethod.h:91
unsigned int number_trajectories_
Number of trajectories per swarm.
Definition: Swarm.h:49
void UpdateWorldString(const CVList &cvs)
Update the world string over MPI.
const Label & GetAtomIDs() const
Access the atom IDs.
Definition: Snapshot.h:541
void StringReparam(double alpha_star)
Reparameterize the string.
unsigned int harvest_length_
Length to run before harvesting a trajectory for unrestrained sampling.
Definition: Swarm.h:43
unsigned int restrained_steps_
Total number of restrained MD steps for one iteration.
Definition: Swarm.h:46
std::vector< CollectiveVariable * > GetCVs(const std::vector< uint > &mask=std::vector< uint >()) const
Get CV iterator.
Definition: CVManager.h:80
void PrintString(const CVList &CV)
Prints the CV positions to file.
unsigned int iterator_
The local method iterator.
Definition: StringMethod.h:70
std::vector< double > cvspring_
Vector of spring constants.
Definition: StringMethod.h:67
unsigned int unrestrained_steps_
Total number of unrestrained MD steps for one iteration.
Definition: Swarm.h:55
std::vector< uint > cvmask_
Mask which identifies which CVs to act on.
Definition: Method.h:50
unsigned int index_
For indexing trajectory vectors.
Definition: Swarm.h:58
std::vector< double > SerializeVelocities()
Return the serialized velocities across all local cores.
Definition: Snapshot.h:681
const std::vector< Vector3 > & GetVelocities() const
Access the particle velocities.
Definition: Snapshot.h:349
const std::vector< Vector3 > & GetForces() const
Access the per-particle forces.
Definition: Snapshot.h:362
const std::vector< Vector3 > & GetPositions() const
Access the particle positions.
Definition: Snapshot.h:323
std::vector< std::vector< double > > prev_positions_
Store positions for starting trajectories.
Definition: StringMethod.h:85
void StringUpdate()
Updates the positions of the string.
Definition: Swarm.cpp:266