23 #include "ElasticBand.h"
24 #include "FiniteTempString.h"
25 #include "StringMethod.h"
27 #include "CVs/CVManager.h"
28 #include "Validator/ObjectRequirement.h"
29 #include "Drivers/DriverException.h"
38 void StringMethod::PrintString(
const CVList& CV)
43 stringout_.precision(8);
44 stringout_ << mpiid_ <<
" " << iteration_ <<
" ";
46 for(
size_t i = 0; i < centers_.size(); i++)
47 stringout_ << worldstring_[mpiid_][i] <<
" " << CV[i]->GetValue() <<
" ";
49 stringout_ << std::endl;
53 void StringMethod::GatherNeighbors(std::vector<double> *lcv0, std::vector<double> *ucv0)
59 MPI_Sendrecv(¢ers_[0], centers_.size(), MPI_DOUBLE, sendneigh_, 1234,
60 &(*lcv0)[0], centers_.size(), MPI_DOUBLE, recneigh_, 1234,
63 MPI_Sendrecv(¢ers_[0], centers_.size(), MPI_DOUBLE, recneigh_, 4321,
64 &(*ucv0)[0], centers_.size(), MPI_DOUBLE, sendneigh_, 4321,
68 MPI_Bcast(&(*lcv0)[0],centers_.size(),MPI_DOUBLE,0,comm_);
69 MPI_Bcast(&(*ucv0)[0],centers_.size(),MPI_DOUBLE,0,comm_);
72 void StringMethod::StringReparam(
double alpha_star)
74 std::vector<double> alpha_star_vector(numnodes_,0.0);
79 alpha_star_vector[mpiid_] = mpiid_ == 0 ? 0 : alpha_star;
82 MPI_Allreduce(MPI_IN_PLACE, &alpha_star_vector[0], numnodes_, MPI_DOUBLE, MPI_SUM, world_);
84 for(
size_t i = 1; i < alpha_star_vector.size(); i++)
85 alpha_star_vector[i] += alpha_star_vector[i-1];
87 for(
size_t i = 1; i < alpha_star_vector.size(); i++)
88 alpha_star_vector[i] /= alpha_star_vector[numnodes_ - 1];
92 for(
size_t i = 0; i < centers_.size(); i++)
94 std::vector<double> cvs_new(numnodes_, 0.0);
97 cvs_new[mpiid_] = centers_[i];
99 MPI_Allreduce(MPI_IN_PLACE, &cvs_new[0], numnodes_, MPI_DOUBLE, MPI_SUM, world_);
101 spl.set_points(alpha_star_vector, cvs_new);
102 centers_[i] = spl(mpiid_/(numnodes_ - 1.0));
106 void StringMethod::UpdateWorldString(
const CVList& cvs)
108 for(
size_t i = 0; i < centers_.size(); i++)
110 std::vector<double> cvs_new(numnodes_, 0.0);
112 if(comm_.rank() == 0)
114 cvs_new[mpiid_] = centers_[i];
117 MPI_Allreduce(MPI_IN_PLACE, &cvs_new[0], numnodes_, MPI_DOUBLE, MPI_SUM, world_);
119 for(
int j = 0; j < numnodes_; j++)
121 worldstring_[j][i] = cvs_new[j];
123 worldstring_[j][i] = cvs[i]->GetPeriodicValue(worldstring_[j][i]);
128 bool StringMethod::CheckEnd(
const CVList& CV)
130 if(maxiterator_ && iteration_ > maxiterator_)
132 std::cout <<
"System has reached max string method iterations (" << maxiterator_ <<
") as specified in the input file(s)." << std::endl;
133 std::cout <<
"Exiting now" << std::endl;
135 MPI_Abort(world_, EXIT_FAILURE);
138 int local_tolvalue = TolCheck();
140 MPI_Allreduce(MPI_IN_PLACE, &local_tolvalue, 1, MPI_INT, MPI_LAND, world_);
144 std::cout <<
"System has converged within tolerance criteria. Exiting now" << std::endl;
146 MPI_Abort(world_, EXIT_FAILURE);
156 sprintf(file,
"node-%04d.log",mpiid_);
157 stringout_.open(file);
159 auto cvs = cvmanager.
GetCVs(cvmask_);
160 SetSendRecvNeighbors();
161 worldstring_.resize(numnodes_);
162 for(
auto& w : worldstring_)
163 w.resize(centers_.size());
165 UpdateWorldString(cvs);
169 void StringMethod::SetSendRecvNeighbors()
171 std::vector<int> wiids(world_.size(), 0);
177 MPI_Allgather(&mpiid_, 1, MPI_INT, &wiids[0], 1, MPI_INT, world_);
178 numnodes_ = int(*std::max_element(wiids.begin(), wiids.end())) + 1;
181 for(
size_t i = 0; i < wiids.size(); i++)
185 sendneigh_ = comm_.size();
186 if(wiids[i] == numnodes_ - 1)
192 else if (mpiid_ == numnodes_ - 1)
195 if(wiids[i] == mpiid_ - 1)
203 if(wiids[i] == mpiid_ + 1)
208 if(wiids[i] == mpiid_ - 1 && recneigh_ == -1)
216 const MPI_Comm& world,
217 const MPI_Comm& comm,
218 const std::string& path)
226 reader.parse(JsonSchema::StringMethod, schema);
227 validator.
Parse(schema, path);
234 unsigned int wid = mxx::comm(world).rank()/mxx::comm(comm).size();
235 std::vector<double> centers;
236 for(
auto& s : json[
"centers"][wid])
237 centers.push_back(s.asDouble());
239 auto maxiterator = json.get(
"max_iterations", 0).asInt();
241 std::vector<double> ksprings;
242 for(
auto& s : json[
"ksprings"])
243 ksprings.push_back(s.asDouble());
245 auto freq = json.get(
"frequency", 1).asInt();
248 std::string flavor = json.get(
"flavor",
"none").asString();
249 if(flavor ==
"ElasticBand")
251 reader.parse(JsonSchema::ElasticBandMethod, schema);
252 validator.
Parse(schema, path);
259 auto eqsteps = json.get(
"equilibration_steps", 20).asInt();
260 auto evsteps = json.get(
"evolution_steps", 5).asInt();
261 auto stringspring = json.get(
"kstring", 10.0).asDouble();
262 auto isteps = json.get(
"block_iterations", 100).asInt();
263 auto tau = json.get(
"time_step", 0.1).asDouble();
267 tau, ksprings, eqsteps,
268 evsteps, stringspring, freq);
270 if(json.isMember(
"tolerance"))
272 std::vector<double> tol;
273 for(
auto& s : json[
"tolerance"])
274 tol.push_back(s.asDouble());
279 else if(flavor ==
"FTS")
281 reader.parse(JsonSchema::FTSMethod, schema);
282 validator.
Parse(schema, path);
289 auto isteps = json.get(
"block_iterations", 2000).asInt();
290 auto tau = json.get(
"time_step", 0.1).asDouble();
291 auto kappa = json.get(
"kappa", 0.1).asDouble();
292 auto springiter = json.get(
"umbrella_iterations",2000).asDouble();
295 tau, ksprings, kappa,
298 if(json.isMember(
"tolerance"))
300 std::vector<double> tol;
301 for(
auto& s : json[
"tolerance"])
302 tol.push_back(s.asDouble());
307 else if(flavor ==
"SWARM")
309 reader.parse(JsonSchema::SwarmMethod, schema);
310 validator.
Parse(schema, path);
317 auto InitialSteps = json.get(
"initial_steps", 2500).asInt();
318 auto HarvestLength = json.get(
"harvest_length", 10).asInt();
319 auto NumberTrajectories = json.get(
"number_of_trajectories", 250).asInt();
320 auto SwarmLength = json.get(
"swarm_length", 20).asInt();
322 m =
new Swarm(world, comm, centers, maxiterator, ksprings, freq, InitialSteps, HarvestLength, NumberTrajectories, SwarmLength);
324 if(json.isMember(
"tolerance"))
326 std::vector<double> tol;
327 for(
auto& s : json[
"tolerance"])
328 tol.push_back(s.asDouble());
unsigned GetWalkerID() const
Get walker ID.
bool HasErrors()
Check if errors have occured.
Collective variable manager.
Finite Temperature Spring Method.
std::vector< CollectiveVariable * > CVList
List of Collective Variables.
String base class for FTS, Swarm, and elastic band.
Class containing a snapshot of the current simulation in time.
Swarm of Trajectories String Method.
virtual void Parse(Value json, const std::string &path) override
Parse JSON value to generate Requirement(s).
Exception to be thrown when building the Driver fails.
std::vector< std::string > GetErrors()
Get list of error messages.
std::vector< CollectiveVariable * > GetCVs(const std::vector< uint > &mask=std::vector< uint >()) const
Get CV iterator.
void SetTolerance(std::vector< double > tol)
Set the tolerance for quitting method.
Requirements on an object.
Multi-walker Elastic Band.
virtual void Validate(const Value &json, const std::string &path) override
Validate JSON value.