TB2J 0.9.9rc7__py3-none-any.whl → 0.9.9rc8__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/exchange.py CHANGED
@@ -566,12 +566,23 @@ class ExchangeNCL(Exchange):
566
566
  AijRs: a list of AijR,
567
567
  wherer AijR: array of ((nR, n, n, 4,4), dtype=complex)
568
568
  """
569
+ # if method == "trapezoidal":
570
+ # integrate = trapezoidal_nonuniform
571
+ # elif method == "simpson":
572
+ # integrate = simpson_nonuniform
573
+ #
574
+
575
+ # self.rho = integrate(self.contour.path, rhoRs)
569
576
  for iR, R in enumerate(self.R_ijatom_dict):
570
577
  for iatom, jatom in self.R_ijatom_dict[R]:
571
578
  f = AijRs[(R, iatom, jatom)]
579
+ # self.A_ijR[(R, iatom, jatom)] = integrate(self.contour.path, f)
572
580
  self.A_ijR[(R, iatom, jatom)] = self.contour.integrate_values(f)
573
581
 
574
582
  if self.orb_decomposition:
583
+ # self.A_ijR_orb[(R, iatom, jatom)] = integrate(
584
+ # self.contour.path, AijRs_orb[(R, iatom, jatom)]
585
+ # )
575
586
  self.contour.integrate_values(AijRs_orb[(R, iatom, jatom)])
576
587
 
577
588
  def get_quantities_per_e(self, e):
@@ -338,12 +338,6 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
338
338
  )
339
339
  return Jtensor
340
340
 
341
- def get_J_tensor_dict(self):
342
- Jdict = {}
343
- for i, j, R in self.ijR_list():
344
- Jdict[(i, j, R)] = self.get_J_tensor(i, j, R)
345
- return Jdict
346
-
347
341
  def get_full_Jtensor_for_one_R(self, R, iso_only=False):
348
342
  """
349
343
  Return the full exchange tensor of all i and j for cell R.
@@ -411,7 +405,6 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
411
405
  self.write_multibinit(path=os.path.join(path, "Multibinit"))
412
406
  self.write_tom_format(path=os.path.join(path, "TomASD"))
413
407
  self.write_vampire(path=os.path.join(path, "Vampire"))
414
- self.write_matjes(path=os.path.join(path, "Matjes"))
415
408
 
416
409
  self.plot_all(savefile=os.path.join(path, "JvsR.pdf"))
417
410
  # self.write_Jq(kmesh=[9, 9, 9], path=path)
@@ -580,11 +573,6 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
580
573
 
581
574
  write_uppasd(self, path=path)
582
575
 
583
- def write_matjes(self, path):
584
- from TB2J.io_exchange.io_matjes import write_matjes
585
-
586
- write_matjes(self, path=path)
587
-
588
576
 
589
577
  def gen_distance_dict(ind_mag_atoms, atoms, Rlist):
590
578
  distance_dict = {}
@@ -600,21 +588,6 @@ def gen_distance_dict(ind_mag_atoms, atoms, Rlist):
600
588
  return distance_dict
601
589
 
602
590
 
603
- def get_ind_shell(distance_dict, symprec=1e-5):
604
- """
605
- return a dictionary of shell index for each pair of atoms.
606
- The index of shell is the ith shortest distances between all magnetic atom pairs.
607
- """
608
- shell_dict = {}
609
- distances = np.array([x[1] for x in distance_dict.values()])
610
- distances_int = np.round(distances / symprec).astype(int)
611
- dint = sorted(np.unique(distances_int))
612
- dintdict = dict(zip(dint, range(len(dint))))
613
- for key, val in enumerate(distances_int):
614
- shell_dict[key] = dintdict[val]
615
- return shell_dict
616
-
617
-
618
591
  def test_spin_io():
619
592
  import numpy as np
620
593
  from ase import Atoms
TB2J/mycfr.py CHANGED
@@ -64,6 +64,10 @@ class CFR:
64
64
  # zp = 1j / eigp * kb * self.T
65
65
  # Rp = 0.25 * np.diag(eigv)**2 * zp **2
66
66
 
67
+ # print the poles and the weights
68
+ for i in range(len(self.poles)):
69
+ print("Pole: ", self.poles[i], "Weight: ", self.weights[i])
70
+
67
71
  # add a point to the poles: 1e10j
68
72
  self.path = np.concatenate((self.path, [self.Rinf * 1j]))
69
73
  # self.path = np.concatenate((self.path, [0.0]))
TB2J/symmetrize_J.py CHANGED
@@ -9,7 +9,7 @@ from TB2J.versioninfo import print_license
9
9
 
10
10
 
11
11
  class TB2JSymmetrizer:
12
- def __init__(self, exc, symprec=1e-8, verbose=True, Jonly=True):
12
+ def __init__(self, exc, symprec=1e-8, verbose=True, Jonly=False):
13
13
  # list of pairs with the index of atoms
14
14
  ijRs = exc.ijR_list_index_atom()
15
15
  finder = SymmetryPairFinder(atoms=exc.atoms, pairs=ijRs, symprec=symprec)
@@ -25,12 +25,6 @@ class TB2JSymmetrizer:
25
25
  )
26
26
  print("-" * 30)
27
27
  if exc.has_dmi:
28
- # raise NotImplementedError(
29
- # "Symmetrization of DMI is not yet implemented."
30
- # )
31
- # raise Warning(
32
- # "WARNING: Symmetrization of DMI is not yet implemented."
33
- # )
34
28
  print(
35
29
  "WARNING: Currently only the isotropic exchange is symmetrized. Symmetrization of DMI and anisotropic exchange are not yet implemented."
36
30
  )
@@ -39,7 +33,7 @@ class TB2JSymmetrizer:
39
33
  print("Symmetry found:")
40
34
  print(finder.spacegroup)
41
35
  print("-" * 30)
42
- self.pldict = finder.get_symmetry_pair_list_dict()
36
+ self.pgdict = finder.get_symmetry_pair_group_dict()
43
37
  self.exc = exc
44
38
  self.new_exc = copy.deepcopy(exc)
45
39
  self.Jonly = Jonly
@@ -52,25 +46,21 @@ class TB2JSymmetrizer:
52
46
  Symmetrize the exchange parameters J.
53
47
  """
54
48
  symJdict = {}
55
- reduced_symJdict = {}
56
49
  # Jdict = self.exc.exchange_Jdict
57
- for ishell, pairlist in enumerate(self.pldict.pairlists):
58
- ijRs = pairlist.get_all_ijR()
50
+ # ngroup = self.pgdict
51
+ for pairgroup in self.pgdict.groups:
52
+ ijRs = pairgroup.get_all_ijR()
59
53
  ijRs_spin = [self.exc.ijR_index_atom_to_spin(*ijR) for ijR in ijRs]
60
54
  Js = [self.exc.get_J(*ijR_spin) for ijR_spin in ijRs_spin]
61
55
  Javg = np.average(Js)
62
56
  for i, j, R in ijRs_spin:
63
57
  symJdict[(R, i, j)] = Javg
64
- ijRs_ref = ijRs_spin[0]
65
- i, j, R = ijRs_ref
66
- reduced_symJdict[(R, i, j)] = Javg
67
58
  self.new_exc.exchange_Jdict = symJdict
68
59
  if self.Jonly:
69
60
  self.new_exc.has_dmi = False
70
61
  self.new_exc.dmi_ddict = None
71
62
  self.new_exc.has_bilinear = False
72
63
  self.new_exc.Jani_dict = None
73
- self.new_exc.reduced_exchange_Jdict = reduced_symJdict
74
64
  self.has_uniaxial_anisotropy = False
75
65
  self.k1 = None
76
66
  self.k1dir = None
@@ -134,12 +124,12 @@ def symmetrize_J_cli():
134
124
  help="precision for symmetry detection. default is 1e-5 Angstrom",
135
125
  )
136
126
 
137
- # parser.add_argument(
138
- # "--Jonly",
139
- # action="store_true",
140
- # help="symmetrize only the exchange parameters and discard the DMI and anisotropic exchange",
141
- # default=True,
142
- # )
127
+ parser.add_argument(
128
+ "--Jonly",
129
+ action="store_true",
130
+ help="symmetrize only the exchange parameters and discard the DMI and anisotropic exchange",
131
+ default=False,
132
+ )
143
133
 
144
134
  args = parser.parse_args()
145
135
  if args.inpath is None:
@@ -149,8 +139,7 @@ def symmetrize_J_cli():
149
139
  path=args.inpath,
150
140
  output_path=args.outpath,
151
141
  symprec=args.symprec,
152
- # Jonly=args.Jonly,
153
- Jonly=True,
142
+ Jonly=args.Jonly,
154
143
  )
155
144
 
156
145
 
TB2J/thetaphi.py ADDED
@@ -0,0 +1,16 @@
1
+ import numpy as np
2
+
3
+
4
+ def theta_phi_even_spaced(n):
5
+ """
6
+ Return n evenly spaced theta and phi values in the ranges [0, pi] and [0, 2*pi] respectively.
7
+ """
8
+ phis = []
9
+ thetas = []
10
+ for i in range(n):
11
+ phi = 2 * np.pi * i / n
12
+ phis.append(phi)
13
+ r = np.sin(np.pi * i / n)
14
+ theta = np.arccos(1 - 2 * r)
15
+ thetas.append(theta)
16
+ return thetas, phis
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: TB2J
3
- Version: 0.9.9rc7
3
+ Version: 0.9.9rc8
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
@@ -11,7 +11,7 @@ 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=742vEE8DQJuWBTlq45RQoPy0-_n_TT6BZOb_DoTpDKI,25739
14
+ TB2J/exchange.py,sha256=1kkrrQvmoOaPgT_rKG7wgLy31rWpbFGNYXai1ysd58M,26221
15
15
  TB2J/exchangeCL2.py,sha256=P7bklMXVYX_tn9DbjEPqeTir1SeZyfPBIP1fhWUzLmY,11419
16
16
  TB2J/exchange_params.py,sha256=AcGYYky27DXSF3yDZWVjksr_3rt6im6qeIzpOwvqssk,7141
17
17
  TB2J/exchange_pert.py,sha256=jmFMtQbYa_uczM4VAeS6TijkIHRFIqEzZJswzE9Wfuo,8523
@@ -22,7 +22,7 @@ TB2J/greentest.py,sha256=2ISSfhor9ecSEOi_E6b4Cv26wEIQlwlzca0ru8z44_E,1603
22
22
  TB2J/io_merge.py,sha256=E1_GfAB2HGpW-ipaO2lqU9SvaslwkiLxssn4DqJpMT8,6899
23
23
  TB2J/kpoints.py,sha256=9L7tBarFBHoIhpuc9zuwA6HdnlgH834SQrPek4yRoWk,3191
24
24
  TB2J/myTB.py,sha256=ok_B4my29bOIghMSZfx0Es6G8FaXaIiLP4gPxTdSj00,17659
25
- TB2J/mycfr.py,sha256=Wgj6PpA-oVuxm8Hh32FVw_vthozVBrDJhRV1hA1ku44,3752
25
+ TB2J/mycfr.py,sha256=ZF1PEE2khlKd_4gPyMkoNXepX3XqwWAL2kDbRJNVX-Y,3908
26
26
  TB2J/orbital_magmom.py,sha256=JTwO9ZDgRRQndqR9aFIua4eTvwLMoGsTiY_HaIPMZ2I,889
27
27
  TB2J/orbmap.py,sha256=XLQjKMxCy2eADaM5eb2F_zG08V7lzpXJxp5uEtTeVYI,7194
28
28
  TB2J/pauli.py,sha256=ESpAhk6LG5ugzuW1YFUTqiDxcg-pQ7wNnzR2FtUnvKM,5295
@@ -31,8 +31,9 @@ TB2J/plot.py,sha256=AnFIFWE2vlmj7Z6f_7-dX_O1stJN-qbuiurPj43dUCM,4104
31
31
  TB2J/rotate_atoms.py,sha256=Dwptn-wdDW4zYzjYb95yxTzuZOe9WPuLjh3d3-YcSs0,3277
32
32
  TB2J/rotate_siestaDM.py,sha256=eR97rspdrRaK9YTwQwUKfobI0S9UnEcbEZ2f5IgR7Tk,1070
33
33
  TB2J/sisl_wrapper.py,sha256=A5x1-tt8efUSPeGY5wM5m6-pJYQFXTCzQHVqD6RBa2g,14792
34
- TB2J/symmetrize_J.py,sha256=gN6Y8zV4IrO5rPh0SG8KHkekrJjMQzNY4GGe2ZBtwbc,4993
34
+ TB2J/symmetrize_J.py,sha256=IypvLL0JxExq-cmqc4o0nLL8psE7OC9ijj9YMcsqJeA,4487
35
35
  TB2J/tensor_rotate.py,sha256=4-DfT_Mg5e40fbd74M5W0D5DqmUq-kVOOLDkkkI834A,8083
36
+ TB2J/thetaphi.py,sha256=Z7N3EOSM7rjHd7b9HxMYLPQO__uR0VwEiV9b471Yudc,399
36
37
  TB2J/utest.py,sha256=z_ahi7tpHQF9WlHNQihcQ7qzfezRJQXQt28eB1X_z64,3897
37
38
  TB2J/utils.py,sha256=DHkc7BK0KUGesfoAv1OxMgIw_iZzcFXh--3ybsFSd_c,12535
38
39
  TB2J/versioninfo.py,sha256=atoCpy6lEcGTCC3xahrxEJjoHgoYVtL41Q_3Ryvp76I,338
@@ -54,8 +55,7 @@ TB2J/interfaces/abacus/test_density_matrix.py,sha256=bMWWJYtDS57SpPZ-eZXZ9Hr_UK4
54
55
  TB2J/interfaces/abacus/test_read_HRSR.py,sha256=W1oO_yigT50Yb5_u-KB_IfTpM7kArGkBuMSMs0H4CTs,1235
55
56
  TB2J/interfaces/abacus/test_read_stru.py,sha256=hoKPHVco8vwzC7Gao4bOPCdAPhh29x-9DTJJqRr7AYM,788
56
57
  TB2J/io_exchange/__init__.py,sha256=KfGHum7B8E4G_KKfillqw0lErtoyKEuFUUttHLs-mg4,32
57
- TB2J/io_exchange/io_exchange.py,sha256=7-Xt7_K5FKVrFkFvBrHhJGCRrL2Sw7zY-93GRBBv2GM,21050
58
- TB2J/io_exchange/io_matjes.py,sha256=klM5Z_t2kk0y_1IoqIILLnhUgjHQmXXmsXiono2LeMU,8594
58
+ TB2J/io_exchange/io_exchange.py,sha256=gaT0fXD3EzPsMgE_VX9gvcf7nEGY3KVYN8xxTAPzxc0,20120
59
59
  TB2J/io_exchange/io_multibinit.py,sha256=8PDmWxzGuv-GwJosj2ZTmiyNY_duFVWJ4ekCuSqGdd8,6739
60
60
  TB2J/io_exchange/io_tomsasd.py,sha256=NqkAC1Fl-CUnFA21eBzSy_S5F_oeQFJysw4UukQbN8o,4173
61
61
  TB2J/io_exchange/io_txt.py,sha256=BMr1eSILlKpgtjvDx7uw2VMAkEKSvGEPNxpaT_zev0I,10547
@@ -80,19 +80,19 @@ TB2J/spinham/supercell.py,sha256=y17uUC6r3gQb278FhxIW4CABihfLTvKFj6flyXrCPR8,122
80
80
  TB2J/wannier/__init__.py,sha256=7ojCbM84PYv1X1Tbo4NHI-d3gWmQsZB_xiYqbfxVV1E,80
81
81
  TB2J/wannier/w90_parser.py,sha256=dbd63LuKyv2DVUzqRINGsbDzEsOxsQyE8_Ear_LQIRg,4620
82
82
  TB2J/wannier/w90_tb_parser.py,sha256=qt8pnuprmPp9iIAYwPkPbmEzk6ZPgMq2xognoQp7vwc,4610
83
- tb2j-0.9.9rc7.data/scripts/TB2J_downfold.py,sha256=i4BVqnpDdgrX_amookVWeLGefGBn-qeAutWiwuY9SfQ,2099
84
- tb2j-0.9.9rc7.data/scripts/TB2J_eigen.py,sha256=Qs9v2hnMm2Tpfoa4h53muUKty2dZjwx8948MBoQooNg,1128
85
- tb2j-0.9.9rc7.data/scripts/TB2J_magnon.py,sha256=q7UwAmorRcFNk4tfE7gl_ny05l6p7pbD9Wm_LkIpKEw,3101
86
- tb2j-0.9.9rc7.data/scripts/TB2J_magnon_dos.py,sha256=TMXQvD2dIbO5FZ4tUMmxJgCgH2O2hDAPUNfEKO4z-x4,110
87
- tb2j-0.9.9rc7.data/scripts/TB2J_merge.py,sha256=y834SF4rIRn1L1ptkhczvavQpC-8Px6DTmDOOSaq_DE,1854
88
- tb2j-0.9.9rc7.data/scripts/TB2J_rotate.py,sha256=zgiDFuYZNmzKK0rwDmTaYD2OpRlmKA_VGeBx83w2Xwc,873
89
- tb2j-0.9.9rc7.data/scripts/TB2J_rotateDM.py,sha256=kCvF7gotuqAX1VnJ06cwfVm7RrhrdtiV5v7d9P2Pn_E,567
90
- tb2j-0.9.9rc7.data/scripts/abacus2J.py,sha256=0HLXoJhAkiZ-ZM1cs26lncccxE8-TzC8JiDTba1h1uM,4163
91
- tb2j-0.9.9rc7.data/scripts/siesta2J.py,sha256=gp31LioqpPkDmMY0y_5gXIjOBPNnf080P37pRo0yjw8,4886
92
- tb2j-0.9.9rc7.data/scripts/wann2J.py,sha256=pTFDf6h72I_LN_NX5UivyCoJPgwvyAyHW175nSAJvLo,2987
93
- tb2j-0.9.9rc7.dist-info/licenses/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
94
- tb2j-0.9.9rc7.dist-info/METADATA,sha256=H5g8ApE237zxKx8_mx0Fr1fUCz2m97VkgDY5LBFYzlg,1660
95
- tb2j-0.9.9rc7.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
96
- tb2j-0.9.9rc7.dist-info/entry_points.txt,sha256=Hdz1WC9waUzyFVmowKnbbZ6j-J4adHh_Ko6JpxGYAtE,131
97
- tb2j-0.9.9rc7.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
98
- tb2j-0.9.9rc7.dist-info/RECORD,,
83
+ tb2j-0.9.9rc8.data/scripts/TB2J_downfold.py,sha256=i4BVqnpDdgrX_amookVWeLGefGBn-qeAutWiwuY9SfQ,2099
84
+ tb2j-0.9.9rc8.data/scripts/TB2J_eigen.py,sha256=Qs9v2hnMm2Tpfoa4h53muUKty2dZjwx8948MBoQooNg,1128
85
+ tb2j-0.9.9rc8.data/scripts/TB2J_magnon.py,sha256=q7UwAmorRcFNk4tfE7gl_ny05l6p7pbD9Wm_LkIpKEw,3101
86
+ tb2j-0.9.9rc8.data/scripts/TB2J_magnon_dos.py,sha256=TMXQvD2dIbO5FZ4tUMmxJgCgH2O2hDAPUNfEKO4z-x4,110
87
+ tb2j-0.9.9rc8.data/scripts/TB2J_merge.py,sha256=y834SF4rIRn1L1ptkhczvavQpC-8Px6DTmDOOSaq_DE,1854
88
+ tb2j-0.9.9rc8.data/scripts/TB2J_rotate.py,sha256=zgiDFuYZNmzKK0rwDmTaYD2OpRlmKA_VGeBx83w2Xwc,873
89
+ tb2j-0.9.9rc8.data/scripts/TB2J_rotateDM.py,sha256=kCvF7gotuqAX1VnJ06cwfVm7RrhrdtiV5v7d9P2Pn_E,567
90
+ tb2j-0.9.9rc8.data/scripts/abacus2J.py,sha256=0HLXoJhAkiZ-ZM1cs26lncccxE8-TzC8JiDTba1h1uM,4163
91
+ tb2j-0.9.9rc8.data/scripts/siesta2J.py,sha256=gp31LioqpPkDmMY0y_5gXIjOBPNnf080P37pRo0yjw8,4886
92
+ tb2j-0.9.9rc8.data/scripts/wann2J.py,sha256=pTFDf6h72I_LN_NX5UivyCoJPgwvyAyHW175nSAJvLo,2987
93
+ tb2j-0.9.9rc8.dist-info/licenses/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
94
+ tb2j-0.9.9rc8.dist-info/METADATA,sha256=4DDVWc-iAm87VSn60YFm-O15MZY-OpcT0ay_lw_0580,1660
95
+ tb2j-0.9.9rc8.dist-info/WHEEL,sha256=DK49LOLCYiurdXXOXwGJm6U4DkHkg4lcxjhqwRa0CP4,91
96
+ tb2j-0.9.9rc8.dist-info/entry_points.txt,sha256=Hdz1WC9waUzyFVmowKnbbZ6j-J4adHh_Ko6JpxGYAtE,131
97
+ tb2j-0.9.9rc8.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
98
+ tb2j-0.9.9rc8.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.3)
2
+ Generator: setuptools (78.0.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,225 +0,0 @@
1
- import os
2
-
3
- import numpy as np
4
-
5
- from TB2J.utils import symbol_number
6
- from ase.units import Bohr, nm
7
-
8
-
9
- def get_ind_shell(distance_dict, symprec=1e-5):
10
- """
11
- return a dictionary of shell index for each pair of atoms.
12
- The index of shell is the ith shortest distances between all magnetic atom pairs.
13
- """
14
- shell_dict = {}
15
- distances = np.array([x[1] for x in distance_dict.values()])
16
- distances_int = np.round(distances / symprec).astype(int)
17
- dint = sorted(np.unique(distances_int))
18
- dintdict = dict(zip(dint, range(len(dint))))
19
- for key, val in distance_dict.items():
20
- di = np.round(val[1] / symprec).astype(int)
21
- shell_dict[key] = dintdict[di]
22
- return shell_dict
23
-
24
-
25
- def _write_symmetry(cls, path, fname="symmetry.in", symmetry=True):
26
- fname = os.path.join(path, fname)
27
- if not symmetry:
28
- with open(fname, "w") as myfile:
29
- myfile.write("1 \n")
30
- myfile.write("\n")
31
- myfile.write("! identity operation\n")
32
- myfile.write("1.0000000000 0.0000000000 0.0000000000\n")
33
- myfile.write("0.0000000000 1.0000000000 0.0000000000\n")
34
- myfile.write("0.0000000000 0.0000000000 1.0000000000\n")
35
- myfile.write("0.0000000000 0.0000000000 0.0000000000\n")
36
- else:
37
- raise NotImplementedError("Symmetry not implemented yet")
38
-
39
-
40
- def write_matjes(cls, path="TB2J_results/Matjes", symmetry=False):
41
- if not os.path.exists(path):
42
- os.makedirs(path)
43
- inputfname = os.path.join(path, "input")
44
- with open(inputfname, "w") as myfile:
45
- _write_lattice_supercell(cls, myfile)
46
- _write_atoms(cls, myfile)
47
- _write_magnetic_interactions(cls, myfile)
48
- #_write_isotropic_exchange(cls, myfile, symmetry=symmetry)
49
- _write_magnetic_anisotropy(cls, myfile)
50
- # _write_dmi(cls, myfile)
51
- _write_exchange_tensor(cls, myfile, symmetry=symmetry)
52
- _write_parameters(cls, myfile, symmetry=symmetry)
53
- print(f"writting symmetries ")
54
- _write_symmetry(cls, path, fname="symmetries.in", symmetry=False)
55
-
56
- def _write_parameters(cls, myfile, symmetry=False):
57
- if symmetry:
58
- myfile.write("cal_sym T\n")
59
- myfile.write("sym_mode 2\n")
60
- else:
61
- myfile.write("cal_sym F \n")
62
- myfile.write("sym_mode 0\n")
63
-
64
- def _write_lattice_supercell(cls, myfile):
65
- myfile.write("# Lattice and supercell\n")
66
- myfile.write(
67
- "Periodic_log .T. .T. .T. # periodic boundary conditions along vector 1, 2 and 3\n"
68
- )
69
- myfile.write("Nsize 8 8 8 # size of the supercell\n")
70
- try:
71
- unitcell = cls.atoms.get_cell().reshape((3, 3))
72
- except Exception:
73
- unitcell = cls.atoms.get_cell().array.reshape((3, 3))
74
- uc_lengths = np.linalg.norm(unitcell, axis=1)
75
- unitcell /= uc_lengths[:, None]
76
- myfile.write(f"alat {uc_lengths[0]/nm} {uc_lengths[1]/nm} {uc_lengths[2]/nm} #lattice constant lengths\n")
77
- myfile.write(
78
- "lattice #lattice vector should be orthogonal or expressed in cartesian\n")
79
- myfile.write(
80
- f"{unitcell[0][0]} {unitcell[0][1]} {unitcell[0][2]} # a_11 a_12 a_1 first lattice vector in line (does not need to be normalize)\n"
81
- )
82
- myfile.write(
83
- f"{unitcell[1][0]} {unitcell[1][1]} {unitcell[1][2]} # a_21 a_22 a_23 second lattice vector in line (does not need to be normalize)\n"
84
- )
85
- myfile.write(
86
- f"{unitcell[2][0]} {unitcell[2][1]} {unitcell[2][2]} # a_31 a_32 a_33 third lattice vector in line\n"
87
- )
88
-
89
-
90
- def get_atoms_info(atoms, spinat, symmetry=False):
91
- if symmetry:
92
- raise NotImplementedError("Symmetry not implemented yet")
93
- else:
94
- symnum = symbol_number(atoms)
95
- atom_types = list(symnum.keys())
96
- magmoms = np.linalg.norm(spinat, axis=1)
97
- masses = atoms.get_masses()
98
- tags = [i for i in range(len(atom_types))]
99
- return atom_types, magmoms, masses, tags
100
-
101
-
102
- def _write_atoms(cls, myfile, symmetry=False):
103
- myfile.write("\n")
104
- myfile.write("# Atoms\n")
105
- atom_types, magmoms, masses, tags = get_atoms_info(
106
- cls.atoms, cls.spinat, symmetry=symmetry
107
- )
108
-
109
- myfile.write(f"atomtypes {len(atom_types)} #Number of types atom\n")
110
- for i, atom_type in enumerate(atom_types):
111
- m = magmoms[i]
112
- mass = masses[i]
113
- charge = 0
114
- myfile.write(
115
- f"{atom_type} {m} {mass} 0.0 F 0 # atom type: (name, mag. moment, mass, charge, displacement, number TB-orb.)\n"
116
- )
117
-
118
- myfile.write(
119
- f"\natoms {len(cls.atoms)} positions of the atom in the unit cell\n"
120
- )
121
- for i, atom in enumerate(cls.atoms):
122
- spos = cls.atoms.get_scaled_positions()[i]
123
- myfile.write(f"{atom_types[tags[i]]} {spos[0]}, {spos[1]}, {spos[2]} \n")
124
-
125
-
126
- def _write_magnetic_interactions(cls, myfile, symmetry=False):
127
- myfile.write("\nThe Hamiltonian\n")
128
- myfile.write("# Magnetic interactions\n")
129
-
130
-
131
- def _write_isotropic_exchange(cls, myfile, symmetry=False):
132
- myfile.write("\nmagnetic_J\n")
133
- shell_dict = get_ind_shell(cls.distance_dict)
134
- if symmetry:
135
- Jdict = cls.reduced_exchange_Jdict
136
- else:
137
- Jdict = cls.exchange_Jdict
138
- for key, val in Jdict.items():
139
- R, i, j = key
140
- ishell = shell_dict[(R, i, j)]
141
- myfile.write(
142
- f"{i+1} {j+1} {ishell} {val} # between atoms type {i+1} and {j+1}, shell {R}, amplitude in eV \n"
143
- )
144
- myfile.write(
145
- "\nc_H_J -1 apply 1/2 in front of the sum of the exchange energy - default is -1\n"
146
- )
147
-
148
-
149
- def _write_magnetic_anisotropy(cls, myfile):
150
- if cls.k1 is None:
151
- return
152
- else:
153
- myfile.write("\nmagnetic_anisotropy \n")
154
- for i, k1 in enumerate(cls.k1):
155
- myfile.write(
156
- f"{i+1} {cls.k1dir[i][0]} {cls.k1dir[i][1]} {cls.k1dir[i][2]} {k1} anisotropy of atoms type {i+1}, direction {cls.k1dir[i][0]} {cls.k1dir[i][1]} {cls.k1dir[i][2]} and amplitude in eV\n"
157
- )
158
- myfile.write("\nc_H_ani 1.0\n")
159
-
160
-
161
- def _write_dmi(cls, myfile):
162
- if cls.has_dmi:
163
- myfile.write("\nmagnetic_D\n")
164
- for key, val in cls.dmi_ddict.items():
165
- R, i, j = key
166
- myfile.write(
167
- f"{i+1} {j+1} {R[0]} {R[1]} {R[2]} {val} #between atoms type {i+1} and {j+1}, mediated by atom type {R}, shell {R}, amplitude in eV\n"
168
- )
169
- myfile.write(
170
- "\nc_H_D -1.0 # coefficients to put in from of the sum - default is -1\n"
171
- )
172
-
173
-
174
- def _write_exchange_tensor(cls, myfile, symmetry=False):
175
- myfile.write(
176
- "\nmagnetic_r2_tensor #Exchange tensor elements, middle 9 entries: xx, xy, xz, yx, etc. (in units of eV) and direction in which it should be applied\n"
177
- )
178
-
179
- Jtensor = cls.get_J_tensor_dict()
180
- shelldict = get_ind_shell(cls.distance_dict)
181
- unitcell = cls.atoms.get_cell().array.reshape((3, 3))
182
- uc_lengths = np.linalg.norm(unitcell, axis=1)
183
- if Jtensor is not None:
184
- for key, val in Jtensor.items():
185
- i, j, R = key
186
- # distance vector
187
- dvec = cls.distance_dict[(R, i, j)][0]/nm/uc_lengths
188
- dscalar = np.linalg.norm(dvec)
189
- val = np.real(val)
190
- ishell = shelldict[(R, i, j)]
191
- myfile.write(
192
- f"{i+1} {j+1} {ishell} {' '.join([str(x) for x in val.flatten()])} {dvec[0]} {dvec[1]} {dvec[2]} \n"
193
- #f"{i+1} {j+1} {dscalar} {' '.join([str(x) for x in val.flatten()])} {dvec[0]} {dvec[1]} {dvec[2]} \n"
194
- )
195
- myfile.write(
196
- "\nc_H_Exchten -1 apply 1/2 in front of the sum of the exchange tensor energy - default is -1\n"
197
- )
198
-
199
- def rattle_atoms_and_cell(atoms, stdev=0.001, cell_stdev=0.001):
200
- """
201
- Rattle both atomic positions and cell parameters.
202
-
203
- Parameters:
204
- -----------
205
- atoms: ASE atoms object
206
- The atoms to be rattled
207
- stdev: float
208
- Standard deviation for atomic displacement in Angstrom
209
- cell_stdev: float
210
- Standard deviation for cell parameter variation (fractional)
211
-
212
- Returns:
213
- --------
214
- None
215
- The atoms object is modified in-place
216
- """
217
- # Rattle atomic positions
218
- positions = atoms.get_positions()
219
- displacement = np.random.normal(0, stdev, positions.shape)
220
- atoms.set_positions(positions + displacement)
221
-
222
- # Rattle cell parameters
223
- cell = atoms.get_cell()
224
- cell_noise = np.random.normal(0, cell_stdev, cell.shape)
225
- atoms.set_cell(cell * (1 + cell_noise), scale_atoms=True)