SSAGES  0.9.3
Software Suite for Advanced General Ensemble Simulations
ParticleCoordinateCV.h
1 
21 #pragma once
22 
23 #include "CollectiveVariable.h"
24 #include "Validator/ObjectRequirement.h"
25 #include "Drivers/DriverException.h"
26 #include "Snapshot.h"
27 #include "schema.h"
28 #include <numeric>
29 
30 namespace SSAGES
31 {
33 
41  {
42  private:
45 
48 
49  public:
51 
60  ParticleCoordinateCV(const Label& atomids, Dimension dim) :
61  atomids_(atomids), dim_(dim)
62  {}
63 
65 
68  void Initialize(const Snapshot& snapshot) override
69  {
70  using std::to_string;
71 
72  auto n = atomids_.size();
73 
74  // Make sure atom ID's are on at least one processor.
75  std::vector<int> found(n, 0);
76  for(size_t i = 0; i < n; ++i)
77  {
78  if(snapshot.GetLocalIndex(atomids_[i]) != -1)
79  found[i] = 1;
80  }
81 
82  MPI_Allreduce(MPI_IN_PLACE, found.data(), n, MPI_INT, MPI_SUM, snapshot.GetCommunicator());
83  unsigned ntot = std::accumulate(found.begin(), found.end(), 0, std::plus<int>());
84  if(ntot != n)
85  throw BuildException({
86  "ParticleCoordinateCV: Expected to find " +
87  to_string(n) +
88  " atoms, but only found " +
89  to_string(ntot) + "."
90  });
91  }
92 
94 
97  void Evaluate(const Snapshot& snapshot) override
98  {
99  // Get local atom indices and compute COM.
100  std::vector<int> idx;
101  snapshot.GetLocalIndices(atomids_, &idx);
102 
103  // Get data from snapshot.
104  auto n = snapshot.GetNumAtoms();
105  const auto& masses = snapshot.GetMasses();
106 
107  // Initialize gradient.
108  std::fill(grad_.begin(), grad_.end(), Vector3{0,0,0});
109  grad_.resize(n, Vector3{0,0,0});
110 
111  // Compute total and center of mass.
112  auto masstot = snapshot.TotalMass(idx);
113  Vector3 com = snapshot.CenterOfMass(idx);
114 
115  // Assign CV value.
116  switch(dim_)
117  {
118  case Dimension::x:
119  val_ = com[0];
120  break;
121  case Dimension::y:
122  val_ = com[1];
123  break;
124  case Dimension::z:
125  val_ = com[2];
126  break;
127  }
128 
129  // Assign gradient to appropriate atoms.
130  for(auto& id : idx)
131  {
132  grad_[id][0] = (dim_ == Dimension::x) ? masses[id]/masstot : 0;
133  grad_[id][1] = (dim_ == Dimension::y) ? masses[id]/masstot : 0;
134  grad_[id][2] = (dim_ == Dimension::z) ? masses[id]/masstot : 0;
135  }
136  }
137 
139 
147  double GetPeriodicValue(double Location) const override
148  {
149  return Location;
150  }
151 
153 
162  double GetDifference(const double Location) const override
163  {
164  return val_ - Location;
165  }
166 
168  static ParticleCoordinateCV* Build(const Json::Value& json, const std::string& path)
169  {
170  Json::ObjectRequirement validator;
171  Json::Value schema;
172  Json::CharReaderBuilder rbuilder;
173  Json::CharReader* reader = rbuilder.newCharReader();
174 
175  reader->parse(JsonSchema::ParticleCoordinateCV.c_str(),
176  JsonSchema::ParticleCoordinateCV.c_str() + JsonSchema::ParticleCoordinateCV.size(),
177  &schema, nullptr);
178  validator.Parse(schema, path);
179 
180  // Validate inputs.
181  validator.Validate(json, path);
182  if(validator.HasErrors())
183  throw BuildException(validator.GetErrors());
184 
185  Label atomids;
186  for(auto& id : json["atom_ids"])
187  atomids.push_back(id.asInt());
188 
189  auto indextype = json.get("dimension","x").asString();
190 
191  Dimension index;
192  if(indextype == "x")
193  index = Dimension::x;
194  else if(indextype == "y")
195  index = Dimension::y;
196  else if(indextype == "z")
197  index = Dimension::z;
198  else
199  throw BuildException({"Could not obtain ParticleCoordinate dimension specified."});
200 
201  return new ParticleCoordinateCV(atomids, index);
202  }
203  };
204 }
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.
Definition: Requirement.h:92
bool HasErrors()
Check if errors have occured.
Definition: Requirement.h:86
Exception to be thrown when building the Driver fails.
Abstract class for a collective variable.
std::vector< Vector3 > grad_
Gradient vector dCv/dxi.
double val_
Current value of CV.
Collective variable on a particle coordinate.
void Initialize(const Snapshot &snapshot) override
Initialize necessary variables.
double GetDifference(const double Location) const override
Return difference considering periodic boundaries.
Dimension dim_
Index of dimension.
double GetPeriodicValue(double Location) const override
Return value taking periodic boundary conditions into account.
ParticleCoordinateCV(const Label &atomids, Dimension dim)
Constructor.
static ParticleCoordinateCV * Build(const Json::Value &json, const std::string &path)
Set up collective variable.
Label atomids_
IDs of atoms of interest.
void Evaluate(const Snapshot &snapshot) override
Evaluate the CV.
Class containing a snapshot of the current simulation in time.
Definition: Snapshot.h:48
unsigned GetNumAtoms() const
Get number of atoms in this snapshot.
Definition: Snapshot.h:202
void GetLocalIndices(const Label &ids, Label *indices) const
Definition: Snapshot.h:537
const mxx::comm & GetCommunicator() const
Get communicator for walker.
Definition: Snapshot.h:186
int GetLocalIndex(int id) const
Gets the local atom index corresponding to an atom ID.
Definition: Snapshot.h:519
double TotalMass(const Label &indices) const
Compute the total mass of a group of particles based on index.
Definition: Snapshot.h:423
const std::vector< double > & GetMasses() const
Const access to the particle masses.
Definition: Snapshot.h:367
Vector3 CenterOfMass(const Label &indices, bool mass_weight=true) const
Compute center of mass of a group of atoms based on index.
Definition: Snapshot.h:442
Eigen::Vector3d Vector3
Three-dimensional vector.
Definition: types.h:33
Dimension
Enum for dimension.
Definition: types.h:54
std::vector< int > Label
List of integers.
Definition: types.h:48