SSAGES  0.9.3
Software Suite for Advanced General Ensemble Simulations
Public Member Functions | Static Public Member Functions | Private Attributes | List of all members
SSAGES::RMSDCV Class Reference

Collective variable to calculate root mean square displacement. More...

#include <RMSDCV.h>

Inheritance diagram for SSAGES::RMSDCV:
Inheritance graph
[legend]

Public Member Functions

 RMSDCV (const Label &atomids, std::string xyzfile, bool use_range=false)
 Constructor. More...
 
void Initialize (const Snapshot &snapshot) override
 Initialize necessary variables. More...
 
void Evaluate (const Snapshot &snapshot) override
 Evaluate the CV. More...
 
- Public Member Functions inherited from SSAGES::CollectiveVariable
 CollectiveVariable ()
 Constructor.
 
virtual ~CollectiveVariable ()
 Destructor.
 
virtual void Initialize (const class Snapshot &)
 Initialize CV. More...
 
virtual void Evaluate (const class Snapshot &)=0
 Evaluate CV. More...
 
double GetValue () const
 Get current value of the CV. More...
 
virtual double GetMinimumImage (double) const
 Returns the minimum image of a CV based on the input location. More...
 
virtual double GetPeriodicValue (double location) const
 Apply periodic boundaries to a given value. More...
 
const std::vector< Vector3 > & GetGradient () const
 Get current gradient of the CV. More...
 
const Matrix3GetBoxGradient () const
 Get gradient contribution to box. More...
 
const std::array< double, 2 > & GetBoundaries ()
 Get CV boundaries. More...
 
virtual double GetDifference (double location) const
 

Static Public Member Functions

static RMSDCVBuild (const Json::Value &json, const std::string &path)
 Set up collective variable. More...
 
- Static Public Member Functions inherited from SSAGES::CollectiveVariable
static CollectiveVariableBuildCV (const Json::Value &json, const std::string &path)
 Set up collective variable. More...
 

Private Attributes

Label atomids_
 IDs of the atoms used for RMSD calculation.
 
std::string xyzfile_
 Name of model structure.
 
std::vector< Vector3refcoord_
 Store reference structure coordinates.
 
Vector3 COMref_
 Center of mass of reference.
 

Additional Inherited Members

- Protected Attributes inherited from SSAGES::CollectiveVariable
std::vector< Vector3grad_
 Gradient vector dCv/dxi.
 
Matrix3 boxgrad_
 Gradient w.r.t box vectors dCv/dHij.
 
double val_
 Current value of CV.
 
std::array< double, 2 > bounds_
 Bounds on CV.
 

Detailed Description

Collective variable to calculate root mean square displacement.

RMSD calculation performed as reported in Coutsias, E. A., Seok, C., and Dill, K. A., "Using Quaternions to Calculate RMSD", J. Comput. Chem. 25: 1849-1857, 2004

Definition at line 42 of file RMSDCV.h.

Constructor & Destructor Documentation

◆ RMSDCV()

SSAGES::RMSDCV::RMSDCV ( const Label atomids,
std::string  xyzfile,
bool  use_range = false 
)
inline

Constructor.

Parameters
atomidsIDs of the atoms defining RMSD.
xyzfileString determining the reference file.
use_rangeIf True Use range of atoms defined by the two atoms in atomids.

Construct a RMSD CV.

Todo:
Bounds needs to be an input and periodic boundary conditions

Definition at line 68 of file RMSDCV.h.

68  :
69  atomids_(atomids), xyzfile_(xyzfile)
70  {
71  if(use_range)
72  {
73  if(atomids.size() != 2)
74  {
75  throw BuildException({
76  "RMSDCV: With use_range, expected 2 atoms, but found " +
77  std::to_string(atomids.size()) + "."
78  });
79  }
80 
81  atomids_.clear();
82  if(atomids[0] >= atomids[1])
83  {
84  throw BuildException({
85  "RMSDCV: Atom range must be strictly increasing."
86  });
87  }
88  for(int i = atomids[0]; i <= atomids[1]; ++i)
89  {
90  atomids_.push_back(i);
91  }
92  }
93  }
std::string xyzfile_
Name of model structure.
Definition: RMSDCV.h:49
Label atomids_
IDs of the atoms used for RMSD calculation.
Definition: RMSDCV.h:46

References atomids_.

Referenced by Build().

Here is the caller graph for this function:

Member Function Documentation

◆ Build()

static RMSDCV* SSAGES::RMSDCV::Build ( const Json::Value &  json,
const std::string &  path 
)
inlinestatic

Set up collective variable.

Parameters
jsonJSON input value.
pathPath for JSON path specification.
Returns
Pointer to the CV built by this function. nullptr in case of unknown error.

Builds a CV from a JSON node. Returns a pointer to the built cv. If an unknown error is encountered, this function will return a nullptr, but generally it will throw a BuildException on failure.

Warning
Object lifetime is the caller's responsibility.

Definition at line 244 of file RMSDCV.h.

245  {
246  Json::ObjectRequirement validator;
247  Json::Value schema;
248  Json::CharReaderBuilder rbuilder;
249  Json::CharReader* reader = rbuilder.newCharReader();
250 
251  reader->parse(JsonSchema::RMSDCV.c_str(),
252  JsonSchema::RMSDCV.c_str() + JsonSchema::RMSDCV.size(),
253  &schema, NULL);
254  validator.Parse(schema, path);
255 
256  //Validate inputs
257  validator.Validate(json, path);
258  if(validator.HasErrors())
259  throw BuildException(validator.GetErrors());
260 
261  std::vector<int> atom_ids;
262  for(auto& s : json["atom_ids"])
263  atom_ids.push_back(s.asInt());
264  auto reference = json["reference"].asString();
265  auto use_range = json.get("use_range",false).asBool();
266 
267  return new RMSDCV(atom_ids, reference, use_range);
268  }
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
RMSDCV(const Label &atomids, std::string xyzfile, bool use_range=false)
Constructor.
Definition: RMSDCV.h:68

References Json::Requirement::GetErrors(), Json::Requirement::HasErrors(), Json::ObjectRequirement::Parse(), RMSDCV(), and Json::ObjectRequirement::Validate().

Referenced by SSAGES::CollectiveVariable::BuildCV().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Evaluate()

void SSAGES::RMSDCV::Evaluate ( const Snapshot snapshot)
inlineoverride

Evaluate the CV.

Parameters
snapshotCurrent simulation snapshot.

Definition at line 162 of file RMSDCV.h.

163  {
164  // Get local atom indices.
165  Label idx;
166  snapshot.GetLocalIndices(atomids_, &idx);
167 
168  // Get data from snapshot.
169  const auto& masses = snapshot.GetMasses();
170  const auto& pos = snapshot.GetPositions();
171  double masstot = snapshot.TotalMass(idx);
172 
173  // Initialize gradient.
174  std::fill(grad_.begin(), grad_.end(), Vector3{0,0,0});
175  grad_.resize(snapshot.GetNumAtoms(), Vector3{0,0,0});
176 
177  // Calculate center of mass
178  Vector3 COM_ = snapshot.CenterOfMass(idx);
179 
180  // Build correlation matrix
181  Matrix3 R = Matrix3::Zero();
182 
183  Vector3 diff, diff_ref;
184  double part_RMSD = 0;
185 
186  for(auto& i : idx)
187  {
188  diff = snapshot.ApplyMinimumImage(pos[i] - COM_);
189  diff_ref = refcoord_[i] - COMref_; // Reference has no "box" or minimum image
190 
191  R.noalias() += masses[i]*diff*diff_ref.transpose();
192 
193  part_RMSD += masses[i]*(diff.squaredNorm() + diff_ref.squaredNorm());
194  }
195  MPI_Allreduce(MPI_IN_PLACE, R.data(), R.size(), MPI_DOUBLE, MPI_SUM, snapshot.GetCommunicator());
196  MPI_Allreduce(MPI_IN_PLACE, &part_RMSD, 1, MPI_DOUBLE, MPI_SUM, snapshot.GetCommunicator());
197  R /= masstot;
198  part_RMSD /= masstot;
199 
200  Eigen::Matrix4d F;
201  F(0,0) = R(0,0) + R(1,1) + R(2,2);
202  F(1,0) = R(1,2) - R(2,1);
203  F(2,0) = R(2,0) - R(0,2);
204  F(3,0) = R(0,1) - R(1,0);
205 
206  F(0,1) = F(1,0);
207  F(1,1) = R(0,0) - R(1,1) - R(2,2);
208  F(2,1) = R(0,1) + R(1,0);
209  F(3,1) = R(0,2) + R(2,0);
210 
211  F(0,2) = F(2,0);
212  F(1,2) = F(2,1);
213  F(2,2) = -R(0,0) + R(1,1) - R(2,2);
214  F(3,2) = R(1,2) + R(2,1);
215 
216  F(0,3) = F(3,0);
217  F(1,3) = F(3,1);
218  F(2,3) = F(3,2);
219  F(3,3) = -R(0,0) - R(1,1) + R(2,2);
220 
221  //Find eigenvalues
222  Eigen::SelfAdjointEigenSolver<Eigen::Matrix4d> es(F);
223  auto max_lambda = es.eigenvalues().real()[3];
224 
225  // Calculate RMSD
226  val_ = sqrt(part_RMSD - (2*max_lambda));
227 
228  // If RMSD is zero, we have nothing to do.
229  if(val_ == 0) return;
230 
231  // Calculate gradient
232  auto ev = es.eigenvectors().real().col(3);
233  auto q = Eigen::Quaterniond(ev(0),ev(1),ev(2),ev(3));
234  Matrix3 RotMatrix = q.toRotationMatrix();
235 
236  for(auto& i : idx)
237  {
238  auto rotref = RotMatrix.transpose()*(refcoord_[i] - COMref_);
239  grad_[i] = masses[i]/masstot*(1-masses[i]/masstot)*(snapshot.ApplyMinimumImage(pos[i] - COM_) - rotref)/val_;
240  }
241  }
std::vector< Vector3 > grad_
Gradient vector dCv/dxi.
double val_
Current value of CV.
std::vector< Vector3 > refcoord_
Store reference structure coordinates.
Definition: RMSDCV.h:52
Vector3 COMref_
Center of mass of reference.
Definition: RMSDCV.h:55
Eigen::Matrix3d Matrix3
3x3 matrix.
Definition: types.h:42
Eigen::Vector3d Vector3
Three-dimensional vector.
Definition: types.h:33
std::vector< int > Label
List of integers.
Definition: types.h:48

References SSAGES::Snapshot::ApplyMinimumImage(), atomids_, SSAGES::Snapshot::CenterOfMass(), COMref_, SSAGES::Snapshot::GetCommunicator(), SSAGES::Snapshot::GetLocalIndices(), SSAGES::Snapshot::GetMasses(), SSAGES::Snapshot::GetNumAtoms(), SSAGES::Snapshot::GetPositions(), SSAGES::CollectiveVariable::grad_, refcoord_, SSAGES::Snapshot::TotalMass(), and SSAGES::CollectiveVariable::val_.

Here is the call graph for this function:

◆ Initialize()

void SSAGES::RMSDCV::Initialize ( const Snapshot snapshot)
inlineoverride

Initialize necessary variables.

Parameters
snapshotCurrent simulation snapshot.

Definition at line 99 of file RMSDCV.h.

100  {
101  const auto& masses = snapshot.GetMasses();
102  auto n = atomids_.size();
103 
104  // Make sure atom IDs are on at least one processor.
105  std::vector<int> found(n, 0);
106  for(size_t i = 0; i < n; ++i)
107  {
108  if(snapshot.GetLocalIndex(atomids_[i]) != -1) found[i] = 1;
109  }
110 
111  MPI_Allreduce(MPI_IN_PLACE, found.data(), n, MPI_INT, MPI_SUM, snapshot.GetCommunicator());
112  unsigned ntot = std::accumulate(found.begin(), found.end(), 0, std::plus<int>());
113  if(ntot != n)
114  {
115  throw BuildException({
116  "RMSDCV: Expected to find " + std::to_string(n) +
117  " atoms, but only found " + std::to_string(ntot) + "."
118  });
119  }
120 
121  Label idx;
122  snapshot.GetLocalIndices(atomids_, &idx);
123 
124  std::vector<std::array<double,4>> xyzinfo = ReadFile::ReadXYZ(xyzfile_);
125 
126  refcoord_.resize(snapshot.GetNumAtoms(), Vector3{0,0,0});
127 
128  // Loop through atom positions
129  for(size_t i = 0; i < xyzinfo.size(); ++i)
130  {
131  int id = snapshot.GetLocalIndex(xyzinfo[i][0]);
132  if(id == -1) continue; // Atom not found
133  for(size_t j = 0; j < atomids_.size(); ++j)
134  {
135  if(atomids_[j] == xyzinfo[i][0])
136  {
137  refcoord_[id][0] = xyzinfo[i][1];
138  refcoord_[id][1] = xyzinfo[i][2];
139  refcoord_[id][2] = xyzinfo[i][3];
140  }
141  }
142  }
143 
144  Vector3 mass_pos_prod_ref = Vector3::Zero();
145  double total_mass = 0;
146 
147  for(auto& i : idx)
148  {
149  mass_pos_prod_ref += masses[i]*refcoord_[i];
150  total_mass += masses[i];
151  }
152  MPI_Allreduce(MPI_IN_PLACE, mass_pos_prod_ref.data(), mass_pos_prod_ref.size(), MPI_DOUBLE, MPI_SUM, snapshot.GetCommunicator());
153  MPI_Allreduce(MPI_IN_PLACE, &total_mass, 1, MPI_DOUBLE, MPI_SUM, snapshot.GetCommunicator());
154 
155  COMref_ = mass_pos_prod_ref/total_mass;
156  }
static std::vector< std::array< double, 4 > > ReadXYZ(std::string FileName)
Read xyz file.
Definition: ReadFile.h:66

References atomids_, COMref_, SSAGES::Snapshot::GetCommunicator(), SSAGES::Snapshot::GetLocalIndex(), SSAGES::Snapshot::GetLocalIndices(), SSAGES::Snapshot::GetMasses(), SSAGES::Snapshot::GetNumAtoms(), SSAGES::ReadFile::ReadXYZ(), refcoord_, and xyzfile_.

Here is the call graph for this function:

The documentation for this class was generated from the following file: