320 reader.parse(JsonSchema::ABFMethod, schema);
321 validator.
Parse(schema, path);
326 throw BuildException(validator.
GetErrors());
328 uint wid = mxx::comm(world).rank()/mxx::comm(comm).size();
333 std::vector<double> minsCV;
334 for(
auto& mins : json[
"CV_lower_bounds"])
337 throw BuildException({
"Separate inputs for multi-walker not fully implemented. Please use global entries for CV ranges"});
343 minsCV.push_back(mins.asDouble());
346 std::vector<double> maxsCV;
347 for(
auto& maxs : json[
"CV_upper_bounds"])
354 maxsCV.push_back(maxs.asDouble());
357 std::vector<int> binsCV;
358 for(
auto& bins : json[
"CV_bins"])
359 binsCV.push_back(bins.asInt());
362 std::vector<double> minsrestCV;
363 for(
auto& mins : json[
"CV_restraint_minimums"])
370 minsrestCV.push_back(mins.asDouble());
373 std::vector<double> maxsrestCV;
374 for(
auto& maxs : json[
"CV_restraint_maximums"])
381 maxsrestCV.push_back(maxs.asDouble());
384 std::vector<double> springkrestCV;
385 for(
auto& bins : json[
"CV_restraint_spring_constants"])
386 springkrestCV.push_back(bins.asDouble());
389 std::vector<bool> isperiodic;
390 for(
auto& isperCV : json[
"CV_isperiodic"])
391 isperiodic.push_back(isperCV.asBool());
394 std::vector<double> minperboundaryCV;
395 for(
auto& minsperCV : json[
"CV_periodic_boundary_lower_bounds"])
396 minperboundaryCV.push_back(minsperCV.asDouble());
399 std::vector<double> maxperboundaryCV;
400 for(
auto& maxsperCV : json[
"CV_periodic_boundary_upper_bounds"])
401 maxperboundaryCV.push_back(maxsperCV.asDouble());
404 if(!(( minsCV.size() == maxsCV.size() &&
405 maxsCV.size() == minsrestCV.size() &&
406 minsrestCV.size() == maxsrestCV.size()) &&
407 (binsCV.size() == springkrestCV.size() &&
408 springkrestCV.size() == isperiodic.size())))
409 throw BuildException({
"CV lower bounds, upper bounds, restrain minimums, restrains maximums must match in size. Bins, spring constants and periodicity info must match in size."});
412 bool anyperiodic=
false;
413 for(
size_t i = 0; i<isperiodic.size(); ++i)
417 if(!(isperiodic.size() == minperboundaryCV.size() &&
418 minperboundaryCV.size() == maxperboundaryCV.size()))
419 throw BuildException({
"If any CV is defined as periodic, please define the full upper and lower bound vectors. They should both have the same number of entries as CV lower bounds, upper bounds... Entries corresponding to non-periodic CVs will not be used."});
422 int dim = binsCV.size();
425 auto FBackupInterv = json.get(
"output_frequency", 1000).asInt();
426 auto unitconv = json.get(
"unit_conversion", 0).asDouble();
427 auto timestep = json.get(
"timestep", 2).asDouble();
428 auto min = json.get(
"minimum_count", 200).asDouble();
429 auto massweigh = json.get(
"mass_weighing",
false).asBool();
431 std::vector<std::vector<double>> histdetails;
432 std::vector<std::vector<double>> restraint;
433 std::vector<std::vector<double>> periodicboundaries;
434 std::vector<double> temp1(3);
435 std::vector<double> temp2(3);
436 std::vector<double> temp3(2);
438 auto freq = json.get(
"frequency", 1).asInt();
439 auto filename = json.get(
"output_file",
"F_out").asString();
440 auto Nworld_filename = json.get(
"Nworld_output_file",
"Nworld").asString();
441 auto Fworld_filename = json.get(
"Fworld_output_file",
"Fworld_cv").asString();
446 std::vector<Grid<double>*> F(dim);
447 std::vector<Grid<double>*> Fworld(dim);
489 N=
new Grid<int>(binsCV, minsCV, maxsCV, isperiodic);
490 Nworld=
new Grid<int>(binsCV, minsCV, maxsCV, isperiodic);
494 grid=
new Grid<double>(binsCV, minsCV, maxsCV, isperiodic);
496 for(
auto& grid : Fworld)
498 grid=
new Grid<double>(binsCV, minsCV, maxsCV, isperiodic);
501 for(
size_t i=0; i<dim; ++i)
503 temp1 = {minsCV[i], maxsCV[i], binsCV[i]};
504 temp2 = {minsrestCV[i], maxsrestCV[i], springkrestCV[i]};
505 histdetails.push_back(temp1);
506 restraint.push_back(temp2);
509 temp3 = {minperboundaryCV[i], maxperboundaryCV[i]};
510 periodicboundaries.push_back(temp3);
516 if(std::ifstream(Nworld_filename) && std::ifstream(Fworld_filename+std::to_string(0)) && wid == 0)
518 std::cout <<
"Attempting to load data from a previous run of ABF." << std::endl;
519 N->LoadFromFile(Nworld_filename);
520 for(
size_t i=0; i<dim; ++i)
521 if(std::ifstream(Fworld_filename+std::to_string(i)))
522 F[i]->LoadFromFile(Fworld_filename+std::to_string(i));
524 throw BuildException({
"Some, but not all Fworld outputs were found. Please check that these are appropriate inputs, or clean the working directory of other Fworld and Nworld inputs."});
528 auto* m =
new ABF(world, comm, N, Nworld, F, Fworld, restraint, isperiodic, periodicboundaries, min, massweigh, filename, Nworld_filename, Fworld_filename, histdetails, FBackupInterv, unitconv, timestep, freq);
531 if(json.isMember(
"iteration"))
532 m->SetIteration(json.get(
"iteration",0).asInt());
ABF(const MPI_Comm &world, const MPI_Comm &comm, Grid< int > *N, Grid< int > *Nworld, std::vector< Grid< double > * > F, std::vector< Grid< double > * > Fworld, std::vector< std::vector< double >> restraint, std::vector< bool > isperiodic, std::vector< std::vector< double >> periodicboundaries, double min, bool massweigh, std::string filename, std::string Nworld_filename, std::string Fworld_filename, const std::vector< std::vector< double >> &histdetails, int FBackupInterv, double unitconv, double timestep, unsigned int frequency)
Constructor.
bool HasErrors()
Check if errors have occured.
virtual void Parse(Value json, const std::string &path) override
Parse JSON value to generate Requirement(s).
std::vector< std::string > GetErrors()
Get list of error messages.
Requirements on an object.
virtual void Validate(const Value &json, const std::string &path) override
Validate JSON value.