diff --git a/include/tadah/mlip/atom.h b/include/tadah/mlip/atom.h index 4a6fd8719b89b28972b40c39a87fef831f1e2e56..04d82a4543da3ebb68f33dd3373f279abed62d7c 100644 --- a/include/tadah/mlip/atom.h +++ b/include/tadah/mlip/atom.h @@ -79,5 +79,11 @@ struct Atom: public Element { */ bool operator==(const Atom &) const; + /** Return true if both atoms have the same position and type. + * + * This method compares chemical type and position only + */ + bool is_the_same(const Atom &, double thr=1e-6) const; + }; #endif diff --git a/include/tadah/mlip/structure.h b/include/tadah/mlip/structure.h index 1fa835b4a0b852dc47bfc5d2f01e619f167091d7..9648e651d066839a2cac3953d789717a4369064f 100644 --- a/include/tadah/mlip/structure.h +++ b/include/tadah/mlip/structure.h @@ -251,10 +251,23 @@ struct Structure { * This operator compares cell, stress tensor, number of atoms, * eweight, fweight and sweight, all atom positions and forces. * - * It does NOT compare labels/ + * Assumes atoms have the same order. + * + * It does NOT compare labels. */ bool operator==(const Structure& st) const; + /** Return true if both structures are the same. + * + * This method compares cell vectors, number of atoms, + * species and atomic coordinates + * + * Order ot atoms does not matter. + * + * It does NOT compare energies, stresses, forces and labels. + */ + bool is_the_same(const Structure& st, double thr=1e-6) const; + // move iterator forward to the next structure // return number of atoms in the structure // return 0 if there is no more structures diff --git a/src/atom.cpp b/src/atom.cpp index a84be1e3ab60da955af783fff4d203c3d457328a..164a6c48fb0cbb3a59ace6f4568c5a8bce54886e 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -5,25 +5,31 @@ Atom::Atom() {} Atom::Atom(const Element &element, - const double px, const double py, const double pz, - const double fx, const double fy, const double fz): - Element(element), - position(px,py,pz), - force(fx,fy,fz) + const double px, const double py, const double pz, + const double fx, const double fy, const double fz): + Element(element), + position(px,py,pz), + force(fx,fy,fz) {} std::ostream& operator<<(std::ostream& os, const Atom& atom) { - os << (Element&)atom; - os << "Coordinates: " << std::left << atom.position << std::endl; - os << "Force: " << std::left << atom.force << std::endl; - return os; + os << (Element&)atom; + os << "Coordinates: " << std::left << atom.position << std::endl; + os << "Force: " << std::left << atom.force << std::endl; + return os; } bool Atom::operator==(const Atom &a) const { - double EPSILON = std::numeric_limits<double>::epsilon(); - return - position.isApprox(a.position, EPSILON) - && force.isApprox(a.force, EPSILON) - && Element::operator==(a) - ; + double EPSILON = std::numeric_limits<double>::epsilon(); + return + position.isApprox(a.position, EPSILON) + && force.isApprox(a.force, EPSILON) + && Element::operator==(a) + ; +} +bool Atom::is_the_same(const Atom &a, double thr) const { + return + position.isApprox(a.position, thr) + && Element::operator==(a) + ; } diff --git a/src/structure.cpp b/src/structure.cpp index 4aa06757172e37fc6e5ac39e66845846f5d99222..f5c67485f3266e556818436c1e8b250be8613a37 100644 --- a/src/structure.cpp +++ b/src/structure.cpp @@ -192,6 +192,23 @@ bool Structure::operator==(const Structure& st) const } return result; } +bool Structure::is_the_same(const Structure& st, double thr) const +{ + bool result = + cell.isApprox(st.cell, thr) + && natoms()==st.natoms(); + if (!result) return result; + + size_t count=0;; + for (size_t i=0;i<natoms();++i) { + for (size_t j=i;j<natoms();++j) { + result = atoms[i].is_the_same(st.atoms[j], thr); + if (result) count++; + } + } + + return count==natoms() ? true : false; +} int Structure::next_structure(std::ifstream &ifs) { std::string line; std::getline(ifs,line);