23 #include "CVs/CollectiveVariable.h"
24 #include "Validator/ObjectRequirement.h"
25 #include "Drivers/DriverException.h"
28 #include <Eigen/Eigenvalues>
101 using std::to_string;
106 std::vector<int> found(n, 0);
107 for(
size_t i = 0; i < n; ++i)
113 MPI_Allreduce(MPI_IN_PLACE, found.data(), n, MPI_INT, MPI_SUM, snapshot.
GetCommunicator());
114 unsigned ntot = std::accumulate(found.begin(), found.end(), 0, std::plus<int>());
117 "GyrationTensorCV: Expected to find " +
119 " atoms, but only found " +
120 to_string(ntot) +
"."
130 using namespace Eigen;
133 std::vector<int> idx;
138 const auto& masses = snapshot.
GetMasses();
151 std::vector<Vector3> ris;
152 ris.reserve(idx.size());
156 S.noalias() += masses[i]*ris.back()*ris.back().transpose();
160 MPI_Allreduce(MPI_IN_PLACE, S.data(), S.size(), MPI_DOUBLE, MPI_SUM, snapshot.
GetCommunicator());
165 SelfAdjointEigenSolver<Matrix3> solver;
166 solver.computeDirect(S);
167 const auto& eigvals = solver.eigenvalues();
168 const auto& eigvecs = solver.eigenvectors();
171 auto l1 = eigvals[2],
174 const auto& n1 = eigvecs.col(2),
179 auto sum = l1 + l2 + l3;
180 auto sqsum = l1*l1 + l2*l2 + l3*l3;
196 val_ = l1 - 0.5*(l2 + l3);
202 val_ = 1.5*sqsum/(sum*sum) - 0.5;
211 auto dl1 = 2.*masses[i]/masstot*(1.-masses[i]/masstot)*ris[j].dot(n1)*n1;
212 auto dl2 = 2.*masses[i]/masstot*(1.-masses[i]/masstot)*ris[j].dot(n2)*n2;
213 auto dl3 = 2.*masses[i]/masstot*(1.-masses[i]/masstot)*ris[j].dot(n3)*n3;
218 grad_[i] = dl1 + dl2 + dl3;
230 grad_[i] = dl1 - 0.5*(dl2 + dl3);
233 grad_[i] = dl2 - dl3;
236 grad_[i] = 3.*(l1*dl1+l2*dl2+l3*dl3)/(sum*sum) -
237 3.*sqsum*(dl1+dl2+dl3)/(sum*sum*sum);
250 Json::CharReaderBuilder rbuilder;
251 Json::CharReader* reader = rbuilder.newCharReader();
253 reader->parse(JsonSchema::GyrationTensorCV.c_str(),
254 JsonSchema::GyrationTensorCV.c_str() + JsonSchema::GyrationTensorCV.size(),
256 validator.
Parse(schema, path);
263 std::vector<int> atomids;
264 for(
auto& s : json[
"atom_ids"])
265 atomids.push_back(s.asInt());
268 auto comp = json[
"component"].asString();
272 else if(comp ==
"principal1")
273 component = principal1;
274 else if(comp ==
"principal2")
275 component = principal2;
276 else if(comp ==
"principal3")
277 component = principal3;
278 else if(comp ==
"asphericity")
279 component = asphericity;
280 else if(comp ==
"acylindricity")
281 component = acylindricity;
282 else if(comp ==
"shapeaniso")
283 component = shapeaniso;
286 if(json.isMember(
"dimension"))
288 auto dimx = json[
"dimension"][0].asBool();
289 auto dimy = json[
"dimension"][1].asBool();
290 auto dimz = json[
"dimension"][2].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.
Abstract class for a collective variable.
std::vector< Vector3 > grad_
Gradient vector dCv/dxi.
double val_
Current value of CV.
Collective variable on components of the gyration tensor.
GyrationTensor component_
Component of gyration tensor to compute.
GyrationTensorCV(const Label &atomids, GyrationTensor component, bool dimx, bool dimy, bool dimz)
Constructor.
GyrationTensorCV(const Label &atomids, GyrationTensor component)
Constructor.
Label atomids_
IDs of the atoms used for calculation.
static GyrationTensorCV * Build(const Json::Value &json, const std::string &path)
Set up collective variable.
Bool3 dim_
Each dimension determines if it is applied by the CV.
void Evaluate(const Snapshot &snapshot) override
Evaluate the CV.
void Initialize(const Snapshot &snapshot) override
Initialize necessary variables.
Class containing a snapshot of the current simulation in time.
unsigned GetNumAtoms() const
Get number of atoms in this snapshot.
void GetLocalIndices(const Label &ids, Label *indices) const
const mxx::comm & GetCommunicator() const
Get communicator for walker.
int GetLocalIndex(int id) const
Gets the local atom index corresponding to an atom ID.
double TotalMass(const Label &indices) const
Compute the total mass of a group of particles based on index.
const std::vector< Vector3 > & GetPositions() const
Access the particle positions.
const std::vector< double > & GetMasses() const
Const access to the particle masses.
Vector3 CenterOfMass(const Label &indices, bool mass_weight=true) const
Compute center of mass of a group of atoms based on index.
void ApplyMinimumImage(Vector3 *v) const
Apply minimum image to a vector.
GyrationTensor
Define components of gyration tensor.
Eigen::Matrix3d Matrix3
3x3 matrix.
Eigen::Vector3d Vector3
Three-dimensional vector.
Eigen::Matrix< bool, 3, 1 > Bool3
Three-dimensional boolean.
std::vector< int > Label
List of integers.