16 #ifndef QMCPLUSPLUS_LATTICE_ANALYZER_H 17 #define QMCPLUSPLUS_LATTICE_ANALYZER_H 42 template<
typename T,
unsigned D>
62 return (offdiag < std::numeric_limits<T>::epsilon());
68 const T rad_to_deg = 180.0 / M_PI;
70 rad_to_deg *
std::acos(
dot(Rv[1], Rv[2]) * OneOverLength[1] * OneOverLength[2]),
71 rad_to_deg *
std::acos(
dot(Rv[2], Rv[0]) * OneOverLength[2] * OneOverLength[0]));
76 T rMin = 0.5 * std::numeric_limits<T>::max();
79 for (
int i = -1; i <= 1; i++)
80 for (
int j = -1; j <= 1; j++)
81 for (
int k = -1; k <= 1; k++)
84 SingleParticlePos L = (
static_cast<T
>(i) * a[0] + static_cast<T>(j) * a[1] +
static_cast<T
>(k) * a[2]);
90 for (
int i = -1; i <= 1; i++)
91 for (
int j = -1; j <= 1; j++)
100 rMin =
dot(a[0], a[0]);
107 T scr = 0.5 * std::numeric_limits<T>::max();
110 for (
int i = 0; i < 3; ++i)
161 return (offdiag < std::numeric_limits<T>::epsilon());
167 const T rad_to_deg = 180.0 / M_PI;
174 T dotP =
dot(a[0], a[1]);
185 T theta1 =
std::acos(
dot(a[0], a[1]) / (a0mag * a1mag));
186 T theta2 = M_PI - theta1;
189 return 0.5 *
std::sin(theta) * dist;
210 const T eps = 10.0 * std::numeric_limits<T>::epsilon();
212 T r2max =
dot(rb[0], rb[0]);
213 for (
int i = 1; i < 3; i++)
215 T r2 =
dot(rb[i], rb[i]);
216 if ((r2 - r2max) > eps)
224 T tol = 4.0 * rmax * eps;
227 rb_new[0] = rb[0] + rb[1] - rb[2];
228 rb_new[1] = rb[0] + rb[2] - rb[1];
229 rb_new[2] = rb[1] + rb[2] - rb[0];
230 rb_new[3] = rb[0] + rb[1] + rb[2];
231 for (
int i = 0; i < 4; ++i)
233 T r2 =
dot(rb_new[i], rb_new[i]);
234 if ((r2 - r2max) < -tol)
236 rb[imax] = rb_new[i];
247 for (
int count = 0; count < maxIter; count++)
250 bool changed =
false;
251 for (
int i = 0; i < 3; ++i)
263 throw std::runtime_error(
"Reduced basis not found in allowed number of iterations. " 264 "Check unit cell or contact a developer.");
helper functions for EinsplineSetBuilder
bool isDiagonalOnly(const Tensor< T, 2 > &R) const
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
MakeReturn< UnaryNode< FnSin, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sin(const Vector< T1, C1 > &l)
T calcWignerSeitzRadius(TinyVector< SingleParticlePos, 3 > &a)
T calcSimulationCellRadius(TinyVector< SingleParticlePos, 2 > &a)
int operator()(const TinyVector< int, 3 > &box)
T calcSimulationCellRadius(TinyVector< SingleParticlePos, 3 > &a)
T calcWignerSeitzRadius(TinyVector< SingleParticlePos, 2 > &a)
bool found_shorter_base(TinyVector< TinyVector< T, 3 >, 3 > &rb)
bool isDiagonalOnly(const Tensor_t &R) const
bool isDiagonalOnly(const Tensor< T, 1 > &R) const
SingleParticlePos calcSolidAngles(const TinyVector< SingleParticlePos, 2 > &Rv, const SingleParticlePos &OneOverLength)
Tensor<T,D> class for D by D tensor.
MakeReturn< UnaryNode< FnArcCos, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t acos(const Vector< T1, C1 > &l)
int operator()(const TinyVector< int, 2 > &box)
return supercell enum
T calcWignerSeitzRadius(TinyVector< SingleParticlePos, 1 > &a)
void find_reduced_basis(TinyVector< TinyVector< T, 3 >, 3 > &rb)
TinyVector< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > cross(const TinyVector< T1, D > &lhs, const TinyVector< T2, D > &rhs)
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
generic class to analyze a Lattice
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
double B(double x, int k, int i, const std::vector< double > &t)
SingleParticlePos calcSolidAngles(const TinyVector< SingleParticlePos, 3 > &Rv, const SingleParticlePos &OneOverLength)
int operator()(const TinyVector< int, 1 > &box)