24 #ifndef COM_DAFER45_TBTK_WIGNER_SEITZ_CELL
25 #define COM_DAFER45_TBTK_WIGNER_SEITZ_CELL
28 #include "TBTK/ParallelepipedCell.h"
37 class WignerSeitzCell :
public ParallelepipedCell{
44 const std::vector<std::vector<double>> &basisVectors,
49 virtual ~WignerSeitzCell();
52 virtual Index getMajorCellIndex(
53 const std::vector<double> &coordinates
57 virtual Index getMinorCellIndex(
58 const std::vector<double> &coordinates,
59 const std::vector<unsigned int> &numMeshPoints
63 virtual std::vector<std::vector<double>> getMajorMesh(
64 const std::vector<unsigned int> &numMeshPoints
68 virtual std::vector<std::vector<double>> getMinorMesh(
69 const std::vector<unsigned int> &numMeshPoints
73 virtual std::vector<double> getMinorMeshPoint(
74 const std::vector<unsigned int> &meshPoint,
75 const std::vector<unsigned int> &numMeshPoints
84 unsigned int getMajorCellIndexInternal(Vector3d coordinates)
const;
88 Vector3d getFirstCellCoordinates(Vector3d coordinate)
const;
91 inline unsigned int WignerSeitzCell::getMajorCellIndexInternal(
94 const std::vector<Vector3d> &basisVectors = getBasisVectors();
95 double coordinatesNorm = coordinates.norm();
97 unsigned int cellIndex = 0;
98 switch(getNumDimensions()){
101 const Vector3d &basisVector = basisVectors.at(0);
102 double relativeMagnitude = std::abs(
103 coordinates.norm()/basisVector.norm()
105 while(relativeMagnitude > 0.5){
107 relativeMagnitude -= 0.5;
114 const Vector3d &b0 = basisVectors.at(0);
115 const Vector3d &b1 = basisVectors.at(1);
116 Vector3d b2 = (b0*b1).unit();
120 double X =
abs(2*coordinatesNorm/minDistanceLine0);
121 double Y =
abs(2*coordinatesNorm/minDistanceLine1);
123 for(
int x = -X-1; x < X+1; x++){
124 for(
int y = -Y-1; y < Y+1; y++){
128 Vector3d latticePoint
129 = x*basisVectors.at(0)
130 + y*basisVectors.at(1);
150 const Vector3d &b0 = basisVectors.at(0);
151 const Vector3d &b1 = basisVectors.at(1);
152 const Vector3d &b2 = basisVectors.at(2);
157 double X =
abs(2*coordinatesNorm/minDistancePlane0);
158 double Y =
abs(2*coordinatesNorm/minDistancePlane1);
159 double Z =
abs(2*coordinatesNorm/minDistancePlane2);
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)
167 Vector3d latticePoint
168 = x*basisVectors.at(0)
169 + y*basisVectors.at(1)
170 + z*basisVectors.at(2);
191 "WignerSeitzCell::getCellIndex()",
192 "Only coordinates with 1-3 componenents supported.",
200 inline Vector3d WignerSeitzCell::getFirstCellCoordinates(Vector3d coordinates)
const{
201 const std::vector<Vector3d> &basisVectors = getBasisVectors();
203 for(
unsigned int n = 0; n < 3; n++)
204 b[n] = basisVectors.at(n);
206 for(
unsigned int n = 0; n < getNumDimensions(); n++){
209 (b[(n+1)%3]*b[(n+2)%3]).unit()
213 (b[(n+1)%3]*b[(n+2)%3]).unit()
216 coordinates = coordinates - ((int)((coordinatesProjection - bProjection)/bProjection + 3/2.))*b[n];
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];
227 if((coordinates + v).norm() < coordinates.norm()){
228 coordinates = coordinates + v;