1use crate::Model;
11use crate::model::Dimension;
12use crate::error::{Result, TbError};
13use crate::kpoints::gen_kmesh;
14use crate::kpath::*;
15use gnuplot::Major;
16use gnuplot::{Auto, AutoOption::Fix, AxesCommon, Custom, Figure, Font, HOT, RAINBOW};
17use ndarray::concatenate;
18use ndarray::linalg::kron;
19use ndarray::prelude::*;
20use ndarray::*;
21use ndarray_linalg::conjugate;
22use ndarray_linalg::*;
23use num_complex::Complex;
24use rayon::prelude::*;
25use std::f64::consts::PI;
26use std::fs::File;
27use std::io::Write;
28use std::ops::AddAssign;
29use std::ops::MulAssign;
30use std::time::Instant;
31
32#[derive(Clone, Debug)]
34pub struct surf_Green {
35 pub dim_r: usize,
37 pub norb: usize,
39 pub nsta: usize,
41 pub natom: usize,
43 pub spin: bool,
45 pub lat: Array2<f64>,
47 pub orb: Array2<f64>,
49 pub atom: Array2<f64>,
51 pub atom_list: Vec<usize>,
53 pub eta: f64,
55 pub ham_bulk: Array3<Complex<f64>>,
56 pub ham_bulkR: Array2<isize>,
58 pub ham_hop: Array3<Complex<f64>>,
60 pub ham_hopR: Array2<isize>,
61}
62
63#[inline(always)]
64fn remove_row<T: Copy>(array: Array2<T>, row_to_remove: usize) -> Array2<T> {
65 let indices: Vec<_> = (0..array.nrows()).filter(|&r| r != row_to_remove).collect();
66 array.select(Axis(0), &indices)
67}
68#[inline(always)]
69fn remove_col<T: Copy>(array: Array2<T>, col_to_remove: usize) -> Array2<T> {
70 let indices: Vec<_> = (0..array.ncols()).filter(|&r| r != col_to_remove).collect();
71 array.select(Axis(1), &indices)
72}
73
74impl Kpath for surf_Green{
75 fn k_path(
76 &self,
77 path: &Array2<f64>,
78 nk: usize,
79 ) -> Result<(Array2<f64>, Array1<f64>, Array1<f64>)> {
80 if self.dim_r == 0 {
82 return Err(TbError::ZeroDimKPathError);
83 }
84 let n_node: usize = path.len_of(Axis(0));
85 if self.dim_r != path.len_of(Axis(1)) {
86 return Err(TbError::PathLengthMismatch {
87 expected: self.dim_r,
88 actual: path.len_of(Axis(1)),
89 });
90 }
91 let k_metric = (self.lat.dot(&self.lat.t())).inv().unwrap();
92 let mut k_node = Array1::<f64>::zeros(n_node);
93 for n in 1..n_node {
94 let dk = &path.row(n) - &path.row(n - 1);
95 let a = k_metric.dot(&dk);
96 let dklen = dk.dot(&a).sqrt();
97 k_node[[n]] = k_node[[n - 1]] + dklen;
98 }
99 let mut node_index: Vec<usize> = vec![0];
100 for n in 1..n_node - 1 {
101 let frac = k_node[[n]] / k_node[[n_node - 1]];
102 let a = (frac * ((nk - 1) as f64).round()) as usize;
103 node_index.push(a)
104 }
105 node_index.push(nk - 1);
106 let mut k_dist = Array1::<f64>::zeros(nk);
107 let mut k_vec = Array2::<f64>::zeros((nk, self.dim_r));
108 k_vec.row_mut(0).assign(&path.row(0));
110 for n in 1..n_node {
111 let n_i = node_index[n - 1];
112 let n_f = node_index[n];
113 let kd_i = k_node[[n - 1]];
114 let kd_f = k_node[[n]];
115 let k_i = path.row(n - 1);
116 let k_f = path.row(n);
117 for j in n_i..n_f + 1 {
118 let frac: f64 = ((j - n_i) as f64) / ((n_f - n_i) as f64);
119 k_dist[[j]] = kd_i + frac * (kd_f - kd_i);
120 k_vec
121 .row_mut(j)
122 .assign(&((1.0 - frac) * &k_i + frac * &k_f));
123 }
124 }
125 Ok((k_vec, k_dist, k_node))
126 }
127}
128
129impl surf_Green {
130 pub fn from_Model(
138 model: &Model,
139 dir: usize,
140 eta: f64,
141 Np: Option<usize>,
142 ) -> Result<surf_Green> {
143 if dir >= model.dim_r as usize {
144 return Err(TbError::InvalidDirection {
145 index: dir,
146 dim: model.dim_r as usize,
147 });
148 }
149 let mut R_max: usize = 0;
150 for R0 in model.hamR.rows() {
151 if R_max < R0[[dir]].abs() as usize {
152 R_max = R0[[dir]].abs() as usize;
153 }
154 }
155 let R_max = match Np {
156 Some(np) => {
157 if R_max > np {
158 np
159 } else {
160 R_max
161 }
162 }
163 None => R_max,
164 };
165
166 let mut U = Array2::<f64>::eye(model.dim_r as usize);
167 U[[dir, dir]] = R_max as f64;
168 let model = model.make_supercell(&U)?;
169 let mut ham0 = Array3::<Complex<f64>>::zeros((0, model.nsta(), model.nsta()));
170 let mut hamR0 = Array2::<isize>::zeros((0, model.dim_r as usize));
171 let mut hamR = Array3::<Complex<f64>>::zeros((0, model.nsta(), model.nsta()));
172 let mut hamRR = Array2::<isize>::zeros((0, model.dim_r as usize));
173 let use_hamR = model.hamR.rows();
174 let use_ham = model.ham.outer_iter();
175 for (ham, R) in use_ham.zip(use_hamR) {
176 let ham = ham.clone();
177 let R = R.clone();
178 if R[[dir]] == 0 {
179 ham0.push(Axis(0), ham.view());
180 hamR0.push_row(R.view());
181 } else if R[[dir]] > 0 {
182 hamR.push(Axis(0), ham.view());
183 hamRR.push_row(R.view());
184 }
185 }
186 let new_lat = remove_row(model.lat.clone(), dir);
187 let new_lat = remove_col(new_lat.clone(), dir);
188 let new_orb = remove_col(model.orb.clone(), dir);
189 let new_atom = remove_col(model.atom_position(), dir);
190 let new_hamR0 = remove_col(hamR0, dir);
191 let new_hamRR = remove_col(hamRR, dir);
192 let green: surf_Green = surf_Green {
193 dim_r: model.dim_r as usize - 1,
194 norb: model.norb(),
195 nsta: model.nsta(),
196 natom: model.natom(),
197 spin: model.spin,
198 lat: new_lat,
199 orb: new_orb,
200 atom: new_atom,
201 atom_list: model.atom_list(),
202 ham_bulk: ham0,
203 ham_bulkR: new_hamR0,
204 ham_hop: hamR,
205 ham_hopR: new_hamRR,
206 eta,
207 };
208 Ok(green)
209 }
210
211 #[inline(always)]
212 pub fn gen_ham_onek<S: Data<Elem = f64>>(
213 &self,
214 kvec: &ArrayBase<S, Ix1>,
215 ) -> (Array2<Complex<f64>>, Array2<Complex<f64>>) {
216 let mut ham0k = Array2::<Complex<f64>>::zeros((self.nsta, self.nsta));
217 let mut hamRk = Array2::<Complex<f64>>::zeros((self.nsta, self.nsta));
218 if kvec.len() != self.dim_r {
219 panic!("Wrong, the k-vector's length must equal to the dimension of model.")
220 }
221 let nR: usize = self.ham_bulkR.len_of(Axis(0));
222 let nRR: usize = self.ham_hopR.len_of(Axis(0));
223 let U0: Array1<f64> = self.orb.dot(kvec);
224 let U0: Array1<Complex<f64>> = U0.map(|x| Complex::<f64>::new(0.0, 2.0 * PI * *x));
225 let U0: Array1<Complex<f64>> = U0.mapv(Complex::exp); let U0 = if self.spin {
227 let U0 = concatenate![Axis(0), U0, U0];
228 U0
229 } else {
230 U0
231 };
232 let U: Array2<Complex<f64>> = Array2::from_diag(&U0);
233 let U_conj = Array2::from_diag(&U0.map(|x| x.conj()));
234 let U0 = (self.ham_bulkR.map(|x| *x as f64))
236 .dot(kvec)
237 .map(|x| Complex::<f64>::new(0.0, *x * 2.0 * PI).exp());
238 let UR = (self.ham_hopR.map(|x| *x as f64))
240 .dot(kvec)
241 .map(|x| Complex::<f64>::new(0.0, *x * 2.0 * PI).exp());
242 let ham0k = self
243 .ham_bulk
244 .outer_iter()
245 .zip(U0.iter())
246 .fold(Array2::zeros((self.nsta, self.nsta)), |acc, (ham, u)| {
247 acc + &ham * *u
248 });
249 let hamRk = self
250 .ham_hop
251 .outer_iter()
252 .zip(UR.iter())
253 .fold(Array2::zeros((self.nsta, self.nsta)), |acc, (ham, u)| {
254 acc + &ham * *u
255 });
256 let ham0k = ham0k.dot(&U);
270 let ham0k = U_conj.dot(&ham0k);
271 let hamRk = hamRk.dot(&U);
272 let hamRk = U_conj.dot(&hamRk);
273 (ham0k, hamRk)
274 }
275 #[inline(always)]
276 pub fn surf_green_one<S: Data<Elem = f64>>(
277 &self,
278 kvec: &ArrayBase<S, Ix1>,
279 Energy: f64,
280 ) -> (f64, f64, f64) {
281 let (hamk, hamRk) = self.gen_ham_onek(kvec);
282 let hamRk_conj: Array2<Complex<f64>> =
283 conjugate::<Complex<f64>, OwnedRepr<Complex<f64>>>(&hamRk);
284 let I0 = Array2::<Complex<f64>>::eye(self.nsta);
285 let accurate: f64 = 1e-8;
286 let epsilon = Complex::new(Energy, self.eta) * &I0;
287 let mut epi = hamk.clone();
288 let mut eps = hamk.clone();
289 let mut eps_t = hamk.clone();
290 let mut ap = hamRk.clone();
291 let mut bt = hamRk_conj.clone();
292
293 for _ in 0..10 {
294 let g0 = (&epsilon - &epi).inv().unwrap();
295 let mat_1 = &ap.dot(&g0);
296 let mat_2 = &bt.dot(&g0);
297 let g0 = &mat_1.dot(&bt);
298 epi = epi + g0;
299 eps = eps + g0;
300 let g0 = &mat_2.dot(&ap);
301 epi = epi + g0;
302 eps_t = eps_t + g0;
303 ap = mat_1.dot(&ap);
304 bt = mat_2.dot(&bt);
305 if ap.sum().norm() < accurate {
306 break;
307 }
308 }
309 let g_LL = (&epsilon - eps).inv().unwrap();
310 let g_RR = (&epsilon - eps_t).inv().unwrap();
311 let g_B = (&epsilon - epi).inv().unwrap();
312 let N_R: f64 = -1.0 / (PI) * g_RR.into_diag().sum().im;
313 let N_L: f64 = -1.0 / (PI) * g_LL.into_diag().sum().im;
314 let N_B: f64 = -1.0 / (PI) * g_B.into_diag().sum().im;
315 (N_R, N_L, N_B)
316 }
317
318 #[inline(always)]
319 pub fn surf_green_onek<S: Data<Elem = f64>>(
320 &self,
321 kvec: &ArrayBase<S, Ix1>,
322 Energy: &Array1<f64>,
323 ) -> (Array1<f64>, Array1<f64>, Array1<f64>) {
324 let (hamk, hamRk) = self.gen_ham_onek(kvec);
325 let hamRk_conj: Array2<Complex<f64>> =
326 conjugate::<Complex<f64>, OwnedRepr<Complex<f64>>>(&hamRk);
327 let I0 = Array2::<Complex<f64>>::eye(self.nsta);
328 let accurate: f64 = 1e-6;
329 let ((N_R, N_L), N_B): ((Vec<_>, Vec<_>), Vec<_>) = Energy
330 .map(|e| {
331 let epsilon = Complex::new(*e, self.eta) * &I0;
332 let mut epi = hamk.clone();
333 let mut eps = hamk.clone();
334 let mut eps_t = hamk.clone();
335 let mut ap = hamRk.clone();
336 let mut bt = hamRk_conj.clone();
337 for _ in 0..10 {
338 let g0 = (&epsilon - &epi).inv().unwrap();
339 let mat_1 = &ap.dot(&g0);
340 let mat_2 = &bt.dot(&g0);
341 let g0 = &mat_1.dot(&bt);
342 epi += g0;
343 eps += g0;
344 let g0 = &mat_2.dot(&ap);
345 epi += g0;
346 eps_t += g0;
347 ap = mat_1.dot(&ap);
348 bt = mat_2.dot(&bt);
349 if ap.map(|x| x.norm()).sum() < accurate {
350 break;
351 }
352 }
353 let g_LL = (&epsilon - eps).inv().unwrap();
354 let g_RR = (&epsilon - eps_t).inv().unwrap();
355 let g_B = (&epsilon - epi).inv().unwrap();
356 let N_R: f64 = -1.0 / (PI) * g_RR.into_diag().sum().im;
358 let N_L: f64 = -1.0 / (PI) * g_LL.into_diag().sum().im;
359 let N_B: f64 = -1.0 / (PI) * g_B.into_diag().sum().im;
360 ((N_R, N_L), N_B)
361 })
362 .into_iter()
363 .unzip();
364 let N_R = Array1::from_vec(N_R);
365 let N_L = Array1::from_vec(N_L);
366 let N_B = Array1::from_vec(N_B);
367 (N_R, N_L, N_B)
368 }
369
370 pub fn surf_green_path(
371 &self,
372 kvec: &Array2<f64>,
373 E_min: f64,
374 E_max: f64,
375 E_n: usize,
376 spin: usize,
377 ) -> (Array2<f64>, Array2<f64>, Array2<f64>) {
378 let Energy = Array1::<f64>::linspace(E_min, E_max, E_n);
379 let nk = kvec.nrows();
380 let mut N_R = Array2::<f64>::zeros((nk, E_n));
381 let mut N_L = Array2::<f64>::zeros((nk, E_n));
382 let mut N_B = Array2::<f64>::zeros((nk, E_n));
383 Zip::from(N_R.outer_iter_mut())
384 .and(N_L.outer_iter_mut())
385 .and(N_B.outer_iter_mut())
386 .and(kvec.outer_iter())
387 .par_for_each(|mut nr, mut nl, mut nb, k| {
388 let (NR, NL, NB) = self.surf_green_onek(&k, &Energy);
389 nr.assign(&NR);
390 nl.assign(&NL);
391 nb.assign(&NB);
392 });
393 (N_L, N_R, N_B)
394 }
395
396 pub fn show_arc_state(&self, name: &str, kmesh: &Array1<usize>, energy: f64, spin: usize) {
397 use std::fs::create_dir_all;
398 use std::io::{BufWriter, Write};
399 create_dir_all(name).expect("can't creat the file");
400 assert_eq!(
401 kmesh.len(),
402 2,
403 "show_arc_state can only calculated the three dimension system, so the kmesh need to be [m,n], but you give {}",
404 kmesh
405 );
406 let kvec = gen_kmesh(kmesh).expect("Failed to generate k-mesh");
407 let nk = kvec.nrows();
408 let mut N_R = Array1::<f64>::zeros(nk);
409 let mut N_L = Array1::<f64>::zeros(nk);
410 let mut N_B = Array1::<f64>::zeros(nk);
411 Zip::from(N_R.view_mut())
412 .and(N_L.view_mut())
413 .and(N_B.view_mut())
414 .and(kvec.outer_iter())
415 .par_for_each(|mut nr, mut nl, mut nb, k| {
416 let (NR, NL, NB) = self.surf_green_one(&k, energy);
417 *nr = NR;
418 *nl = NL;
419 *nb = NB;
420 });
421 let K = 2.0 * PI * self.lat.inv().unwrap().reversed_axes();
422 let kvec_real = kvec.dot(&K);
423 let mut file_name = String::new();
424 file_name.push_str(&name);
425 file_name.push_str("/arc.dat");
426 let mut file = File::create(file_name).expect("Uable to create arc.dat");
427 writeln!(file, r"# nk1, nk2, N_L, N_R, N_B");
428 let mut writer = BufWriter::new(file);
429 let mut s = String::new();
430 for i in 0..nk {
431 let aa = format!("{:.6}", kvec_real[[i, 0]]);
432 s.push_str(&aa);
433 let bb: String = format!("{:.6}", kvec_real[[i, 1]]);
434 if kvec_real[[i, 1]] >= 0.0 {
435 s.push_str(" ");
436 } else {
437 s.push_str(" ");
438 }
439 s.push_str(&bb);
440 let cc: String = format!("{:.6}", N_L[[i]]);
441 if N_L[[i]] >= 0.0 {
442 s.push_str(" ");
443 } else {
444 s.push_str(" ");
445 }
446 s.push_str(&cc);
447 let cc: String = format!("{:.6}", N_R[[i]]);
448 if N_R[[i]] >= 0.0 {
449 s.push_str(" ");
450 } else {
451 s.push_str(" ");
452 }
453 let cc: String = format!("{:.6}", N_B[[i]]);
454 if N_B[[i]] >= 0.0 {
455 s.push_str(" ");
456 } else {
457 s.push_str(" ");
458 }
459 s.push_str(&cc);
460 s.push_str("\n");
461 }
462 writer.write_all(s.as_bytes()).unwrap();
463 let _ = file;
464
465 let width: usize = kmesh[[0]];
466 let height: usize = kmesh[[1]];
467
468 let N_L: Array2<f64> =
469 Array2::from_shape_vec((height, width), N_L.to_vec()).expect("Shape error");
470 let N_L = N_L.reversed_axes(); let N_L = N_L.iter().cloned().collect::<Vec<f64>>();
472 let N_R: Array2<f64> =
473 Array2::from_shape_vec((height, width), N_R.to_vec()).expect("Shape error");
474 let N_R = N_R.reversed_axes(); let N_R = N_R.iter().cloned().collect::<Vec<f64>>();
476 let N_B: Array2<f64> =
477 Array2::from_shape_vec((height, width), N_B.to_vec()).expect("Shape error");
478 let N_B = N_B.reversed_axes(); let N_B = N_B.iter().cloned().collect::<Vec<f64>>();
480
481 let mut fg = Figure::new();
483 let mut heatmap_data = N_L;
484 let axes = fg.axes2d();
485 axes.set_palette(Custom(&[
487 (-1.0, 0.0, 0.0, 0.0),
488 (-0.9, 65.0 / 255.0, 9.0 / 255.0, 103.0 / 255.0),
489 (0.0, 147.0 / 255.0, 37.0 / 255.0, 103.0 / 255.0),
490 (0.2, 220.0 / 255.0, 80.0 / 255.0, 57.0 / 255.0),
491 (1.0, 252.0 / 255.0, 254.0 / 255.0, 164.0 / 255.0),
492 ]));
493 axes.image(
494 heatmap_data.iter(),
495 width,
496 height,
497 Some((0.0, 0.0, 1.0, 1.0)),
498 &[],
499 );
500 let axes = axes.set_x_range(Fix(0.0), Fix(1.0));
501 let axes = axes.set_y_range(Fix(0.0), Fix(1.0));
502 let axes = axes.set_aspect_ratio(Fix(1.0));
503 axes.set_x_ticks(Some((Auto, 0)), &[], &[Font("Times New Roman", 24.0)]);
504 axes.set_y_ticks(Some((Auto, 0)), &[], &[Font("Times New Roman", 24.0)]);
505 axes.set_cb_ticks_custom(
506 [
507 Major(-10.0, Fix("low")),
508 Major(0.0, Fix("0")),
509 Major(10.0, Fix("high")),
510 ]
511 .into_iter(),
512 &[],
513 &[Font("Times New Roman", 24.0)],
514 );
515 let mut pdfname = String::new();
516 pdfname.push_str(&name.clone());
517 pdfname.push_str("/surf_state_l.pdf");
518 fg.set_terminal("pdfcairo", &pdfname);
519 fg.show().expect("Unable to draw heatmap");
520 let _ = fg;
521
522 let mut fg = Figure::new();
523 let mut heatmap_data = N_R;
524 let axes = fg.axes2d();
525 axes.set_palette(Custom(&[
527 (-1.0, 0.0, 0.0, 0.0),
528 (-0.9, 65.0 / 255.0, 9.0 / 255.0, 103.0 / 255.0),
529 (0.0, 147.0 / 255.0, 37.0 / 255.0, 103.0 / 255.0),
530 (0.2, 220.0 / 255.0, 80.0 / 255.0, 57.0 / 255.0),
531 (1.0, 252.0 / 255.0, 254.0 / 255.0, 164.0 / 255.0),
532 ]));
533 axes.image(
534 heatmap_data.iter(),
535 width,
536 height,
537 Some((0.0, 0.0, 1.0, 1.0)),
538 &[],
539 );
540 let axes = axes.set_x_range(Fix(0.0), Fix(1.0));
541 let axes = axes.set_y_range(Fix(0.0), Fix(1.0));
542 let axes = axes.set_aspect_ratio(Fix(1.0));
543 axes.set_x_ticks(Some((Auto, 0)), &[], &[Font("Times New Roman", 24.0)]);
544 axes.set_y_ticks(Some((Auto, 0)), &[], &[Font("Times New Roman", 24.0)]);
545 axes.set_cb_ticks_custom(
546 [
547 Major(-10.0, Fix("low")),
548 Major(0.0, Fix("0")),
549 Major(10.0, Fix("high")),
550 ]
551 .into_iter(),
552 &[],
553 &[Font("Times New Roman", 24.0)],
554 );
555 let mut pdfname = String::new();
556 pdfname.push_str(&name.clone());
557 pdfname.push_str("/surf_state_r.pdf");
558 fg.set_terminal("pdfcairo", &pdfname);
559 fg.show().expect("Unable to draw heatmap");
560 let _ = fg;
561
562 let mut fg = Figure::new();
563 let mut heatmap_data = N_B;
564 let axes = fg.axes2d();
565 axes.set_palette(Custom(&[
567 (-1.0, 0.0, 0.0, 0.0),
568 (-0.9, 65.0 / 255.0, 9.0 / 255.0, 103.0 / 255.0),
569 (0.0, 147.0 / 255.0, 37.0 / 255.0, 103.0 / 255.0),
570 (0.2, 220.0 / 255.0, 80.0 / 255.0, 57.0 / 255.0),
571 (1.0, 252.0 / 255.0, 254.0 / 255.0, 164.0 / 255.0),
572 ]));
573 axes.image(
574 heatmap_data.iter(),
575 width,
576 height,
577 Some((0.0, 0.0, 1.0, 1.0)),
578 &[],
579 );
580 let axes = axes.set_x_range(Fix(0.0), Fix(1.0));
581 let axes = axes.set_y_range(Fix(0.0), Fix(1.0));
582 let axes = axes.set_aspect_ratio(Fix(1.0));
583 axes.set_x_ticks(Some((Auto, 0)), &[], &[Font("Times New Roman", 24.0)]);
584 axes.set_y_ticks(Some((Auto, 0)), &[], &[Font("Times New Roman", 24.0)]);
585 axes.set_cb_ticks_custom(
586 [
587 Major(-10.0, Fix("low")),
588 Major(0.0, Fix("0")),
589 Major(10.0, Fix("high")),
590 ]
591 .into_iter(),
592 &[],
593 &[Font("Times New Roman", 24.0)],
594 );
595 let mut pdfname = String::new();
596 pdfname.push_str(&name.clone());
597 pdfname.push_str("/surf_state_b.pdf");
598 fg.set_terminal("pdfcairo", &pdfname);
599 fg.show().expect("Unable to draw heatmap");
600 let _ = fg;
601 }
602 pub fn show_surf_state(
603 &self,
604 name: &str,
605 kpath: &Array2<f64>,
606 label: &Vec<&str>,
607 nk: usize,
608 E_min: f64,
609 E_max: f64,
610 E_n: usize,
611 spin: usize,
612 ) {
613 use std::fs::create_dir_all;
614 use std::io::{BufWriter, Write};
615 create_dir_all(name).expect("can't creat the file");
616 let (kvec, kdist, knode) = self.k_path(kpath, nk).expect("Failed to generate k-path");
617 let Energy = Array1::<f64>::linspace(E_min, E_max, E_n);
618 let (N_L, N_R, N_B) = self.surf_green_path(&kvec, E_min, E_max, E_n, spin);
619 let ((N_L, N_R), N_B) = if spin == 0 {
623 let N_L = N_L.mapv(|x| x.ln());
624 let N_R = N_R.mapv(|x| x.ln());
625 let N_B = N_B.mapv(|x| x.ln());
626 let max = N_L.iter().fold(f64::NEG_INFINITY, |acc, &x| acc.max(x));
627 let min = N_L.iter().fold(f64::INFINITY, |acc, &x| acc.min(x));
628 let N_L = (N_L - min) / (max - min) * 20.0 - 10.0;
629 let max = N_R.iter().fold(f64::NEG_INFINITY, |acc, &x| acc.max(x));
630 let min = N_R.iter().fold(f64::INFINITY, |acc, &x| acc.min(x));
631 let N_R = (N_R - min) / (max - min) * 20.0 - 10.0;
632 let max = N_B.iter().fold(f64::NEG_INFINITY, |acc, &x| acc.max(x));
633 let min = N_B.iter().fold(f64::INFINITY, |acc, &x| acc.min(x));
634 let N_B = (N_B - min) / (max - min) * 20.0 - 10.0;
635 ((N_L, N_R), N_B)
636 } else {
637 ((N_L, N_R), N_B)
638 };
639
640 let mut left_name: String = String::new();
642 left_name.push_str(&name.clone());
643 left_name.push_str("/dos.surf_l");
644 let mut file = File::create(left_name).expect("Unable to dos.surf_l.dat");
645 let mut writer = BufWriter::new(file);
646 let mut s = String::new();
647 for i in 0..nk {
648 for j in 0..E_n {
649 let aa = format!("{:.6}", kdist[[i]]);
650 s.push_str(&aa);
651 let bb: String = format!("{:.6}", Energy[[j]]);
652 if Energy[[j]] >= 0.0 {
653 s.push_str(" ");
654 } else {
655 s.push_str(" ");
656 }
657 s.push_str(&bb);
658 let cc: String = format!("{:.6}", N_L[[i, j]]);
659 if N_L[[i, j]] >= 0.0 {
660 s.push_str(" ");
661 } else {
662 s.push_str(" ");
663 }
664 s.push_str(&cc);
665 s.push_str(" ");
666 s.push_str("\n");
668 }
669 s.push_str("\n");
670 }
672 writer.write_all(s.as_bytes()).unwrap();
673 let _ = file;
674
675 let mut left_name: String = String::new();
677 left_name.push_str(&name.clone());
678 left_name.push_str("/dos.surf_r");
679 let mut file = File::create(left_name).expect("Unable to dos.surf_l.dat");
680 let mut writer = BufWriter::new(file);
681 let mut s = String::new();
682 for i in 0..nk {
683 for j in 0..E_n {
684 let aa = format!("{:.6}", kdist[[i]]);
685 s.push_str(&aa);
686 let bb: String = format!("{:.6}", Energy[[j]]);
687 if Energy[[j]] >= 0.0 {
688 s.push_str(" ");
689 } else {
690 s.push_str(" ");
691 }
692 s.push_str(&bb);
693 let cc: String = format!("{:.6}", N_R[[i, j]]);
694 if N_L[[i, j]] >= 0.0 {
695 s.push_str(" ");
696 } else {
697 s.push_str(" ");
698 }
699 s.push_str(&cc);
700 s.push_str(" ");
701 s.push_str("\n");
703 }
704 s.push_str("\n");
705 }
707 writer.write_all(s.as_bytes()).unwrap();
708 let _ = file;
709
710 let mut left_name: String = String::new();
712 left_name.push_str(&name.clone());
713 left_name.push_str("/dos.surf_bulk");
714 let mut file = File::create(left_name).expect("Unable to dos.surf_l.dat");
715 let mut writer = BufWriter::new(file);
716 let mut s = String::new();
717 for i in 0..nk {
718 for j in 0..E_n {
719 let aa = format!("{:.6}", kdist[[i]]);
720 s.push_str(&aa);
721 let bb: String = format!("{:.6}", Energy[[j]]);
722 if Energy[[j]] >= 0.0 {
723 s.push_str(" ");
724 } else {
725 s.push_str(" ");
726 }
727 s.push_str(&bb);
728 let cc: String = format!("{:.6}", N_B[[i, j]]);
729 if N_L[[i, j]] >= 0.0 {
730 s.push_str(" ");
731 } else {
732 s.push_str(" ");
733 }
734 s.push_str(&cc);
735 s.push_str(" ");
736 s.push_str("\n");
738 }
739 s.push_str("\n");
740 }
742 writer.write_all(s.as_bytes()).unwrap();
743 let _ = file;
744
745 let mut fg = Figure::new();
747 let width: usize = nk;
748 let height: usize = E_n;
749 let mut heatmap_data = vec![];
750 for i in 0..height {
751 for j in 0..width {
752 heatmap_data.push(N_L[[j, i]]);
753 }
754 }
755 let axes = fg.axes2d();
756 axes.set_palette(Custom(&[
758 (-1.0, 0.0, 0.0, 0.0),
759 (-0.9, 65.0 / 255.0, 9.0 / 255.0, 103.0 / 255.0),
760 (0.0, 147.0 / 255.0, 37.0 / 255.0, 103.0 / 255.0),
761 (0.2, 220.0 / 255.0, 80.0 / 255.0, 57.0 / 255.0),
762 (1.0, 252.0 / 255.0, 254.0 / 255.0, 164.0 / 255.0),
763 ]));
764 axes.image(
765 heatmap_data.iter(),
766 width,
767 height,
768 Some((kdist[[0]], E_min, kdist[[nk - 1]], E_max)),
769 &[],
770 );
771 let axes = axes.set_y_range(Fix(E_min), Fix(E_max));
772 let axes = axes.set_x_range(Fix(kdist[[0]]), Fix(kdist[[nk - 1]]));
773 let axes = axes.set_aspect_ratio(Fix(1.0));
774 let mut show_ticks = Vec::new();
775 for i in 0..knode.len() {
776 let A = knode[[i]];
777 let B = label[i];
778 show_ticks.push(Major(A, Fix(B)));
779 }
780 axes.set_x_ticks_custom(
781 show_ticks.into_iter(),
782 &[],
783 &[Font("Times New Roman", 24.0)],
784 );
785 axes.set_y_ticks(Some((Auto, 0)), &[], &[Font("Times New Roman", 24.0)]);
786 axes.set_cb_ticks_custom(
788 [
789 Major(-10.0, Fix("low")),
790 Major(0.0, Fix("0")),
791 Major(10.0, Fix("high")),
792 ]
793 .into_iter(),
794 &[],
795 &[Font("Times New Roman", 24.0)],
796 );
797 let mut pdfname = String::new();
798 pdfname.push_str(&name.clone());
799 pdfname.push_str("/surf_state_l.pdf");
800 fg.set_terminal("pdfcairo", &pdfname);
801 fg.show().expect("Unable to draw heatmap");
802 let _ = fg;
803
804 let mut fg = Figure::new();
806 let width: usize = nk;
807 let height: usize = E_n;
808 let mut heatmap_data = vec![];
809 for i in 0..height {
810 for j in 0..width {
811 heatmap_data.push(N_R[[j, i]]);
812 }
813 }
814 let axes = fg.axes2d();
815 axes.set_palette(Custom(&[
817 (-1.0, 0.0, 0.0, 0.0),
818 (-0.9, 65.0 / 255.0, 9.0 / 255.0, 103.0 / 255.0),
819 (0.0, 147.0 / 255.0, 37.0 / 255.0, 103.0 / 255.0),
820 (0.2, 220.0 / 255.0, 80.0 / 255.0, 57.0 / 255.0),
821 (1.0, 252.0 / 255.0, 254.0 / 255.0, 164.0 / 255.0),
822 ]));
823 axes.image(
824 heatmap_data.iter(),
825 width,
826 height,
827 Some((kdist[[0]], E_min, kdist[[nk - 1]], E_max)),
828 &[],
829 );
830 let axes = axes.set_y_range(Fix(E_min), Fix(E_max));
831 let axes = axes.set_x_range(Fix(kdist[[0]]), Fix(kdist[[nk - 1]]));
832 let axes = axes.set_aspect_ratio(Fix(1.0));
833 let mut show_ticks = Vec::new();
834 for i in 0..knode.len() {
835 let A = knode[[i]];
836 let B = label[i];
837 show_ticks.push(Major(A, Fix(B)));
838 }
839 axes.set_x_ticks_custom(
840 show_ticks.into_iter(),
841 &[],
842 &[Font("Times New Roman", 24.0)],
843 );
844 axes.set_y_ticks(Some((Auto, 0)), &[], &[Font("Times New Roman", 24.0)]);
845 axes.set_cb_ticks_custom(
847 [
848 Major(-10.0, Fix("low")),
849 Major(0.0, Fix("0")),
850 Major(10.0, Fix("high")),
851 ]
852 .into_iter(),
853 &[],
854 &[Font("Times New Roman", 24.0)],
855 );
856 let mut pdfname = String::new();
857 pdfname.push_str(&name.clone());
858 pdfname.push_str("/surf_state_r.pdf");
859 fg.set_terminal("pdfcairo", &pdfname);
860 fg.show().expect("Unable to draw heatmap");
861 let _ = fg;
862 let mut fg = Figure::new();
864 let width: usize = nk;
865 let height: usize = E_n;
866 let mut heatmap_data = vec![];
867 for i in 0..height {
868 for j in 0..width {
869 heatmap_data.push(N_B[[j, i]]);
870 }
871 }
872 let axes = fg.axes2d();
873 axes.set_palette(Custom(&[
875 (-1.0, 0.0, 0.0, 0.0),
876 (-0.9, 65.0 / 255.0, 9.0 / 255.0, 103.0 / 255.0),
877 (0.0, 147.0 / 255.0, 37.0 / 255.0, 103.0 / 255.0),
878 (0.2, 220.0 / 255.0, 80.0 / 255.0, 57.0 / 255.0),
879 (1.0, 252.0 / 255.0, 254.0 / 255.0, 164.0 / 255.0),
880 ]));
881 axes.image(
882 heatmap_data.iter(),
883 width,
884 height,
885 Some((kdist[[0]], E_min, kdist[[nk - 1]], E_max)),
886 &[],
887 );
888 let axes = axes.set_y_range(Fix(E_min), Fix(E_max));
889 let axes = axes.set_x_range(Fix(kdist[[0]]), Fix(kdist[[nk - 1]]));
890 let axes = axes.set_aspect_ratio(Fix(1.0));
891 let mut show_ticks = Vec::new();
892 for i in 0..knode.len() {
893 let A = knode[[i]];
894 let B = label[i];
895 show_ticks.push(Major(A, Fix(B)));
896 }
897 axes.set_x_ticks_custom(
898 show_ticks.into_iter(),
899 &[],
900 &[Font("Times New Roman", 24.0)],
901 );
902 axes.set_y_ticks(Some((Auto, 0)), &[], &[Font("Times New Roman", 24.0)]);
903 axes.set_cb_ticks_custom(
905 [
906 Major(-10.0, Fix("low")),
907 Major(0.0, Fix("0")),
908 Major(10.0, Fix("high")),
909 ]
910 .into_iter(),
911 &[],
912 &[Font("Times New Roman", 24.0)],
913 );
914 let mut pdfname = String::new();
915 pdfname.push_str(&name.clone());
916 pdfname.push_str("/surf_state_b.pdf");
917 fg.set_terminal("pdfcairo", &pdfname);
918 fg.show().expect("Unable to draw heatmap");
919 let _ = fg;
920 }
921}