28 return mat[0] * (mat[4] * mat[8] - mat[7] * mat[5]) - mat[1] * (mat[3] * mat[8] - mat[5] * mat[6]) +
29 mat[2] * (mat[3] * mat[7] - mat[4] * mat[6]);
34 super[0] = tile[0] * prim[0] + tile[1] * prim[3] + tile[2] * prim[6];
35 super[1] = tile[0] * prim[1] + tile[1] * prim[4] + tile[2] * prim[7];
36 super[2] = tile[0] * prim[2] + tile[1] * prim[5] + tile[2] * prim[8];
37 super[3] = tile[3] * prim[0] + tile[4] * prim[3] + tile[5] * prim[6];
38 super[4] = tile[3] * prim[1] + tile[4] * prim[4] + tile[5] * prim[7];
39 super[5] = tile[3] * prim[2] + tile[4] * prim[5] + tile[5] * prim[8];
40 super[6] = tile[6] * prim[0] + tile[7] * prim[3] + tile[8] * prim[6];
41 super[7] = tile[6] * prim[1] + tile[7] * prim[4] + tile[8] * prim[7];
42 super[8] = tile[6] * prim[2] + tile[7] * prim[5] + tile[8] * prim[8];
48 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
54 c[0] = a[1] * b[2] - a[2] * b[1];
55 c[1] = -a[0] * b[2] + a[2] * b[0];
56 c[2] = a[0] * b[1] - a[1] * b[0];
65 double radius = 5000000000000000.0;
66 for (
int i = 0; i < 3; i++)
68 const int astart = i * 3;
69 const int bstart = ((i + 1) % 3) * 3;
70 const int cstart = ((i + 2) % 3) * 3;
71 for (
int j = 0; j < 3; j++)
73 A[j] = mat[astart + j];
74 B[j] = mat[bstart + j];
75 C[j] = mat[cstart + j];
88 static const double tol = 0.001;
90 const double abssumoffidag =
92 if (abssumoffidag < tol)
98 for (
int i = 0; i < 9; i++)
103 double v = (9.0 -
static_cast<double>(i)) * 0.1;
112 double rmin = 1000000000000000;
113 for (
int i = -1; i <= 1; i++)
115 for (
int j = -1; j <= 1; j++)
117 for (
int k = -1; k <= 1; k++)
119 if ((i != 0) || (j != 0) || (k != 0))
122 d[0] = i * mat[0] + j * mat[3] + k * mat[6];
123 d[1] = i * mat[1] + j * mat[4] + k * mat[7];
124 d[2] = i * mat[2] + j * mat[5] + k * mat[8];
125 double dist = 0.5 *
sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
136 void getBestTile(
double* primcell,
int target,
int* tilemat,
double& radius,
int range = 7)
138 double largest = 0.0;
139 double bestScore = 0.0;
140 static const double tol = 0.0000001;
141 double detPrim =
getDet(primcell);
148 double my_largest = 0.0;
150 double localBestScore = 0.0;
152 for (
int i = -range; i <= range; i++)
157 for (
int j = -range; j <= range; j++)
160 for (
int k = -range; k <= range; k++)
163 for (
int l = -range; l <= range; l++)
166 for (
int m = -range;
m <= range;
m++)
169 int denominator = j * l - i *
m;
170 for (
int n = -range;
n <= range;
n++)
173 int fpp = k * l - i *
n;
174 for (
int o = -range; o <= range; o++)
177 int sp = o * (
n * j - k *
m);
178 for (
int p = -range; p <= range; p++)
181 int numpart = p * fpp + sp;
182 if (denominator != 0)
185 rem = (numpart - target) % denominator;
188 d[8] = (numpart - target) / denominator;
193 if (rad > my_largest + tol || (rad > my_largest - tol && score > localBestScore))
196 localBestScore = score;
197 std::memcpy(my_besttile, d, 9 *
sizeof(
int));
204 if (numpart == target)
207 for (
int q = -range; q <= range; q++)
214 if (rad > my_largest + tol || (rad > my_largest - tol && score > localBestScore))
217 localBestScore = score;
218 std::memcpy(my_besttile, d, 9 *
sizeof(
int));
231 if (my_largest > largest + tol || (my_largest > largest - tol && localBestScore > bestScore))
235 if (my_largest > largest + tol || (my_largest > largest - tol && localBestScore > bestScore))
237 largest = my_largest;
238 bestScore = localBestScore;
239 std::memcpy(tilemat, my_besttile, 9 *
sizeof(
int));
248 int main(
int argc,
char* argv[])
255 for (
int i = 1; i < argc; i++)
259 if (!std::strcmp(argv[i],
"--ptvs"))
261 for (
int j = 0; j < 9; j++)
263 prim[j] = strtod(argv[i + j + 1], &pend);
267 if (!std::strcmp(argv[i],
"--target"))
269 target = strtol(argv[i + 1], &pend, 10);
272 if (!std::strcmp(argv[i],
"--verbose"))
276 if (!std::strcmp(argv[i],
"--maxentry"))
278 maxentry = strtol(argv[i + 1], &pend, 10);
287 getBestTile(prim, target, besttile, radius, maxentry);
291 std::cout <<
"Best Tiling Matrix = " << std::endl;
292 for (
int i = 0; i < 3; i++)
294 for (
int j = 0; j < 3; j++)
296 std::cout << besttile[i * 3 + j] <<
" ";
298 std::cout << std::endl;
300 std::cout <<
"Best Supercell = " << std::endl;
301 for (
int i = 0; i < 3; i++)
303 for (
int j = 0; j < 3; j++)
305 std::cout << super[i * 3 + j] <<
" ";
307 std::cout << std::endl;
309 std::cout <<
"radius = " << radius << std::endl;
311 std::cout <<
"score = " << score << std::endl;
324 std::cout <<
"Trial Supercell = " << std::endl;
325 for (
int i = 0; i < 3; i++)
327 for (
int j = 0; j < 3; j++)
329 std::cout << ts[i * 3 + j] <<
" ";
331 std::cout << std::endl;
333 std::cout <<
"radius = " <<
SimCellRad(ts) << std::endl;
335 std::cout <<
"score = " << score << std::endl;
339 std::cout << radius <<
" ";
340 for (
int i = 0; i < 9; i++)
342 std::cout << besttile[i] <<
" ";
344 for (
int i = 0; i < 9; i++)
346 std::cout << super[i] <<
" ";
348 std::cout << std::endl;
double SimCellRad(double *mat)
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
double getScore(double *mat)
int main(int argc, char *argv[])
void getSupercell(double *prim, int *tile, double *super)
void cross(T *a, T *b, T *c)
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
double WigSeitzRad(double *mat)
double B(double x, int k, int i, const std::vector< double > &t)
void getBestTile(double *primcell, int target, int *tilemat, double &radius, int range=7)