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.
@@ -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
@@ -3,10 +3,7 @@
3
3
  """
4
4
  class for basis set
5
5
  """
6
- from typing import Any
7
- import numpy as np
8
6
  import dataclasses
9
- from TB2J.utils import symbol_number
10
7
 
11
8
 
12
9
  @dataclasses.dataclass
TB2J/contour.py CHANGED
@@ -27,8 +27,9 @@ class Contour:
27
27
  integrate f along the path
28
28
  """
29
29
  ret = 0
30
- for i in range(len(values)):
31
- ret += values[i] * self.weights[i]
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):