23 #include "CVs/CVManager.h"
24 #include "Validator/ObjectRequirement.h"
25 #include "Drivers/DriverException.h"
35 if(IsMasterRank(comm_))
38 umbrella_.open(filename_.c_str(), std::ofstream::out | std::ofstream::app);
42 umbrella_.open(filename_.c_str(), std::ofstream::out);
44 umbrella_ <<
"Iteration ";
46 auto cvs = cvmanager.
GetCVs(cvmask_);
47 for(
size_t i = 0; i < cvs.size(); ++i)
48 umbrella_ <<
"cv_" + std::to_string(i) <<
" ";
50 for(
size_t i = 0; i < cvs.size() - 1; ++i)
51 umbrella_ <<
"center_" + std::to_string(i) <<
" ";
52 umbrella_ <<
"center_" + std::to_string(cvs.size() - 1) << std::endl;
60 auto cvs = cvmanager.
GetCVs(cvmask_);
64 for(
size_t i = 0; i < cvs.size(); ++i)
68 auto& grad = cv->GetGradient();
69 auto& boxgrad = cv->GetBoxGradient();
71 auto center = GetCurrentCenter(snapshot->
GetIteration(), i);
72 auto D = kspring_[i]*cv->GetDifference(center);
75 for(
size_t j = 0; j < forces.size(); ++j)
76 forces[j] -= D*grad[j];
88 if(IsMasterRank(comm_))
92 void Umbrella::PrintUmbrella(
const CVList& cvs,
size_t iteration)
94 if(IsMasterRank(comm_))
96 umbrella_.precision(8);
97 umbrella_ << iteration <<
" ";
101 umbrella_ << cv->GetValue() <<
" ";
104 for(
size_t i = 0; i < cvs.size() - 1; ++i)
105 umbrella_ << GetCurrentCenter(iteration, i) <<
" ";
106 umbrella_ << GetCurrentCenter(iteration, cvs.size() - 1);
108 umbrella_ << std::endl;
113 const MPI_Comm& world,
114 const MPI_Comm& comm,
115 const std::string& path)
119 CharReaderBuilder rbuilder;
120 CharReader* reader = rbuilder.newCharReader();
122 reader->parse(JsonSchema::UmbrellaMethod.c_str(),
123 JsonSchema::UmbrellaMethod.c_str() + JsonSchema::UmbrellaMethod.size(),
125 validator.
Parse(schema, path);
132 unsigned int wid = GetWalkerID(world, comm);
133 unsigned int wcount = GetNumWalkers(world, comm);
134 bool ismulti = wcount > 1;
136 std::vector<std::vector<double>> ksprings;
137 for(
auto& s : json[
"ksprings"])
139 std::vector<double> kspring;
142 kspring.push_back(k.asDouble());
144 kspring.push_back(s.asDouble());
146 ksprings.push_back(kspring);
149 std::vector<std::vector<double>> centers0, centers1;
150 if(json.isMember(
"centers"))
152 for(
auto& s : json[
"centers"])
154 std::vector<double> center;
157 center.push_back(k.asDouble());
159 center.push_back(s.asDouble());
161 centers0.push_back(center);
164 else if(json.isMember(
"centers0") && json.isMember(
"centers1") && json.isMember(
"timesteps"))
166 for(
auto& s : json[
"centers0"])
168 std::vector<double> center;
171 center.push_back(k.asDouble());
173 center.push_back(s.asDouble());
175 centers0.push_back(center);
178 for(
auto& s : json[
"centers1"])
180 std::vector<double> center;
183 center.push_back(k.asDouble());
185 center.push_back(s.asDouble());
187 centers1.push_back(center);
191 throw BuildException({
"Either \"centers\" or \"timesteps\", \"centers0\" and \"centers1\" must be defined for umbrella."});
193 if(ksprings[0].size() != centers0[0].size())
194 throw BuildException({
"Need to define a spring for every center or a center for every spring!"});
199 if(ksprings.size() == 1)
200 for(
size_t i = 1; i < wcount; ++i)
201 ksprings.push_back(ksprings[0]);
202 else if(ksprings.size() != wcount)
203 throw std::invalid_argument(path +
": Multi-walker simulations requires that the number of \"ksprings\" match the number of walkers.");
204 if(centers0.size() == 1)
205 for(
size_t i = 1; i < wcount; ++i)
206 centers0.push_back(centers0[0]);
207 else if(centers0.size() != wcount)
208 throw std::invalid_argument(path +
": Multi-walker simulations requires that the number of \"centers\"/\"centers0\" match the number of walkers.");
209 if(centers1.size() == 1)
210 for(
size_t i = 1; i < wcount; ++i)
211 centers1.push_back(centers1[0]);
212 else if(centers1.size())
213 throw std::invalid_argument(path +
": Multi-walker simulations requires that the number of \"centers1\" match the number of walkers.");
216 auto freq = json.get(
"frequency", 1).asInt();
218 size_t timesteps = 0;
219 if(json.isMember(
"timesteps"))
221 if(json[
"timesteps"].isArray())
222 timesteps = json[
"timesteps"][wid].asUInt();
224 timesteps = json[
"timesteps"].asUInt();
227 std::string name =
"umbrella.dat";
228 if(json[
"output_file"].isArray())
229 name = json[
"output_file"][wid].asString();
231 throw std::invalid_argument(path +
": Multi-walker simulations require a separate output file for each.");
233 name = json[
"output_file"].asString();
237 m =
new Umbrella(world, comm, ksprings[wid], centers0[wid], name, freq);
239 m =
new Umbrella(world, comm, ksprings[wid], centers0[wid], centers1[wid], timesteps, name, freq);
242 m->
SetAppend(json.get(
"append",
false).asBool());
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 GetIteration() const
Get the current iteration.
Umbrella sampling method.
void SetOutputFrequency(int outfreq)
Set output frequency.
void SetAppend(bool append)
Set append mode.
std::vector< CollectiveVariable * > CVList
List of Collective Variables.