fermisurfer  2.0.0
fermisurfer
section.cpp
Go to the documentation of this file.
1 /*
2 The MIT License (MIT)
3 
4 Copyright (c) 2014 Mitsuaki KAWAMURA
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 */
24 /**
25 @file
26 @brief Functions for the 2D Fermi line
27 */
28 #if defined(HAVE_CONFIG_H)
29 #include <config.h>
30 #endif
31 #if defined(HAVE_GL_GL_H)
32 #include <GL/gl.h>
33 #elif defined(HAVE_OPENGL_GL_H)
34 #include <OpenGL/gl.h>
35 #endif
36 #include <wx/wx.h>
37 #include <vector>
38 #include <cstdio>
39 #include <cstdlib>
40 #include <cmath>
41 #include "basic_math.hpp"
42 #include "variable.hpp"
43 /**
44  @brief Project 3D \f$k\f$-vector into 2D plane.
45 
46  Modify: ::kv2d
47 */
48 static void proj_2d(
49  GLfloat axis2d[2][3],
50  GLfloat vec[3] //!< [in,out] Line ends to be projected
51 )
52 {
53  int ii, kk;
54  GLfloat vec0[3];
55 
56  for (kk = 0; kk < 2; kk++) {
57  vec0[kk] = 0.0;
58  for (ii = 0; ii < 3; ii++)
59  vec0[kk] += axis2d[kk][ii] * vec[ii];
60  }/*for (kk = 0; kk < 2; kk++)*/
61  vec0[2] = 0.0;
62  for (kk = 0; kk < 3; kk++)vec[kk] = vec0[kk];
63 }/*proj_2d*/
64 /**
65  @brief Set Projection axis for 2D plane
66 
67  Modify : ::axis2d
68 */
69 static void set2daxis(
70  GLfloat secvec[3],
71  GLfloat axis2d[2][3]
72 ) {
73  int ii, jj;
74  GLfloat snorm, norm, thr = 0.001f;
75 
76  snorm = 0.0;
77  for (ii = 0; ii < 3; ii++) snorm += secvec[ii] * secvec[ii];
78  /*
79  Define the first axis
80  */
81  for (ii = 0; ii < 3; ii++) {
82  for (jj = 0; jj < 3; jj++) axis2d[0][jj] = 0.0;
83  axis2d[0][ii] = 1.0;
84  for (jj = 0; jj < 3; jj++) axis2d[0][jj] += - secvec[ii] * secvec[jj] / snorm;
85 
86  norm = 0.0;
87  for (jj = 0; jj < 3; jj++) norm += axis2d[0][jj] * axis2d[0][jj];
88  norm = sqrtf(norm);
89  if (norm > thr) {
90  for (jj = 0; jj < 3; jj++) axis2d[0][jj] /= norm;
91  break;
92  }/*if (norm > 0.thr)*/
93  }/*for (ii = 0; ii < 3; ii++)*/
94  /*
95  Define the second axis with outor product
96  */
97  axis2d[1][0] = secvec[1] * axis2d[0][2] - secvec[2] * axis2d[0][1];
98  axis2d[1][1] = secvec[2] * axis2d[0][0] - secvec[0] * axis2d[0][2];
99  axis2d[1][2] = secvec[0] * axis2d[0][1] - secvec[1] * axis2d[0][0];
100  norm = 0.0;
101  for (jj = 0; jj < 3; jj++) norm += axis2d[1][jj] * axis2d[1][jj];
102  norm = sqrtf(norm);
103  for (jj = 0; jj < 3; jj++) axis2d[1][jj] /= norm;
104 }/*static void set_2daxis*/
105 /**
106  @brief Judge wheser this line is the edge of 1st BZ (or the premitive BZ)
107 */
109  int nbragg,
110  GLfloat bragg[26][3],
111  GLfloat brnrm[26],
112  GLfloat secvec[3],
113  GLfloat secscale,
114  int jbr, //!< [in] Index of a Bragg plane
115  int nbr, //!< [in]
116  GLfloat vert[3], //!< [inout] start point of line
117  GLfloat vert2[3] //!< [in] end point of line
118 )
119 {
120  int kbr, i, lbr, nbr0;
121  GLfloat bmat[3][3], rhs[3], prod, thr, det;
122  /**/
123  nbr0 = nbr;
124  /**/
125  for (kbr = nbr0; kbr < nbragg; ++kbr) {
126  /**/
127  /**/
128  for (i = 0; i<3; ++i) bmat[0][i] = secvec[i];
129  for (i = 0; i<3; ++i) bmat[1][i] = bragg[jbr][i];
130  for (i = 0; i<3; ++i) bmat[2][i] = bragg[kbr][i];
131  /**/
132  rhs[0] = 0.0;
133  for (i = 0; i < 3; ++i)rhs[0] += secvec[i] * secvec[i];
134  rhs[1] = brnrm[jbr];
135  rhs[2] = brnrm[kbr];
136  thr = sqrtf(rhs[0] * rhs[1] * rhs[2]) * 0.001f;
137  rhs[0] *= secscale;
138  /*
139  if Bragg planes do not cross, roop next kbr
140  */
141  det = solve3(bmat, rhs);
142  if (fabsf(det) < thr) continue;
143  /*
144  if vert0 = vert1, roop next kbr
145  */
146  prod = (vert2[0] - rhs[0]) * (vert2[0] - rhs[0])
147  + (vert2[1] - rhs[1]) * (vert2[1] - rhs[1])
148  + (vert2[2] - rhs[2]) * (vert2[2] - rhs[2]);
149  if (prod < thr) continue;
150  /*
151  is corner really in 1st BZ ?
152  */
153  i = 0;
154  for (lbr = 0; lbr < nbragg; ++lbr) {
155  prod = bragg[lbr][0] * rhs[0]
156  + bragg[lbr][1] * rhs[1]
157  + bragg[lbr][2] * rhs[2];
158  /**/
159  if (prod > brnrm[lbr] + thr) {
160  i = 1;
161  break;
162  }
163  }/*for (lbr = 0; lbr < nbragg; ++lbr)*/
164  if (i == 1) {
165  }
166  else {
167  for (i = 0; i<3; ++i) vert[i] = rhs[i];
168  return kbr + 1;
169  }
170  }/*for (kbr = nbr0; kbr < nbragg; ++kbr)*/
171  /*
172  this line is not a BZ boundary
173  */
174  return 0;
175 }/* bragg_vert2d */
176 /**
177  @brief Compute boundary of 2D BZ
178 
179  Modify : ::nbzl2d, ::bzl2d_proj
180 */
181 void calc_2dbz() {
182  int jbr, nbr, i, j, lvert, ibzl;
183  GLfloat vert[2][3], vec[26][2][3], prod, thr;
184 
185  if (fbz != 1)return;
186  /*
187  Set Projection axis for 2D plane
188  */
190 
191  nbzl2d = 0;
192 
193  for (jbr = 0; jbr < nbragg; ++jbr) {
194  /**/
195  for (i = 0; i < 3; ++i) vert[1][i] = 0.0;
196  nbr = 0;
197  lvert = bragg_vert2d(nbragg, bragg, brnrm, secvec, secscale, jbr, nbr, vert[0], vert[1]);
198  if (lvert == 0) continue;
199  nbr = lvert;
200  /**/
201  lvert = bragg_vert2d(nbragg, bragg, brnrm, secvec, secscale, jbr, nbr, vert[1], vert[0]);
202  if (lvert == 0) continue;
203  /**/
204  for (i = 0; i < 2; ++i) for (j = 0; j < 3; ++j) vec[nbzl2d][i][j] = vert[i][j];
205  nbzl2d += 1;
206  }/*for (jbr = 0; jbr < nbragg; ++jbr)*/
207  /*
208  Order bz lines
209  */
210  for (i = 0; i < 3; i++) bzl2d[0][i] = vec[0][0][i];
211  for (i = 0; i < 3; i++) bzl2d[1][i] = vec[0][1][i];
212  for (ibzl = 0; ibzl < nbzl2d; ibzl++) {
213 
214  thr = 0.0f;
215  for (j = 0; j < 2; j++) for (i = 0; i < 3; i++) thr += bzl2d[j][i] * bzl2d[j][i];
216  thr *= 0.001f;
217 
218  prod = 0.0;
219  for (j = 0; j < 2; j++) for (i = 0; i < 3; i++)
220  prod += (bzl2d[j][i] - vec[ibzl][j][i]) * (bzl2d[j][i] - vec[ibzl][j][i]);
221  if (prod < thr)
222  for (j = 0; j < 2; j++) for (i = 0; i < 3; i++) vec[ibzl][j][i] = 0.0;
223 
224  prod = 0.0;
225  for (j = 0; j < 2; j++) for (i = 0; i < 3; i++)
226  prod += (bzl2d[1 - j][i] - vec[ibzl][j][i]) * (bzl2d[1 - j][i] - vec[ibzl][j][i]);
227  if (prod < thr)
228  for (j = 0; j < 2; j++) for (i = 0; i < 3; i++) vec[ibzl][j][i] = 0.0;
229  }/*for (ibzl = 1; ibzl < *nbzl2d; ibzl++)*/
230 
231  for (jbr = 1; jbr < nbzl2d - 1; jbr++) {
232 
233  thr = 0.0f;
234  for (j = 0; j < 2; j++) for (i = 0; i < 3; i++) thr += bzl2d[jbr][i] * bzl2d[jbr][i];
235  thr *= 0.001f;
236 
237  prod = 0.0;
238  for (ibzl = 0; ibzl < nbzl2d; ibzl++) for (i = 0; i < 3; i++)
239  prod += vec[ibzl][0][i] * vec[ibzl][0][i];
240  if (prod < thr) {
241  nbzl2d = jbr + 1;
242  break;
243  }
244 
245  for (ibzl = 1; ibzl < nbzl2d; ibzl++) {
246  prod = (bzl2d[jbr][0] - vec[ibzl][0][0]) * (bzl2d[jbr][0] - vec[ibzl][0][0])
247  + (bzl2d[jbr][1] - vec[ibzl][0][1]) * (bzl2d[jbr][1] - vec[ibzl][0][1])
248  + (bzl2d[jbr][2] - vec[ibzl][0][2]) * (bzl2d[jbr][2] - vec[ibzl][0][2]);
249  if (prod < thr) {
250  for (i = 0; i < 3; i++) bzl2d[jbr + 1][i] = vec[ibzl][1][i];
251  for (j = 0; j < 2; j++) for (i = 0; i < 3; i++) vec[ibzl][j][i] = 0.0;
252  }
253 
254  prod = (bzl2d[jbr][0] - vec[ibzl][1][0]) * (bzl2d[jbr][0] - vec[ibzl][1][0])
255  + (bzl2d[jbr][1] - vec[ibzl][1][1]) * (bzl2d[jbr][1] - vec[ibzl][1][1])
256  + (bzl2d[jbr][2] - vec[ibzl][1][2]) * (bzl2d[jbr][2] - vec[ibzl][1][2]);
257  if (prod < thr) {
258  for (i = 0; i < 3; i++) bzl2d[jbr + 1][i] = vec[ibzl][0][i];
259  for (j = 0; j < 2; j++) for (i = 0; i < 3; i++) vec[ibzl][j][i] = 0.0;
260  }
261  }/*for (ibzl = 1; ibzl < *nbzl2d; ibzl++)*/
262  }/*for (ibzl = 1; ibzl < nbzl; ibzl++)*/
263  /*
264  Project into 2D plane
265  */
266  for (ibzl = 0; ibzl < nbzl2d; ibzl++) {
267  for (i = 0; i < 3; i++) bzl2d_proj[ibzl][i] = bzl2d[ibzl][i];
268  proj_2d(axis2d, bzl2d_proj[ibzl]);
269  }/*for (ibzl = 0; ibzl < *nbzl2d; ibzl++)*/
270 }/*calc_2dbz()*/
271 /**
272  @brief Compute Fermi-line
273 
274  Modify : ::n2d, ::clr2d, ::kv2d
275 */
276 void calc_section() {
277  int i, j, ib, itri, ithread, n2d0;
278  std::vector<std::vector<std::vector<std::vector<GLfloat> > > > kv2d_v, clr2d_v;
279 
280  kv2d_v.resize(nthreads);
281  clr2d_v.resize(nthreads);
282 
283  if (fbz != 1)return;
284 
285  *terminal << wxT(" band # of Fermi-line\n");
286  for (ib = 0; ib < nb; ib++) {
287 
288 #pragma omp parallel default(none) \
289 shared(nb,ib,clr,clr2d_v,kvp,kv2d_v,ntri,secvec,secscale,axis2d) \
290 private(itri,i,j,ithread)
291  {
292  int sw[3];
293  GLfloat norm[3], a[3][3];
294  std::vector<std::vector<GLfloat> > kv2d_0, clr2d_0;
295 
296  kv2d_0.resize(2);
297  clr2d_0.resize(2);
298  for (i = 0; i < 2; i++) {
299  kv2d_0.at(i).resize(3);
300  clr2d_0.at(i).resize(4);
301  }
302 
303  ithread = get_thread();
304  kv2d_v.at(ithread).resize(0);
305  clr2d_v.at(ithread).resize(0);
306 
307 #pragma omp for
308  for (itri = 0; itri < ntri[ib]; ++itri) {
309  /**/
310  for (i = 0; i < 3; i++) {
311  norm[i] = 0.0;
312  for (j = 0; j < 3; j++) norm[i] += secvec[j] * (kvp[ib][itri][i][j] - secscale * secvec[j]);
313  }
314  eigsort(3, norm, sw);
315  for (i = 0; i < 3; ++i) {
316  for (j = 0; j < 3; ++j) {
317  a[i][j] = (0.0f - norm[sw[j]]) / (norm[sw[i]] - norm[sw[j]]);
318  }/*for (j = 0; j < 3; ++j)*/
319  }/*for (i = 0; i < 3; ++i)*/
320  /**/
321  if ((norm[sw[0]] < 0.0 && 0.0 <= norm[sw[1]]) || (norm[sw[0]] <= 0.0 && 0.0 < norm[sw[1]])) {
322  for (i = 0; i < 3; ++i) {
323  kv2d_0.at(0).at(i)
324  = kvp[ib][itri][sw[1]][i] * a[1][0] + kvp[ib][itri][sw[0]][i] * a[0][1];
325  kv2d_0.at(1).at(i)
326  = kvp[ib][itri][sw[2]][i] * a[2][0] + kvp[ib][itri][sw[0]][i] * a[0][2];
327  }/*for (i = 0; i < 3; ++i)*/
328  for (i = 0; i < 4; ++i) {
329  clr2d_0.at(0).at(i)
330  = clr[ib][i + 4 * sw[1] + 12 * itri] * a[1][0]
331  + clr[ib][i + 4 * sw[0] + 12 * itri] * a[0][1];
332  clr2d_0.at(1).at(i)
333  = clr[ib][i + 4 * sw[2] + 12 * itri] * a[2][0]
334  + clr[ib][i + 4 * sw[0] + 12 * itri] * a[0][2];
335  }/*for (i = 0; i < 4; ++i)*/
336  proj_2d(axis2d, &kv2d_0.at(0).at(0));
337  proj_2d(axis2d, &kv2d_0.at(1).at(0));
338  kv2d_v.at(ithread).push_back(kv2d_0);
339  clr2d_v.at(ithread).push_back(clr2d_0);
340  }/*else if (norm[sw[0]] < 0.0 && 0.0 <= norm[sw[1]])*/
341  else if ((norm[sw[1]] < 0.0 && 0.0 <= norm[sw[2]]) || (norm[sw[1]] <= 0.0 && 0.0 < norm[sw[2]])) {
342  for (i = 0; i < 3; ++i) {
343  kv2d_0.at(0).at(i)
344  = kvp[ib][itri][sw[2]][i] * a[2][0] + kvp[ib][itri][sw[0]][i] * a[0][2];
345  kv2d_0.at(1).at(i)
346  = kvp[ib][itri][sw[2]][i] * a[2][1] + kvp[ib][itri][sw[1]][i] * a[1][2];
347  }/*for (i = 0; i < 3; ++i)*/
348  for (i = 0; i < 4; ++i) {
349  clr2d_0.at(0).at(i)
350  = clr[ib][i + 4 * sw[2] + 12 * itri] * a[2][0]
351  + clr[ib][i + 4 * sw[0] + 12 * itri] * a[0][2];
352  clr2d_0.at(1).at(i)
353  = clr[ib][i + 4 * sw[2] + 12 * itri] * a[2][1]
354  + clr[ib][i + 4 * sw[1] + 12 * itri] * a[1][2];
355  }/*for (i = 0; i < 4; ++i)*/
356  proj_2d(axis2d, &kv2d_0.at(0).at(0));
357  proj_2d(axis2d, &kv2d_0.at(1).at(0));
358  kv2d_v.at(ithread).push_back(kv2d_0);
359  clr2d_v.at(ithread).push_back(clr2d_0);
360  }/*else if (norm[sw[1]] < 0.0 && 0.0 <= norm[sw[2]])*/
361  }/*for (itri = 0; itri < ntri[ib]; ++itri)*/
362  }/* End of parallel region */
363  /*
364  Allocation of Fermi-lines
365  */
366  n2d[ib] = 0;
367  for (ithread = 0; ithread < nthreads; ithread++)
368  n2d[ib] += kv2d_v.at(ithread).size();
369 
370  *terminal << wxString::Format(wxT(" %d %d\n"), ib + 1, n2d[ib]);
371  kv2d[ib] = new GLfloat[6 * n2d[ib]];
372  clr2d[ib] = new GLfloat[8 * n2d[ib]];
373 
374  n2d0 = 0;
375  for (ithread = 0; ithread < nthreads; ithread++) {
376  for (itri = 0; itri < kv2d_v.at(ithread).size(); itri++) {
377  for (i = 0; i < 2; i++) {
378  for (j = 0; j < 3; j++) {
379  kv2d[ib][j + i * 3 + 6 * n2d0] = kv2d_v.at(ithread).at(itri).at(i).at(j);
380  }
381  for (j = 0; j < 3; j++) {
382  clr2d[ib][j + i * 4 + 8 * n2d0] = clr2d_v.at(ithread).at(itri).at(i).at(j);
383  }
384  }
385  n2d0 += 1;
386  }
387  }
388  }/*for (ib = 0; ib < nb; ib++)*/
389 }/*void calc_nodeline()*/
secvec
GLfloat secvec[3]
-vector to define section
Definition: fermisurfer.cpp:160
kvp
GLfloat **** kvp
-vectors of points [nb][ntri][3][3]
Definition: fermisurfer.cpp:140
get_thread
int get_thread()
OpenMP wrapper, get the number of threads.
Definition: basic_math.cpp:139
n2d
int * n2d
Number of line segment.
Definition: fermisurfer.cpp:164
bragg_vert2d
int bragg_vert2d(int nbragg, GLfloat bragg[26][3], GLfloat brnrm[26], GLfloat secvec[3], GLfloat secscale, int jbr, int nbr, GLfloat vert[3], GLfloat vert2[3])
Judge wheser this line is the edge of 1st BZ (or the premitive BZ)
Definition: section.cpp:108
ntri
int * ntri
The number of triangle patch [nb].
Definition: fermisurfer.cpp:136
kv2d
GLfloat ** kv2d
-vector for 2D plot [nb][n2d*2*3]
Definition: fermisurfer.cpp:165
eigsort
void eigsort(int n, GLfloat *key, int *swap)
Simple sort.
Definition: basic_math.cpp:88
proj_2d
static void proj_2d(GLfloat axis2d[2][3], GLfloat vec[3])
Project 3D -vector into 2D plane.
Definition: section.cpp:48
axis2d
GLfloat axis2d[2][3]
-vector to define section
Definition: fermisurfer.cpp:163
solve3
GLfloat solve3(GLfloat a[3][3], GLfloat b[3])
Solve linear system.
Definition: basic_math.cpp:58
basic_math.hpp
variable.hpp
Global variables.
bragg
GLfloat bragg[26][3]
Bragg plane vectors.
Definition: fermisurfer.cpp:129
calc_section
void calc_section()
Compute Fermi-line.
Definition: section.cpp:276
clr
GLfloat ** clr
Colors of points [nb][ntri*3*4].
Definition: fermisurfer.cpp:146
fbz
int fbz
Switch for 1st Brillouin zone mode.
Definition: fermisurfer.cpp:116
bzl2d
GLfloat bzl2d[26][3]
Lines of 1st BZ [nbzl2d (max:26)][3].
Definition: fermisurfer.cpp:168
nbzl2d
int nbzl2d
The number of Lines of 1st Brillouin zone.
Definition: fermisurfer.cpp:167
nb
int nb
The number of Bands.
Definition: fermisurfer.cpp:99
bzl2d_proj
GLfloat bzl2d_proj[26][3]
Lines of 1st BZ [nbzl2d (max:26)][3], projected into 2D plane.
Definition: fermisurfer.cpp:169
brnrm
GLfloat brnrm[26]
Norms of Bragg plane vectors.
Definition: fermisurfer.cpp:130
clr2d
GLfloat ** clr2d
Matrix element for 2D plot [nb][n2d*2*4].
Definition: fermisurfer.cpp:166
calc_2dbz
void calc_2dbz()
Compute boundary of 2D BZ.
Definition: section.cpp:181
set2daxis
static void set2daxis(GLfloat secvec[3], GLfloat axis2d[2][3])
Set Projection axis for 2D plane.
Definition: section.cpp:69
secscale
GLfloat secscale
0.0 (across ) or 1.0
Definition: fermisurfer.cpp:162
terminal
wxTextCtrl * terminal
Definition: fermisurfer.cpp:237
nthreads
int nthreads
Number of OpenMP threads.
Definition: fermisurfer.cpp:227
nbragg
int nbragg
Number of Bragg plane og 1st BZ.
Definition: fermisurfer.cpp:132