25 #include "Drivers/DriverException.h"
26 #include "CVs/CVManager.h"
27 #include "Validator/ObjectRequirement.h"
28 #include "Drivers/DriverException.h"
44 double arg = (dx * dx) / (2. * sigma * sigma);
56 double arg = (dx * dx) / (2. * sigma * sigma);
57 double pre = - dx / (sigma * sigma);
58 return pre * exp(-arg);
64 auto cvs = cvmanager.
GetCVs(cvmask_);
66 if(IsMasterRank(world_))
68 hillsout_.open(
"hills.out");
69 hillsout_ <<
"#Iteration ";
71 for(
size_t i = 0; i < cvs.size(); ++i)
72 hillsout_ <<
"center." << i <<
" ";
74 for(
size_t i = 0; i < cvs.size(); ++i)
75 hillsout_ <<
"sigma." << i <<
" ";
77 hillsout_ <<
"height" << std::endl;
85 Vector vec = Vector::Zero(cvs.size());
86 std::fill(grid_->begin(), grid_->end(), vec);
94 derivatives_.resize(cvs.size());
95 tder_.resize(cvs.size());
96 dx_.resize(cvs.size());
102 auto cvs = cvmanager.
GetCVs(cvmask_);
115 for(
size_t i = 0; i < cvs.size(); ++i)
117 auto& grad = cvs[i]->GetGradient();
118 auto& boxgrad = cvs[i]->GetBoxGradient();
122 for (
size_t j = 0; j < forces.size(); ++j)
123 for(
size_t k = 0; k < 3; ++k)
124 forces[j][k] -= derivatives_[i]*grad[j][k];
126 virial += derivatives_[i]*boxgrad;
136 void Meta::LoadHills(
const std::string& filename)
138 std::ifstream file(filename);
141 auto dim = widths_.size();
142 double iteration = 0, height = 0;
143 std::vector<double> width(dim, 0.), center(dim, 0);
146 std::getline(file, line);
147 while(std::getline(file, line))
149 std::istringstream iss(line);
153 for(
size_t i = 0; i < dim; ++i)
157 for(
size_t i = 0; i < dim; ++i)
163 hills_.emplace_back(center, width, height);
168 void Meta::AddHill(
const CVList& cvs,
int iteration)
170 size_t n = cvs.size();
173 int nwalkers = world_.size()/comm_.size();
177 std::vector<double> cvals(n*nwalkers, 0);
179 if(IsMasterRank(comm_))
181 for(
size_t i = 0, j = GetWalkerID(world_,comm_)*n; i < n; ++i,++j)
182 cvals[j] = cvs[i]->GetValue();
186 MPI_Allreduce(MPI_IN_PLACE, cvals.data(), n*nwalkers, MPI_DOUBLE, MPI_SUM, world_);
188 for(
size_t i = 0; i < n*nwalkers; i += n)
190 std::vector<double> cval(cvals.begin() + i, cvals.begin() + i + n);
191 hills_.emplace_back(cval, widths_, height_);
194 if(IsMasterRank(world_))
195 PrintHill(hills_.back(), iteration);
201 std::vector<double> dx(n, 0.0), df(n, 1.0);
202 auto& hill = hills_.back();
203 for(
auto it = grid_->begin(); it != grid_->end(); ++it)
206 auto coord = it.coordinates();
209 for(
size_t i = 0; i < n; ++i)
211 dx[i] = -cvs[i]->GetDifference(coord[i]);
216 for(
size_t i = 0; i < n; ++i)
218 for(
size_t j = 0; j < n; ++j)
221 df[i] *=
gaussian(dx[j], hill.width[j]);
228 for(
size_t i = 0; i < n; ++i)
229 val[i] += height_*df[i];
236 void Meta::PrintHill(
const Hill& hill,
int iteration)
238 hillsout_.open(
"hills.out", std::fstream::app);
240 hillsout_ << iteration <<
" ";
241 hillsout_.precision(8);
243 for(
auto& cv : hill.
center)
244 hillsout_ << cv <<
" ";
246 for(
auto& w : hill.
width)
247 hillsout_ << w <<
" ";
249 hillsout_ << height_ << std::endl;
253 void Meta::CalcBiasForce(
const CVList& cvs)
260 std::fill(derivatives_.begin(), derivatives_.end(), 0);
265 bool inbounds =
true;
266 std::vector<double> val(n, 0.);
267 for(
size_t i = 0; i < n; ++i)
269 val[i] = cvs[i]->GetValue();
270 if(val[i] < grid_->GetLower(i) || val[i] > grid_->GetUpper(i))
276 auto frc = (*grid_)[val];
277 for(
size_t i = 0; i < n; ++i)
278 derivatives_[i] = frc[i];
282 if(IsMasterRank(comm_))
284 std::cerr <<
"Metadynamics: out of bounds ( ";
286 std::cerr << v <<
" ";
287 std::cerr <<
")" << std::endl;
294 for(
auto& hill : hills_)
297 std::fill(tder_.begin(), tder_.end(), 1.0);
298 std::fill(dx_.begin(), dx_.end(), 1.0);
300 for(
size_t i = 0; i < n; ++i)
302 dx_[i] = cvs[i]->GetDifference(hill.center[i]);
303 tbias *=
gaussian(dx_[i], hill.width[i]);
306 for(
size_t i = 0; i < n; ++i)
307 for(
size_t j = 0; j < n; ++j)
310 tder_[i] *=
gaussian(dx_[j], hill.width[j]);
315 bias += height_ * tbias;
316 for(
size_t i = 0; i < n; ++i)
317 derivatives_[i] += height_*tder_[i];
322 for(
size_t i = 0; i < n; ++i)
324 auto cval = cvs[i]->GetValue();
325 if(cval < lowerb_[i])
326 derivatives_[i] += lowerk_[i]*(cval - lowerb_[i]);
327 else if(cval > upperb_[i])
328 derivatives_[i] += upperk_[i]*(cval - upperb_[i]);
332 Meta* Meta::Build(
const Json::Value& json,
333 const MPI_Comm& world,
334 const MPI_Comm& comm,
335 const std::string& path)
339 CharReaderBuilder rbuilder;
340 CharReader* reader = rbuilder.newCharReader();
342 reader->parse(JsonSchema::MetadynamicsMethod.c_str(),
343 JsonSchema::MetadynamicsMethod.c_str() + JsonSchema::MetadynamicsMethod.size(),
345 validator.
Parse(schema, path);
352 std::vector<double> widths;
353 for(
auto& s : json[
"widths"])
354 widths.push_back(s.asDouble());
356 std::vector<double> lowerb, upperb, lowerk, upperk;
358 if(json.isMember(
"grid"))
360 else if(!json.isMember(
"lower_bounds") || !json.isMember(
"upper_bounds"))
362 "#/Method/Metadynamics: Both upper_bounds and lower_bounds "
363 "must be defined if grid is not being used."});
366 for(
int i = 0; i < static_cast<int>(json[
"lower_bound_restraints"].size()); ++i)
368 lowerk.push_back(json[
"lower_bound_restraints"][i].asDouble());
369 upperk.push_back(json[
"upper_bound_restraints"][i].asDouble());
370 lowerb.push_back(json[
"lower_bounds"][i].asDouble());
371 upperb.push_back(json[
"upper_bounds"][i].asDouble());
374 auto height = json.get(
"height", 1.0).asDouble();
375 auto hillfreq = json.get(
"hill_frequency", 1).asInt();
376 auto freq = json.get(
"frequency", 1).asInt();
379 world, comm, height, widths,
380 lowerb, upperb, lowerk, upperk,
384 if(json.isMember(
"load_hills"))
385 m->LoadHills(json[
"load_hills"].asString());
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.
Class containing a snapshot of the current simulation in time.
const Matrix3 & GetVirial() const
Get box virial.
const std::vector< Vector3 > & GetForces() const
Access the per-particle forces.
size_t GetTargetIterations() const
Get target iterations.
size_t GetIteration() const
Get the current iteration.
Eigen::VectorXd Vector
Arbitrary length vector.
double gaussianDerv(double dx, double sigma)
Evaluate Gaussian derivative. Helper function.
double gaussian(double dx, double sigma)
Evlauate Gaussian. Helper function.
std::vector< CollectiveVariable * > CVList
List of Collective Variables.
std::vector< double > center
Hill center.
std::vector< double > width
Hill width.