TB2J 0.9.12.7__py3-none-any.whl → 0.9.12.18__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/.gitignore +5 -0
- TB2J/Jdownfolder.py +4 -3
- TB2J/MAEGreen.py +78 -60
- TB2J/__init__.py +0 -2
- TB2J/agent_files/debug_spinphon_fd/debug_main.py +156 -0
- TB2J/agent_files/debug_spinphon_fd/test_compute_dJdx.py +272 -0
- TB2J/agent_files/debug_spinphon_fd/test_ispin0_only.py +120 -0
- TB2J/agent_files/debug_spinphon_fd/test_no_d2j.py +31 -0
- TB2J/agent_files/debug_spinphon_fd/test_with_d2j.py +28 -0
- TB2J/anisotropy.py +2 -2
- TB2J/basis.py +0 -3
- TB2J/contour.py +3 -2
- TB2J/exchange.py +335 -47
- TB2J/exchangeCL2.py +283 -47
- TB2J/exchange_params.py +24 -0
- TB2J/gpaw_wrapper.py +0 -3
- TB2J/green.py +58 -33
- TB2J/interfaces/wannier90_interface.py +4 -4
- TB2J/io_exchange/io_espins.py +276 -0
- TB2J/io_exchange/io_exchange.py +11 -3
- TB2J/io_exchange/io_uppasd.py +0 -1
- TB2J/io_exchange/io_vampire.py +3 -1
- TB2J/myTB.py +11 -11
- TB2J/pauli.py +32 -2
- TB2J/plot.py +8 -7
- TB2J/rotate_atoms.py +10 -7
- TB2J/spinham/hamiltonian.py +0 -1
- TB2J/symmetrize_J.py +2 -2
- TB2J/tensor_rotate.py +1 -2
- TB2J/wannier/w90_tb_parser.py +0 -2
- {tb2j-0.9.12.7.dist-info → tb2j-0.9.12.18.dist-info}/METADATA +7 -7
- {tb2j-0.9.12.7.dist-info → tb2j-0.9.12.18.dist-info}/RECORD +36 -29
- {tb2j-0.9.12.7.dist-info → tb2j-0.9.12.18.dist-info}/WHEEL +0 -0
- {tb2j-0.9.12.7.dist-info → tb2j-0.9.12.18.dist-info}/entry_points.txt +0 -0
- {tb2j-0.9.12.7.dist-info → tb2j-0.9.12.18.dist-info}/licenses/LICENSE +0 -0
- {tb2j-0.9.12.7.dist-info → tb2j-0.9.12.18.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Test script for ispin0_only parameter.
|
|
3
|
+
|
|
4
|
+
PURPOSE:
|
|
5
|
+
Tests that ispin0_only=True correctly filters exchange pairs to only include
|
|
6
|
+
those where the first spin index (ispin) is 0, significantly reducing computation time.
|
|
7
|
+
|
|
8
|
+
USAGE:
|
|
9
|
+
uv run python TB2J/agent_files/debug_spinphon_fd/test_ispin0_only.py
|
|
10
|
+
|
|
11
|
+
EXPECTED OUTPUT:
|
|
12
|
+
- Comparison of number of pairs computed with ispin0_only=False vs True
|
|
13
|
+
- Verification that all pairs in ispin0_only=True output have ispin=0
|
|
14
|
+
- Demonstration of computational savings
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import sys
|
|
18
|
+
import os
|
|
19
|
+
sys.path.insert(0, '../..')
|
|
20
|
+
from test_compute_dJdx import compute_dJdx_from_exchanges, load_exchange
|
|
21
|
+
|
|
22
|
+
print("Testing ispin0_only parameter...")
|
|
23
|
+
print("=" * 80)
|
|
24
|
+
|
|
25
|
+
# Use available test data
|
|
26
|
+
base_path = 'FD_spinphon_results_0.001_k333_nocenter/idisp0_Ru0_0_0'
|
|
27
|
+
|
|
28
|
+
print("\n1. Testing with ispin0_only=False (default - all pairs)")
|
|
29
|
+
print("-" * 80)
|
|
30
|
+
neg = load_exchange(os.path.join(base_path, 'negative/TB2J.pickle'))
|
|
31
|
+
pos = load_exchange(os.path.join(base_path, 'positive/TB2J.pickle'))
|
|
32
|
+
|
|
33
|
+
compute_dJdx_from_exchanges(None, neg, pos, 0.001, 'test_all_pairs_output', compute_d2J=False)
|
|
34
|
+
|
|
35
|
+
# Count total pairs
|
|
36
|
+
with open('test_all_pairs_output/exchange.out', 'r') as f:
|
|
37
|
+
all_pairs_count = sum(1 for line in f if not line.startswith('#'))
|
|
38
|
+
|
|
39
|
+
print(f"Total number of exchange pairs computed: {all_pairs_count}")
|
|
40
|
+
|
|
41
|
+
# Check ispin distribution
|
|
42
|
+
ispin_counts = {}
|
|
43
|
+
with open('test_all_pairs_output/exchange.out', 'r') as f:
|
|
44
|
+
for line in f:
|
|
45
|
+
if not line.startswith('#'):
|
|
46
|
+
parts = line.split()
|
|
47
|
+
ispin = int(parts[0])
|
|
48
|
+
ispin_counts[ispin] = ispin_counts.get(ispin, 0) + 1
|
|
49
|
+
|
|
50
|
+
print(f"Distribution by ispin: {dict(sorted(ispin_counts.items()))}")
|
|
51
|
+
|
|
52
|
+
print("\n2. Testing with ispin0_only=True (only ispin=0 or jspin=0 pairs)")
|
|
53
|
+
print("-" * 80)
|
|
54
|
+
|
|
55
|
+
# Note: In actual usage, we would create new Exchange objects with ispin0_only=True
|
|
56
|
+
# Here we're just testing the filtering in compute_dJdx_from_exchanges
|
|
57
|
+
# The real performance gain comes from Exchange class not computing the other pairs
|
|
58
|
+
|
|
59
|
+
# For this test, we manually filter to simulate the behavior
|
|
60
|
+
neg_filtered = load_exchange(os.path.join(base_path, 'negative/TB2J.pickle'))
|
|
61
|
+
pos_filtered = load_exchange(os.path.join(base_path, 'positive/TB2J.pickle'))
|
|
62
|
+
|
|
63
|
+
# Filter the dictionaries
|
|
64
|
+
def filter_ispin0(exchange_dict):
|
|
65
|
+
"""Filter exchange dict to only include pairs where ispin=0 or jspin=0"""
|
|
66
|
+
filtered = {}
|
|
67
|
+
filtered['exchange_Jdict'] = {k: v for k, v in exchange_dict['exchange_Jdict'].items() if k[1] == 0 or k[2] == 0}
|
|
68
|
+
filtered['distance_dict'] = {k: v for k, v in exchange_dict['distance_dict'].items() if k[1] == 0 or k[2] == 0}
|
|
69
|
+
return filtered
|
|
70
|
+
|
|
71
|
+
neg_filtered = filter_ispin0(neg_filtered)
|
|
72
|
+
pos_filtered = filter_ispin0(pos_filtered)
|
|
73
|
+
|
|
74
|
+
compute_dJdx_from_exchanges(None, neg_filtered, pos_filtered, 0.001, 'test_ispin0_output', compute_d2J=False)
|
|
75
|
+
|
|
76
|
+
# Count ispin0 pairs
|
|
77
|
+
with open('test_ispin0_output/exchange.out', 'r') as f:
|
|
78
|
+
ispin0_pairs_count = sum(1 for line in f if not line.startswith('#'))
|
|
79
|
+
|
|
80
|
+
print(f"Number of exchange pairs with ispin=0 or jspin=0: {ispin0_pairs_count}")
|
|
81
|
+
|
|
82
|
+
# Verify all pairs have ispin=0 or jspin=0
|
|
83
|
+
all_valid = True
|
|
84
|
+
ispin0_count = 0
|
|
85
|
+
jspin0_count = 0
|
|
86
|
+
both0_count = 0
|
|
87
|
+
with open('test_ispin0_output/exchange.out', 'r') as f:
|
|
88
|
+
for line in f:
|
|
89
|
+
if not line.startswith('#'):
|
|
90
|
+
parts = line.split()
|
|
91
|
+
ispin = int(parts[0])
|
|
92
|
+
jspin = int(parts[1])
|
|
93
|
+
if ispin != 0 and jspin != 0:
|
|
94
|
+
all_valid = False
|
|
95
|
+
print(f"ERROR: Found pair with ispin={ispin}, jspin={jspin}")
|
|
96
|
+
break
|
|
97
|
+
if ispin == 0 and jspin == 0:
|
|
98
|
+
both0_count += 1
|
|
99
|
+
elif ispin == 0:
|
|
100
|
+
ispin0_count += 1
|
|
101
|
+
elif jspin == 0:
|
|
102
|
+
jspin0_count += 1
|
|
103
|
+
|
|
104
|
+
if all_valid:
|
|
105
|
+
print("✓ All pairs have ispin=0 or jspin=0")
|
|
106
|
+
print(f" - Pairs with both ispin=0 and jspin=0: {both0_count}")
|
|
107
|
+
print(f" - Pairs with ispin=0 only: {ispin0_count}")
|
|
108
|
+
print(f" - Pairs with jspin=0 only: {jspin0_count}")
|
|
109
|
+
|
|
110
|
+
print("\n3. Performance comparison")
|
|
111
|
+
print("-" * 80)
|
|
112
|
+
reduction = (all_pairs_count - ispin0_pairs_count) / all_pairs_count * 100
|
|
113
|
+
print(f"Pairs reduced: {all_pairs_count} → {ispin0_pairs_count}")
|
|
114
|
+
print(f"Reduction: {reduction:.1f}%")
|
|
115
|
+
print(f"Speedup factor: ~{all_pairs_count / ispin0_pairs_count:.1f}x")
|
|
116
|
+
|
|
117
|
+
print("\n" + "=" * 80)
|
|
118
|
+
print("Test completed successfully!")
|
|
119
|
+
print("\nNOTE: In actual usage with Exchange class, the performance gain comes from")
|
|
120
|
+
print("not computing the filtered pairs at all, not just filtering the output.")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Test script with compute_d2J=False"""
|
|
2
|
+
import sys
|
|
3
|
+
import os
|
|
4
|
+
sys.path.insert(0, '../..')
|
|
5
|
+
from test_compute_dJdx import compute_dJdx_from_exchanges, load_exchange
|
|
6
|
+
|
|
7
|
+
print("Testing with compute_d2J=False (skips J_0 computation)...")
|
|
8
|
+
|
|
9
|
+
# Use available test data
|
|
10
|
+
base_path = 'FD_spinphon_results_0.001_k333_nocenter/idisp0_Ru0_0_0'
|
|
11
|
+
neg = load_exchange(os.path.join(base_path, 'negative/TB2J.pickle'))
|
|
12
|
+
pos = load_exchange(os.path.join(base_path, 'positive/TB2J.pickle'))
|
|
13
|
+
|
|
14
|
+
# Note: passing orig=None when compute_d2J=False
|
|
15
|
+
compute_dJdx_from_exchanges(None, neg, pos, 0.001, 'test_no_d2j_output', compute_d2J=False)
|
|
16
|
+
|
|
17
|
+
print("\nFirst 12 lines of output:")
|
|
18
|
+
with open('test_no_d2j_output/exchange.out', 'r') as f:
|
|
19
|
+
for i, line in enumerate(f):
|
|
20
|
+
if i < 12:
|
|
21
|
+
print(line.rstrip())
|
|
22
|
+
|
|
23
|
+
print("\nChecking number of columns:")
|
|
24
|
+
with open('test_no_d2j_output/exchange.out', 'r') as f:
|
|
25
|
+
for line in f:
|
|
26
|
+
if not line.startswith('#'):
|
|
27
|
+
parts = line.split()
|
|
28
|
+
print(f"Found {len(parts)} columns (expected 12: no J_0, no d2J/dx2)")
|
|
29
|
+
break
|
|
30
|
+
|
|
31
|
+
print("\nTest completed!")
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Test script with compute_d2J=True (default)"""
|
|
2
|
+
import sys
|
|
3
|
+
sys.path.insert(0, '../..')
|
|
4
|
+
from test_compute_dJdx import compute_dJdx_from_exchanges, load_exchange
|
|
5
|
+
|
|
6
|
+
print("Testing with compute_d2J=True (default)...")
|
|
7
|
+
|
|
8
|
+
orig = load_exchange('FD_spinphon_results_222/original/TB2J.pickle')
|
|
9
|
+
neg = load_exchange('FD_spinphon_results_222/negative/TB2J.pickle')
|
|
10
|
+
pos = load_exchange('FD_spinphon_results_222/positive/TB2J.pickle')
|
|
11
|
+
|
|
12
|
+
compute_dJdx_from_exchanges(orig, neg, pos, 0.01, 'test_with_d2j_output')
|
|
13
|
+
|
|
14
|
+
print("\nFirst 12 lines of output:")
|
|
15
|
+
with open('test_with_d2j_output/exchange.out', 'r') as f:
|
|
16
|
+
for i, line in enumerate(f):
|
|
17
|
+
if i < 12:
|
|
18
|
+
print(line.rstrip())
|
|
19
|
+
|
|
20
|
+
print("\nChecking number of columns:")
|
|
21
|
+
with open('test_with_d2j_output/exchange.out', 'r') as f:
|
|
22
|
+
for line in f:
|
|
23
|
+
if not line.startswith('#'):
|
|
24
|
+
parts = line.split()
|
|
25
|
+
print(f"Found {len(parts)} columns (expected 14 with d2J)")
|
|
26
|
+
break
|
|
27
|
+
|
|
28
|
+
print("\nTest completed!")
|
TB2J/anisotropy.py
CHANGED
|
@@ -339,8 +339,8 @@ class Anisotropy:
|
|
|
339
339
|
# print(X_max, Y_max, X_min, Y_min)
|
|
340
340
|
# ax.scatter(X_max, Y_max, color="r", marker="o")
|
|
341
341
|
# ax.scatter(X_min, Y_min, color="b", marker="o")
|
|
342
|
-
ax.set_xlabel("$\theta$ (degree)")
|
|
343
|
-
ax.set_ylabel("$\phi$ degree")
|
|
342
|
+
ax.set_xlabel(r"$\theta$ (degree)")
|
|
343
|
+
ax.set_ylabel(r"$\phi$ degree")
|
|
344
344
|
# ax.scatter(X_max, Y_max, color="r", marker="o")
|
|
345
345
|
# ax.scatter(X_min, Y_min, color="r", marker="o")
|
|
346
346
|
|
TB2J/basis.py
CHANGED
TB2J/contour.py
CHANGED
|
@@ -27,8 +27,9 @@ class Contour:
|
|
|
27
27
|
integrate f along the path
|
|
28
28
|
"""
|
|
29
29
|
ret = 0
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
ret = np.einsum("i...,i->...", values, self.weights)
|
|
31
|
+
# for i in range(len(values)):
|
|
32
|
+
# ret += values[i] * self.weights[i]
|
|
32
33
|
return ret
|
|
33
34
|
|
|
34
35
|
def build_path_semicircle(self, npoints, endpoint=True):
|