8#ifndef model_Lattice_cpp_
9#define model_Lattice_cpp_
11#include <LatticeModule.h>
22 if ((QQT - MatrixDimD::Identity()).norm() > 2.0 * DBL_EPSILON * dim * dim)
26 std::cout <<
"Q*Q^T=\n"
28 throw std::runtime_error(
"ROTATION MATRIX IS NOT ORTHOGONAL.");
33 if(std::fabs(
Q.determinant() - 1.0) > FLT_EPSILON)
35 throw std::runtime_error(
"ROTATION MATRIX IS NOT PROPER.");
41 if(std::fabs(
A.determinant()) < FLT_EPSILON)
43 throw std::runtime_error(
"A matrix is singular");
60 Eigen::Array<long int, dim, 1> nums = Eigen::Matrix<long int, dim, 1>::Zero();
62 if (nd.squaredNorm() > 0.0)
64 const Eigen::Array<double, dim, 1> nda(nd.array().abs());
66 const double maxVal(nda.maxCoeff(&maxID));
69 nums = Eigen::Matrix<long int, dim, 1>::Ones();
70 Eigen::Array<long int, dim, 1> dens = Eigen::Matrix<long int, dim, 1>::Ones();
73 for (
int k = 0;
k < dim; ++
k)
82 for (
int k = 0;
k < dim; ++
k)
84 nums(
k) *= (denProd / dens(
k));
94 return LatticeVectorType(nd.array().round().matrix().template cast<long int>().eval(), *
this);
104 const double crossNorm(
temp.cartesian().normalized().cross(d.normalized()).norm());
105 if (crossNorm > FLT_EPSILON)
107 std::cout <<
"input direction=" << d.normalized().transpose() << std::endl;
108 std::cout <<
"lattice direction=" <<
temp.cartesian().normalized().transpose() << std::endl;
109 std::cout <<
"cross product norm=" << std::setprecision(15) << std::scientific << crossNorm << std::endl;
110 throw std::runtime_error(
"LATTICE DIRECTION NOT FOUND");
122 const double crossNorm(
temp.cartesian().normalized().cross(d.normalized()).norm());
123 if (crossNorm > FLT_EPSILON)
125 std::cout <<
"input direction=" << std::setprecision(15) << std::scientific << d.normalized().transpose() << std::endl;
126 std::cout <<
"reciprocal lattice direction=" << std::setprecision(15) << std::scientific <<
temp.cartesian().normalized().transpose() << std::endl;
127 std::cout <<
"cross product norm=" << std::setprecision(15) << std::scientific << crossNorm << std::endl;
128 throw std::runtime_error(
"RECIPROCAL LATTICE DIRECTION NOT FOUND");
143 if ((rld.
cartesian() - d).squaredNorm() > FLT_EPSILON)
145 std::cout <<
"input vector=" << d.transpose() << std::endl;
146 std::cout <<
"lattice direction=" << ld.
cartesian().transpose() << std::endl;
147 std::cout <<
"rational=" << rat << std::endl;
148 std::cout <<
"d.norm()/ld.cartesian().norm()=" << d.norm() / ld.
cartesian().norm() << std::endl;
149 throw std::runtime_error(
"RationalLatticeDirectionType NOT FOUND");
Eigen::Matrix< double, dim, dim > MatrixDimD
LatticeVectorType snapToLattice(const VectorDimD &d) const
ReciprocalLatticeDirectionType reciprocalLatticeDirection(const VectorDimD &d) const
const MatrixDimD latticeBasis
LatticeVector< dim > LatticeVectorType
Lattice(const MatrixDimD &A, const MatrixDimD &Q)
LatticeVectorType latticeVector(const VectorDimD &p) const
LatticeDirection< dim > LatticeDirectionType
RationalLatticeDirectionType rationalLatticeDirection(const VectorDimD &d, const typename BestRationalApproximation::LongIntType &maxDen=1000) const
LatticeDirectionType latticeDirection(const VectorDimD &d) const
Eigen::Matrix< double, dim, 1 > VectorDimD
ReciprocalLatticeVector< dim > ReciprocalLatticeVectorType
RationalLatticeDirection< dim > RationalLatticeDirectionType
static Eigen::Matrix< long int, dim, 1 > rationalApproximation(VectorDimD nd)
ReciprocalLatticeDirection< dim > ReciprocalLatticeDirectionType
static MatrixDimD getLatticeBasis(const MatrixDimD &A, const MatrixDimD &Q)
const MatrixDimD reciprocalBasis
ReciprocalLatticeVectorType reciprocalLatticeVector(const VectorDimD &p) const
VectorDimD cartesian() const
function infiniteDisplacement syms Ax Ay Az Bx By Bz qx qy qz u L x y z real A
VectorDimD cartesian() const