TB2J 0.8.0__py3-none-any.whl → 0.8.2.1__py3-none-any.whl

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.
TB2J/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.8.0"
1
+ __version__ = "0.8.2.1"
@@ -4,6 +4,7 @@
4
4
  The abacus wrapper
5
5
  """
6
6
  from pathlib import Path
7
+ import os
7
8
  import numpy as np
8
9
  from scipy.linalg import eigh
9
10
  from TB2J.utils import symbol_number_list
@@ -117,13 +118,20 @@ class AbacusParser:
117
118
  return "non-polarized"
118
119
  elif nspin == 2:
119
120
  return "collinear"
120
- elif nspin == 2:
121
+ elif nspin == 4:
121
122
  return "noncollinear"
122
123
  else:
123
124
  raise ValueError("nspin should be either 1 or 4.")
124
125
 
125
126
  def read_atoms(self):
126
- self.atoms = read_abacus(str(Path(self.outpath) / "../Stru"))
127
+ path1=str(Path(self.outpath) / "../STRU")
128
+ path2=str(Path(self.outpath) / "../Stru")
129
+ if os.path.exists(path1):
130
+ self.atoms = read_abacus(path1)
131
+ elif os.path.exists(path2):
132
+ self.atoms = read_abacus(path2)
133
+ else:
134
+ raise Exception("The STRU or Stru file cannot be found.")
127
135
  return self.atoms
128
136
 
129
137
  def read_basis(self):
@@ -145,14 +153,15 @@ class AbacusParser:
145
153
 
146
154
  def Read_HSR_noncollinear(self, binary=None):
147
155
  p = Path(self.outpath)
148
- SR_filename = (p / "data-SR-sparse_SPIN0.csr").as_posix()
149
- HR_filename = p / "data-HR-sparse_SPIN0.csr".as_posix()
150
- self.nbasis, self.Rlist, self.HR, self.SR = read_HR_SR(
156
+ SR_filename = str(p / "data-SR-sparse_SPIN0.csr")
157
+ HR_filename = str(p / "data-HR-sparse_SPIN0.csr")
158
+ nbasis, Rlist, HR, SR = read_HR_SR(
151
159
  nspin=4,
152
160
  binary=self.binary,
153
161
  HR_fileName=HR_filename,
154
162
  SR_fileName=SR_filename,
155
163
  )
164
+ return nbasis, Rlist, HR, SR
156
165
 
157
166
  def get_models(self):
158
167
  if self.spin == "collinear":
@@ -205,7 +214,7 @@ class AbacusParser:
205
214
  return basis
206
215
 
207
216
 
208
- def test_abacus_wrapper():
217
+ def test_abacus_wrapper_collinear():
209
218
  outpath = "/Users/hexu/projects/TB2J_abacus/abacus-tb2j-master/abacus_example/case_Fe/1_no_soc/OUT.Fe"
210
219
  parser = AbacusParser(outpath=outpath, spin=None, binary=False)
211
220
  atoms = parser.read_atoms()
@@ -216,8 +225,19 @@ def test_abacus_wrapper():
216
225
  # print(H.shape)
217
226
  # print(H.diagonal().real)
218
227
  # print(model_up.get_HR0().diagonal().real)
219
- print(parser.get_efermi())
228
+ print(parser.efermi)
229
+
230
+
231
+ def test_abacus_wrapper_ncl():
232
+ outpath = "/Users/hexu/projects/TB2J_abacus/abacus-tb2j-master/abacus_example/case_Fe/2_soc/OUT.Fe"
233
+
234
+ parser = AbacusParser(outpath=outpath, spin=None, binary=False)
235
+ atoms = parser.read_atoms()
236
+ model = parser.get_models()
237
+ H, S, E, V = model.HSE_k([0, 0, 0])
238
+ print(parser.efermi)
220
239
 
221
240
 
222
241
  if __name__ == "__main__":
223
- test_abacus_wrapper()
242
+ # test_abacus_wrapper()
243
+ test_abacus_wrapper_ncl()
@@ -68,7 +68,7 @@ data directory: {outpath}
68
68
  else:
69
69
  tbmodel = parser.get_models()
70
70
  print("Starting to calculate exchange.")
71
- description = f""" Input from collinear Abacus data.
71
+ description = f""" Input from non-collinear Abacus data.
72
72
  data directory: {outpath}
73
73
  \n"""
74
74
  exchange = ExchangeNCL(
@@ -83,6 +83,7 @@ data directory: {outpath}
83
83
  nz=nz,
84
84
  exclude_orbs=exclude_orbs,
85
85
  Rcut=Rcut,
86
+ np=np,
86
87
  use_cache=use_cache,
87
88
  description=description,
88
89
  )
@@ -93,8 +94,8 @@ data directory: {outpath}
93
94
 
94
95
  if __name__ == "__main__":
95
96
  gen_exchange_abacus(
96
- path="/Users/hexu/projects/TB2J_abacus/abacus-tb2j-master/abacus_example/case_Fe/1_no_soc",
97
- label="Fe",
97
+ path="/Users/hexu/projects/TB2J_abacus/abacus-tb2j-master/abacus_example/case_Fe/2_soc",
98
+ suffix="Fe",
98
99
  magnetic_elements=["Fe"],
99
100
  nz=50,
100
101
  Rcut=8,
TB2J/abacus/stru_api.py CHANGED
@@ -1,7 +1,8 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- Created on Wed Jun 13 10:31:30 2018
4
- @author: shenzx
3
+ @author: Zhen-Xiong Shen
4
+ @email: shenzx@iai.ustc.edu.cn
5
+ @workplace: Institute of Artificial Intelligence, Hefei Comprehensive National Science Center
5
6
 
6
7
  Modified on Wed Aug 01 11:44:51 2022
7
8
  @author: Ji Yu-yang
@@ -19,6 +19,7 @@ from datetime import datetime
19
19
  import matplotlib.pyplot as plt
20
20
  from TB2J.spinham.spin_api import SpinModel
21
21
  from TB2J.io_exchange.io_txt import write_Jq_info
22
+ from TB2J.utils import symbol_number
22
23
 
23
24
 
24
25
  class SpinIO(object):
@@ -212,7 +213,23 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
212
213
  def get_spin_ispin(self, i):
213
214
  return self.spinat[self.iatom(i)]
214
215
 
216
+ def get_symbol_number_ispin(self, symnum):
217
+ """
218
+ Return the spin index for a given symbol number.
219
+ """
220
+ symdict = symbol_number(self.atoms)
221
+ return self.index_spin[symdict[symnum]]
222
+
223
+ def i_spin(self, i):
224
+ if isinstance(i, int):
225
+ return i
226
+ elif isinstance(i, str):
227
+ return self.get_symbol_number_ispin(i)
228
+ else:
229
+ raise ValueError("i must be either an integer or a string.")
230
+
215
231
  def get_charge_ispin(self, i):
232
+ i = self.i_spin(i)
216
233
  return self.charges[self.iatom(i)]
217
234
 
218
235
  def get_spin_iatom(self, iatom):
@@ -222,6 +239,8 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
222
239
  return self.charges[iatom]
223
240
 
224
241
  def get_J(self, i, j, R, default=None):
242
+ i = self.i_spin(i)
243
+ j = self.i_spin(j)
225
244
  key = (
226
245
  tuple(R),
227
246
  i,
@@ -233,6 +252,8 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
233
252
  return default
234
253
 
235
254
  def get_Jiso(self, i, j, R, default=None):
255
+ i = self.i_spin(i)
256
+ j = self.i_spin(j)
236
257
  key = (
237
258
  tuple(R),
238
259
  i,
@@ -244,6 +265,8 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
244
265
  return default
245
266
 
246
267
  def get_DMI(self, i, j, R, default=None):
268
+ i = self.i_spin(i)
269
+ j = self.i_spin(j)
247
270
  key = (
248
271
  tuple(R),
249
272
  i,
@@ -261,6 +284,8 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
261
284
  param j: spin index j
262
285
  param R (tuple of integers): cell index R
263
286
  """
287
+ i = self.i_spin(i)
288
+ j = self.i_spin(j)
264
289
  key = (
265
290
  tuple(R),
266
291
  i,
@@ -278,6 +303,8 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
278
303
  param j: spin index j
279
304
  param R (tuple of integers): cell index R
280
305
  """
306
+ i = self.i_spin(i)
307
+ j = self.i_spin(j)
281
308
  if iso_only:
282
309
  Jtensor = np.eye(3) * self.get_J(i, j, R)
283
310
  else:
@@ -295,6 +322,8 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
295
322
  returns:
296
323
  Jmat: (3*nspin,3*nspin) matrix.
297
324
  """
325
+ i = self.i_spin(i)
326
+ j = self.i_spin(j)
298
327
  n3 = self.nspin * 3
299
328
  Jmat = np.zeros((n3, n3), dtype=float)
300
329
  for i in range(self.nspin):
TB2J/io_merge.py CHANGED
@@ -215,9 +215,9 @@ class Merger2:
215
215
  )
216
216
  w = Jani_removed / Jani
217
217
  Jani_sum += Jani * w # Jani_removed
218
- print(f"{Jani* w=}")
218
+ #print(f"{Jani* w=}")
219
219
  weights += w
220
- print(f"{weights=}")
220
+ #print(f"{weights=}")
221
221
  if np.any(weights == 0):
222
222
  raise RuntimeError(
223
223
  "The data set to be merged does not give a complete anisotropic J tensor, please add more data"
TB2J/manager.py CHANGED
@@ -284,6 +284,21 @@ def gen_exchange_siesta(
284
284
  raise ImportError(
285
285
  f"sisl version is {sisl.__version__}, but should be larger than 0.10.0."
286
286
  )
287
+
288
+ include_orbs = {}
289
+ if isinstance(magnetic_elements, str):
290
+ magnetic_elements = [magnetic_elements]
291
+ for element in magnetic_elements:
292
+ if "_" in element:
293
+ elem = element.split("_")[0]
294
+ orb = element.split("_")[1:]
295
+ include_orbs[elem] = orb
296
+ else:
297
+ include_orbs[element] = None
298
+ magnetic_elements = list(include_orbs.keys())
299
+ print(magnetic_elements)
300
+ print(include_orbs)
301
+
287
302
  fdf = sisl.get_sile(fdf_fname)
288
303
  geom = fdf.read_geometry()
289
304
  H = fdf.read_hamiltonian()
TB2J/myTB.py CHANGED
@@ -9,7 +9,7 @@ from collections import defaultdict
9
9
  # from tbmodels import Model
10
10
  from ase.atoms import Atoms
11
11
  from TB2J.utils import auto_assign_basis_name
12
- from TB2J.wannier import parse_ham, parse_xyz, parse_atoms
12
+ from TB2J.wannier import parse_ham, parse_xyz, parse_atoms, parse_tb
13
13
 
14
14
 
15
15
  class AbstractTB:
@@ -84,6 +84,7 @@ class MyTB(AbstractTB):
84
84
  self,
85
85
  nbasis,
86
86
  data=None,
87
+ R_degens=None,
87
88
  positions=None,
88
89
  sparse=False,
89
90
  ndim=3,
@@ -93,6 +94,7 @@ class MyTB(AbstractTB):
93
94
  """
94
95
  :param nbasis: number of basis.
95
96
  :param data: a dictionary of {R: matrix}. R is a tuple, matrix is a nbasis*nbasis matrix.
97
+ :param R_degens: degeneracy of R.
96
98
  :param positions: reduced positions.
97
99
  :param sparse: Bool, whether to use a sparse matrix.
98
100
  :param ndim: number of dimensions.
@@ -107,6 +109,10 @@ class MyTB(AbstractTB):
107
109
  self._nspin = nspin
108
110
  self._norb = nbasis // nspin
109
111
  self._ndim = ndim
112
+ if R_degens is not None:
113
+ self.R_degens = R_degens
114
+ else:
115
+ self.R_degens = np.ones(len(self.data.keys()), dtype=int)
110
116
  if positions is None:
111
117
  self._positions = np.zeros((nbasis, self.ndim))
112
118
  else:
@@ -121,7 +127,6 @@ class MyTB(AbstractTB):
121
127
  self.k2Rfactor = -2.0j * np.pi
122
128
  self.is_siesta = False
123
129
  self.is_orthogonal = True
124
-
125
130
  self._name = "Wannier"
126
131
 
127
132
  def set_atoms(self, atoms):
@@ -178,12 +183,17 @@ class MyTB(AbstractTB):
178
183
  :param path: path
179
184
  :param prefix: prefix to the wannier files, often wannier90, or wannier90_up, or wannier90_dn for vasp.
180
185
  """
181
- # tbmodel = Model.from_wannier_folder(
182
- # folder=path, prefix=prefix)
183
- # m = MyTB.from_tbmodel(tbmodel)
184
186
 
185
- nbasis, data = parse_ham(fname=os.path.join(path, prefix + "_hr.dat"))
186
- xcart, _, _ = parse_xyz(fname=os.path.join(path, prefix + "_centres.xyz"))
187
+ tb_fname = os.path.join(path, prefix + "_tb.dat")
188
+ hr_fname = os.path.join(path, prefix + "_hr.dat")
189
+ if os.path.exists(tb_fname):
190
+ xcart, nbasis, data, R_degens = parse_tb(fname=tb_fname)
191
+ else:
192
+ nbasis, data, R_degens = parse_ham(
193
+ fname=os.path.join(path, prefix + "_hr.dat")
194
+ )
195
+ xcart, _, _ = parse_xyz(fname=os.path.join(path, prefix + "_centres.xyz"))
196
+
187
197
  if atoms is None:
188
198
  atoms = parse_atoms(os.path.join(path, prefix + ".win"))
189
199
  cell = atoms.get_cell()
@@ -200,7 +210,7 @@ class MyTB(AbstractTB):
200
210
  data[key][1::2, ::2] = dtmp[norb:, :norb]
201
211
  data[key][1::2, 1::2] = dtmp[norb:, norb:]
202
212
  ind, positions = auto_assign_basis_name(xred, atoms)
203
- m = MyTB(nbasis=nbasis, data=data, positions=xred)
213
+ m = MyTB(nbasis=nbasis, data=data, positions=xred, R_degens=R_degens)
204
214
  nm = m.shift_position(positions)
205
215
  nm.set_atoms(atoms)
206
216
  return nm
@@ -243,13 +253,16 @@ class MyTB(AbstractTB):
243
253
  """
244
254
  Hk = np.zeros((self.nbasis, self.nbasis), dtype="complex")
245
255
  if convention == 2:
246
- for R, mat in self.data.items():
247
- phase = np.exp(self.R2kfactor * np.dot(k, R))
256
+ for iR, (R, mat) in enumerate(self.data.items()):
257
+ phase = np.exp(self.R2kfactor * np.dot(k, R)) # /self.R_degens[iR]
248
258
  H = mat * phase
249
259
  Hk += H + H.conjugate().T
250
260
  elif convention == 1:
251
- for R, mat in self.data.items():
252
- phase = np.exp(self.R2kfactor * np.dot(k, R + self.rjminusri))
261
+ for iR, (R, mat) in enumerate(self.data.items()):
262
+ phase = (
263
+ np.exp(self.R2kfactor * np.dot(k, R + self.rjminusri))
264
+ / self.R_degens[iR]
265
+ )
253
266
  H = mat * phase
254
267
  Hk += H + H.conjugate().T
255
268
  else:
@@ -369,7 +382,7 @@ class MyTB(AbstractTB):
369
382
  newpos = copy.deepcopy(pos)
370
383
  for i in range(self.nbasis):
371
384
  newpos[i] = pos[i] - shift[i]
372
- d = MyTB(self.nbasis, ndim=self.ndim, nspin=self.nspin)
385
+ d = MyTB(self.nbasis, ndim=self.ndim, nspin=self.nspin, R_degens=self.R_degens)
373
386
  d._positions = newpos
374
387
 
375
388
  for R, v in self.data.items():
TB2J/sisl_wrapper.py CHANGED
@@ -258,6 +258,110 @@ class SislWrapper(AbstractTB):
258
258
  return 0.0
259
259
 
260
260
 
261
+ class SislWFSXWrapper(SislWrapper):
262
+ """Wrapper for retrieving eigenvalues and eigenvectors from siesta WFSX file
263
+
264
+ Parameters
265
+ ----------
266
+ geom : sisl.Geometry
267
+ the geometry containing information about atomic positions and orbitals
268
+ wfsx_sile: sisl.io.siesta.wfsxSileSiesta
269
+ file reader for WFSX file
270
+ spin : sisl.physics.Spin
271
+ spin object carrying information about spin configurations and spin component.
272
+ ispin : None or int
273
+ index of spin channel to be considered. Only takes effect for collinear spin calculations (UP: 0, DOWN: 1).
274
+ (default: None)
275
+ shift_fermi: None or float
276
+ energy shift to be applied to all energies. If `None` no shift is applied. (default: None)
277
+ """
278
+
279
+ def __init__(self, geom, wfsx_sile, spin, ispin=None, shift_fermi=None):
280
+ # super().__init__(geom, spin=spin, ispin=ispin, shift_fermi=shift_fermi)
281
+ super().__init__(sisl_hamiltonian, geom=None, spin=None)
282
+ self.geom = geom
283
+ self.wfsx_sile = wfsx_sile
284
+ self.read_all()
285
+
286
+ def read_all(self):
287
+ """Read all wavefunctions, eigenvalues, and k-points from WFSX file."""
288
+ evals = []
289
+ evecs = []
290
+ wfsx_kpts = []
291
+
292
+ def change_gauge(k, evec):
293
+ """Change the eigenvector gauge"""
294
+ phase = np.dot(
295
+ self.geom.xyz[self.geom.o2a(np.arange(self.geom.no)), :],
296
+ np.dot(k, self.geom.rcell),
297
+ )
298
+ if self.spin.has_noncolinear:
299
+ # for NC/SOC we have a 2x2 spin-box per orbital
300
+ phase = np.repeat(phase, 2)
301
+ # r -> R gauge tranformation.
302
+ return evec * np.exp(1j * phase).reshape(1, -1)
303
+
304
+ # Read wavefunctions and eigenvalues
305
+ for wfc in self.wfsx_sile.yield_eigenstate(parent=self.geom):
306
+ wfsx_kpts.append(wfc.info["k"])
307
+ evals.append(wfc.c)
308
+ # To get the same eigvecs as eigh returns we need to transpose the
309
+ # array and change the gauge from 'r' to 'R'
310
+ evecs.append(change_gauge(wfc.info["k"], wfc.state).T)
311
+
312
+ # If any k-point occurs more than once in the WaveFuncKPoints block,
313
+ # we discard the duplicates
314
+ is_duplicate = self._is_duplicate(wfsx_kpts)
315
+ self.wfsx_kpts = wfsx_kpts[~is_duplicate]
316
+ self.evals = np.array(evals, dtype=float)[~is_duplicate]
317
+ if self.shift_fermi is not None:
318
+ self.evals += self.shift_fermi
319
+ self.evecs = np.array(evecs, dtype=np.complex64, order="C")[~is_duplicate]
320
+
321
+ def _is_duplicate(self, array):
322
+ # TODO: Move into utils
323
+ # Find all matches (i,j): array[i] == array[j]
324
+ matches = np.all(np.isclose(array[None, :], array[:, None]), axis=-1)
325
+ # Remove double counting of matches: (i,j) and (j,i)
326
+ # Also, remove matches of elements with themselves: (i,i)
327
+ matches = np.triu(matches, 1)
328
+
329
+ # Finally determine elements which are duplicates
330
+ return np.any(matches, axis=0)
331
+
332
+ def find_all(self, kpts):
333
+ """Find the correct eigenvectors and eigenvalues and sort them
334
+ to match the order in kpts.
335
+
336
+ Parameters
337
+ ----------
338
+ kpts : list of float (3,) or (nk, 3)
339
+ list of k points
340
+
341
+ Returns
342
+ -------
343
+ evals : list of float (nk, n)
344
+ list of eigenvalues for every requested k point
345
+ evecs :
346
+ list of eiegnvector for every requested k point
347
+ """
348
+ kpts = np.asarray(kpts)
349
+ sort_idx = np.where(
350
+ np.all(np.isclose(self.wfsx_kpts[None, :], kpts[:, None]), axis=-1)
351
+ )[1]
352
+ if len(sort_idx) < len(kpts):
353
+ # k-point not found
354
+ raise ValueError(
355
+ f"{self.__class__.__name__}._read_all unable to find at least one "
356
+ "required k point in '{self.wfsx_sile.file}'. Please, ensure that "
357
+ "all k points listed below are included:\n"
358
+ + "\n".join([str(k) for k in kpts])
359
+ )
360
+ if not np.all(np.isclose(self.wfsx_kpts[sort_idx], kpts)):
361
+ # raise ValueError( wfsx_kpts = np.asarray(wfsx_kpts)
362
+ pass
363
+
364
+
261
365
  # def test():
262
366
  # fdf = sisl.get_sile('/home/hexu/projects/learn_siesta/SMO_Wannier/siesta.fdf')
263
367
  # H = fdf.read_hamiltonian(order='nc',dim=2)
TB2J/wannier/__init__.py CHANGED
@@ -1 +1 @@
1
- from TB2J.wannier.w90_parser import parse_xyz, parse_ham, parse_atoms
1
+ from TB2J.wannier.w90_parser import parse_xyz, parse_ham, parse_atoms, parse_tb
@@ -5,6 +5,7 @@ import numpy as np
5
5
  from ase.io import read
6
6
  from ase.atoms import Atoms
7
7
  from ase.units import Angstrom, Bohr
8
+ from .w90_tb_parser import parse_tb_file
8
9
 
9
10
  unit_dict = {"ANG": Angstrom, "BOHR": Bohr}
10
11
 
@@ -49,6 +50,7 @@ def parse_ham(fname="wannier90_hr.dat", cutoff=None):
49
50
  for i in range(3, 3 + nline):
50
51
  d = map(float, lines[i].strip().split())
51
52
  dlist += d
53
+ R_degens = np.array(dlist, dtype=int)
52
54
  H_mnR = defaultdict(lambda: np.zeros((n_wann, n_wann), dtype=complex))
53
55
  for i in range(3 + nline, 3 + nline + n_wann**2 * n_R):
54
56
  t = lines[i].strip().split()
@@ -65,7 +67,7 @@ def parse_ham(fname="wannier90_hr.dat", cutoff=None):
65
67
  H_mnR[R][m, n] = val / 2.0
66
68
  else:
67
69
  H_mnR[R][m, n] = val / 2.0
68
- return n_wann, H_mnR
70
+ return n_wann, H_mnR, R_degens
69
71
 
70
72
 
71
73
  def parse_cell(fname, unit=Angstrom):
@@ -138,3 +140,11 @@ def parse_atoms(fname):
138
140
  taus = taus * factor
139
141
  atoms = Atoms(symbols=symbols, cell=cell, positions=taus)
140
142
  return atoms
143
+
144
+
145
+ def parse_tb(fname):
146
+ """
147
+ return the wannier center, number of wannier functions and the Hamiltonian from the wannier90 _tb.dat file.
148
+ """
149
+ result = parse_tb_file(fname)
150
+ return result["centers"], result["n_wann"], result["H"], result["Rdegens"]
@@ -0,0 +1,129 @@
1
+ """
2
+ parse the tb files in Wannier90
3
+ """
4
+
5
+ import os
6
+ import re
7
+ import numpy as np
8
+ from typing import List, Tuple, Dict
9
+
10
+
11
+ def ssrline(file):
12
+ """
13
+ Read a line and split it into a list of strings"""
14
+ line = file.readline().strip()
15
+ return re.split(r"\s+", line)
16
+
17
+
18
+ def parse_vector(file, vector_type, size):
19
+ result = np.zeros((size,), dtype=vector_type)
20
+ for i in range(size):
21
+ result[i] = np.fromstring(file.readline().strip(), sep=" ")
22
+ result[i] = result[i].astype(vector_type)
23
+ return result
24
+
25
+
26
+ def find_Rvectors(Rvectors, R):
27
+ for i, Rvec in enumerate(Rvectors):
28
+ if np.all(Rvec == R):
29
+ return i
30
+ return -1
31
+
32
+
33
+ def parse_tb_file(filename):
34
+ with open(filename, "r") as io:
35
+ header = io.readline().strip()
36
+ a1 = np.fromstring(io.readline().strip(), sep=" ")
37
+ a2 = np.fromstring(io.readline().strip(), sep=" ")
38
+ a3 = np.fromstring(io.readline().strip(), sep=" ")
39
+ # a1, a2, a3 = np.array(list(map(float, [a1, a2, a3])), dtype=np.float64)
40
+ # lattice = np.vstack((a1.reshape(-1, 1), a2.reshape(-1, 1), a3.reshape(-1, 1))).T
41
+ lattice = np.vstack((a1, a2, a3))
42
+
43
+ n_wann = int(ssrline(io)[0])
44
+ n_Rvecs = int(ssrline(io)[0])
45
+
46
+ Rdegens = []
47
+ line = io.readline().strip()
48
+ while line != "":
49
+ Rdegens += [int(x) for x in line.split()]
50
+ line = io.readline().strip()
51
+ assert len(Rdegens) == n_Rvecs, "Rdegens length does not match n_Rvecs"
52
+
53
+ Rvectors = np.zeros((n_Rvecs, 3), dtype=np.int32)
54
+ # H = np.zeros((n_Rvecs,n_wann, n_wann), dtype=np.complex128)
55
+ H = {}
56
+ r_x = np.zeros((n_Rvecs, n_wann, n_wann), dtype=np.complex128)
57
+ r_y = np.zeros((n_Rvecs, n_wann, n_wann), dtype=np.complex128)
58
+ r_z = np.zeros((n_Rvecs, n_wann, n_wann), dtype=np.complex128)
59
+ pos_operator = np.zeros((n_Rvecs, n_wann, n_wann, 3), dtype=np.complex128)
60
+
61
+ for iR in range(n_Rvecs):
62
+ # read Rvectors
63
+ Rvectors[iR] = np.fromstring(io.readline().strip(), sep=" ")
64
+ Rvectors[iR] = Rvectors[iR].astype(np.int32)
65
+ R = tuple(Rvectors[iR])
66
+ H[R] = np.zeros((n_wann, n_wann), dtype=np.complex128)
67
+ # read H
68
+ for n in range(n_wann):
69
+ for m in range(n_wann):
70
+ line = ssrline(io)
71
+ assert (
72
+ m == int(line[0]) - 1 and n == int(line[1]) - 1
73
+ ), "Unexpected indices"
74
+ reH, imH = float(line[2]), float(line[3])
75
+ # H[iR][m, n] = reH + 1j * imH
76
+ H[R][m, n] = (reH + 1j * imH) / 2.0
77
+ io.readline() # empty line
78
+ # set the onsite term to half
79
+ # np.fill_diagonal(H[(0, 0, 0)], H[(0, 0, 0)].diagonal() / 2.0)
80
+ # print("onsite H from TB: ", H[(0, 0, 0)].diagonal())
81
+
82
+ iR0 = find_Rvectors(Rvectors, [0, 0, 0])
83
+ for iR in range(n_Rvecs):
84
+ # read Rvectors
85
+ line = io.readline().strip()
86
+ Rvectors[iR] = np.fromstring(line, sep=" ")
87
+ Rvectors[iR] = Rvectors[iR].astype(np.int32)
88
+ # read r_x, r_y, r_z
89
+ for n in range(n_wann):
90
+ for m in range(n_wann):
91
+ line = ssrline(io)
92
+ assert (
93
+ m == int(line[0]) - 1 and n == int(line[1]) - 1
94
+ ), f"Unexpected indices in line {line}"
95
+ pos_operator[iR, m, n, 0] = complex(float(line[2]), float(line[3]))
96
+ pos_operator[iR, m, n, 1] = complex(float(line[4]), float(line[5]))
97
+ pos_operator[iR, m, n, 2] = complex(float(line[6]), float(line[7]))
98
+ io.readline()
99
+
100
+ # print(
101
+ # f"Reading tb.dat file: {filename} | Header: {header} | n_wann: {n_wann} | n_Rvecs: {n_Rvecs}"
102
+ # )
103
+
104
+ centers = pos_operator[iR0, :, :, :].diagonal(offset=0, axis1=0, axis2=1).T.real
105
+
106
+ return {
107
+ "n_wann": n_wann,
108
+ "lattice": lattice,
109
+ "Rvectors": Rvectors,
110
+ "Rdegens": Rdegens,
111
+ "H": H,
112
+ "pos_operator": pos_operator,
113
+ "centers": centers,
114
+ "header": header,
115
+ }
116
+
117
+
118
+ def test_parse_tb_file():
119
+ filename = "cri3_up_tb.dat"
120
+ result = parse_tb_file(filename)
121
+ # rvecs=result["Rvectors"]
122
+ # iR=find_Rvectors(rvecs, [0, 0, 0])
123
+ # for i in range(30):
124
+ # print(np.real(result["pos_operator"][iR, i, i, :]))
125
+ print(result["centers"])
126
+
127
+
128
+ if __name__ == "__main__":
129
+ test_parse_tb_file()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: TB2J
3
- Version: 0.8.0
3
+ Version: 0.8.2.1
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
@@ -2,7 +2,7 @@ TB2J/Jdownfolder.py,sha256=Nw2ixvn2Uq-o1wficz6rdaYHjfRN3U_kQCvrNJGNb68,6980
2
2
  TB2J/Jtensor.py,sha256=0fhfOcfVQGu75gytEnApKWTJZfg9ksKJ0anJgco5wRQ,3179
3
3
  TB2J/Oiju.py,sha256=yQMfxQGnOSLbuTS22upkEFsJ9UAZk7wFaWynvg1NVdA,3595
4
4
  TB2J/Oiju_epc.py,sha256=sqjLIuWWT-d0uH2O7-6mobsUYQjHP5GyGlmdYqvkXFk,7332
5
- TB2J/__init__.py,sha256=iPlYCcIzuzW7T2HKDkmYlMkRI51dBLfNRxPPiWrfw9U,22
5
+ TB2J/__init__.py,sha256=Gz3blTF1z7t2vohcgNvCiRBFGzinOatDXOyHy8k81ow,24
6
6
  TB2J/basis.py,sha256=DFo6_QUwjBwisP6zGxvoO0lpGTMDPAOkiL9giNCjOjA,1558
7
7
  TB2J/citation.py,sha256=gcQeyJZaT1Qrtsl8Y3s4neOH3-vvgmIcCvXeV2o3vj0,2891
8
8
  TB2J/contour.py,sha256=aw8LX6wVFCRPhcpkzuI0jGnHisvk4cezvUhkF_6Yx94,2633
@@ -16,17 +16,17 @@ TB2J/exchange_qspace.py,sha256=ZL68qBGFUaQ9BsSPsJaaoWOr9RssPiqX34R_9I3nk_8,8436
16
16
  TB2J/gpaw_wrapper.py,sha256=aJ--9Dtyq7jOP1Hkh-Sh1nWcfXm6zKcljOCO0DNCAr0,6890
17
17
  TB2J/green.py,sha256=aaXFZn8B60kjsvThoBk0fVi5jm5RJBb-LT4E9XCFo2w,13169
18
18
  TB2J/greentest.py,sha256=2ISSfhor9ecSEOi_E6b4Cv26wEIQlwlzca0ru8z44_E,1603
19
- TB2J/io_merge.py,sha256=p9ylwsWRN3YgUgj0GH0J9-GlTUUfuyIMJYxDhYxhV7g,15261
19
+ TB2J/io_merge.py,sha256=H1jovWIvYRw4KABS6mEL5OwGZHm9emJ-QJjQpeJHwRU,15263
20
20
  TB2J/kpoints.py,sha256=6XK2KqTncidEq3o9GuO6VEZRPNTRtWeXg9QfcV-9smI,532
21
- TB2J/manager.py,sha256=IqZ0cpGz6pBFA7uf9Jc1GzSDCxdIDnTlS1BWqq2mkzw,15389
21
+ TB2J/manager.py,sha256=hiryBJ5b2LMmZ34GXc-gbk3WhWHh6Tjy5OXD-lposVo,15846
22
22
  TB2J/mathutils.py,sha256=tHA6q3KPDpXLIbZHdDZ2NU5s886VVM_oEG490zQ6Ris,300
23
- TB2J/myTB.py,sha256=WAGXqJ4SHSUQhHLN8ODTYXoExw9oEDK2eNY0YS-RAy0,17158
23
+ TB2J/myTB.py,sha256=cm9Kkyzi686QyoxrR3lm4rsSnE6Imee3-j2xM78XnGI,17721
24
24
  TB2J/orbmap.py,sha256=RCMJkOPGbfPrcZzcc5ia1ZMKBQWxGcyj8W1ve8BJaEw,6669
25
25
  TB2J/pauli.py,sha256=_FIF62jq2CkQdWC473a3S2F6NmzCdeCnglO9PjNVmMI,4120
26
26
  TB2J/pert.py,sha256=RaCJfewl0doht4cjAnzzGKe-uj2le4aqe0iPKFrq9fo,1192
27
27
  TB2J/plot.py,sha256=AnFIFWE2vlmj7Z6f_7-dX_O1stJN-qbuiurPj43dUCM,4104
28
28
  TB2J/rotate_atoms.py,sha256=-fxlQN7LbyQAbGUCUBqDJ5ENR0pT8MLBd-5sLxaX_vI,3031
29
- TB2J/sisl_wrapper.py,sha256=wk9tYfF9cPLYXAbs5Vs3Uf_wbPCtFSgH9CS0ClIhqvE,10580
29
+ TB2J/sisl_wrapper.py,sha256=szeNB_VrRklcMCfWrwnI1Vsv5wqJ92EwwlrWNrIPHM0,14785
30
30
  TB2J/supercell.py,sha256=4hgLGPBLRUDhtD-eF29v46ex7fHdkH-OENjS2wGLFww,19588
31
31
  TB2J/tensor_rotate.py,sha256=4-DfT_Mg5e40fbd74M5W0D5DqmUq-kVOOLDkkkI834A,8083
32
32
  TB2J/utest.py,sha256=z_ahi7tpHQF9WlHNQihcQ7qzfezRJQXQt28eB1X_z64,3897
@@ -34,16 +34,16 @@ TB2J/utils.py,sha256=xIKX6p6ULoESWngDLSJsfQQewxsvIWI5l7Uwj_Y5H7U,9262
34
34
  TB2J/versioninfo.py,sha256=wZwS9QDFRVDe7rf8JyPDDI8UGdTQiO6Pb_sWv8GAegA,337
35
35
  TB2J/abacus/__init__.py,sha256=5sHiDnF2L-Y80QeET9zOiS83a5T_TQAXvnIhcYB6wNU,56
36
36
  TB2J/abacus/abacus_api.py,sha256=D_NyXW-Pno92d3RVHByx0l1HDPHQAvXsmQVt8cfIGR8,7267
37
- TB2J/abacus/abacus_wrapper.py,sha256=-d0vYFi3IkTpSkiKyF_0_qkiYHIu2nqk46SWeNcmeTU,7832
38
- TB2J/abacus/gen_exchange_abacus.py,sha256=dRDZWELfD209uNEyr-QscgYm3ZvGW-Lb9LoJFIbobxQ,2952
37
+ TB2J/abacus/abacus_wrapper.py,sha256=cvOem5WiWYcYqLRBopPACTMEFOvl2jFu2O9rlNbtoPI,8488
38
+ TB2J/abacus/gen_exchange_abacus.py,sha256=lKZqkWMnLQtaSwgn8O5Fzr-pV6tzwoMqfZU_vbET6gU,2973
39
39
  TB2J/abacus/orbital_api.py,sha256=l48Hn5z7TA0TH7Is4NDmz74b6B9L2ztYO4dRR37U4mQ,1562
40
- TB2J/abacus/stru_api.py,sha256=uB_SGqcmYaj4zPGD_2eqSymcXWpu8paxXprFuJsowIQ,67790
40
+ TB2J/abacus/stru_api.py,sha256=aBKKlZ2hvAZChVCfNxRdxH51rfHKqZn6kOlazY-yW8k,67888
41
41
  TB2J/abacus/test_read_HRSR.py,sha256=cAT-e79jGjCBXLTJ9UYX0WvalG_yD4Awl79tTOUcwaQ,1254
42
42
  TB2J/abacus/test_read_stru.py,sha256=CpK4zWhlCVAMCmYQmp9Hy-A40OblZQLFpo5JokpNcWQ,785
43
43
  TB2J/external/__init__.py,sha256=yD_ZIMi76H49rj6GAQpiB7UlKa3TgSaMkkLHT6M-8w8,137
44
44
  TB2J/external/p_tqdm.py,sha256=ug1jy3-43r8iW7bC37xzPSIe0EjYKH_GUluGzMiQiDw,5831
45
45
  TB2J/io_exchange/__init__.py,sha256=KfGHum7B8E4G_KKfillqw0lErtoyKEuFUUttHLs-mg4,32
46
- TB2J/io_exchange/io_exchange.py,sha256=ucd5wtRrMfobpHmF45C-NSmJjuE9Ho8kBe3W6q8KqWw,18550
46
+ TB2J/io_exchange/io_exchange.py,sha256=eJRQM1-ikuNJTfCAB0tgTFwvMA_TiWkGlevVu5CeeAk,19408
47
47
  TB2J/io_exchange/io_multibinit.py,sha256=8PDmWxzGuv-GwJosj2ZTmiyNY_duFVWJ4ekCuSqGdd8,6739
48
48
  TB2J/io_exchange/io_pickle.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
49
  TB2J/io_exchange/io_tomsasd.py,sha256=NqkAC1Fl-CUnFA21eBzSy_S5F_oeQFJysw4UukQbN8o,4173
@@ -60,19 +60,20 @@ TB2J/spinham/qsolver.py,sha256=Sr9I3aGfVNYn5wzwPx1QonHe6ZZUXBAujWRa7nTA5u4,4986
60
60
  TB2J/spinham/spin_api.py,sha256=oN3AKg1WQl0YzR4f5ealcJOaVoAy8d7HodIwrbXvQeY,2219
61
61
  TB2J/spinham/spin_xml.py,sha256=mneeZzkCE5andvIlur_6VK3XzWvoL-PVqSoWKXtDYTM,11033
62
62
  TB2J/spinham/supercell.py,sha256=y17uUC6r3gQb278FhxIW4CABihfLTvKFj6flyXrCPR8,12217
63
- TB2J/wannier/__init__.py,sha256=XGE3zbL2zI4CK08oNDOhOiAfF6aGl0lj3wE2VxswpYE,70
64
- TB2J/wannier/w90_parser.py,sha256=1MtVqOmMKwz4_jrkxyju9WfEBqzTXdgxpF6f0IGnAKo,4102
65
- TB2J-0.8.0.data/scripts/TB2J_downfold.py,sha256=F9oImXFysejCMP7eIBjbCX2jdHFOCvDW5beF1sG-UM8,1854
66
- TB2J-0.8.0.data/scripts/TB2J_eigen.py,sha256=Qs9v2hnMm2Tpfoa4h53muUKty2dZjwx8948MBoQooNg,1128
67
- TB2J-0.8.0.data/scripts/TB2J_magnon.py,sha256=q7UwAmorRcFNk4tfE7gl_ny05l6p7pbD9Wm_LkIpKEw,3101
68
- TB2J-0.8.0.data/scripts/TB2J_magnon_dos.py,sha256=TMXQvD2dIbO5FZ4tUMmxJgCgH2O2hDAPUNfEKO4z-x4,110
69
- TB2J-0.8.0.data/scripts/TB2J_merge.py,sha256=uZKLM__EyCHwxrQvx3Wd73dOEADp_SqfYC8KQvA-N9g,1622
70
- TB2J-0.8.0.data/scripts/TB2J_rotate.py,sha256=XPacPb7-DaFafBXFdWuNW_eNbjd5XPdNhBRNYhge_cg,634
71
- TB2J-0.8.0.data/scripts/abacus2J.py,sha256=M4B07lvTCDczTPTqvnDh_PERzCARAd09TLKv4aIdSQM,4408
72
- TB2J-0.8.0.data/scripts/siesta2J.py,sha256=Q_kvdgE34JJKVUMgBCSe07kARge0XULJ9B6z8hQFu6M,4706
73
- TB2J-0.8.0.data/scripts/wann2J.py,sha256=0g8Y5RbsYgV7iuoRQEeOnpaBy3oNpRfiw1dy6lWD13E,6520
74
- TB2J-0.8.0.dist-info/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
75
- TB2J-0.8.0.dist-info/METADATA,sha256=vSK6t7OXXDLM_tpYrSBF-aTtmOTlBrhGhrV6_hpQnZo,1462
76
- TB2J-0.8.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
77
- TB2J-0.8.0.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
78
- TB2J-0.8.0.dist-info/RECORD,,
63
+ TB2J/wannier/__init__.py,sha256=7ojCbM84PYv1X1Tbo4NHI-d3gWmQsZB_xiYqbfxVV1E,80
64
+ TB2J/wannier/w90_parser.py,sha256=vkZljyHu-TBts-5jmjgDNdfsQoD06PJQeBwajwOq9qg,4459
65
+ TB2J/wannier/w90_tb_parser.py,sha256=qt8pnuprmPp9iIAYwPkPbmEzk6ZPgMq2xognoQp7vwc,4610
66
+ TB2J-0.8.2.1.data/scripts/TB2J_downfold.py,sha256=F9oImXFysejCMP7eIBjbCX2jdHFOCvDW5beF1sG-UM8,1854
67
+ TB2J-0.8.2.1.data/scripts/TB2J_eigen.py,sha256=Qs9v2hnMm2Tpfoa4h53muUKty2dZjwx8948MBoQooNg,1128
68
+ TB2J-0.8.2.1.data/scripts/TB2J_magnon.py,sha256=q7UwAmorRcFNk4tfE7gl_ny05l6p7pbD9Wm_LkIpKEw,3101
69
+ TB2J-0.8.2.1.data/scripts/TB2J_magnon_dos.py,sha256=TMXQvD2dIbO5FZ4tUMmxJgCgH2O2hDAPUNfEKO4z-x4,110
70
+ TB2J-0.8.2.1.data/scripts/TB2J_merge.py,sha256=uZKLM__EyCHwxrQvx3Wd73dOEADp_SqfYC8KQvA-N9g,1622
71
+ TB2J-0.8.2.1.data/scripts/TB2J_rotate.py,sha256=XPacPb7-DaFafBXFdWuNW_eNbjd5XPdNhBRNYhge_cg,634
72
+ TB2J-0.8.2.1.data/scripts/abacus2J.py,sha256=M4B07lvTCDczTPTqvnDh_PERzCARAd09TLKv4aIdSQM,4408
73
+ TB2J-0.8.2.1.data/scripts/siesta2J.py,sha256=Q_kvdgE34JJKVUMgBCSe07kARge0XULJ9B6z8hQFu6M,4706
74
+ TB2J-0.8.2.1.data/scripts/wann2J.py,sha256=0g8Y5RbsYgV7iuoRQEeOnpaBy3oNpRfiw1dy6lWD13E,6520
75
+ TB2J-0.8.2.1.dist-info/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
76
+ TB2J-0.8.2.1.dist-info/METADATA,sha256=wqoI-chRFjU7XfO3zZTNH8B2L6mJsPefB_JJR_CkE-E,1464
77
+ TB2J-0.8.2.1.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
78
+ TB2J-0.8.2.1.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
79
+ TB2J-0.8.2.1.dist-info/RECORD,,
File without changes
File without changes
File without changes