TB2J 0.8.2.5__tar.gz → 0.8.2.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/PKG-INFO +1 -1
  2. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/Oiju.py +0 -12
  3. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/Oiju_epc.py +0 -8
  4. TB2J-0.8.2.8/TB2J/__init__.py +1 -0
  5. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/exchange.py +32 -54
  6. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/exchangeCL2.py +11 -16
  7. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/exchange_pert.py +1 -1
  8. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/green.py +16 -9
  9. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/manager.py +0 -20
  10. TB2J-0.8.2.8/TB2J/spinham/h_matrix.py +68 -0
  11. TB2J-0.8.2.8/TB2J/spinham/obtain_J.py +79 -0
  12. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J.egg-info/PKG-INFO +1 -1
  13. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J.egg-info/SOURCES.txt +2 -0
  14. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/scripts/siesta2J.py +0 -10
  15. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/scripts/wann2J.py +0 -22
  16. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/setup.py +1 -1
  17. TB2J-0.8.2.5/TB2J/__init__.py +0 -1
  18. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/LICENSE +0 -0
  19. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/README.md +0 -0
  20. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/Jdownfolder.py +0 -0
  21. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/Jtensor.py +0 -0
  22. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/abacus/__init__.py +0 -0
  23. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/abacus/abacus_api.py +0 -0
  24. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/abacus/abacus_wrapper.py +0 -0
  25. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/abacus/gen_exchange_abacus.py +0 -0
  26. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/abacus/orbital_api.py +0 -0
  27. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/abacus/stru_api.py +0 -0
  28. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/abacus/test_read_HRSR.py +0 -0
  29. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/abacus/test_read_stru.py +0 -0
  30. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/basis.py +0 -0
  31. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/citation.py +0 -0
  32. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/contour.py +0 -0
  33. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/density_matrix.py +0 -0
  34. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/epc.py +0 -0
  35. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/exchange_qspace.py +0 -0
  36. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/external/__init__.py +0 -0
  37. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/external/p_tqdm.py +0 -0
  38. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/gpaw_wrapper.py +0 -0
  39. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/greentest.py +0 -0
  40. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/io_exchange/__init__.py +0 -0
  41. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/io_exchange/io_exchange.py +0 -0
  42. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/io_exchange/io_multibinit.py +0 -0
  43. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/io_exchange/io_tomsasd.py +0 -0
  44. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/io_exchange/io_txt.py +0 -0
  45. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/io_exchange/io_uppasd.py +0 -0
  46. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/io_exchange/io_vampire.py +0 -0
  47. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/io_merge.py +0 -0
  48. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/kpoints.py +0 -0
  49. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/mathutils.py +0 -0
  50. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/myTB.py +0 -0
  51. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/orbmap.py +0 -0
  52. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/pauli.py +0 -0
  53. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/pert.py +0 -0
  54. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/plot.py +0 -0
  55. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/rotate_atoms.py +0 -0
  56. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/sisl_wrapper.py +0 -0
  57. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/spinham/__init__.py +0 -0
  58. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/spinham/base_parser.py +0 -0
  59. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/spinham/constants.py +0 -0
  60. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/spinham/hamiltonian.py +0 -0
  61. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/spinham/hamiltonian_terms.py +0 -0
  62. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/spinham/plot.py +0 -0
  63. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/spinham/qsolver.py +0 -0
  64. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/spinham/spin_api.py +0 -0
  65. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/spinham/spin_xml.py +0 -0
  66. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/spinham/supercell.py +0 -0
  67. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/tensor_rotate.py +0 -0
  68. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/utest.py +0 -0
  69. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/utils.py +0 -0
  70. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/versioninfo.py +0 -0
  71. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/wannier/__init__.py +0 -0
  72. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/wannier/w90_parser.py +0 -0
  73. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J/wannier/w90_tb_parser.py +0 -0
  74. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J.egg-info/dependency_links.txt +0 -0
  75. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J.egg-info/requires.txt +0 -0
  76. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/TB2J.egg-info/top_level.txt +0 -0
  77. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/scripts/TB2J_downfold.py +0 -0
  78. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/scripts/TB2J_eigen.py +0 -0
  79. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/scripts/TB2J_magnon.py +0 -0
  80. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/scripts/TB2J_magnon_dos.py +0 -0
  81. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/scripts/TB2J_merge.py +0 -0
  82. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/scripts/TB2J_rotate.py +0 -0
  83. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/scripts/abacus2J.py +0 -0
  84. {TB2J-0.8.2.5 → TB2J-0.8.2.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: TB2J
3
- Version: 0.8.2.5
3
+ Version: 0.8.2.8
4
4
  Summary: TB2J: First principle to Heisenberg exchange J using tight-binding Green function method
5
5
  Home-page: UNKNOWN
6
6
  Author: Xu He
@@ -45,10 +45,6 @@ def gen_exchange_Oiju(
45
45
  kmesh=[5, 5, 5],
46
46
  emin=-12.0,
47
47
  emax=0.0,
48
- height=0.2,
49
- nz1=50,
50
- nz2=200,
51
- nz3=50,
52
48
  exclude_orbs=[],
53
49
  Rmesh=[1, 1, 1],
54
50
  description="",
@@ -93,10 +89,6 @@ def gen_exchange_Oiju(
93
89
  kmesh=kmesh,
94
90
  emin=emin,
95
91
  emax=emax,
96
- height=height,
97
- nz1=nz1,
98
- nz2=nz2,
99
- nz3=nz3,
100
92
  exclude_orbs=exclude_orbs,
101
93
  Rmesh=Rmesh,
102
94
  description=description,
@@ -123,10 +115,6 @@ if __name__ == "__main__":
123
115
  kmesh=[4, 4, 4],
124
116
  emin=-12.0,
125
117
  emax=0.0,
126
- height=0.1,
127
- nz1=50,
128
- nz2=200,
129
- nz3=50,
130
118
  exclude_orbs=[],
131
119
  Rmesh=[1, 1, 1],
132
120
  description="",
@@ -19,10 +19,6 @@ class OijuWannEPC(ExchangeCL2):
19
19
  kmesh=[4, 4, 4],
20
20
  emin=-15, # integration lower bound, relative to fermi energy
21
21
  emax=0.05, # integration upper bound. Should be 0 (fermi energy). But DFT codes define Fermi energy in various ways.
22
- height=0.5, # the delta in the (i delta) in green's function to prevent divergence
23
- nz1=150, # grid from emin to emin+(i delta)
24
- nz2=300, # grid from emin +(i delta) to emax+(i delta)
25
- nz3=150, # grid from emax + (i delta) to emax
26
22
  exclude_orbs=[], #
27
23
  Rmesh=[0, 0, 0], # Rmesh.
28
24
  description="",
@@ -40,10 +36,6 @@ class OijuWannEPC(ExchangeCL2):
40
36
  emin=-15, # integration lower bound, relative to fermi energy
41
37
  emax=0.05, # integration upper bound. Should be 0 (fermi energy).
42
38
  # But DFT codes define Fermi energy in various ways.
43
- height=0.5, # the delta in the (i delta) in green's function.
44
- nz1=150, # grid from emin to emin+(i delta)
45
- nz2=300, # grid from emin +(i delta) to emax+(i delta)
46
- nz3=150, # grid from emax + (i delta) to emax
47
39
  exclude_orbs=[], #
48
40
  Rmesh=[0, 0, 0], # Rmesh.
49
41
  description="",
@@ -0,0 +1 @@
1
+ __version__ = "0.8.2.8"
@@ -26,10 +26,6 @@ class ExchangeParams:
26
26
  emax=0.05,
27
27
  nz=100,
28
28
  # the delta in the (i delta) in green's function to prevent divergence
29
- height=0.5,
30
- nz1=150, # grid from emin to emin+(i delta)
31
- nz2=300, # grid from emin +(i delta) to emax+(i delta)
32
- nz3=150, # grid from emax + (i delta) to emax
33
29
  exclude_orbs=[], #
34
30
  ne=None, # number of electrons in Wannier function.
35
31
  Rcut=None, # Rcut.
@@ -44,12 +40,6 @@ class ExchangeParams:
44
40
  self.emin = emin
45
41
  self.emax = emax
46
42
  self.nz = nz
47
- self.height = height
48
- self.nz1 = nz1
49
- self.nz2 = nz2
50
- self.nz3 = nz3
51
- if nz is None:
52
- self.nz = nz1 + nz2 + nz3
53
43
  self.Rcut = Rcut
54
44
  self.basis = basis
55
45
  self.magnetic_elements = magnetic_elements
@@ -81,10 +71,6 @@ class Exchange(ExchangeParams):
81
71
  emax=0.05,
82
72
  nz=100,
83
73
  # the delta in the (i delta) in green's function to prevent divergence
84
- height=0.5,
85
- nz1=150, # grid from emin to emin+(i delta)
86
- nz2=300, # grid from emin +(i delta) to emax+(i delta)
87
- nz3=150, # grid from emax + (i delta) to emax
88
74
  exclude_orbs=[], #
89
75
  ne=None, # number of electrons in Wannier function.
90
76
  Rcut=None, # Rcut.
@@ -105,10 +91,6 @@ class Exchange(ExchangeParams):
105
91
  emin=emin,
106
92
  emax=emax,
107
93
  nz=nz,
108
- height=height,
109
- nz1=nz1,
110
- nz2=nz2,
111
- nz3=nz3,
112
94
  exclude_orbs=exclude_orbs,
113
95
  ne=ne,
114
96
  Rcut=Rcut,
@@ -164,11 +146,11 @@ class Exchange(ExchangeParams):
164
146
  emin --1-> emin + 1j*height --2-> emax+1j*height --3-> emax
165
147
  """
166
148
  self.contour = Contour(self.emin, self.emax)
167
- if method.lower() == "rectangle":
168
- self.contour.build_path_rectangle(
169
- height=self.height, nz1=self.nz1, nz2=self.nz2, nz3=self.nz3
170
- )
171
- elif method.lower() == "semicircle":
149
+ # if method.lower() == "rectangle":
150
+ # self.contour.build_path_rectangle(
151
+ # height=self.height, nz1=self.nz1, nz2=self.nz2, nz3=self.nz3
152
+ # )
153
+ if method.lower() == "semicircle":
172
154
  self.contour.build_path_semicircle(npoints=self.nz, endpoint=True)
173
155
  elif method.lower() == "legendre":
174
156
  self.contour.build_path_legendre(npoints=self.nz, endpoint=True)
@@ -362,7 +344,8 @@ class ExchangeNCL(Exchange):
362
344
  )
363
345
  self.norb = self.G.norb
364
346
  self.nbasis = self.G.nbasis
365
- self.rho = np.zeros((self.nbasis, self.nbasis), dtype=complex)
347
+ # self.rho = np.zeros((self.nbasis, self.nbasis), dtype=complex)
348
+ self.rho = self.G.get_density_matrix().real
366
349
  self.A_ijR_list = defaultdict(lambda: [])
367
350
  self.A_ijR = defaultdict(lambda: np.zeros((4, 4), dtype=complex))
368
351
  self.A_ijR_orb = dict()
@@ -595,22 +578,22 @@ class ExchangeNCL(Exchange):
595
578
  B = np.imag(val[3, 3])
596
579
  self.B[keyspin] = Jprime, B
597
580
 
598
- def get_N_e(self, GR, de):
599
- """
600
- calcualte density matrix for all R,i, j
601
- """
602
- self.N = defaultdict(lambda: 0.0)
603
- for R, G in GR.items():
604
- self.N[R] += -1.0 / np.pi * np.imag(G * de)
581
+ # def get_N_e(self, GR, de):
582
+ # """
583
+ # calcualte density matrix for all R,i, j
584
+ # """
585
+ # self.N = defaultdict(lambda: 0.0)
586
+ # for R, G in GR.items():
587
+ # self.N[R] += -1.0 / np.pi * np.imag(G * de)
605
588
 
606
- def get_rho_e(self, rhoR):
607
- """add component to density matrix from a green's function
608
- :param GR: Green's funciton in real space.
609
- """
610
- return -1.0 / np.pi * rhoR[0, 0, 0]
589
+ # def get_rho_e(self, rhoR):
590
+ # """add component to density matrix from a green's function
591
+ # :param GR: Green's funciton in real space.
592
+ # """
593
+ # return -1.0 / np.pi * rhoR[0, 0, 0]
611
594
 
612
- def get_total_charges(self):
613
- return np.sum(np.imag(np.diag(self.rho)))
595
+ # def get_total_charges(self):
596
+ # return np.sum(np.imag(np.diag(self.rho)))
614
597
 
615
598
  def get_rho_atom(self):
616
599
  """
@@ -623,9 +606,9 @@ class ExchangeNCL(Exchange):
623
606
  iorb = self.iorb(iatom)
624
607
  tmp = self.rho[np.ix_(iorb, iorb)]
625
608
  # *2 because there is a 1/2 in the paui_block_all function
626
- rho[iatom] = np.array([np.trace(x) * 2 for x in pauli_block_all(tmp)])
627
- self.charges[iatom] = np.imag(rho[iatom][0])
628
- self.spinat[iatom, :] = np.imag(rho[iatom][1:])
609
+ rho[iatom] = np.array([np.trace(x) * 2 for x in pauli_block_all(tmp)]).real
610
+ self.charges[iatom] = rho[iatom][0]
611
+ self.spinat[iatom, :] = rho[iatom][1:]
629
612
  self.rho_dict = rho
630
613
  return self.rho_dict
631
614
 
@@ -676,7 +659,7 @@ class ExchangeNCL(Exchange):
676
659
  self.Ddict_NJT = Ddict_NJT
677
660
  return Ddict_NJT
678
661
 
679
- def integrate(self, rhoRs, AijRs, AijRs_orb=None, method="simpson"):
662
+ def integrate(self, AijRs, AijRs_orb=None, method="simpson"):
680
663
  """
681
664
  AijRs: a list of AijR,
682
665
  wherer AijR: array of ((nR, n, n, 4,4), dtype=complex)
@@ -686,7 +669,7 @@ class ExchangeNCL(Exchange):
686
669
  elif method == "simpson":
687
670
  integrate = simpson_nonuniform
688
671
 
689
- self.rho = integrate(self.contour.path, rhoRs)
672
+ # self.rho = integrate(self.contour.path, rhoRs)
690
673
  for iR, R in enumerate(self.R_ijatom_dict):
691
674
  for iatom, jatom in self.R_ijatom_dict[R]:
692
675
  f = AijRs[(R, iatom, jatom)]
@@ -696,10 +679,10 @@ class ExchangeNCL(Exchange):
696
679
  self.contour.path, AijRs_orb[(R, iatom, jatom)]
697
680
  )
698
681
 
699
- def get_AijR_rhoR(self, e):
700
- GR, rhoR = self.G.get_GR(self.short_Rlist, energy=e, get_rho=True)
682
+ def get_AijR(self, e):
683
+ GR = self.G.get_GR(self.short_Rlist, energy=e, get_rho=False)
701
684
  AijR, AijR_orb = self.get_all_A(GR)
702
- return AijR, AijR_orb, self.get_rho_e(rhoR)
685
+ return AijR, AijR_orb
703
686
 
704
687
  def save_AijR(self, AijRs, fname):
705
688
  result = dict(path=self.contour.path, AijRs=AijRs)
@@ -717,7 +700,6 @@ class ExchangeNCL(Exchange):
717
700
  """
718
701
  print("Green's function Calculation started.")
719
702
 
720
- rhoRs = []
721
703
  AijRs = {}
722
704
 
723
705
  AijRs_orb = {}
@@ -726,11 +708,9 @@ class ExchangeNCL(Exchange):
726
708
 
727
709
  npole = len(self.contour.path)
728
710
  if self.np > 1:
729
- # executor = ProcessPool(nodes=self.np)
730
- # results = executor.map(self.get_AijR_rhoR, self.contour.path)
731
- results = p_map(self.get_AijR_rhoR, self.contour.path, num_cpus=self.np)
711
+ results = p_map(self.get_AijR, self.contour.path, num_cpus=self.np)
732
712
  else:
733
- results = map(self.get_AijR_rhoR, tqdm(self.contour.path, total=npole))
713
+ results = map(self.get_AijR, tqdm(self.contour.path, total=npole))
734
714
 
735
715
  for i, result in enumerate(results):
736
716
  for iR, R in enumerate(self.R_ijatom_dict):
@@ -750,7 +730,6 @@ class ExchangeNCL(Exchange):
750
730
  AijRs_orb[(R, iatom, jatom)].append(
751
731
  result[1][R, iatom, jatom]
752
732
  )
753
- rhoRs.append(result[2])
754
733
  if self.np > 1:
755
734
  # executor.close()
756
735
  # executor.join()
@@ -758,8 +737,7 @@ class ExchangeNCL(Exchange):
758
737
  pass
759
738
 
760
739
  # self.save_AijRs(AijRs)
761
- self.integrate(rhoRs, AijRs, AijRs_orb)
762
-
740
+ self.integrate(AijRs, AijRs_orb)
763
741
  self.get_rho_atom()
764
742
  self.A_to_Jtensor()
765
743
  self.A_to_Jtensor_orb()
@@ -42,10 +42,10 @@ class ExchangeCL2(ExchangeCL):
42
42
  )
43
43
  self.norb = self.Gup.norb
44
44
  self.nbasis = self.Gup.nbasis + self.Gdn.nbasis
45
- self.rho_up_list = []
46
- self.rho_dn_list = []
47
- self.rho_up = np.zeros((self.norb, self.norb), dtype=float)
48
- self.rho_dn = np.zeros((self.norb, self.norb), dtype=float)
45
+ # self.rho_up_list = []
46
+ # self.rho_dn_list = []
47
+ self.rho_up = self.Gup.get_density_matrix()
48
+ self.rho_dn = self.Gdn.get_density_matrix()
49
49
  self.Jorb_list = defaultdict(lambda: [])
50
50
  self.JJ_list = defaultdict(lambda: [])
51
51
  self.JJ = defaultdict(lambda: 0.0j)
@@ -225,8 +225,6 @@ class ExchangeCL2(ExchangeCL):
225
225
  integrate = trapezoidal_nonuniform
226
226
  elif method == "simpson":
227
227
  integrate = simpson_nonuniform
228
- self.rho_up = np.imag(integrate(self.contour.path, self.rho_up_list))
229
- self.rho_dn = np.imag(integrate(self.contour.path, self.rho_dn_list))
230
228
  for R, ijpairs in self.R_ijatom_dict.items():
231
229
  for iatom, jatom in ijpairs:
232
230
  self.Jorb[(R, iatom, jatom)] = integrate(
@@ -236,12 +234,11 @@ class ExchangeCL2(ExchangeCL):
236
234
  self.contour.path, self.JJ_list[(R, iatom, jatom)]
237
235
  )
238
236
 
239
- def get_AijR_rhoR(self, e):
240
- GR_up, rho_up = self.Gup.get_GR(self.short_Rlist, energy=e, get_rho=True)
241
- GR_dn, rho_dn = self.Gdn.get_GR(self.short_Rlist, energy=e, get_rho=True)
242
- rup, rdn = self.get_rho_e(rho_up, rho_dn)
237
+ def get_AijR(self, e):
238
+ GR_up = self.Gup.get_GR(self.short_Rlist, energy=e, get_rho=False)
239
+ GR_dn = self.Gdn.get_GR(self.short_Rlist, energy=e, get_rho=False)
243
240
  Jorb_list, JJ_list = self.get_all_A(GR_up, GR_dn)
244
- return rup, rdn, Jorb_list, JJ_list
241
+ return Jorb_list, JJ_list
245
242
 
246
243
  def calculate_all(self):
247
244
  """
@@ -251,15 +248,13 @@ class ExchangeCL2(ExchangeCL):
251
248
 
252
249
  npole = len(self.contour.path)
253
250
  if self.np == 1:
254
- results = map(self.get_AijR_rhoR, tqdm(self.contour.path, total=npole))
251
+ results = map(self.get_AijR, tqdm(self.contour.path, total=npole))
255
252
  else:
256
253
  # pool = ProcessPool(nodes=self.np)
257
254
  # results = pool.map(self.get_AijR_rhoR ,self.contour.path)
258
- results = p_map(self.get_AijR_rhoR, self.contour.path, num_cpus=self.np)
255
+ results = p_map(self.get_AijR, self.contour.path, num_cpus=self.np)
259
256
  for i, result in enumerate(results):
260
- rup, rdn, Jorb_list, JJ_list = result
261
- self.rho_up_list.append(rup)
262
- self.rho_dn_list.append(rdn)
257
+ Jorb_list, JJ_list = result
263
258
  for iR, R in enumerate(self.R_ijatom_dict):
264
259
  for iatom, jatom in self.R_ijatom_dict[R]:
265
260
  key = (R, iatom, jatom)
@@ -194,7 +194,7 @@ class ExchangePert(ExchangeNCL):
194
194
  e = self.contour.elist[ie]
195
195
  de = self.contour.de[ie]
196
196
  GR, dGdx = self.G.get_GR_and_dGRdx(self.Rlist, energy=e, dHdx=self.dHdx)
197
- self.get_rho_e(GR, de)
197
+ # self.get_rho_e(GR, de)
198
198
  self.get_all_A(GR, dGdx, de)
199
199
  if self.calc_NJt:
200
200
  self.get_N_e(GR, de)
@@ -225,12 +225,22 @@ class TBGreen:
225
225
 
226
226
  def get_density_matrix(self):
227
227
  rho = np.zeros((self.nbasis, self.nbasis), dtype=complex)
228
- for ik, _ in enumerate(self.kpts):
229
- rho += (
230
- (self.get_evecs(ik) * fermi(self.evals[ik], self.efermi))
231
- @ self.get_evecs(ik).T.conj()
232
- * self.kweights[ik]
233
- )
228
+ if self.is_orthogonal:
229
+ for ik, _ in enumerate(self.kpts):
230
+ rho += (
231
+ (self.get_evecs(ik) * fermi(self.evals[ik], self.efermi))
232
+ @ self.get_evecs(ik).T.conj()
233
+ * self.kweights[ik]
234
+ )
235
+ else:
236
+ for ik, _ in enumerate(self.kpts):
237
+ rho += (
238
+ (self.get_evecs(ik) * fermi(self.evals[ik], self.efermi))
239
+ @ self.get_evecs(ik).T.conj()
240
+ @ self.get_Sk(ik)
241
+ * self.kweights[ik]
242
+ )
243
+
234
244
  return rho
235
245
 
236
246
  def get_rho_R(self, Rlist):
@@ -238,9 +248,6 @@ class TBGreen:
238
248
  rho_R = np.zeros((nR, self.nbasis, self.nbasis), dtype=complex)
239
249
  for ik, kpt in enumerate(self.kpts):
240
250
  evec = self.get_evecs(ik)
241
- # rhok=(evec * fermi(self.evals[ik], self.efermi)
242
- # ) @ evec.T.conj()
243
- # print(fermi(self.evals[ik] , self.efermi))
244
251
  rhok = np.einsum(
245
252
  "ib,b, bj-> ij", evec, fermi(self.evals[ik], self.efermi), evec.conj().T
246
253
  )
@@ -27,10 +27,6 @@ def gen_exchange(
27
27
  emin=-12.0,
28
28
  emax=0.0,
29
29
  nz=100,
30
- height=0.2,
31
- nz1=50,
32
- nz2=200,
33
- nz3=50,
34
30
  exclude_orbs=[],
35
31
  Rcut=None,
36
32
  ne=None,
@@ -113,10 +109,6 @@ Warning: Please check if the noise level of Wannier function Hamiltonian to make
113
109
  emin=emin,
114
110
  emax=emax,
115
111
  nz=nz,
116
- height=height,
117
- nz1=nz1,
118
- nz2=nz2,
119
- nz3=nz3,
120
112
  exclude_orbs=exclude_orbs,
121
113
  Rcut=Rcut,
122
114
  ne=ne,
@@ -137,10 +129,6 @@ Warning: Please check if the noise level of Wannier function Hamiltonian to make
137
129
  emin=emin,
138
130
  emax=emax,
139
131
  nz=nz,
140
- height=height,
141
- nz1=nz1,
142
- nz2=nz2,
143
- nz3=nz3,
144
132
  exclude_orbs=exclude_orbs,
145
133
  Rcut=Rcut,
146
134
  ne=ne,
@@ -185,10 +173,6 @@ Warning: Please check if the noise level of Wannier function Hamiltonian to make
185
173
  emin=emin,
186
174
  emax=emax,
187
175
  nz=nz,
188
- height=height,
189
- nz1=nz1,
190
- nz2=nz2,
191
- nz3=nz3,
192
176
  exclude_orbs=exclude_orbs,
193
177
  Rcut=Rcut,
194
178
  ne=ne,
@@ -237,10 +221,6 @@ Warning: Please check if the noise level of Wannier function Hamiltonian to make
237
221
  emin=emin,
238
222
  emax=emax,
239
223
  nz=nz,
240
- height=height,
241
- nz1=nz1,
242
- nz2=nz2,
243
- nz3=nz3,
244
224
  exclude_orbs=exclude_orbs,
245
225
  Rcut=Rcut,
246
226
  ne=ne,
@@ -0,0 +1,68 @@
1
+ import numpy as np
2
+ import matplotlib.pyplot as plt
3
+ import aiida
4
+ from aiida_tb2j.data import ExchangeData
5
+
6
+ def plot_dispersion(bands, kpoint_labels, color='blue', title=None):
7
+
8
+ fig, axs = plt.subplots(1, 1, constrained_layout=True)
9
+ fig.set_size_inches(6, 6/1.618)
10
+
11
+ '''
12
+ Plot the bands
13
+ '''
14
+ kpoints = np.arange(len(bands))
15
+ axs.plot(kpoints, bands, color=color, linewidth=1.5)
16
+
17
+ '''
18
+ Plot the symmetry points
19
+ '''
20
+ bmin = bands.min(); bmax = bands.max()
21
+ ymin = bmin - 0.05*np.abs(bmin-bmax); ymax = bmax + 0.05*np.abs(bmax-bmin);
22
+ axs.set_xticks(kpoint_labels[0], kpoint_labels[1], fontsize=10)
23
+ axs.vlines(x=kpoint_labels[0], ymin=ymin, ymax=ymax, color='black', linewidth=0.5)
24
+ axs.set_xlim([0, len(kpoints)])
25
+ axs.set_ylim([ymin, ymax])
26
+
27
+ if title is not None:
28
+ plt.title(title, fontsize=10)
29
+
30
+ plt.show()
31
+
32
+
33
+ if __name__ == "__main__":
34
+
35
+ from argparse import ArgumentParser
36
+
37
+ parser = ArgumentParser()
38
+ parser.add_argument('-f', '--pickle_filename', type=str, help="Path of the 'TB2J.pickle' file.", required=True)
39
+ args = parser.parse_args()
40
+
41
+ '''
42
+ Right now the implementation depends on AiiDA and so we must create and load an AiiDA profile,
43
+ even if we do not store any information on a data base.
44
+ '''
45
+ aiida.load_profile()
46
+ '''
47
+ Create an ExchangeData object with the informations from the TB2J.pickle file
48
+ '''
49
+ exchange = ExchangeData.load_tb2j(pickle_file=args.pickle_filename, isotropic=False, pbc=(True, True, True))
50
+ '''
51
+ Compute the magnon band structure along a high symmetry path generated with
52
+ the ASE package. The informations is stored in an AiiDA BandsData object.
53
+ Here tol is the symmetry tolerance to determine the space group of the system.
54
+ They are in units of eV
55
+ '''
56
+ magnon_data = exchange.get_magnon_bands(npoints=300, tol=1e-1, with_DMI=True, with_Jani=True)
57
+ magnon_bands = 1000*magnon_data.get_bands() # Convert to meV
58
+ raw_labels = [(k, '$\Gamma$') if s == 'GAMMA' else (k, s) for k, s in magnon_data.labels]
59
+ kpoint_labels = list( zip( *raw_labels ) )
60
+ plot_dispersion(magnon_bands, kpoint_labels, color='blue', title='Magnon Bands')
61
+ '''
62
+ We can also obtain the dynamical matrix h instead of the actual magnon bands. The result
63
+ is stored in a numpy array with shape (number of kpoints, 2*natoms, 2*natoms)
64
+ '''
65
+ kpoints = magnon_data.get_kpoints() # The shape of the kpoints must be (nkpoints, 3)
66
+ h_matrix = 1000*exchange._H_matrix(kpoints, with_DMI=True, with_Jani=True) # Convert to meV
67
+ h_dispersion = np.linalg.eigvalsh(h_matrix) # We can also get the eigenvectors with np.linalg.eigh
68
+ plot_dispersion(h_dispersion, kpoint_labels, color='red', title='h matrix dispersion')
@@ -0,0 +1,79 @@
1
+ import numpy as np
2
+ from aiida_tb2j.data import ExchangeData
3
+ from aiida_tb2j.data.exchange import get_rotation_arrays
4
+ from itertools import combinations_with_replacement
5
+
6
+ ux, uy, uz = np.eye(3).reshape((3, 1, 3))
7
+
8
+ def combine_arrays(u, v):
9
+
10
+ return np.concatenate([u*v, np.roll(u, -1, axis=-1)*v, np.roll(v, -1, axis=-1)*u], axis=-1)
11
+
12
+ def get_coefficients(magmoms, indices):
13
+
14
+ i, j = indices
15
+
16
+ U, V = zip(*[get_rotation_arrays(magmoms, u=u) for u in [ux, uy, uz]])
17
+ U = np.stack(U).swapaxes(0, 1)
18
+ V = np.stack(V).swapaxes(0, 1)
19
+
20
+ uc = combine_arrays(U[i], U[j].conj())
21
+ ur = combine_arrays(U[i], U[j])
22
+ uc2 = combine_arrays(U[i].conj(), U[j])
23
+ u = np.concatenate([uc, ur, uc2], axis=1)
24
+
25
+ return u, V
26
+
27
+ def get_C(H0, u, V):
28
+
29
+ n = int(H0.shape[-1]/2)
30
+ upi = np.triu_indices(n)
31
+ dig = np.diag_indices(n)
32
+
33
+ i, j = upi
34
+ AB0 = H0[:, [i, i, i+n], [j, j+n, j+n]]
35
+ AB0 = np.swapaxes(AB0, 0, 2).reshape(len(i), 9)
36
+ J0_flat = np.linalg.solve(u, AB0)
37
+
38
+ J0 = np.empty((n, n, 3, 3), dtype=complex)
39
+ J0[*upi] = J0_flat[:, [0, 6, 5, 3, 1, 7, 8, 4, 2]].reshape(-1, 3, 3)
40
+ J0 += J0.swapaxes(0, 1)
41
+ J0[*dig] = 0.0
42
+
43
+ C = np.array([np.diag(a) for a in np.einsum('imx,ijxy,jmy->mi', V, 2*J0, V)])
44
+
45
+ return C
46
+
47
+ def get_J(H, kpoints, exchange):
48
+
49
+ n = int(H.shape[-1]/2)
50
+ upi = np.triu_indices(n)
51
+ dig = np.diag_indices(n)
52
+ i, j = upi
53
+
54
+ magmoms = exchange.magmoms()[np.unique(exchange.pairs)]
55
+ magmoms /= np.linalg.norm(magmoms, axis=-1).reshape(-1, 1)
56
+ u, V = get_coefficients(magmoms, indices=upi)
57
+
58
+ H0 = np.stack([1000*exchange._H_matrix(kpoints=np.zeros((1, 3)), with_DMI=True, with_Jani=True, u=u) for u in [ux, uy, uz]])[:, 0, :, :]
59
+ C = get_C(H0, u, V)
60
+ H[:, :, :n, :n] += C.reshape(3, 1, n, n)
61
+ H[:, :, n:, n:] += C.reshape(3, 1, n, n)
62
+
63
+ AB = H[:, :, [i, i, i+n], [j, j+n, j+n]]
64
+ AB[:, :, 2, :] = AB[:, ::-1, 2, :]
65
+ AB = np.moveaxis(AB, [2, 3], [1, 0]).reshape(len(i), 9, -1)
66
+
67
+ vectors = exchange.get_vectors()
68
+ exp_summand = np.exp( -2j*np.pi*vectors @ kpoints.T )
69
+ nAB = np.einsum('nik,ndk->nid', AB, exp_summand) / len(kpoints)
70
+
71
+ ii = np.where(i == j)
72
+ i0 = np.where(np.linalg.norm(vectors, axis=-1) == 0.0)
73
+ J = np.linalg.solve(u, nAB).swapaxes(1, 2)
74
+ J = J[:, :, [0, 6, 5, 3, 1, 7, 8, 4, 2]].reshape(len(i), -1, 3, 3)
75
+ J *= -1
76
+ J[ii] *= 2
77
+ J[i0] *= 0
78
+
79
+ return J
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: TB2J
3
- Version: 0.8.2.5
3
+ Version: 0.8.2.8
4
4
  Summary: TB2J: First principle to Heisenberg exchange J using tight-binding Green function method
5
5
  Home-page: UNKNOWN
6
6
  Author: Xu He
@@ -58,8 +58,10 @@ TB2J/io_exchange/io_vampire.py
58
58
  TB2J/spinham/__init__.py
59
59
  TB2J/spinham/base_parser.py
60
60
  TB2J/spinham/constants.py
61
+ TB2J/spinham/h_matrix.py
61
62
  TB2J/spinham/hamiltonian.py
62
63
  TB2J/spinham/hamiltonian_terms.py
64
+ TB2J/spinham/obtain_J.py
63
65
  TB2J/spinham/plot.py
64
66
  TB2J/spinham/qsolver.py
65
67
  TB2J/spinham/spin_api.py
@@ -54,19 +54,9 @@ def run_siesta2J():
54
54
  action="store_true",
55
55
  default=False,
56
56
  )
57
- # parser.add_argument(
58
- # '--height',
59
- # help=
60
- # 'energy contour, a small number (often between 0.1 to 0.5, default 0.2)',
61
- # type=float,
62
- # default=0.1)
63
57
  parser.add_argument(
64
58
  "--nz", help="number of integration steps. Default: 50", default=50, type=int
65
59
  )
66
- # parser.add_argument(
67
- # '--nz2', help='number of steps 2, default: 200', default=200, type=int)
68
- # parser.add_argument(
69
- # '--nz3', help='number of steps 3, default: 50', default=50, type=int)
70
60
  parser.add_argument(
71
61
  "--cutoff",
72
62
  help="The minimum of J amplitude to write, (in eV). Default: 1e-5 eV",
@@ -86,24 +86,6 @@ def run_wann2J():
86
86
  default=100,
87
87
  type=int,
88
88
  )
89
- # parser.add_argument(
90
- # '--height',
91
- # help=
92
- # 'energy contour, a small number (often between 0.1 to 0.5, default 0.1)',
93
- # type=float,
94
- # default=0.1)
95
- # parser.add_argument('--nz1',
96
- # help='number of steps 1, default: 50',
97
- # default=50,
98
- # type=int)
99
- # parser.add_argument('--nz2',
100
- # help='number of steps 2, default: 200',
101
- # default=200,
102
- # type=int)
103
- # parser.add_argument('--nz3',
104
- # help='number of steps 3, default: 50',
105
- # default=50,
106
- # type=int)
107
89
  parser.add_argument(
108
90
  "--cutoff",
109
91
  help="The minimum of J amplitude to write, (in eV), default is 1e-5 eV",
@@ -196,10 +178,6 @@ def run_wann2J():
196
178
  emin=args.emin,
197
179
  emax=args.emax,
198
180
  nz=args.nz,
199
- # height=args.height,
200
- # nz1=args.nz1,
201
- # nz2=args.nz2,
202
- # nz3=args.nz3,
203
181
  use_cache=args.use_cache,
204
182
  np=args.np,
205
183
  description=args.description,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python
2
2
  from setuptools import setup, find_packages
3
3
 
4
- __version__ = "0.8.2.5"
4
+ __version__ = "0.8.2.8"
5
5
 
6
6
  long_description = """TB2J is a Python package aimed to compute automatically the magnetic interactions (superexchange and Dzyaloshinskii-Moriya) between atoms of magnetic crystals from DFT Hamiltonian based on Wannier functions or Linear combination of atomic orbitals. It uses the Green's function method and take the local rigid spin rotation as a perturbation. The package can take the output from Wannier90, which is interfaced with many density functional theory codes or from codes based on localised orbitals. A minimal user input is needed, which allows for an easily integration into a high-throughput workflows. """
7
7
 
@@ -1 +0,0 @@
1
- __version__ = "0.8.2.5"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes