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)
40 if(IsMasterRank(comm_))
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)
57 if(IsMasterRank(comm_))
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);
78 if(IsMasterRank(comm_))
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);
96 if(IsMasterRank(comm_))
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(IsMasterRank(comm_))
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);
174 void StringMethod::SetSendRecvNeighbors()
176 std::vector<int> wiids(world_.size(), 0);
182 MPI_Allgather(&mpiid_, 1, MPI_INT, &wiids[0], 1, MPI_INT, world_);
183 numnodes_ = int(*std::max_element(wiids.begin(), wiids.end())) + 1;
186 for(
size_t i = 0; i < wiids.size(); i++)
190 sendneigh_ = comm_.size();
191 if(wiids[i] == numnodes_ - 1)
197 else if (mpiid_ == numnodes_ - 1)
200 if(wiids[i] == mpiid_ - 1)
208 if(wiids[i] == mpiid_ + 1)
213 if(wiids[i] == mpiid_ - 1 && recneigh_ == -1)
221 const MPI_Comm& world,
222 const MPI_Comm& comm,
223 const std::string& path)
227 CharReaderBuilder rbuilder;
228 CharReader* reader = rbuilder.newCharReader();
232 reader->parse(JsonSchema::StringMethod.c_str(),
233 JsonSchema::StringMethod.c_str() + JsonSchema::StringMethod.size(),
235 validator.
Parse(schema, path);
242 unsigned int wid = GetWalkerID(world, comm);
243 std::vector<double> centers;
244 for(
auto& s : json[
"centers"][wid])
245 centers.push_back(s.asDouble());
247 auto maxiterator = json.get(
"max_iterations", 0).asInt();
249 std::vector<double> ksprings;
250 for(
auto& s : json[
"ksprings"])
251 ksprings.push_back(s.asDouble());
253 auto freq = json.get(
"frequency", 1).asInt();
256 std::string flavor = json.get(
"flavor",
"none").asString();
257 if(flavor ==
"ElasticBand")
259 reader->parse(JsonSchema::ElasticBandMethod.c_str(),
260 JsonSchema::ElasticBandMethod.c_str() + JsonSchema::ElasticBandMethod.size(),
262 validator.
Parse(schema, path);
269 auto eqsteps = json.get(
"equilibration_steps", 20).asInt();
270 auto evsteps = json.get(
"evolution_steps", 5).asInt();
271 auto stringspring = json.get(
"kstring", 10.0).asDouble();
272 auto isteps = json.get(
"block_iterations", 100).asInt();
273 auto tau = json.get(
"time_step", 0.1).asDouble();
277 tau, ksprings, eqsteps,
278 evsteps, stringspring, freq);
280 if(json.isMember(
"tolerance"))
282 std::vector<double> tol;
283 for(
auto& s : json[
"tolerance"])
284 tol.push_back(s.asDouble());
289 else if(flavor ==
"FTS")
291 reader->parse(JsonSchema::FTSMethod.c_str(),
292 JsonSchema::FTSMethod.c_str() + JsonSchema::FTSMethod.size(),
294 validator.
Parse(schema, path);
301 auto isteps = json.get(
"block_iterations", 2000).asInt();
302 auto tau = json.get(
"time_step", 0.1).asDouble();
303 auto kappa = json.get(
"kappa", 0.1).asDouble();
304 auto springiter = json.get(
"umbrella_iterations",2000).asDouble();
307 tau, ksprings, kappa,
310 if(json.isMember(
"tolerance"))
312 std::vector<double> tol;
313 for(
auto& s : json[
"tolerance"])
314 tol.push_back(s.asDouble());
319 else if(flavor ==
"SWARM")
321 reader->parse(JsonSchema::SwarmMethod.c_str(),
322 JsonSchema::SwarmMethod.c_str() + JsonSchema::SwarmMethod.size(),
324 validator.
Parse(schema, path);
331 auto InitialSteps = json.get(
"initial_steps", 2500).asInt();
332 auto HarvestLength = json.get(
"harvest_length", 10).asInt();
333 auto NumberTrajectories = json.get(
"number_of_trajectories", 250).asInt();
334 auto SwarmLength = json.get(
"swarm_length", 20).asInt();
336 m =
new Swarm(world, comm, centers, maxiterator, ksprings, freq, InitialSteps, HarvestLength, NumberTrajectories, SwarmLength);
338 if(json.isMember(
"tolerance"))
340 std::vector<double> tol;
341 for(
auto& s : json[
"tolerance"])
342 tol.push_back(s.asDouble());
Requirements on an object.
virtual void Parse(Value json, const std::string &path) override
Parse JSON value to generate Requirement(s).
virtual void Validate(const Value &json, const std::string &path) override
Validate JSON value.
std::vector< std::string > GetErrors()
Get list of error messages.
bool HasErrors()
Check if errors have occured.
Exception to be thrown when building the Driver fails.
Collective variable manager.
CVList GetCVs(const std::vector< unsigned int > &mask=std::vector< unsigned int >()) const
Get CV iterator.
Multi-walker Elastic Band.
Finite Temperature Spring Method.
Class containing a snapshot of the current simulation in time.
unsigned GetWalkerID() const
Get walker ID.
String base class for FTS, Swarm, and elastic band.
void SetTolerance(std::vector< double > tol)
Set the tolerance for quitting method.
Swarm of Trajectories String Method.
std::vector< CollectiveVariable * > CVList
List of Collective Variables.