25 #include "CollectiveVariable.h"
26 #include "../Utility/ReadFile.h"
28 #include <Eigen/Dense>
29 #include <Eigen/Eigenvalues>
67 RMSDCV(std::vector<int> atomids, std::string molxyz,
bool use_range =
false) :
72 if(atomids.size() != 2)
73 { std::cout<<
"RMSDCV: If using range, must define only two atoms!"<<std::endl;
79 if(atomids[0] >= atomids[1])
80 { std::cout<<
"RMSDCV: Please reverse atom range or check that atom range is not equal!"<<std::endl;
83 for(
int i = atomids[0]; i <= atomids[1];i++)
89 void Initialize(
const Snapshot& snapshot)
override
103 throw std::runtime_error(
"Reference structure and input structure atom size do not match!");
105 for(
size_t i = 0; i < xyzinfo.size(); i++)
113 mass_pos_prod_ref.setZero();
114 double total_mass = 0;
117 for(
size_t i = 0; i < mass.size(); ++i)
120 for(
size_t j = 0; j <
atomids_.size(); j++)
124 mass_pos_prod_ref += mass[i]*
refcoord_[j];
125 total_mass += mass[i];
131 COMref_ = mass_pos_prod_ref/total_mass;
135 void Evaluate(
const Snapshot& snapshot)
override
137 const auto& pos = snapshot.GetPositions();
138 const auto& ids = snapshot.GetAtomIDs();
139 const auto& mass = snapshot.GetMasses();
140 const auto& image_flags = snapshot.GetImageFlags();
141 Vector3 mass_pos_prod = {0,0,0};
145 for(
size_t i = 0; i < pos.size(); ++i)
149 for(
size_t j = 0; j <
atomids_.size(); j++)
154 auto u_coord = snapshot.UnwrapVector(pos[i], image_flags[i]);
156 mass_pos_prod += mass[i]*u_coord;
157 total_mass += mass[i];
183 COM_ = mass_pos_prod/total_mass;
190 double part_RMSD = 0;
192 for(
size_t j = 0; j <
pertatoms_.size(); ++j)
195 auto u_coord = snapshot.UnwrapVector(pos[i], image_flags[i]);
197 diff = u_coord -COM_;
200 R(0,0) += diff[0]*diff_ref[0];
201 R(0,1) += diff[0]*diff_ref[1];
202 R(0,2) += diff[0]*diff_ref[2];
203 R(1,0) += diff[1]*diff_ref[0];
204 R(1,1) += diff[1]*diff_ref[1];
205 R(1,2) += diff[1]*diff_ref[2];
206 R(2,0) += diff[2]*diff_ref[0];
207 R(2,1) += diff[2]*diff_ref[1];
208 R(2,2) += diff[2]*diff_ref[2];
211 auto normdiff2 = diff.norm()*diff.norm();
212 auto normref2 = diff_ref.norm()*diff_ref.norm();
214 part_RMSD += (normdiff2 + normref2);
218 F(0,0)= R(0,0) + R(1,1) + R(2,2);
219 F(1,0)= R(1,2) - R(2,1);
220 F(2,0)= R(2,0) - R(0,2);
221 F(3,0)= R(0,1) - R(1,0);
223 F(0,1)= R(1,2) - R(2,1);
224 F(1,1)= R(0,0) - R(1,1) - R(2,2);
225 F(2,1)= R(0,1) + R(1,0);
226 F(3,1)= R(0,2) + R(2,0);
228 F(0,2)= R(2,0) - R(0,2);
229 F(1,2)= R(0,1) - R(1,0);
230 F(2,2)= -R(0,0) + R(1,1) - R(2,2);
231 F(3,2)= R(1,2) + R(2,1);
233 F(0,3)= R(0,1) - R(1,0);
234 F(1,3)= R(0,2) - R(2,0);
235 F(2,3)= R(1,2) - R(2,1);
236 F(3,3)= -R(0,0) - R(1,1) + R(2,2);
239 Eigen::EigenSolver<Eigen::Matrix4d> es(F);
243 auto lambda = es.eigenvalues().real();
245 auto max_lambda = lambda.maxCoeff();
249 for (i =0; i < 4; ++i)
250 if(es.eigenvalues()[i] == max_lambda)
256 auto RMSD = sqrt((part_RMSD - (2*max_lambda))/(
atomids_.size()));
262 auto eigenvector = es.eigenvectors().col(column);
264 auto q0 = eigenvector[0].real();
265 auto q1 = eigenvector[1].real();
266 auto q2 = eigenvector[2].real();
267 auto q3 = eigenvector[3].real();
270 RotMatrix(0,0) = q0*q0+q1*q1-q2*q2-q3*q3;
271 RotMatrix(1,0) = 2*(q1*q2+q0*q3);
272 RotMatrix(2,0) = 2*(q1*q3-q0*q2);
274 RotMatrix(0,1) = 2*(q1*q2-q0*q3);
275 RotMatrix(1,1) = q0*q0-q1*q1+q2*q2-q3*q3;
276 RotMatrix(2,1) = 1*(q2*q3+q0*q1);
278 RotMatrix(0,2) = 2*(q1*q3+q0*q2);
279 RotMatrix(1,2) = 2*(q2*q3-q0*q1);
280 RotMatrix(2,2) = q0*q0-q1*q1-q2*q2+q3*q3;
285 auto trans = RotMatrix.transpose()*
refcoord_[j];
288 auto u_coord = pos[i];
std::vector< int > pertatoms_
Array to store indicies of atoms of interest.
Eigen::Matrix3d Matrix3
3x3 matrix.
Vector3 COMref_
Center of mass of reference.
std::string molecule_
Name of model structure.
Class containing a snapshot of the current simulation in time.
RMSDCV(std::vector< int > atomids, std::string molxyz, bool use_range=false)
Constructor.
std::vector< Vector3 > grad_
Gradient vector dCv/dxi.
const Label & GetAtomIDs() const
Access the atom IDs.
const std::vector< double > & GetMasses() const
Const access to the particle masses.
Eigen::Vector3d Vector3
Three-dimensional vector.
double val_
Current value of CV.
std::vector< int > atomids_
IDs of the atoms used for Rg calculation.
Abstract class for a collective variable.
static std::vector< std::array< double, 4 > > ReadXYZ(std::string FileName)
Read xyz file.
std::vector< Vector3 > refcoord_
Store reference structure coordinates.
const std::vector< Vector3 > & GetPositions() const
Access the particle positions.
Collective variable to calculate root mean square displacement.