7#ifndef model_Lattice_cpp_
8#define model_Lattice_cpp_
10#include <Eigen/Eigenvalues>
12#include <LatticeModule.h>
27 const double QQTerror((QQT - MatrixDimD::Identity()).norm());
28 if (QQTerror > 10.0 * DBL_EPSILON * dim * dim)
30 throw std::runtime_error(
"The rotation matrix Q is not orthogonal: norm(Q*Q^T-I)="+std::to_string(QQTerror)+
"\n");
33 const double Qdet(
Q.determinant());
34 if (std::fabs(
Q.determinant() - 1.0)>FLT_EPSILON)
36 throw std::runtime_error(
"The rotation matrix is not proper: det(Q)="+std::to_string(Qdet)+
"\n");
47 latticeBasis(getLatticeBasis(
A,
Q))
48 ,reciprocalBasis(latticeBasis.inverse().transpose())
56 LatticeDirection<dim> Lattice<dim>::latticeDirection(
const VectorDimD &d)
const
58 const VectorDimD nd(reciprocalBasis.transpose()*d);
59 const LatticeVector<dim>
temp(LatticeCore<dim>::rationalApproximation(nd),*
this);
60 const GramMatrix<double,2> G(std::array<VectorDimD,2>{
temp.cartesian().normalized(),d.normalized()});
61 const double crossNorm(sqrt(G.determinant()));
62 if(crossNorm>FLT_EPSILON)
64 std::cout<<
"input direction="<<d.normalized().transpose()<<std::endl;
65 std::cout<<
"lattice direction="<<
temp.cartesian().normalized().transpose()<<std::endl;
66 std::cout<<
"cross product norm="<<std::setprecision(15)<<std::scientific<<crossNorm<<std::endl;
67 throw std::runtime_error(
"LATTICE DIRECTION NOT FOUND\n");
69 return LatticeDirection<dim>(
temp);
74 ReciprocalLatticeDirection<dim> Lattice<dim>::reciprocalLatticeDirection(
const VectorDimD &d)
const
76 const VectorDimD nd(latticeBasis.transpose()*d);
77 const ReciprocalLatticeVector<dim>
temp(LatticeCore<dim>::rationalApproximation(nd),*
this);
78 const GramMatrix<double,2> G(std::array<VectorDimD,2>{
temp.cartesian().normalized(),d.normalized()});
79 const double crossNorm(sqrt(G.determinant()));
80 if(crossNorm>FLT_EPSILON)
82 std::cout<<
"input direction="<<std::setprecision(15)<<std::scientific<<d.normalized().transpose()<<std::endl;
83 std::cout<<
"reciprocal lattice direction="<<std::setprecision(15)<<std::scientific<<
temp.cartesian().normalized().transpose()<<std::endl;
84 std::cout<<
"cross product norm="<<std::setprecision(15)<<std::scientific<<crossNorm<<std::endl;
85 throw std::runtime_error(
"RECIPROCAL LATTICE DIRECTION NOT FOUND\n");
87 return ReciprocalLatticeDirection<dim>(
temp);
92 RationalLatticeDirection<dim> Lattice<dim>::rationalLatticeDirection(
const VectorDimD &d,
93 const typename BestRationalApproximation::LongIntType &maxDen )
const
95 const LatticeDirection<dim> ld(latticeDirection(d));
96 const BestRationalApproximation bra(d.norm() / ld.cartesian().norm(), maxDen);
97 const Rational rat(bra.num, bra.den);
98 const RationalLatticeDirection<dim> rld(rat, ld);
99 if ((rld.cartesian() - d).squaredNorm() > FLT_EPSILON)
101 std::cout <<
"input vector=" << d.transpose() << std::endl;
102 std::cout <<
"lattice direction=" << ld.cartesian().transpose() << std::endl;
103 std::cout <<
"rational=" << rat << std::endl;
104 std::cout <<
"d.norm()/ld.cartesian().norm()=" << d.norm() / ld.norm() << std::endl;
105 throw std::runtime_error(
"Rational Lattice DirectionType NOT FOUND\n");
112 LatticeVector<dim> Lattice<dim>::latticeVector(
const VectorDimD &
p)
const
114 return LatticeVector<dim>(
p, *
this);
119 ReciprocalLatticeVector<dim> Lattice<dim>::reciprocalLatticeVector(
const VectorDimD &
p)
const
121 return ReciprocalLatticeVector<dim>(
p, *
this);
126 template class Lattice<1>;
127 template class Lattice<2>;
128 template class Lattice<3>;
Eigen::Matrix< double, dim, dim > MatrixDimD
Lattice(const MatrixDimD &A, const MatrixDimD &Q)
static MatrixDimD getLatticeBasis(const MatrixDimD &A, const MatrixDimD &Q)
function infiniteDisplacement syms Ax Ay Az Bx By Bz qx qy qz u L x y z real A