TBTK
Need a break? Support the development by playing Polarity Puzzles
WignerSeitzCell.h
1 /* Copyright 2016 Kristofer Björnson
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
17 
24 #ifndef COM_DAFER45_TBTK_WIGNER_SEITZ_CELL
25 #define COM_DAFER45_TBTK_WIGNER_SEITZ_CELL
26 
27 #include "TBTK/Index.h"
28 #include "TBTK/ParallelepipedCell.h"
29 #include "TBTK/Vector3d.h"
30 
31 #include <cmath>
32 #include <vector>
33 
34 namespace TBTK{
35 
37 class WignerSeitzCell : public ParallelepipedCell{
38 public:
40  WignerSeitzCell();
41 
43  WignerSeitzCell(
44  const std::vector<std::vector<double>> &basisVectors,
45  MeshType meshType
46  );
47 
49  virtual ~WignerSeitzCell();
50 
52  virtual Index getMajorCellIndex(
53  const std::vector<double> &coordinates
54  ) const;
55 
57  virtual Index getMinorCellIndex(
58  const std::vector<double> &coordinates,
59  const std::vector<unsigned int> &numMeshPoints
60  ) const;
61 
63  virtual std::vector<std::vector<double>> getMajorMesh(
64  const std::vector<unsigned int> &numMeshPoints
65  ) const;
66 
68  virtual std::vector<std::vector<double>> getMinorMesh(
69  const std::vector<unsigned int> &numMeshPoints
70  ) const;
71 
73  virtual std::vector<double> getMinorMeshPoint(
74  const std::vector<unsigned int> &meshPoint,
75  const std::vector<unsigned int> &numMeshPoints
76  ) const;
77 private:
81 // static constexpr double ROUNDOFF_MARGIN_MULTIPLIER = 1.000001;
82 
84  unsigned int getMajorCellIndexInternal(Vector3d coordinates) const;
85 
88  Vector3d getFirstCellCoordinates(Vector3d coordinate) const;
89 };
90 
91 inline unsigned int WignerSeitzCell::getMajorCellIndexInternal(
92  Vector3d coordinates
93 ) const{
94  const std::vector<Vector3d> &basisVectors = getBasisVectors();
95  double coordinatesNorm = coordinates.norm();
96 
97  unsigned int cellIndex = 0;
98  switch(getNumDimensions()){
99  case 1:
100  {
101  const Vector3d &basisVector = basisVectors.at(0);
102  double relativeMagnitude = std::abs(
103  coordinates.norm()/basisVector.norm()
104  );
105  while(relativeMagnitude > 0.5){
106  cellIndex++;
107  relativeMagnitude -= 0.5;
108  }
109 
110  break;
111  }
112  case 2:
113  {
114  const Vector3d &b0 = basisVectors.at(0);
115  const Vector3d &b1 = basisVectors.at(1);
116  Vector3d b2 = (b0*b1).unit();
117 
118  double minDistanceLine0 = Vector3d::dotProduct(b0, (b1*b2).unit());
119  double minDistanceLine1 = Vector3d::dotProduct(b1, (b2*b0).unit());
120  double X = abs(2*coordinatesNorm/minDistanceLine0);
121  double Y = abs(2*coordinatesNorm/minDistanceLine1);
122 
123  for(int x = -X-1; x < X+1; x++){
124  for(int y = -Y-1; y < Y+1; y++){
125  if(x == 0 && y == 0)
126  continue;
127 
128  Vector3d latticePoint
129  = x*basisVectors.at(0)
130  + y*basisVectors.at(1);
131 
132  if(
134  latticePoint,
135  coordinates
137  latticePoint,
138  latticePoint
139  ) > 1/2.
140  ){
141  cellIndex++;
142  }
143  }
144  }
145 
146  break;
147  }
148  case 3:
149  {
150  const Vector3d &b0 = basisVectors.at(0);
151  const Vector3d &b1 = basisVectors.at(1);
152  const Vector3d &b2 = basisVectors.at(2);
153 
154  double minDistancePlane0 = Vector3d::dotProduct(b0, (b1*b2).unit());
155  double minDistancePlane1 = Vector3d::dotProduct(b1, (b2*b0).unit());
156  double minDistancePlane2 = Vector3d::dotProduct(b2, (b0*b1).unit());
157  double X = abs(2*coordinatesNorm/minDistancePlane0);
158  double Y = abs(2*coordinatesNorm/minDistancePlane1);
159  double Z = abs(2*coordinatesNorm/minDistancePlane2);
160 
161  for(int x = -X-1; x < X+1; x++){
162  for(int y = -Y-1; y < Y+1; y++){
163  for(int z = -Z-1; z < Z+1; z++){
164  if(x == 0 && y == 0 && z == 0)
165  continue;
166 
167  Vector3d latticePoint
168  = x*basisVectors.at(0)
169  + y*basisVectors.at(1)
170  + z*basisVectors.at(2);
171 
172  if(
174  latticePoint,
175  coordinates
177  latticePoint,
178  latticePoint
179  ) > 1/2.
180  ){
181  cellIndex++;
182  }
183  }
184  }
185  }
186 
187  break;
188  }
189  default:
190  TBTKExit(
191  "WignerSeitzCell::getCellIndex()",
192  "Only coordinates with 1-3 componenents supported.",
193  ""
194  );
195  }
196 
197  return cellIndex;
198 }
199 
200 inline Vector3d WignerSeitzCell::getFirstCellCoordinates(Vector3d coordinates) const{
201  const std::vector<Vector3d> &basisVectors = getBasisVectors();
202  Vector3d b[3];
203  for(unsigned int n = 0; n < 3; n++)
204  b[n] = basisVectors.at(n);
205 
206  for(unsigned int n = 0; n < getNumDimensions(); n++){
207  double coordinatesProjection = Vector3d::dotProduct(
208  coordinates,
209  (b[(n+1)%3]*b[(n+2)%3]).unit()
210  );
211  double bProjection = Vector3d::dotProduct(
212  b[n],
213  (b[(n+1)%3]*b[(n+2)%3]).unit()
214  );
215 
216  coordinates = coordinates - ((int)((coordinatesProjection - bProjection)/bProjection + 3/2.))*b[n];
217  }
218 
219  bool done = false;
220  while(!done){
221  done = true;
222  for(int x = -1; x <= 1; x++){
223  for(int y = -1; y <= 1; y++){
224  for(int z = -1; z <= 1; z++){
225  const Vector3d v = x*b[0] + y*b[1] + z*b[2];
226 
227  if((coordinates + v).norm() < coordinates.norm()){
228  coordinates = coordinates + v;
229  done = false;
230  }
231  }
232  }
233  }
234  }
235 
236  return coordinates;
237 }
238 
239 }; //End namespace TBTK
240 
241 #endif
242 
Physical index.
Three-dimensional vector with components of double type.
Definition: Boolean.h:32
static double dotProduct(const Vector3d &lhs, const Vector3d &rhs)
Definition: Vector3d.h:185
std::enable_if< !std::is_same< DataType, std::complex< double > >::value, Array< DataType >>::type abs(const Array< DataType > &array)
Definition: ArrayAlgorithms.h:770