TB2J 0.9.10.1__py3-none-any.whl → 0.9.10.3__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/Jdownfolder.py CHANGED
@@ -35,6 +35,7 @@ class JR_model:
35
35
 
36
36
  class JDownfolder:
37
37
  def __init__(self, JR, Rlist, iM, iL, qmesh, iso_only=False):
38
+ self.nxyz = 1 if iso_only else 3
38
39
  self.model = JR_model(JR, Rlist)
39
40
  self.Rlist = Rlist
40
41
  self.nR = len(Rlist)
@@ -53,15 +54,14 @@ class JDownfolder:
53
54
  def get_JR(self):
54
55
  JR_downfolded = np.zeros((self.nR, self.nMn, self.nMn), dtype=float)
55
56
  Jq_downfolded = np.zeros((self.nqpt, self.nMn, self.nMn), dtype=complex)
56
- self.iMn = ind_to_indn(self.iM, n=3)
57
- self.iLn = ind_to_indn(self.iL, n=3)
57
+ self.iMn = ind_to_indn(self.iM, n=self.nxyz)
58
+ self.iLn = ind_to_indn(self.iL, n=self.nxyz)
58
59
  for iq, q in enumerate(self.qpts):
59
60
  Jq = self.model.get_Jq(q)
60
61
  Jq_downfolded[iq] = self.downfold_oneq(Jq)
61
62
  for iR, R in enumerate(self.Rlist):
62
63
  phase = np.exp(-2.0j * np.pi * np.dot(q, R))
63
64
  JR_downfolded[iR] += np.real(Jq_downfolded[iq] * phase / self.nqpt)
64
- return JR_downfolded, self.Rlist
65
65
 
66
66
  def downfold_oneq(self, J):
67
67
  JMM = J[np.ix_(self.iMn, self.iMn)]
@@ -79,12 +79,13 @@ class PWFDownfolder:
79
79
  MagnonWrapper,
80
80
  )
81
81
 
82
- model = MagnonWrapper(JR, Rlist, atoms)
82
+ model = MagnonWrapper(JR, Rlist, atoms, align_evecs=not iso_only)
83
83
  wann = MagnonDownfolder(model)
84
84
  # Downfold the band structure.
85
85
  index_basis = []
86
+ self.nxyz = 1 if iso_only else 3
86
87
  for i in iM:
87
- index_basis += list(range(i * 3, i * 3 + 3))
88
+ index_basis += list(range(i * self.nxyz, i * self.nxyz + self.nxyz))
88
89
  params = dict(
89
90
  method="projected",
90
91
  # method="maxprojected",
@@ -93,8 +94,10 @@ class PWFDownfolder:
93
94
  selected_basis=index_basis,
94
95
  # anchors={(0, 0, 0): (-1, -2, -3, -4)},
95
96
  # anchors={(0, 0, 0): ()},
96
- # use_proj=True,
97
- enhance_Amn=1.4,
97
+ # weight_func="Gauss",
98
+ # weight_func_params=(-0.143, 0.04),
99
+ use_proj=True,
100
+ enhance_Amn=0.0,
98
101
  )
99
102
  params.update(kwargs)
100
103
  wann.set_parameters(**params)
@@ -176,7 +179,19 @@ class JDownfolder_pickle:
176
179
  self.nsite = self.nM + self.nL
177
180
 
178
181
  def _downfold(self, **kwargs):
179
- JR2 = self.exc.get_full_Jtensor_for_Rlist(order="i3j3_2D", asr=True)
182
+ if self.iso_only:
183
+ JR2 = self.exc.get_full_Jtensor_for_Rlist(
184
+ order="ij", asr=True, DMI=False, Jani=False
185
+ )
186
+ # magmoms = self.exc.magmoms
187
+ # magmoms of magnetic atoms (metal + ligand)
188
+ # mmagmoms = magmoms[self.iM + self.iL]
189
+ # sqrt_magmoms = np.sqrt(np.abs(mmagmoms))
190
+ # magmoms_mat = np.outer(sqrt_magmoms, sqrt_magmoms)
191
+ # JR2 = JR2 / magmoms_mat
192
+ else:
193
+ JR2 = self.exc.get_full_Jtensor_for_Rlist(order="i3j3_2D", asr=True)
194
+
180
195
  if self.method.lower() == "lowdin":
181
196
  d = JDownfolder(
182
197
  JR2,
@@ -199,6 +214,8 @@ class JDownfolder_pickle:
199
214
  **kwargs,
200
215
  )
201
216
  Jd, Rlist = d.get_JR()
217
+ # metal_sqrt_magmoms = np.sqrt(np.abs(self.exc.magmoms[self.iM]))
218
+ # Jd = Jd * np.outer(metal_sqrt_magmoms, metal_sqrt_magmoms)
202
219
  return Jd, Rlist
203
220
 
204
221
  def _Jd_to_exchange(self, Jd, Rlist):
@@ -217,15 +234,21 @@ class JDownfolder_pickle:
217
234
  for j, jspin in enumerate(self.index_spin):
218
235
  if ispin >= 0 and jspin >= 0:
219
236
  if not (tuple(R) == (0, 0, 0) and ispin == jspin):
220
- # self interaction.
221
- J33 = Jd[
222
- iR, ispin * 3 : ispin * 3 + 3, jspin * 3 : jspin * 3 + 3
223
- ]
224
- J, DMI, Jani = decompose_J_tensor(J33)
225
- self.Jdict[(tuple(R), ispin, jspin)] = J
226
- if not self.iso_only:
227
- self.DMIdict[(tuple(R), ispin, jspin)] = DMI
228
- self.Janidict[(tuple(R), ispin, jspin)] = Jani
237
+ if self.iso_only:
238
+ J = Jd[iR, ispin, jspin]
239
+ self.DMIdict = None
240
+ self.Janidict = None
241
+ self.Jdict[(tuple(R), ispin, jspin)] = J.real
242
+ else:
243
+ J33 = Jd[
244
+ iR,
245
+ ispin * 3 : ispin * 3 + 3,
246
+ jspin * 3 : jspin * 3 + 3,
247
+ ]
248
+ J, DMI, Jani = decompose_J_tensor(J33)
249
+ self.Jdict[(tuple(R), ispin, jspin)] = J.real
250
+ self.DMIdict[(tuple(R), ispin, jspin)] = DMI.real
251
+ self.Janidict[(tuple(R), ispin, jspin)] = Jani.real
229
252
 
230
253
  io = SpinIO(
231
254
  atoms=self.atoms,
TB2J/exchange.py CHANGED
@@ -202,7 +202,6 @@ class Exchange(ExchangeParams):
202
202
  include_only=self.include_orbs[syms[iatom]],
203
203
  )
204
204
  else:
205
- # print(f"orbs: {orbs}")
206
205
  mmat, reduced_orbs = map_orbs_matrix(
207
206
  orbs, spinor=not (self._is_collinear), include_only=None
208
207
  )
TB2J/exchangeCL2.py CHANGED
@@ -186,15 +186,17 @@ class ExchangeCL2(ExchangeCL):
186
186
  jspin = self.ispin(jatom)
187
187
  keyspin = (R, ispin, jspin)
188
188
  is_nonself = not (R == (0, 0, 0) and iatom == jatom)
189
- Jij = np.imag(val) / np.sign(np.dot(self.spinat[iatom], self.spinat[jatom]))
190
189
  Jorbij = np.imag(self.Jorb[key]) / np.sign(
191
190
  np.dot(self.spinat[iatom], self.spinat[jatom])
192
191
  )
192
+
193
+ Jij = np.imag(val) / np.sign(np.dot(self.spinat[iatom], self.spinat[jatom]))
194
+
193
195
  if is_nonself:
194
196
  self.exchange_Jdict[keyspin] = Jij
195
- self.Jiso_orb[keyspin] = self.simplify_orbital_contributions(
196
- Jorbij, iatom, jatom
197
- )
197
+ Jsimp = self.simplify_orbital_contributions(Jorbij, iatom, jatom)
198
+ self.Jiso_orb[keyspin] = Jsimp
199
+ self.exchange_Jdict[keyspin] = np.sum(Jsimp)
198
200
 
199
201
  def get_rho_e(self, rho_up, rho_dn):
200
202
  # self.rho_up_list.append(-1.0 / np.pi * np.imag(rho_up[(0,0,0)]))
@@ -399,6 +399,26 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
399
399
  )
400
400
  return Jmat
401
401
 
402
+ def get_full_Jtensor_for_one_R_ij(self, R, Jiso=True, Jani=True, DMI=True):
403
+ """
404
+ Return the full exchange tensor of all i and j for cell R.
405
+ param R (tuple of integers): cell index R
406
+ returns:
407
+ Jmat: (nspin,nspin,3,3) matrix.
408
+ """
409
+ if Jani or DMI:
410
+ raise ValueError(
411
+ "Jani and DMI are not supported for this method. Use get_full_Jtensor_for_one_R_ij33 instead."
412
+ )
413
+ n = self.nspin
414
+ Jmat = np.zeros((n, n), dtype=float)
415
+ for i in range(self.nspin):
416
+ for j in range(self.nspin):
417
+ J = self.get_Jiso(i, j, R)
418
+ if J is not None:
419
+ Jmat[i, j] = J
420
+ return Jmat
421
+
402
422
  def get_full_Jtensor_for_Rlist(
403
423
  self, asr=False, Jiso=True, Jani=True, DMI=True, order="i3j3"
404
424
  ):
@@ -439,11 +459,28 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
439
459
  if asr:
440
460
  iR0 = np.argmin(np.linalg.norm(self.Rlist, axis=1))
441
461
  assert np.linalg.norm(self.Rlist[iR0]) == 0
462
+ sum_JR = np.sum(np.sum(Jmat, axis=0))
442
463
  for i in range(n3):
443
- sum_JRi = np.sum(np.sum(Jmat, axis=0)[i])
444
- Jmat[iR0][i, i] -= sum_JRi
464
+ Jmat[iR0][i, i] -= sum_JRi[i]
465
+ elif order == "ij":
466
+ Jmat = np.zeros((nR, n, n), dtype=float)
467
+ for iR, R in enumerate(self.Rlist):
468
+ Jmat[iR] = self.get_full_Jtensor_for_one_R_ij(
469
+ R, Jiso=Jiso, Jani=Jani, DMI=DMI
470
+ )
471
+ if asr:
472
+ iR0 = np.argmin(np.linalg.norm(self.Rlist, axis=1))
473
+ assert np.linalg.norm(self.Rlist[iR0]) == 0
474
+ # check if Jmat has NaN values
475
+ # sum_JR = np.sum(np.sum(Jmat, axis=0), axis=0)
476
+ # sum over axis 0 and 1
477
+ sum_JR = np.sum(Jmat, axis=(0, 1))
478
+ for i in range(n):
479
+ Jmat[iR0][i, i] -= sum_JR[i]
445
480
  else:
446
- raise ValueError("order must be either 'i3j3' or 'ij33', or 'i3j3_2D'.")
481
+ raise ValueError(
482
+ "order must be either 'i3j3' or 'ij33', or 'i3j3_2D', or 'ij'."
483
+ )
447
484
  return Jmat
448
485
 
449
486
  def write_pickle(self, path="TB2J_results", fname="TB2J.pickle"):
@@ -473,6 +510,7 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
473
510
 
474
511
  def write_all(self, path="TB2J_results"):
475
512
  self.write_pickle(path=path)
513
+ self.atoms.write(os.path.join(path, "structure.vasp"), vasp5=True)
476
514
  self.write_txt(path=path)
477
515
  if self.Jiso_orb:
478
516
  self.write_txt(
@@ -492,11 +530,6 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
492
530
 
493
531
  write_txt(self, *args, **kwargs)
494
532
 
495
- # def write_txt_with_orb(self, path):
496
- # from TB2J.io_exchange.io_txt import write_txt
497
- # write_txt_with_orb(
498
- # self, path=path, write_experimental=self.write_experimental)
499
-
500
533
  def write_multibinit(self, path):
501
534
  from TB2J.io_exchange.io_multibinit import write_multibinit
502
535
 
@@ -541,7 +574,7 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
541
574
  Js.append(val * 1e3)
542
575
  ax.scatter(ds, Js, marker=marker, color=color, **kwargs)
543
576
  ax.axhline(color="gray")
544
- ax.set_xlabel("Distance ($\AA$)")
577
+ ax.set_xlabel(r"Distance ($\AA$)")
545
578
  ax.set_ylabel("J (meV)")
546
579
  if fname is not None:
547
580
  plt.savefig(fname)
@@ -569,7 +602,7 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
569
602
  ax.axhline(color="gray")
570
603
  ax.legend(loc=1)
571
604
  ax.set_ylabel("D (meV)")
572
- ax.set_xlabel("Distance ($\AA$)")
605
+ ax.set_xlabel(r"Distance ($\AA$)")
573
606
  if fname is not None:
574
607
  plt.savefig(fname)
575
608
  if show:
@@ -601,7 +634,7 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
601
634
  )
602
635
  ax.axhline(color="gray")
603
636
  ax.legend(loc=1, ncol=2)
604
- ax.set_xlabel("Distance ($\AA$)")
637
+ ax.set_xlabel(r"Distance ($\AA$)")
605
638
  ax.set_ylabel("Jani (meV)")
606
639
  if fname is not None:
607
640
  plt.savefig(fname)
@@ -1,8 +1,10 @@
1
- import numpy as np
2
1
  import os
3
- from TB2J.utils import symbol_number
2
+
3
+ import numpy as np
4
4
  from numpy import array_str
5
5
 
6
+ from TB2J.utils import symbol_number
7
+
6
8
 
7
9
  def write_info_section(cls, myfile):
8
10
  myfile.write("=" * 90 + "\n")
@@ -17,7 +19,7 @@ def write_atom_section(cls, myfile):
17
19
  write the atom section
18
20
  including the cell and the atomic positions.
19
21
  """
20
- myfile.write("=" * 90 + "\n")
22
+ myfile.write("\n" + "=" * 90 + "\n")
21
23
  myfile.write("Cell (Angstrom):\n")
22
24
  cell = cls.atoms.get_cell()
23
25
  for c in cell:
@@ -42,7 +44,7 @@ def write_atom_section(cls, myfile):
42
44
  )
43
45
 
44
46
  symnum = symbol_number(cls.atoms)
45
- sns = list(symnum.keys())
47
+ # sns = list(symnum.keys())
46
48
  poses = cls.atoms.get_positions()
47
49
 
48
50
  tchg, tmx, tmy, tmz = 0, 0, 0, 0
@@ -105,7 +107,7 @@ def write_exchange_section(
105
107
  ):
106
108
  symnum = symbol_number(cls.atoms)
107
109
  sns = list(symnum.keys())
108
- poses = cls.atoms.get_positions()
110
+ # poses = cls.atoms.get_positions()
109
111
 
110
112
  myfile.write("=" * 90 + "\n")
111
113
  myfile.write("Exchange: \n")
@@ -183,9 +185,8 @@ def write_exchange_section(
183
185
  DMI2[0], DMI2[1], DMI2[2]
184
186
  )
185
187
  )
186
- pass
187
- except:
188
- pass
188
+ except Exception as e:
189
+ myfile.write(f"[Debug!] DMI2 not available: {e}\n")
189
190
 
190
191
  if cls.Jani_dict is not None:
191
192
  J = cls.Jani_dict[ll] * 1e3
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: TB2J
3
- Version: 0.9.10.1
3
+ Version: 0.9.10.3
4
4
  Summary: TB2J: First principle to Heisenberg exchange J using tight-binding Green function method
5
5
  Author-email: Xu He <mailhexu@gmail.com>
6
6
  Maintainer-email: Xu He <mailhexu@gmail.com>
@@ -1,4 +1,4 @@
1
- TB2J/Jdownfolder.py,sha256=ZKF0AVnwaJ4DPKfQ28NsJXhpOZE9_rsusEFtNCm5kls,9675
1
+ TB2J/Jdownfolder.py,sha256=U6R8v6ZC-AgMA6wvvFPyacXX_lYJcRu1kzNr7aVB1tg,10827
2
2
  TB2J/Jtensor.py,sha256=WRhpp5N92a6lA1jeM1hc7jYUoTOLIdMnIIKpdOyzjR4,3192
3
3
  TB2J/MAE.py,sha256=fM8U-Dgp9HcQOEeC_kyZV1oVrygBvcux9BraUXVouvY,10994
4
4
  TB2J/MAEGreen.py,sha256=zVLjQtFDFcRmC8PYm7MOgKnkOuFJEMKr-eoNBABUsMc,15759
@@ -11,8 +11,8 @@ TB2J/citation.py,sha256=gcQeyJZaT1Qrtsl8Y3s4neOH3-vvgmIcCvXeV2o3vj0,2891
11
11
  TB2J/contour.py,sha256=zLHQZZ3hhgLkLFPATCraLOJyLJKLC0fba_L_5sRz23o,3246
12
12
  TB2J/density_matrix.py,sha256=D5k8Oe21OCiLVORNYbo4TZOFG0slrQSbj91kJ3TMFjs,1514
13
13
  TB2J/epc.py,sha256=zLbtqZJhDr8DnnGN6YENcXwrMb3Qxu6KB08mLy9Pw20,3474
14
- TB2J/exchange.py,sha256=-BEXSQqx374cRbJWjvjyJAZkchzNK1uPUDvTYox3Axs,26982
15
- TB2J/exchangeCL2.py,sha256=P7bklMXVYX_tn9DbjEPqeTir1SeZyfPBIP1fhWUzLmY,11419
14
+ TB2J/exchange.py,sha256=qDID0faZOWggPLaIC8QY2tOinZaEFU88FNqOJid53-s,26937
15
+ TB2J/exchangeCL2.py,sha256=1b0Lx5dSjgCUYSSng5cqJzo-hmXCD91cbaes9jqsU5s,11474
16
16
  TB2J/exchange_params.py,sha256=VW9nGVio6M_Ub9-36L_LExhjgdD1E_joYpI8AxmM360,8029
17
17
  TB2J/exchange_pert.py,sha256=jmFMtQbYa_uczM4VAeS6TijkIHRFIqEzZJswzE9Wfuo,8523
18
18
  TB2J/exchange_qspace.py,sha256=ZL68qBGFUaQ9BsSPsJaaoWOr9RssPiqX34R_9I3nk_8,8436
@@ -56,10 +56,10 @@ TB2J/interfaces/abacus/test_density_matrix.py,sha256=bMWWJYtDS57SpPZ-eZXZ9Hr_UK4
56
56
  TB2J/interfaces/abacus/test_read_HRSR.py,sha256=W1oO_yigT50Yb5_u-KB_IfTpM7kArGkBuMSMs0H4CTs,1235
57
57
  TB2J/interfaces/abacus/test_read_stru.py,sha256=hoKPHVco8vwzC7Gao4bOPCdAPhh29x-9DTJJqRr7AYM,788
58
58
  TB2J/io_exchange/__init__.py,sha256=LqEnG67qDVKt4hCUywDEQvUIJ7jsQjmtueOW_J16NOE,54
59
- TB2J/io_exchange/io_exchange.py,sha256=KQNCd3G_9Ck-qQX1UMKjfEPHyv5mC3BgRot_ngpACYs,23340
59
+ TB2J/io_exchange/io_exchange.py,sha256=hJ8Z0m46KKjK5aAsM70Fn4dR6vRmSIrR1B_QZz8Wrj8,24686
60
60
  TB2J/io_exchange/io_multibinit.py,sha256=8PDmWxzGuv-GwJosj2ZTmiyNY_duFVWJ4ekCuSqGdd8,6739
61
61
  TB2J/io_exchange/io_tomsasd.py,sha256=NqkAC1Fl-CUnFA21eBzSy_S5F_oeQFJysw4UukQbN8o,4173
62
- TB2J/io_exchange/io_txt.py,sha256=BMr1eSILlKpgtjvDx7uw2VMAkEKSvGEPNxpaT_zev0I,10547
62
+ TB2J/io_exchange/io_txt.py,sha256=jFScdZ5W5_VNSEWYq6WDNKWeshZ0wxFfEzyjfvvU9MA,10601
63
63
  TB2J/io_exchange/io_uppasd.py,sha256=bI4iPEgnK4TvCZNvb6x2xYXgjW7pEehCqmcizy2pqFU,3301
64
64
  TB2J/io_exchange/io_vampire.py,sha256=vOStLmtCiWLp9GPhZpsAmrtaRHg9KSmtOM2Fky6yCQA,5762
65
65
  TB2J/magnon/__init__.py,sha256=Q69duroGIIotgW_71ZdHYarSiJLGAu9NPYgEacUk6eI,117
@@ -92,9 +92,9 @@ TB2J/spinham/supercell.py,sha256=y17uUC6r3gQb278FhxIW4CABihfLTvKFj6flyXrCPR8,122
92
92
  TB2J/wannier/__init__.py,sha256=7ojCbM84PYv1X1Tbo4NHI-d3gWmQsZB_xiYqbfxVV1E,80
93
93
  TB2J/wannier/w90_parser.py,sha256=dbd63LuKyv2DVUzqRINGsbDzEsOxsQyE8_Ear_LQIRg,4620
94
94
  TB2J/wannier/w90_tb_parser.py,sha256=qt8pnuprmPp9iIAYwPkPbmEzk6ZPgMq2xognoQp7vwc,4610
95
- tb2j-0.9.10.1.dist-info/licenses/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
96
- tb2j-0.9.10.1.dist-info/METADATA,sha256=aCAWVmSmHiwD7uwDvnlBQocGJaXPpqJAbBtOoJznASc,4138
97
- tb2j-0.9.10.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
98
- tb2j-0.9.10.1.dist-info/entry_points.txt,sha256=RuFfrRenhXgzZA1ND_4j4D8ylTXl6VbWLyV3fDx6KKw,734
99
- tb2j-0.9.10.1.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
100
- tb2j-0.9.10.1.dist-info/RECORD,,
95
+ tb2j-0.9.10.3.dist-info/licenses/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
96
+ tb2j-0.9.10.3.dist-info/METADATA,sha256=tdo-W3OUCQH6J7S4kYa9CUgpzpAO0r6ZOkOQCZr-v0U,4138
97
+ tb2j-0.9.10.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
98
+ tb2j-0.9.10.3.dist-info/entry_points.txt,sha256=RuFfrRenhXgzZA1ND_4j4D8ylTXl6VbWLyV3fDx6KKw,734
99
+ tb2j-0.9.10.3.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
100
+ tb2j-0.9.10.3.dist-info/RECORD,,