13 std::vector<Eigen::Matrix3d> result(24, Eigen::Matrix3d::Zero());
15 result[i].setIdentity();
18 result[i](0, 1) = result[i](1, 2) = result[i](2, 0) = 1;
21 result[i](0, 2) = result[i](1, 0) = result[i](2, 1) = 1;
24 result[i](0, 1) = result[i](1, 0) = result[i](2, 2) = -1;
27 result[i](0, 2) = result[i](1, 1) = result[i](2, 0) = -1;
30 result[i](0, 0) = result[i](1, 2) = result[i](2, 1) = -1;
34 for (
Index j = 0; j < 3; ++j) {
36 for (
Index k = 0; k < 6; ++k) {
37 result[++i] = result[k] * tmat;
51 : m_metrical_matrix(init_lat_col_mat.transpose() * init_lat_col_mat),
52 m_scale_factor(
cuberoot(init_lat_col_mat.determinant())) {}
74 bool does_meet =
true;
91 bool does_meet =
true;
110 bool does_meet =
false;
122 bool does_meet =
false;
135 bool does_meet =
true;
158 bool does_meet =
true;
182 bool does_meet =
true;
206 bool does_meet =
true;
211 if (
compare(clobber,
C(), compare_tol)) {
233 bool totally_niggli =
false;
238 totally_niggli =
true;
241 return totally_niggli;
251 std::cout <<
A() <<
" " <<
B() <<
" " <<
C() <<
" " <<
ksi() <<
" " <<
eta()
252 <<
" " <<
zeta() << std::endl;
284 std::set<Eigen::Matrix3d, StandardOrientationCompare>
_niggli_set(
285 const Lattice &in_lat,
double compare_tol,
bool keep_handedness) {
288 if (!keep_handedness) {
292 std::set<Eigen::Matrix3d, StandardOrientationCompare> result(
306 const std::vector<Eigen::Matrix3i> &candidate_trans_mats =
309 for (
auto it = candidate_trans_mats.begin(); it != candidate_trans_mats.end();
311 candidate_lat_mat = reduced_in.
lat_column_mat() * it->cast<
double>();
312 if (
is_niggli(candidate_lat_mat, compare_tol)) {
313 result.insert(candidate_lat_mat);
331 bool keep_handedness) {
332 auto lat_set =
_niggli_set(in_lat, compare_tol, keep_handedness);
333 if (lat_set.empty()) {
334 throw std::runtime_error(
335 "In niggli(), did not find any lattices matching niggli criteria!");
337 return Lattice(*lat_set.rbegin(), in_lat.
tol());
355 double compare_tol) {
358 int non_negatives = 0;
359 for (
int i = 0; i < 3; i++) {
360 for (
int j = 0; j < 3; j++) {
361 if (
float_sgn(lat_mat(i, j), compare_tol) != -1) {
369 lat_spatial_descriptor <<
374 lat_mat(0, 0), lat_mat(1, 1), lat_mat(2, 2),
377 -std::abs(lat_mat(2, 1)), -std::abs(lat_mat(2, 0)),
378 -std::abs(lat_mat(1, 0)), -std::abs(lat_mat(1, 2)),
379 -std::abs(lat_mat(0, 2)), -std::abs(lat_mat(0, 1)),
389 return lat_spatial_descriptor;
409 high_score_lat_unroll, compare_tol);
429 double compare_tol) {
430 bool low_score_is_symmetric =
432 bool low_score_is_bisymmetric =
435 bool high_score_is_symmetric =
437 bool high_score_is_bisymmetric =
441 if ((low_score_is_bisymmetric && !high_score_is_bisymmetric) ||
442 (low_score_is_symmetric && !high_score_is_symmetric)) {
448 else if ((!low_score_is_bisymmetric && high_score_is_bisymmetric) ||
449 (!low_score_is_symmetric && high_score_is_symmetric)) {
457 low_score_lat_mat, high_score_lat_mat, compare_tol);
const Eigen::Matrix3d & lat_column_mat() const
3x3 matrix with lattice vectors as its columne
Lattice reduced_cell() const
Find the lattice vectors which give most compact unit cell Compactness is measured by how close lat_c...
Lattice & make_right_handed()
Flip c vector if it's on the wrong side of a-b plane – return (*this)
double zeta() const
2ab*cos(gamma)
double ksi() const
2bc*cos(alpha)
const Eigen::Matrix3d & metrical_matrix() const
NiggliRep(const Lattice &init_lat)
bool meets_criteria_3(double compare_tol) const
For type I: ksi>0 && eta>0 && zeta>0 (all angles < 90)
bool is_niggli(double compare_tol) const
True if all conditions are true, and either 4 OR 3 is false.
bool meets_criteria_7(double compare_tol) const
|zeta|<=A OR (zeta==A, eta<=2*ksi) OR (zeta==-A, eta==0)
bool meets_criteria_5(double compare_tol) const
|ksi|<=B OR (ksi==B, zeta<=2*eta) OR (ksi==-B, zeta==0)
double eta() const
2ac*cos(beta)
Index niggli_index(double compare_tol) const
Number of criteria met.
bool meets_criteria_4(double compare_tol) const
For type II: ksi<=0 && eta<=0 && zeta<=0 (all angles >= 90)
bool meets_criteria_6(double compare_tol) const
|eta|<=A OR (eta==A, zeta<=2*ksi) OR (eta==-A, zeta==0)
bool meets_criteria_1(double compare_tol) const
A<=B OR (A==B, |ksi| <= |eta|)
bool meets_criteria_8(double compare_tol) const
double C() const
Square of lattice length c.
static std::vector< Eigen::Matrix3d > const & cell_invariant_transforms()
double A() const
Square of lattice length a.
bool is_niggli_type1(double compare_tol) const
True if all conditions except 4 are true.
bool is_niggli_type2(double compare_tol) const
True if all conditions except 3 are true.
void debug_criteria(double compare_tol) const
bool meets_criteria_2(double compare_tol) const
B<=C OR (B==C, |eta| <= |zeta|)
const Eigen::Matrix3d m_metrical_matrix
Transpose of initialization lattice dotted with itself.
const double m_scale_factor
Scaling factor for niggli comparisons.
double B() const
Square of lattice length b.
const std::vector< Eigen::Matrix3i > & positive_unimodular_matrices()
IdentitySymRepBuilder Identity()
Index niggli_index(const Eigen::Matrix3d &test_lat_mat, double compare_tol)
Number of niggli criteria met.
bool standard_orientation_spatial_compare(const Eigen::Matrix3d &low_score_lat_mat, Eigen::Matrix3d &high_score_lat_mat, double compare_tol)
Compare the spatial orientation (ignoring matrix symmetry) and determine which one is oriented more s...
bool is_niggli(const Eigen::Matrix3d &test_lat_mat, double compare_tol)
Eigen::VectorXd spatial_unroll(const Eigen::Matrix3d &lat_mat, double compare_tol)
Generate a vector whose lexicographical value determines how well it's oriented in space.
Lattice niggli(const Lattice &in_lat, double compare_tol, bool keep_handedness=false)
std::set< Eigen::Matrix3d, StandardOrientationCompare > _niggli_set(const Lattice &in_lat, double compare_tol, bool keep_handedness)
std::vector< Eigen::Matrix3d > _cell_invariant_transforms()
bool standard_orientation_compare(const Eigen::Matrix3d &low_score_lat_mat, const Eigen::Matrix3d &high_score_lat_mat, double compare_tol)
Determine whether high_score has a more standard format than low_score.
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
bool compare(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Compare ClusterInvariants.
double cuberoot(double number)
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
int float_sgn(T val, double compare_tol=TOL)
bool float_lexicographical_compare(const Eigen::Ref< const Eigen::MatrixXd > &A, const Eigen::Ref< const Eigen::MatrixXd > &B, double tol)
Floating point lexicographical comparison with tol.
INDEX_TYPE Index
For long integer indexing:
bool is_symmetric(const Eigen::MatrixBase< Derived > &test_mat, double test_tol=CASM::TOL)
bool is_bisymmetric(const Eigen::MatrixBase< Derived > &test_mat, double test_tol=CASM::TOL)