TB2J 0.9.0.1__py3-none-any.whl → 0.9.2rc0__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.
Files changed (38) hide show
  1. TB2J/Jdownfolder.py +110 -24
  2. TB2J/Jtensor.py +1 -1
  3. TB2J/MAE.py +185 -0
  4. TB2J/abacus/MAE.py +320 -0
  5. TB2J/abacus/abacus_wrapper.py +103 -4
  6. TB2J/abacus/occupations.py +278 -0
  7. TB2J/abacus/test_density_matrix.py +38 -0
  8. TB2J/cut_cell.py +82 -0
  9. TB2J/exchange.py +99 -73
  10. TB2J/exchangeCL2.py +10 -5
  11. TB2J/green.py +14 -15
  12. TB2J/io_exchange/io_pickle.py +0 -0
  13. TB2J/manager.py +10 -4
  14. TB2J/mathutils/__init__.py +1 -0
  15. TB2J/mathutils/fermi.py +22 -0
  16. TB2J/mathutils/kR_convert.py +90 -0
  17. TB2J/mathutils/lowdin.py +12 -0
  18. TB2J/mathutils/rotate_spin.py +56 -0
  19. TB2J/patch.py +50 -0
  20. TB2J/pauli.py +17 -0
  21. TB2J/spinham/h_matrix.py +68 -0
  22. TB2J/spinham/obtain_J.py +79 -0
  23. TB2J/supercell.py +532 -0
  24. {TB2J-0.9.0.1.data → TB2J-0.9.2rc0.data}/scripts/TB2J_downfold.py +8 -0
  25. {TB2J-0.9.0.1.dist-info → TB2J-0.9.2rc0.dist-info}/METADATA +1 -1
  26. {TB2J-0.9.0.1.dist-info → TB2J-0.9.2rc0.dist-info}/RECORD +38 -23
  27. {TB2J-0.9.0.1.dist-info → TB2J-0.9.2rc0.dist-info}/WHEEL +1 -1
  28. {TB2J-0.9.0.1.data → TB2J-0.9.2rc0.data}/scripts/TB2J_eigen.py +0 -0
  29. {TB2J-0.9.0.1.data → TB2J-0.9.2rc0.data}/scripts/TB2J_magnon.py +0 -0
  30. {TB2J-0.9.0.1.data → TB2J-0.9.2rc0.data}/scripts/TB2J_magnon_dos.py +0 -0
  31. {TB2J-0.9.0.1.data → TB2J-0.9.2rc0.data}/scripts/TB2J_merge.py +0 -0
  32. {TB2J-0.9.0.1.data → TB2J-0.9.2rc0.data}/scripts/TB2J_rotate.py +0 -0
  33. {TB2J-0.9.0.1.data → TB2J-0.9.2rc0.data}/scripts/TB2J_rotateDM.py +0 -0
  34. {TB2J-0.9.0.1.data → TB2J-0.9.2rc0.data}/scripts/abacus2J.py +0 -0
  35. {TB2J-0.9.0.1.data → TB2J-0.9.2rc0.data}/scripts/siesta2J.py +0 -0
  36. {TB2J-0.9.0.1.data → TB2J-0.9.2rc0.data}/scripts/wann2J.py +0 -0
  37. {TB2J-0.9.0.1.dist-info → TB2J-0.9.2rc0.dist-info}/LICENSE +0 -0
  38. {TB2J-0.9.0.1.dist-info → TB2J-0.9.2rc0.dist-info}/top_level.txt +0 -0
TB2J/supercell.py ADDED
@@ -0,0 +1,532 @@
1
+ """
2
+ A helper class for building supercells
3
+ """
4
+ import numpy as np
5
+ from collections import OrderedDict, defaultdict
6
+ from itertools import product
7
+ from functools import lru_cache
8
+ from ase.build import make_supercell
9
+ from ase.atoms import Atoms
10
+
11
+
12
+ def close_to_int(x, tol=1e-4):
13
+ return np.allclose(x, np.round(x), atol=tol)
14
+
15
+
16
+ class SupercellMaker(object):
17
+
18
+ def __init__(self, sc_matrix, center=False):
19
+ """
20
+ a helper class for making supercells.
21
+ sc_matrix, supercell matrix. sc_matrix .dot. unitcell = supercell
22
+ """
23
+ sc_matrix = np.array(sc_matrix, dtype=int)
24
+ if len(sc_matrix.flatten()) == 3:
25
+ sc_matrix = np.diag(sc_matrix)
26
+ elif sc_matrix.shape == (3, 3):
27
+ pass
28
+ else:
29
+ raise ValueError('sc_matrix should be 3 or 3*3 matrix')
30
+ self.sc_matrix = sc_matrix
31
+ self.center = center
32
+ if center:
33
+ self.shift = np.array([0.5, 0.5, 0.5])
34
+ else:
35
+ self.shift = np.zeros(3, dtype=float)
36
+ self.inv_scmat = np.linalg.inv(self.sc_matrix.T)
37
+ self.build_sc_vec()
38
+ self.ncell = int(round(abs(np.linalg.det(sc_matrix))))
39
+
40
+ def to_red_sc(self, x):
41
+ return np.dot(self.inv_scmat, x) + self.shift
42
+
43
+ def build_sc_vec(self):
44
+ eps_shift = np.sqrt(
45
+ 2.0) * 1.0E-8 # shift of the grid, so to avoid double counting
46
+ #max_R = np.max(np.abs(self.sc_matrix)) * 3
47
+ if self.center:
48
+ minr = -0.5
49
+ maxr = 0.5
50
+ else:
51
+ minr = 0.0
52
+ maxr = 1.0
53
+ sc_vec = []
54
+ newcell = self.sc_matrix
55
+ scorners_newcell = np.array([[0., 0., 0.], [0., 0., 1.], [0., 1., 0.],
56
+ [0., 1., 1.], [1., 0., 0.], [1., 0., 1.],
57
+ [1., 1., 0.], [1., 1., 1.]])
58
+ corners = np.dot(scorners_newcell - self.shift, newcell)
59
+ scorners = corners
60
+ #rep = np.ceil(scorners.ptp(axis=0)).astype('int') + 1
61
+ minrep = np.ceil(np.min(scorners, axis=0)).astype('int')
62
+ maxrep = np.ceil(np.max(scorners, axis=0)).astype('int') + 1
63
+
64
+ # sc_vec: supercell vector (map atom from unit cell to supercell)
65
+ # for vec in product(range(rep[0]), range(rep[1]), range(rep[2])):
66
+ for vec in product(range(minrep[0], maxrep[0]),
67
+ range(minrep[1], maxrep[1]),
68
+ range(minrep[2], maxrep[2])):
69
+ # compute reduced coordinates of this candidate vector in the super-cell frame
70
+ tmp_red = self.to_red_sc(vec)
71
+ # check if in the interior
72
+ if (not (tmp_red <= -eps_shift).any()) and (
73
+ not (tmp_red > 1.0 - eps_shift).any()):
74
+ sc_vec.append(np.array(vec))
75
+
76
+ # number of times unit cell is repeated in the super-cell
77
+ num_sc = len(sc_vec)
78
+
79
+ # check that found enough super-cell vectors
80
+ if int(round(np.abs(np.linalg.det(self.sc_matrix)))) != num_sc:
81
+ raise Exception(
82
+ "\n\nSuper-cell generation failed! Wrong number of super-cell vectors found."
83
+ )
84
+
85
+ sc_vec = np.array(sc_vec)
86
+ self.sc_vec = np.array(sc_vec)
87
+ svtuple = (tuple(s) for s in sc_vec)
88
+ self.sc_vec_dict = dict(zip(svtuple, range(sc_vec.shape[0])))
89
+
90
+ def get_R(self):
91
+ return self.sc_vec
92
+
93
+ @property
94
+ def R_sc(self):
95
+ return self.sc_vec
96
+
97
+ def sc_cell(self, cell):
98
+ cell = np.array(cell)
99
+ if len(cell.flatten()) == 3:
100
+ cell = np.diag(cell)
101
+ return np.dot(self.sc_matrix, cell)
102
+
103
+ def sc_pos(self, positions, return_R=False):
104
+ """
105
+ pos -> pos in supercell (reduced.)
106
+ """
107
+ sc_pos = []
108
+ sc_R = []
109
+ for cur_sc_vec in self.sc_vec: # go over all super-cell vectors
110
+ for pos in positions:
111
+ # shift orbital and compute coordinates in
112
+ # reduced coordinates of super-cell
113
+ sc_pos.append(self.to_red_sc(pos + cur_sc_vec))
114
+ sc_R.append(cur_sc_vec)
115
+ if return_R:
116
+ return sc_pos, sc_R
117
+ else:
118
+ return sc_pos
119
+
120
+ def sc_trans_invariant(self, q, return_R=False):
121
+ """
122
+ translation invariant quantities. Like on-site energy of tight binding,
123
+ chemical symbols, magnetic moments of spin.
124
+ """
125
+ sc_q = []
126
+ sc_R = [] # supercell R
127
+ for cur_sc_vec in self.sc_vec: # go over all super-cell vectors
128
+ for qitem in q:
129
+ sc_q.append(qitem)
130
+ sc_R.append(cur_sc_vec)
131
+ if return_R:
132
+ return sc_q, sc_R
133
+ else:
134
+ return sc_q
135
+
136
+ def sc_trans_kvector(self, x, kpt, phase=0.0, real=False):
137
+ """
138
+ x is a vector of quantities inside the primitive cell.
139
+ qpoint is the wavevector
140
+ phase
141
+ x_sc= x * exp(i(qR + phase))
142
+
143
+ Note: if x is a 2D m*n array, the first m*n block is the primitive cell.
144
+ [block1, block2, block3, ... block_ncell]
145
+ """
146
+ factor = self.phase_factor(kpt, phase=phase)
147
+ ret = np.kron(factor, x)
148
+ if real:
149
+ ret = np.real(ret)
150
+ return ret
151
+
152
+ def Rvector_for_each_element(self, n_ind=1):
153
+ """
154
+ repeat the R_sc vectors.
155
+ """
156
+ return np.kron(self.sc_vec, np.ones((n_ind, 1)))
157
+
158
+ def sc_index(self, indices, n_ind=None):
159
+ """
160
+ Note that the number of indices could be inequal to the repeat period.
161
+ e.g. for n_orb of orbitals, the indices of atoms iatom for each orbital.
162
+ In that case, in the second unit cell (c=1 here), iatom-> iatom+n_ind,
163
+ where n_ind=natoms in primitive cell.
164
+ """
165
+ sc_ind = []
166
+ if n_ind is None:
167
+ n_ind = len(indices)
168
+ for c, cur_sc_vec in enumerate(
169
+ self.sc_vec): # go over all super-cell vectors
170
+ for ind in indices:
171
+ sc_ind.append(ind + c * n_ind)
172
+ return sc_ind
173
+
174
+ @lru_cache(maxsize=5000)
175
+ def _sc_R_to_pair_ind(self, R_plus_Rv):
176
+ """
177
+ R: initial R vector (e.g. R in (i, jR) pair)
178
+ Rv: translation vector. (e.g. for Rv in self.sc_vec)
179
+
180
+ Returns:
181
+ sc_part: R in
182
+ pair_ind:
183
+ """
184
+ R_plus_Rv = np.asarray(R_plus_Rv)
185
+ sc_part = np.floor(self.to_red_sc(R_plus_Rv)) # round down!
186
+ sc_part = np.array(sc_part, dtype=int)
187
+ # find remaining vector in the original reduced coordinates
188
+ orig_part = R_plus_Rv - np.dot(sc_part, self.sc_matrix)
189
+ pair_ind1 = self.sc_vec_dict[tuple(orig_part)]
190
+ return sc_part, pair_ind1
191
+
192
+ def sc_jR_to_scjR(self, j, R, Rv, n_basis):
193
+ """
194
+ (j, R) in primitive cell to (j', R') in supercell.
195
+ """
196
+ Rprim, pair_ind = self._sc_R_to_pair_ind(
197
+ tuple(np.array(R) + np.array(Rv)))
198
+ return j + pair_ind * n_basis, tuple(Rprim)
199
+
200
+ def sc_i_to_sci(self, i, ind_Rv, n_basis):
201
+ return i + ind_Rv * n_basis
202
+
203
+ def sc_ijR_only(self, i, j, R, n_basis):
204
+ ret = []
205
+ for c, cur_sc_vec in enumerate(
206
+ self.sc_vec): # go over all super-cell vectors
207
+ sc_part, pair_ind = self._sc_R_to_pair_ind(tuple(R + cur_sc_vec))
208
+ sc_i = i + c * n_basis
209
+ sc_j = j + pair_ind * n_basis
210
+ ret.append((sc_i, sc_j, tuple(sc_part)))
211
+ return ret
212
+
213
+ def sc_jR(self, jlist, Rjlist, n_basis):
214
+ sc_jlist = []
215
+ sc_Rjlist = []
216
+ for c, cur_sc_vec in enumerate(
217
+ self.sc_vec): # go over all super-cell vectors
218
+ # for i , j, ind_R, val in
219
+ for j, Rj in zip(jlist, Rjlist):
220
+ sc_part, pair_ind = self._sc_R_to_pair_ind(
221
+ tuple(Rj + cur_sc_vec))
222
+ sc_j = j + pair_ind * n_basis
223
+ sc_jlist.append(sc_j)
224
+ sc_Rjlist.append(tuple(sc_part))
225
+ return sc_jlist, sc_Rjlist
226
+
227
+ def sc_ijR(self, terms, n_basis):
228
+ """
229
+ # TODO very slow when supercell is large, should improve it.
230
+ map Val(i, j, R) which is a funciton of (R+rj-ri) to supercell.
231
+ e.g. hopping in Tight binding. exchange in heisenberg model,...
232
+ Args:
233
+ ========================
234
+ terms: either list of [i, j, R, val] or dict{(i,j, R): val}
235
+ pos: reduced positions in the unit cell.
236
+ Returns:
237
+ =======================
238
+ """
239
+ ret_dict = OrderedDict()
240
+ for c, cur_sc_vec in enumerate(
241
+ self.sc_vec): # go over all super-cell vectors
242
+ # for i , j, ind_R, val in
243
+ for (i, j, ind_R), val in terms.items():
244
+ sc_part, pair_ind = self._sc_R_to_pair_ind(
245
+ tuple(ind_R + cur_sc_vec))
246
+ # index of "from" and "to" hopping indices
247
+ sc_i = i + c * n_basis
248
+ sc_j = j + pair_ind * n_basis
249
+
250
+ # hi = self._hoppings[h][1] + c * self._norb
251
+ # hj = self._hoppings[h][2] + pair_ind * self._norb
252
+ ret_dict[(sc_i, sc_j, tuple(sc_part))] = val
253
+ return ret_dict
254
+
255
+ def sc_Rlist_HR(self, Rlist, HR, n_basis):
256
+ """
257
+ terms: H[R][i,j] = val
258
+ ========================
259
+ terms: either list of [i, j, R, val] or dict{(i,j, R): val}
260
+ pos: reduced positions in the unit cell.
261
+ Returns:
262
+ =======================
263
+ """
264
+ sc_Rlist = []
265
+ sc_HR = []
266
+ for c, cur_sc_vec in enumerate(
267
+ self.sc_vec): # go over all super-cell vectors
268
+ # for i , j, ind_R, val in
269
+ for iR, R in enumerate(Rlist):
270
+ H = HR[iR]
271
+ sc_part, pair_ind = self._sc_R_to_pair_ind(
272
+ tuple(R + cur_sc_vec))
273
+ sc_Rlist.append(sc_part)
274
+ sc_val = np.zeros((n_basis * self.ncell, n_basis * self.ncell),
275
+ dtype=HR.dtype)
276
+ for i in range(n_basis):
277
+ for j in range(n_basis):
278
+ sc_i = i + c * n_basis
279
+ sc_j = j + pair_ind * n_basis
280
+ sc_val[sc_i, sc_j] = H[i, j]
281
+ sc_HR.append(sc_val)
282
+ return np.array(sc_Rlist, dtype=int), np.array(sc_HR)
283
+
284
+ def sc_RHdict(self, RHdict, n_basis):
285
+ """
286
+ terms: H[R][i,j] = val
287
+ ========================
288
+ terms: either list of [i, j, R, val] or dict{(i,j, R): val}
289
+ pos: reduced positions in the unit cell.
290
+ Returns:
291
+ =======================
292
+ """
293
+ sc_RHdict = defaultdict(lambda: np.zeros(
294
+ (n_basis * self.ncell, n_basis * self.ncell), dtype=H.dtype))
295
+ for c, cur_sc_vec in enumerate(
296
+ self.sc_vec): # go over all super-cell vectors
297
+ for R, H in RHdict.items():
298
+ sc_part, pair_ind = self._sc_R_to_pair_ind(
299
+ tuple(R + cur_sc_vec))
300
+ ii = c * n_basis
301
+ jj = pair_ind * n_basis
302
+ sc_RHdict[tuple(sc_part)][ii:ii + n_basis,
303
+ jj:jj + n_basis] += H
304
+ return sc_RHdict
305
+
306
+ def sc_RHdict_notrans(self, RHdict, n_basis, Rshift=(0, 0, 0)):
307
+ sc_RHdict = defaultdict(lambda: np.zeros(
308
+ (n_basis * self.ncell, n_basis * self.ncell), dtype=H.dtype))
309
+ cur_sc_vec = np.array(Rshift)
310
+ for R, H in RHdict.items():
311
+ sc_part, pair_ind = self._sc_R_to_pair_ind(
312
+ tuple(np.array(R) + cur_sc_vec))
313
+ c = self.sc_vec_dict[Rshift]
314
+ ii = c * n_basis
315
+ jj = pair_ind * n_basis
316
+ sc_RHdict[tuple(sc_part)][ii:ii + n_basis, jj:jj + n_basis] += H
317
+ return sc_RHdict
318
+
319
+ def sc_H_RpRk_notrans(self, Rplist, Rklist, n_basis, Rpprime, H):
320
+ """
321
+ For a given perturbation at Rp',
322
+ <Rm|Rp'=Rp+Rm|Rk+Rm>
323
+ =H(Rp,Rk)=<0|Rp|Rk> is a matrix of nbasis*nbasis
324
+ First: Rm = Rp'-Rp, Rk+Rm = Rp'-Rp+Rm
325
+ Input: Rplist, Rklist, H
326
+ H: [iRg, iRk, ibasis, ibasis]
327
+ """
328
+ sc_RHdict = defaultdict(lambda: np.zeros(
329
+ (n_basis * self.ncell, n_basis * self.ncell), dtype=H.dtype))
330
+ for iRp, Rp in enumerate(Rplist):
331
+ Rm = np.array(Rpprime) - np.array(Rp)
332
+
333
+ sc_part_i, pair_ind_i = self._sc_R_to_pair_ind(tuple(np.array(Rm)))
334
+ ii = pair_ind_i * n_basis
335
+ if tuple(sc_part_i) == (0, 0, 0):
336
+ for iRk, Rk in enumerate(Rklist):
337
+ sc_part_j, pair_ind_j = self._sc_R_to_pair_ind(
338
+ tuple(np.array(Rk) + np.array(Rm)))
339
+ jj = pair_ind_j * n_basis
340
+ sc_RHdict[tuple(sc_part_j)][ii:ii + n_basis, jj:jj +
341
+ n_basis] += H[iRp, iRk, :, :]
342
+ # elif tuple(sc_part_j) == (0, 0, 0):
343
+ # sc_RHdict[tuple(-sc_part_j)][jj:jj + n_basis,
344
+ # ii:ii + n_basis] += H[iRp, iRk, :, :].T.conj()
345
+
346
+ return sc_RHdict
347
+
348
+ def sc_atoms(self, atoms):
349
+ """
350
+ This function is compatible with ase.build.make_supercell.
351
+ They should produce the same result.
352
+ """
353
+ sc_cell = self.sc_cell(atoms.get_cell())
354
+ sc_pos = self.sc_pos(atoms.get_scaled_positions())
355
+ sc_numbers = self.sc_trans_invariant(atoms.get_atomic_numbers())
356
+ sc_magmoms = self.sc_trans_invariant(
357
+ atoms.get_initial_magnetic_moments())
358
+ return Atoms(cell=sc_cell,
359
+ scaled_positions=sc_pos,
360
+ numbers=sc_numbers,
361
+ magmoms=sc_magmoms)
362
+
363
+ def phase_factor(self, qpoint, phase=0, real=True):
364
+ f = np.exp(2j * np.pi * np.einsum('i, ji -> j', qpoint, self.sc_vec) +
365
+ 1j * phase)
366
+ if real:
367
+ f = np.real(f)
368
+ return f
369
+
370
+ def modulation_function_R(self, func):
371
+ return [func(R) for R in self.R_sc]
372
+
373
+ def _make_translate_maps(positions, basis, sc_mat, tol_r=1e-4):
374
+ """
375
+ find the mapping between supercell and translated cell.
376
+ Returns:
377
+ ===============
378
+ A N * nbasis array.
379
+ index[i] is the mapping from supercell to translated supercell so that
380
+ T(r_i) psi = psi[indices[i]].
381
+
382
+ """
383
+ a1 = Atoms(symbols='H', positions=[(0, 0, 0)], cell=[1, 1, 1])
384
+ sc = make_supercell(a1, self._scmat)
385
+ rs = sc.get_scaled_positions()
386
+
387
+ indices = np.zeros([len(rs), len(positions)], dtype='int32')
388
+ for i, ri in enumerate(rs):
389
+ inds = []
390
+ Tpositions = positions + np.array(ri)
391
+ for i_basis, pos in enumerate(positions):
392
+ for j_basis, Tpos in enumerate(Tpositions):
393
+ dpos = Tpos - pos
394
+ if close_to_int(dpos, tol_r) and (self._basis[i_basis]
395
+ == self._basis[j_basis]):
396
+ indices[i, j_basis] = i_basis
397
+
398
+ self._trans_rs = rs
399
+ self._trans_indices = indices
400
+
401
+
402
+ def smod(x):
403
+ x = np.mod(x, 1)
404
+ return x if x < 0.5 else x - 1
405
+
406
+
407
+ smod = np.vectorize(smod)
408
+
409
+
410
+ def map_to_primitive(atoms, primitive_atoms, offset=(0, 0, 0)):
411
+ """
412
+ Find the mapping of a supercell to a primitive cell.
413
+ :param atoms: the positions of atoms
414
+ :param primitive_atoms:
415
+ :param offset:
416
+ :param 0:
417
+ :param 0):
418
+
419
+ """
420
+ ilist = []
421
+ Rlist = []
422
+ offset = np.array(offset, dtype=float)
423
+ ppos = primitive_atoms.get_positions()
424
+ pos = atoms.get_positions()
425
+ cell = primitive_atoms.get_cell()
426
+ for p in pos:
427
+ found = False
428
+ for i, pp in enumerate(ppos):
429
+ res0 = np.linalg.solve(cell.T, p - pp)
430
+ res = smod(res0)
431
+ if np.linalg.norm(res) < 0.01:
432
+ found = True
433
+ R = res0 - res
434
+ ilist.append(i)
435
+ Rlist.append(R)
436
+ break
437
+ if not found:
438
+ print("Not found")
439
+ ilist.append(-1)
440
+ Rlist.append([-999, -999, -999])
441
+ return np.array(ilist, dtype=int), np.array(Rlist, dtype=int)
442
+
443
+
444
+ def find_primitive_cell(atoms,
445
+ sc_matrix,
446
+ origin_atom_id=None,
447
+ thr=1e-5,
448
+ perfect=True):
449
+ """
450
+ Find a primitive cell atoms from the supercell atom structure.
451
+ :param atoms: the supercell structure.
452
+ :param sc_matrix: the matrix which maps the primitive cell to supercell.
453
+ :param origin: the origin of the primitive cell.
454
+ :param thr: the atoms which the reduced position is within -thr to 1.0+thr are considered as inside the primitive atoms
455
+ :params perfect: True|False, whether the primitive cell should contains the same number of atoms .
456
+ :returns: (patoms, selected)
457
+ patoms: the primitive cell atoms
458
+ selected: the selected indices of the atoms in the supercell.
459
+ """
460
+ scell = atoms.get_cell().array
461
+ inv_scmat = np.linalg.inv(sc_matrix)
462
+ pcell = scell@inv_scmat
463
+ print(f"{inv_scmat=}")
464
+
465
+ xcart = atoms.get_positions()
466
+ xred = atoms.get_scaled_positions()
467
+ print(xred)
468
+ if origin_atom_id is not None:
469
+ origin = xred[origin_atom_id]
470
+ else:
471
+ origin = np.zeros(3)
472
+ # check if some atom is exactly at the origin.
473
+ # if so, shift the positions by thr so that this atom is inside the cell
474
+ # if np.any(np.linalg.norm(xred - origin[None, :], axis=1) < thr):
475
+ # xred += thr
476
+ #xred += 0.05
477
+
478
+ sc_xred = xred@sc_matrix
479
+ print(sc_xred)
480
+ #np.all(sc_xred<1 and sc_xred>=0.0)
481
+ # print(sc_xred<1)
482
+ x = np.logical_and(sc_xred < 1+thr, sc_xred >= -thr)
483
+ print(np.all(x, axis=1))
484
+ selected = np.where(np.all(x, axis=1))[0]
485
+ print(selected)
486
+ symbols = atoms.get_chemical_symbols()
487
+ psymbols = [symbols[i] for i in selected]
488
+ patoms = Atoms(symbols=psymbols, positions=xcart[selected], cell=pcell)
489
+ ncell = abs(np.linalg.det(sc_matrix))
490
+ natom = len(atoms)
491
+ if perfect:
492
+ assert len(symbols) == int(
493
+ natom/ncell), "The number of atoms in the found primitive cell does not equal to natom in the supercell divided by the size of the cell"
494
+ return patoms, selected
495
+
496
+
497
+ def test_find_primitive_cell():
498
+ atoms = Atoms('HO', positions=[[0, 0, 0], [0, 0.2, 0]], cell=[1, 1, 1])
499
+ sc_matrix = np.diag([1, 1, 3])
500
+ atoms2 = make_supercell(atoms, sc_matrix)
501
+ patoms = find_primitive_cell(atoms2, sc_matrix)
502
+
503
+
504
+ def test():
505
+ sc_mat = np.diag([1, 1, 3])
506
+ #sc_mat[0, 1] = 2
507
+ spm = SupercellMaker(sc_matrix=sc_mat, center=False)
508
+ print("sc_vec", spm.sc_vec)
509
+ print(spm.sc_cell([1, 1, 1]))
510
+ print(spm.sc_pos([[0.5, 1, 1]]))
511
+ print(spm.sc_pos([[0.5, 1, 0.5]]))
512
+ print(spm.sc_trans_invariant(['Fe']))
513
+ print(spm.sc_ijR({
514
+ (0, 0, (0, 0, 1)): 1.2,
515
+ (1, 1, (0, 0, 1)): 1.2,
516
+ }, 2))
517
+ print(spm.sc_index(indices=(1, 2)))
518
+ print(spm.sc_index(indices=(1, 2), n_ind=4))
519
+ from ase.atoms import Atoms
520
+ atoms = Atoms('HO', positions=[[0, 0, 0], [0, 0.2, 0]], cell=[1, 1, 1])
521
+ from ase.build import make_supercell
522
+ atoms2 = make_supercell(atoms, sc_mat)
523
+ atoms3 = spm.sc_atoms(atoms)
524
+ # print(atoms2.get_positions())
525
+ # print(atoms3.get_positions())
526
+ assert (atoms2 == atoms3)
527
+ assert (atoms2.get_positions() == atoms3.get_positions()).all()
528
+
529
+
530
+ if __name__ == '__main__':
531
+ # test()
532
+ test_find_primitive_cell()
@@ -58,6 +58,13 @@ def main():
58
58
  default=False,
59
59
  )
60
60
 
61
+ parser.add_argument(
62
+ "--method",
63
+ help="The method to downfold the exchange parameter. Options are Lowdin and PWF (projected Wannier function). ",
64
+ type=str,
65
+ default="Lowdin",
66
+ )
67
+
61
68
  args = parser.parse_args()
62
69
 
63
70
  if len(args.metals) == []:
@@ -73,6 +80,7 @@ def main():
73
80
  outpath=args.outpath,
74
81
  qmesh=args.qmesh,
75
82
  iso_only=args.iso_only,
83
+ method=args.method,
76
84
  )
77
85
 
78
86
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: TB2J
3
- Version: 0.9.0.1
3
+ Version: 0.9.2rc0
4
4
  Summary: TB2J: First principle to Heisenberg exchange J using tight-binding Green function method
5
5
  Author: Xu He
6
6
  Author-email: mailhexu@gmail.com
@@ -1,42 +1,49 @@
1
- TB2J/Jdownfolder.py,sha256=Nw2ixvn2Uq-o1wficz6rdaYHjfRN3U_kQCvrNJGNb68,6980
2
- TB2J/Jtensor.py,sha256=0fhfOcfVQGu75gytEnApKWTJZfg9ksKJ0anJgco5wRQ,3179
1
+ TB2J/Jdownfolder.py,sha256=Rmg6KfQ-Lkhei5daTJ2POzr0XL-R1WM-rzUnDcfoDhc,9595
2
+ TB2J/Jtensor.py,sha256=t6OsqrSlYW6Im4H7ykVAW8Al_pFXN4C5yj2UEsV6r7g,3181
3
+ TB2J/MAE.py,sha256=0w2kOgj7lczrN4rS4OHKPoRueXGvbYtmvRvacZHgUnY,7390
3
4
  TB2J/Oiju.py,sha256=cNGv8N5uH_swGq7cnAt2OyiDfqtjLlLrwseGu0E4iaM,3383
4
5
  TB2J/Oiju_epc.py,sha256=oytM3NYW7nWmklrGgNlqwIpI_JYv_hb7ZnR4o9nYNog,6809
5
6
  TB2J/__init__.py,sha256=hcEWkag_UvLm1ZSbjsgcTWkGVlR3Bwmzg1QYAwsvf-g,24
6
7
  TB2J/basis.py,sha256=DFo6_QUwjBwisP6zGxvoO0lpGTMDPAOkiL9giNCjOjA,1558
7
8
  TB2J/citation.py,sha256=gcQeyJZaT1Qrtsl8Y3s4neOH3-vvgmIcCvXeV2o3vj0,2891
8
9
  TB2J/contour.py,sha256=aw8LX6wVFCRPhcpkzuI0jGnHisvk4cezvUhkF_6Yx94,2633
10
+ TB2J/cut_cell.py,sha256=kr9WeQhBQLm8QXL2B3NcsSYmSw-OAtJk3f9wksAOZbs,2952
9
11
  TB2J/density_matrix.py,sha256=D5k8Oe21OCiLVORNYbo4TZOFG0slrQSbj91kJ3TMFjs,1514
10
12
  TB2J/epc.py,sha256=zLbtqZJhDr8DnnGN6YENcXwrMb3Qxu6KB08mLy9Pw20,3474
11
- TB2J/exchange.py,sha256=dsXQhlxXaBurxa7z3YkBjqmEFFtfEy1xaHf0VT3eKZE,29581
12
- TB2J/exchangeCL2.py,sha256=TIr-d2X56AiGe4qEhyXyZhRuwXvQG6clJMwDmjnTOaE,10985
13
+ TB2J/exchange.py,sha256=Tltunv85eNr-jsVL_SvfqG_WVkQyJX99RszaJRQRBD8,29945
14
+ TB2J/exchangeCL2.py,sha256=QSbQ_WxgJyiByn2U-tJ3xy2iYIQI8YMrN3vhw9_k2Cs,11149
13
15
  TB2J/exchange_pert.py,sha256=jmFMtQbYa_uczM4VAeS6TijkIHRFIqEzZJswzE9Wfuo,8523
14
16
  TB2J/exchange_qspace.py,sha256=ZL68qBGFUaQ9BsSPsJaaoWOr9RssPiqX34R_9I3nk_8,8436
15
17
  TB2J/gpaw_wrapper.py,sha256=aJ--9Dtyq7jOP1Hkh-Sh1nWcfXm6zKcljOCO0DNCAr0,6890
16
- TB2J/green.py,sha256=X-D8UZcIyz6zh_0W9VgUUv5yXPP3KWJ6C03m6CMWE3o,13377
18
+ TB2J/green.py,sha256=giWSPhrLKc3ZKOpwyY3snUKFWH08GMqBlsJWbFG9Qo8,13565
17
19
  TB2J/greentest.py,sha256=2ISSfhor9ecSEOi_E6b4Cv26wEIQlwlzca0ru8z44_E,1603
18
20
  TB2J/io_merge.py,sha256=t85k3L6IL9X5ys-PWK7CzResb3xJsyqM3LAlKPUe9vM,6825
19
21
  TB2J/kpoints.py,sha256=6XK2KqTncidEq3o9GuO6VEZRPNTRtWeXg9QfcV-9smI,532
20
- TB2J/manager.py,sha256=4-4x9jJRHpUEqJuhc5HqpXfh2-Ze5G9Wg8gOtn-AqR4,15372
22
+ TB2J/manager.py,sha256=Ogb_yRCnroNmGttKPRcbF70ddF9UNV_1UytdKbNFN4E,15685
21
23
  TB2J/mathutils.py,sha256=tHA6q3KPDpXLIbZHdDZ2NU5s886VVM_oEG490zQ6Ris,300
22
24
  TB2J/myTB.py,sha256=ok_B4my29bOIghMSZfx0Es6G8FaXaIiLP4gPxTdSj00,17659
23
25
  TB2J/orbmap.py,sha256=RCMJkOPGbfPrcZzcc5ia1ZMKBQWxGcyj8W1ve8BJaEw,6669
24
- TB2J/pauli.py,sha256=_FIF62jq2CkQdWC473a3S2F6NmzCdeCnglO9PjNVmMI,4120
26
+ TB2J/patch.py,sha256=Z3KZklID9U8zKuk6Ek1Tq95JcY3eT4770dsdcXz6mAA,1067
27
+ TB2J/pauli.py,sha256=zOELm7Vgxw6SMaO5l7qVWx1pBKZt25RLnEpnVM3dz_0,4545
25
28
  TB2J/pert.py,sha256=RaCJfewl0doht4cjAnzzGKe-uj2le4aqe0iPKFrq9fo,1192
26
29
  TB2J/plot.py,sha256=AnFIFWE2vlmj7Z6f_7-dX_O1stJN-qbuiurPj43dUCM,4104
27
30
  TB2J/rotate_atoms.py,sha256=Dwptn-wdDW4zYzjYb95yxTzuZOe9WPuLjh3d3-YcSs0,3277
28
31
  TB2J/rotate_siestaDM.py,sha256=eR97rspdrRaK9YTwQwUKfobI0S9UnEcbEZ2f5IgR7Tk,1070
29
32
  TB2J/sisl_wrapper.py,sha256=A5x1-tt8efUSPeGY5wM5m6-pJYQFXTCzQHVqD6RBa2g,14792
33
+ TB2J/supercell.py,sha256=4hgLGPBLRUDhtD-eF29v46ex7fHdkH-OENjS2wGLFww,19588
30
34
  TB2J/tensor_rotate.py,sha256=4-DfT_Mg5e40fbd74M5W0D5DqmUq-kVOOLDkkkI834A,8083
31
35
  TB2J/utest.py,sha256=z_ahi7tpHQF9WlHNQihcQ7qzfezRJQXQt28eB1X_z64,3897
32
36
  TB2J/utils.py,sha256=_ARYKAeWfP1p5w0mEl-d7KwNfXoqC85TveYl0iCBD3c,9880
33
37
  TB2J/versioninfo.py,sha256=wZwS9QDFRVDe7rf8JyPDDI8UGdTQiO6Pb_sWv8GAegA,337
38
+ TB2J/abacus/MAE.py,sha256=q9aSVDRZFAnZL3gHdNmde7sxj80oe-BRjwDO-ipyfew,12237
34
39
  TB2J/abacus/__init__.py,sha256=5sHiDnF2L-Y80QeET9zOiS83a5T_TQAXvnIhcYB6wNU,56
35
40
  TB2J/abacus/abacus_api.py,sha256=D_NyXW-Pno92d3RVHByx0l1HDPHQAvXsmQVt8cfIGR8,7267
36
- TB2J/abacus/abacus_wrapper.py,sha256=QR3ZW6v-d7dgneKwBO5s9FfCjBp-fkWMEaTO4SlcROA,8461
41
+ TB2J/abacus/abacus_wrapper.py,sha256=k0ZyTQ0jungp7jtlVCcdFQVK9YKeWokZvASCvfKCuKs,11880
37
42
  TB2J/abacus/gen_exchange_abacus.py,sha256=lKZqkWMnLQtaSwgn8O5Fzr-pV6tzwoMqfZU_vbET6gU,2973
43
+ TB2J/abacus/occupations.py,sha256=vaMVeZwldgzGDxjA7i3-2-V6akXjpgJwJFWKozJ-l2k,8947
38
44
  TB2J/abacus/orbital_api.py,sha256=l48Hn5z7TA0TH7Is4NDmz74b6B9L2ztYO4dRR37U4mQ,1562
39
45
  TB2J/abacus/stru_api.py,sha256=aBKKlZ2hvAZChVCfNxRdxH51rfHKqZn6kOlazY-yW8k,67888
46
+ TB2J/abacus/test_density_matrix.py,sha256=f0xHOTzIssT-XTvBJrQHU0JVbvBYOE1Mduh-j7qiLO8,774
40
47
  TB2J/abacus/test_read_HRSR.py,sha256=cAT-e79jGjCBXLTJ9UYX0WvalG_yD4Awl79tTOUcwaQ,1254
41
48
  TB2J/abacus/test_read_stru.py,sha256=CpK4zWhlCVAMCmYQmp9Hy-A40OblZQLFpo5JokpNcWQ,785
42
49
  TB2J/external/__init__.py,sha256=yD_ZIMi76H49rj6GAQpiB7UlKa3TgSaMkkLHT6M-8w8,137
@@ -44,15 +51,23 @@ TB2J/external/p_tqdm.py,sha256=ug1jy3-43r8iW7bC37xzPSIe0EjYKH_GUluGzMiQiDw,5831
44
51
  TB2J/io_exchange/__init__.py,sha256=KfGHum7B8E4G_KKfillqw0lErtoyKEuFUUttHLs-mg4,32
45
52
  TB2J/io_exchange/io_exchange.py,sha256=RxCZ7OOxhiIzGrIidCOqxNbgLsrHUfCqDVinMvrPdmI,19354
46
53
  TB2J/io_exchange/io_multibinit.py,sha256=8PDmWxzGuv-GwJosj2ZTmiyNY_duFVWJ4ekCuSqGdd8,6739
54
+ TB2J/io_exchange/io_pickle.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
55
  TB2J/io_exchange/io_tomsasd.py,sha256=NqkAC1Fl-CUnFA21eBzSy_S5F_oeQFJysw4UukQbN8o,4173
48
56
  TB2J/io_exchange/io_txt.py,sha256=BMr1eSILlKpgtjvDx7uw2VMAkEKSvGEPNxpaT_zev0I,10547
49
57
  TB2J/io_exchange/io_uppasd.py,sha256=bI4iPEgnK4TvCZNvb6x2xYXgjW7pEehCqmcizy2pqFU,3301
50
58
  TB2J/io_exchange/io_vampire.py,sha256=UllC4twf06_q2vBCnAYFzEDGvS8mSefwQXDquBuyc0M,5583
59
+ TB2J/mathutils/__init__.py,sha256=tQLBfHkZqdVfVxPOahy42qMUkFYnFFFhM-uc4QsYFxI,27
60
+ TB2J/mathutils/fermi.py,sha256=tzEicVoxE_5DxPDDZMvi4ynR1_Iqf-Qh0-0zfm-iVBo,480
61
+ TB2J/mathutils/kR_convert.py,sha256=p_9XWJVNanTzTK2rI6KRjTkbSq42la6N448-zJOsMwY,2671
62
+ TB2J/mathutils/lowdin.py,sha256=tHA6q3KPDpXLIbZHdDZ2NU5s886VVM_oEG490zQ6Ris,300
63
+ TB2J/mathutils/rotate_spin.py,sha256=NT12khB8lN1qf_jQ2SwnAhhtWxptZXkzpUQ2JvZEnkM,1710
51
64
  TB2J/spinham/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
65
  TB2J/spinham/base_parser.py,sha256=oQRHvFE_BlUtTaTZykKgvicu40oXcbICB-D1aAt-qlA,2196
53
66
  TB2J/spinham/constants.py,sha256=y4-hRyl5EAR42k24Oa5XhAsUQtKVn1MAgyqNf-p3PrM,762
67
+ TB2J/spinham/h_matrix.py,sha256=MfHIz6RViKkEB3Mu-WcwNx5uk7A5sjAlbqVG9wYA4xk,2784
54
68
  TB2J/spinham/hamiltonian.py,sha256=OfsjlGIgFwpXaohopZcgPamSfjm3X46_zc245eyTr_A,16607
55
69
  TB2J/spinham/hamiltonian_terms.py,sha256=7e84tfEjvAfZltUkrSWi1sUEiW_itLKy83lxi5iBpcQ,9714
70
+ TB2J/spinham/obtain_J.py,sha256=sg8tiCRRLEN57Olb3MHIuqkDhAkmu-w87AkM00ylXtA,2401
56
71
  TB2J/spinham/plot.py,sha256=tLLNqFAATVrP1kmSVLPKzn686i-CUyqu4qgOcs-okHI,6599
57
72
  TB2J/spinham/qsolver.py,sha256=Sr9I3aGfVNYn5wzwPx1QonHe6ZZUXBAujWRa7nTA5u4,4986
58
73
  TB2J/spinham/spin_api.py,sha256=oN3AKg1WQl0YzR4f5ealcJOaVoAy8d7HodIwrbXvQeY,2219
@@ -61,18 +76,18 @@ TB2J/spinham/supercell.py,sha256=y17uUC6r3gQb278FhxIW4CABihfLTvKFj6flyXrCPR8,122
61
76
  TB2J/wannier/__init__.py,sha256=7ojCbM84PYv1X1Tbo4NHI-d3gWmQsZB_xiYqbfxVV1E,80
62
77
  TB2J/wannier/w90_parser.py,sha256=dbd63LuKyv2DVUzqRINGsbDzEsOxsQyE8_Ear_LQIRg,4620
63
78
  TB2J/wannier/w90_tb_parser.py,sha256=qt8pnuprmPp9iIAYwPkPbmEzk6ZPgMq2xognoQp7vwc,4610
64
- TB2J-0.9.0.1.data/scripts/TB2J_downfold.py,sha256=F9oImXFysejCMP7eIBjbCX2jdHFOCvDW5beF1sG-UM8,1854
65
- TB2J-0.9.0.1.data/scripts/TB2J_eigen.py,sha256=Qs9v2hnMm2Tpfoa4h53muUKty2dZjwx8948MBoQooNg,1128
66
- TB2J-0.9.0.1.data/scripts/TB2J_magnon.py,sha256=q7UwAmorRcFNk4tfE7gl_ny05l6p7pbD9Wm_LkIpKEw,3101
67
- TB2J-0.9.0.1.data/scripts/TB2J_magnon_dos.py,sha256=TMXQvD2dIbO5FZ4tUMmxJgCgH2O2hDAPUNfEKO4z-x4,110
68
- TB2J-0.9.0.1.data/scripts/TB2J_merge.py,sha256=y834SF4rIRn1L1ptkhczvavQpC-8Px6DTmDOOSaq_DE,1854
69
- TB2J-0.9.0.1.data/scripts/TB2J_rotate.py,sha256=zgiDFuYZNmzKK0rwDmTaYD2OpRlmKA_VGeBx83w2Xwc,873
70
- TB2J-0.9.0.1.data/scripts/TB2J_rotateDM.py,sha256=kCvF7gotuqAX1VnJ06cwfVm7RrhrdtiV5v7d9P2Pn_E,567
71
- TB2J-0.9.0.1.data/scripts/abacus2J.py,sha256=M4B07lvTCDczTPTqvnDh_PERzCARAd09TLKv4aIdSQM,4408
72
- TB2J-0.9.0.1.data/scripts/siesta2J.py,sha256=hBzS7ZgoHM3oXlTCQd-xVA07Ks2FiIwyRpQWUFITRPE,4303
73
- TB2J-0.9.0.1.data/scripts/wann2J.py,sha256=2t2hWwyELskYCwkGDziCgiIAnfr6odLLJ6cQBJ2RQwQ,5714
74
- TB2J-0.9.0.1.dist-info/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
75
- TB2J-0.9.0.1.dist-info/METADATA,sha256=ky_ng24tVY8IC_GQn9420M7jzPnCpUiNcp-QtFkUbsk,1420
76
- TB2J-0.9.0.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
77
- TB2J-0.9.0.1.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
78
- TB2J-0.9.0.1.dist-info/RECORD,,
79
+ TB2J-0.9.2rc0.data/scripts/TB2J_downfold.py,sha256=i4BVqnpDdgrX_amookVWeLGefGBn-qeAutWiwuY9SfQ,2099
80
+ TB2J-0.9.2rc0.data/scripts/TB2J_eigen.py,sha256=Qs9v2hnMm2Tpfoa4h53muUKty2dZjwx8948MBoQooNg,1128
81
+ TB2J-0.9.2rc0.data/scripts/TB2J_magnon.py,sha256=q7UwAmorRcFNk4tfE7gl_ny05l6p7pbD9Wm_LkIpKEw,3101
82
+ TB2J-0.9.2rc0.data/scripts/TB2J_magnon_dos.py,sha256=TMXQvD2dIbO5FZ4tUMmxJgCgH2O2hDAPUNfEKO4z-x4,110
83
+ TB2J-0.9.2rc0.data/scripts/TB2J_merge.py,sha256=y834SF4rIRn1L1ptkhczvavQpC-8Px6DTmDOOSaq_DE,1854
84
+ TB2J-0.9.2rc0.data/scripts/TB2J_rotate.py,sha256=zgiDFuYZNmzKK0rwDmTaYD2OpRlmKA_VGeBx83w2Xwc,873
85
+ TB2J-0.9.2rc0.data/scripts/TB2J_rotateDM.py,sha256=kCvF7gotuqAX1VnJ06cwfVm7RrhrdtiV5v7d9P2Pn_E,567
86
+ TB2J-0.9.2rc0.data/scripts/abacus2J.py,sha256=M4B07lvTCDczTPTqvnDh_PERzCARAd09TLKv4aIdSQM,4408
87
+ TB2J-0.9.2rc0.data/scripts/siesta2J.py,sha256=hBzS7ZgoHM3oXlTCQd-xVA07Ks2FiIwyRpQWUFITRPE,4303
88
+ TB2J-0.9.2rc0.data/scripts/wann2J.py,sha256=2t2hWwyELskYCwkGDziCgiIAnfr6odLLJ6cQBJ2RQwQ,5714
89
+ TB2J-0.9.2rc0.dist-info/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
90
+ TB2J-0.9.2rc0.dist-info/METADATA,sha256=oV593Fk_girgJbc0w4u3U9PBEC_Crhx6B1p9ff1pcBY,1421
91
+ TB2J-0.9.2rc0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
92
+ TB2J-0.9.2rc0.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
93
+ TB2J-0.9.2rc0.dist-info/RECORD,,