JDFTx  1.2.0
WignerSeitz.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------
2 Copyright 2012 Ravishankar Sundararaman
3 
4 This file is part of JDFTx.
5 
6 JDFTx is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10 
11 JDFTx is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with JDFTx. If not, see <http://www.gnu.org/licenses/>.
18 -------------------------------------------------------------------*/
19 
20 #ifndef JDFTX_CORE_WIGNERSEITZ_H
21 #define JDFTX_CORE_WIGNERSEITZ_H
22 
24 
25 #include <core/matrix3.h>
26 #include <float.h>
27 #include <array>
28 #include <list>
29 #include <set>
30 
33 {
34 public:
35  WignerSeitz(const matrix3<>& R);
36  ~WignerSeitz();
37 
39  inline vector3<> restrict(const vector3<>& x) const
40  { static const double tol = 1e-8;
41  vector3<> xWS = x;
42  bool changed = true;
43  while(changed)
44  { changed = false;
45  for(const Face* f: faceHalf)
46  { double d = 0.5 * (1. + dot(f->eqn, xWS));
47  if(d<-tol || d>1.+tol) //not in fundamental zone
48  { xWS -= floor(d) * f->img;
49  changed = true;
50  }
51  }
52  }
53  return xWS;
54  }
55 
57  inline vector3<int> restrict(const vector3<int>& iv, const vector3<int>& S, const vector3<>& invS) const
58  { static const double tol = 1e-8;
59  vector3<int> ivWS = iv;
60  bool changed = true;
61  while(changed)
62  { changed = false;
63  for(const Face* f: faceHalf)
64  { double xDotEqn = 0.;
65  for(int k=0; k<3; k++)
66  xDotEqn += f->eqn[k] * ivWS[k] * invS[k];
67  double d = 0.5 * (1. + xDotEqn);
68  if(d<-tol || d>1.+tol) //not in fundamental zone
69  { int id = int(floor(d));
70  for(int k=0; k<3; k++)
71  ivWS[k] -= id * f->img[k] * S[k];
72  changed = true;
73  }
74  }
75  }
76  return ivWS;
77  }
78 
82  inline double boundaryDistance(const vector3<>& x, int iDir=-1) const
83  { double minDistSq = DBL_MAX;
84  for(const Face* f: faceHalf)
85  if(iDir<0 || !f->img[iDir])
86  { double dDiff = 0.5*(1. - fabs(dot(f->eqn, x))); //fractional distance from planes
87  if(dDiff < 0.) return 0.; //point outside Wigner Seitz cell
88  double distSq = dDiff*dDiff * RTR.metric_length_squared(f->img);
89  if(distSq<minDistSq) minDistSq = distSq;
90  }
91  return sqrt(minDistSq);
92  }
93 
96  inline bool onBoundary(const vector3<>& x, int iDir=-1) const
97  { static const double tol = 1e-8;
98  double minDistSq = DBL_MAX;
99  for(const Face* f: faceHalf)
100  if(iDir<0 || !f->img[iDir])
101  { double dDiff = 0.5*(1. - fabs(dot(f->eqn, x))); //fractional distance from planes
102  if(dDiff < -tol) return false; //point outside Wigner Seitz cell
103  double distSq = dDiff*dDiff * RTR.metric_length_squared(f->img);
104  if(distSq<minDistSq) minDistSq = distSq;
105  }
106  return minDistSq<tol;
107  }
108 
111  double inRadius(int iDir=-1) const;
112 
115  double circumRadius(int iDir=-1) const;
116 
118  void writeWireframePlot(const char* filename) const;
119 
121  void writeWireframeDX(const char* filename) const;
122 
124  void checkGraph() const;
125 
127  void writeGraph(FILE* fp=stdout) const;
128 
129  static const double geomRelTol;
130 
132  static bool isOrthogonal(const vector3<>&, const vector3<>&);
133 
134 private:
135  struct Vertex;
136  struct Edge;
137  struct Face;
138 
139  matrix3<> R, invR, RTR;
140  double minDistSq;
141  std::list<Vertex*> vertex;
142  std::set<Edge*> edge;
143  std::set<Face*> face;
144  std::vector<Face*> faceHalf;
145 
147  struct Vertex
148  { vector3<> pos;
149  std::list<Edge*> edge;
150  };
151 
153  struct Edge
154  { std::array<Vertex*,2> vertex;
155  std::array<Face*,2> face;
156  };
157 
159  struct Face
160  { vector3<int> img;
161  vector3<> eqn;
162  std::list<Edge*> edge;
163  };
164 
166  void addPlane(const vector3<int>& a);
167 
171  void addEdge(Face* f, Vertex* vStart, Vertex* vEnd, bool lastEdge=false);
172 };
173 
174 #endif // JDFTX_CORE_WIGNERSEITZ_H
ScalarField sqrt(const ScalarField &)
Elementwise square root (preserve input)
double inRadius(int iDir=-1) const
complex dot(const Tptr &X, const Tptr &Y)
Definition: Operators.h:196
WignerSeitz(const matrix3<> &R)
Construct Wigner-Seitz cell given lattice vectors.
void checkGraph() const
Check if the data structure is valid (all links are reciprocated etc.)
vector3 restrict(const vector3<> &x) const
Find the point within the Wigner-Seitz cell equivalent to x (lattice coordinates) ...
Definition: WignerSeitz.h:39
void writeWireframePlot(const char *filename) const
Write a wireframe plot to file (for gnuplot)
void writeGraph(FILE *fp=stdout) const
Output vertex, edge and face connectivity info:
static const double geomRelTol
relative tolerance for orthogonality and volume checks
Definition: WignerSeitz.h:129
vector3< int > restrict(const vector3< int > &iv, const vector3< int > &S, const vector3<> &invS) const
Find the point within the Wigner-Seitz cell equivalent to iv (mesh coordinates with sample count S) ...
Definition: WignerSeitz.h:57
Wigner-Seitz construction for a 3D lattice (2D lattice may be handled with orthogonal 3rd direction) ...
Definition: WignerSeitz.h:32
static bool isOrthogonal(const vector3<> &, const vector3<> &)
Check whether lattice vectors are orthogonal (within relative tolerance geomRelTol) ...
double boundaryDistance(const vector3<> &x, int iDir=-1) const
Definition: WignerSeitz.h:82
void writeWireframeDX(const char *filename) const
Write a wireframe plot for Data Explorer (.dx)
bool onBoundary(const vector3<> &x, int iDir=-1) const
Definition: WignerSeitz.h:96
double circumRadius(int iDir=-1) const