50 n += n.transpose().eval();
52 n(0, 0) = sxx + syy + szz;
53 n(1, 1) = sxx - syy - szz;
54 n(2, 2) = -sxx + syy - szz;
55 n(3, 3) = -sxx - syy + szz;
57 Eigen::SelfAdjointEigenSolver<Matrix4d> es(n);
58 Eigen::Vector4d maxv = es.eigenvectors().col(3);
60 double aa = maxv[0] * maxv[0];
61 double bb = maxv[1] * maxv[1];
62 double cc = maxv[2] * maxv[2];
63 double dd = maxv[3] * maxv[3];
64 double ab = maxv[0] * maxv[1];
65 double ac = maxv[0] * maxv[2];
66 double ad = maxv[0] * maxv[3];
67 double bc = maxv[1] * maxv[2];
68 double bd = maxv[1] * maxv[3];
69 double cd = maxv[2] * maxv[3];
71 R(0, 0) = aa + bb - cc - dd;
72 R(0, 1) = 2 * (bc - ad);
73 R(0, 2) = 2 * (bd + ac);
74 R(1, 0) = 2 * (bc + ad);
75 R(1, 1) = aa - bb + cc - dd;
76 R(1, 2) = 2 * (cd - ab);
77 R(2, 0) = 2 * (bd - ac);
78 R(2, 1) = 2 * (cd + ab);
79 R(2, 2) = aa - bb - cc + dd;
85 const double max_diff) {
90 Eigen::VectorXd c1(3);
91 Eigen::VectorXd c2(3);
93 c1[0] = r1.col(0).sum();
94 c1[1] = r1.col(1).sum();
95 c1[2] = r1.col(2).sum();
96 c2[0] = r2.col(0).sum();
97 c2[1] = r2.col(1).sum();
98 c2[2] = r2.col(2).sum();
102 for (
int i = 0; i < r1.rows(); i++) {
117 for (
int i = 0; i < r1.rows(); i++) {
118 double diff = (r2.row(i) - r1.row(i)).norm();
119 if (diff > max_diff) {
134 long nAtoms = positions.rows();
135 long dof = nAtoms * 3;
138 Eigen::Vector3d com = Eigen::Vector3d::Zero();
139 for (
long i = 0; i < nAtoms; ++i) {
140 com(0) += positions(i, 0);
141 com(1) += positions(i, 1);
142 com(2) += positions(i, 2);
144 com /=
static_cast<double>(nAtoms);
147 std::vector<Eigen::VectorXd> basis;
151 for (
int d = 0; d < 3; ++d) {
152 Eigen::VectorXd t = Eigen::VectorXd::Zero(dof);
153 for (
long j = 0; j < nAtoms; ++j) {
160 Eigen::VectorXd rx = Eigen::VectorXd::Zero(dof);
161 Eigen::VectorXd ry = Eigen::VectorXd::Zero(dof);
162 Eigen::VectorXd rz = Eigen::VectorXd::Zero(dof);
164 for (
long i = 0; i < nAtoms; ++i) {
165 double x = positions(i, 0) - com(0);
166 double y = positions(i, 1) - com(1);
167 double z = positions(i, 2) - com(2);
183 std::vector<Eigen::VectorXd> ortho;
186 for (
auto &v : basis) {
187 Eigen::VectorXd u = v;
188 for (
const auto &e : ortho) {
192 if (u.norm() > 1e-9) {
199 for (
const auto &e : ortho) {
200 step -= step.dot(e) * e;
205 std::shared_ptr<Matter> m2) {
209 if (m2->numberOfFixedAtoms() > 0) {
214 long n = r1_passed.size();
217 Eigen::VectorXd step(n);
218 Eigen::Map<const Eigen::VectorXd> r1_flat(r1_passed.data(), n);
219 Eigen::Map<const Eigen::VectorXd> r2_flat(r2.data(), n);
220 step = r2_flat - r1_flat;
226 Eigen::VectorXd result = r1_flat + step;
228 Eigen::Map<Eigen::VectorXd>(resultMat.data(), n) = result;
230 m2->setPositions(resultMat);
234 std::shared_ptr<Matter> m2) {
245 Eigen::VectorXd disp(3);
248 disp[0] = r12.col(0).sum();
249 disp[1] = r12.col(1).sum();
250 disp[2] = r12.col(2).sum();
253 for (
int i = 0; i < r1.rows(); i++) {
270 return v1.rowwise().norm().maxCoeff();
280 for (
long i = 0; i + 3 <= n; i += 3) {
281 double norm = v1.segment<3>(i).norm();
289 double norm = v1.tail(rem).norm();
299 for (
int i = 0; i < v1.rows(); i++) {
300 double norm = v1.row(i).norm();
301 if (norm >= cutoff) {
313 if (max > maxMotion) {
314 v2 *= maxMotion / max;
324 if (max > maxMotion) {
325 v2 *= maxMotion / max;
334 double max = v1.norm();
335 if (max > maxMotion) {
336 v2 *= maxMotion / max;
345 double max = v1.norm();
346 if (max > maxMotion) {
347 v2 *= maxMotion / max;
370 const double distanceDifference) {
375 std::set<int> matched;
376 double tolerance = distanceDifference;
378 if (r1.rows() != r2.rows()) {
383 for (
int i = 0; i < N; i++) {
384 if (std::fabs((m1.
pbc(r1.row(i) - r2.row(i))).norm()) < tolerance &&
390 for (
int j = 0; j < N; j++) {
392 if (matched.count(j) == 1)
395 for (
int k = 0; k < N; k++) {
396 if (matched.count(j) == 1)
399 if (std::fabs((m1.
pbc(r1.row(j) - r2.row(k))).norm()) < tolerance &&
406 if (matched.size() ==
static_cast<unsigned>(N)) {
414 const double distanceDifference) {
418 double tolerance = distanceDifference;
421 if (r1.rows() != r2.rows()) {
426 std::vector<std::set<atom, by_atom>> rdf1(r1.rows());
427 std::vector<std::set<atom, by_atom>> rdf2(r2.rows());
429 for (
int i2 = 0; i2 < r2.rows(); i2++) {
431 for (
int j2 = 0; j2 < r2.rows(); j2++) {
442 for (
int i1 = 0; i1 < r1.rows(); i1++) {
443 if (matches == i1 - 2) {
446 for (
int j1 = 0; j1 < r1.rows(); j1++) {
455 for (
int x = 0; x < r2.rows(); x++) {
456 auto it2 = rdf2[x].begin();
457 auto it = rdf1[i1].begin();
460 for (; c < r1.rows(); c++) {
461 if (it == rdf1[i1].end() || it2 == rdf2[x].end())
465 if (std::fabs(k1.
r - k2.
r) < tolerance && k1.
z == k2.
z) {
474 if (counter == r1.rows()) {
482 return matches >= r1.rows();
486 if (minDistance <= 0)
492 double cut = minDistance;
493 double pushAparts = 500;
494 for (
int p = 0; p < r1.rows(); p++) {
495 for (
int axis = 0; axis <= 2; axis++) {
499 for (
int count = 0; count < pushAparts; count++) {
501 for (
int i = 0; i < r1.rows(); i++) {
502 for (
int j = i + 1; j < r1.rows(); j++) {
503 double d = m1->distance(i, j);
506 for (
int axis = 0; axis <= 2; axis++) {
507 double componant = f * (r1(i, axis) - r1(j, axis)) / d;
508 Force(i, axis) += componant;
509 Force(j, axis) -= componant;
516 for (
int k = 0; k < r1.rows(); k++) {
517 for (
int axis = 0; axis <= 2; axis++) {
518 r1(k, axis) += Force(k, axis);
522 m1->setPositions(r1);
Eigen::Matrix< double, 3, 3, eOnStorageOrder > RotationMatrix
Eigen::Matrix< double, 3, 3, eOnStorageOrder > Matrix3d
Eigen::Matrix< double, 4, 4, eOnStorageOrder > Matrix4d
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
#define EONC_LOG_INFO(...)
double distance(long index1, long index2) const
AtomMatrix pbc(const AtomMatrix &diff) const
long getAtomicNr(long int atom) const
void setPositions(const AtomMatrix &pos)
const AtomMatrix & getPositions() const
RotationMatrix rotationExtract(const AtomMatrix r1, const AtomMatrix r2)
AtomMatrix maxAtomMotionApplied(const AtomMatrix v1, double maxMotion)
long numAtomsMoved(const AtomMatrix v1, double cutoff)
double maxAtomMotion(const AtomMatrix v1)
void pushApart(std::shared_ptr< Matter > m1, double minDistance)
bool rotationMatch(const Matter &m1, const Matter &m2, const double max_diff)
VectorXd maxMotionAppliedV(const VectorXd v1, double maxMotion)
void projectOutRotTrans(Eigen::VectorXd &step, const AtomMatrix &positions)
bool identical(const Matter &m1, const Matter &m2, const double distanceDifference)
VectorXd maxAtomMotionAppliedV(const VectorXd v1, double maxMotion)
double maxAtomMotionV(const VectorXd v1)
bool sortedR(const Matter &m1, const Matter &m2, const double distanceDifference)
void rotationRemove(const AtomMatrix r1, std::shared_ptr< Matter > m2)
AtomMatrix maxMotionApplied(const AtomMatrix v1, double maxMotion)
void translationRemove(Matter &m1, const AtomMatrix r1)
bool operator()(atom const &a, atom const &b) const