@@ -4,108 +4,59 @@ Released under Apache 2.0 license as described in the file LICENSE.
44Authors: Yizhou Tong
55-/
66import SPG.Algebra.Basic
7- import SPG.Algebra.Group
8- import SPG.Geometry.SpatialOps
9- import SPG.Geometry.SpinOps
10- import SPG.Interface.Notation
117import SPG.Physics.Hamiltonian
8+ import SPG.Data.MagneticGroups
129import Mathlib.LinearAlgebra.Matrix.Determinant.Basic
1310
1411namespace Demo.Altermagnet
1512
1613open SPG
17- open SPG.Geometry.SpatialOps
18- open SPG.Geometry.SpinOps
19- open SPG.Interface
20- open SPG.Algebra
2114open SPG.Physics.Hamiltonian
15+ open SPG.Data.MagneticGroups
2216
23- -- 1. Generators for D4h altermagnet
24- def mat_4_z : Matrix (Fin 3 ) (Fin 3 ) ℚ := ![![0 , -1 , 0 ], ![1 , 0 , 0 ], ![0 , 0 , 1 ]]
25- def mat_inv : Matrix (Fin 3 ) (Fin 3 ) ℚ := ![![ -1 , 0 , 0 ], ![0 , -1 , 0 ], ![0 , 0 , -1 ]]
26- -- mat_2_xy defined explicitly for clarity (rotation by 180 degrees about x+y axis)
27- def mat_2_xy : Matrix (Fin 3 ) (Fin 3 ) ℚ := ![![0 , 1 , 0 ], ![1 , 0 , 0 ], ![0 , 0 , -1 ]]
28-
29- -- Generators
30- -- C4z * T : The key altermagnetic symmetry
31- -- C2xy : Rotation about x+y axis
32- -- I : Inversion
33- def gen_C4z_TR : SPGElement := Op[mat_4_z, ^-1 ]
34- def gen_C2xy : SPGElement := Op[mat_2_xy, ^1 ]
35- def gen_Inv : SPGElement := Op[mat_inv, ^1 ]
36-
37- def Altermagnet_Group : List SPGElement := generate_group [gen_C4z_TR, gen_C2xy, gen_Inv]
38-
39- -- 2. ICE Symbol Output (Simplistic)
40- -- We just print generators for now, as full ICE symbol logic is complex.
41- def ice_symbol : String :=
42- "4'22 (D4h magnetic)" -- Placeholder, deriving from generators
17+ def ice_symbol : String := "4'22 (D4h magnetic)"
4318
4419end Demo.Altermagnet
4520
4621def main : IO Unit := do
47- IO.println s! "Generated Group Size: { Demo.Altermagnet.Altermagnet_Group .length} "
22+ IO.println s! "Generated Group Size: { SPG.Data.MagneticGroups.Altermagnet_Group_D4h .length} "
4823 IO.println s! "ICE Symbol (Approx): { Demo.Altermagnet.ice_symbol} "
49- IO.println "Allowed Hamiltonian Terms H(k) (up to quadratic):"
50-
51- let invariants := SPG.Physics.Hamiltonian.find_invariants Demo.Altermagnet.Altermagnet_Group
52- for (p, s) in invariants do
53- let p_str := match p with
54- | .const => "1"
55- | .x => "kx" | .y => "ky" | .z => "kz"
56- | .xx => "kx^2" | .yy => "ky^2" | .zz => "kz^2"
57- | .xy => "kx ky" | .yz => "ky kz" | .zx => "kz kx"
58- let s_str := match s with
59- | .I => "I" | .x => "σx" | .y => "σy" | .z => "σz"
60- IO.println s! " { p_str} * { s_str} "
61-
62- -- Manually check d-wave altermagnet term: (kx^2 - ky^2) * sigma_z?
63- -- Or kx ky * sigma_z ?
64- -- Let's define a custom checker for kx^2 - ky^2
65- let check_custom (f : SPG.Vec3 → ℚ) (s : SPG.Physics.Hamiltonian.SpinComp) : Bool :=
66- let test_ks : List SPG.Vec3 := [![1 , 0 , 0 ], ![0 , 1 , 0 ], ![0 , 0 , 1 ], ![1 , 1 , 0 ], ![1 , 0 , 1 ], ![0 , 1 , 1 ], ![1 , 2 , 3 ]]
67- test_ks.all fun k =>
68- -- Re-implement loop
69- Demo.Altermagnet.Altermagnet_Group.all fun g =>
70- let val_gk := f (SPG.Physics.Hamiltonian.act_on_k g k)
71- let val_k := f k
72- -- Re-use projection logic from check_invariant
73- if s == .I then
74- val_gk == val_k
75- else
76- let s_prime := SPG.Physics.Hamiltonian.act_on_spin g s
77- let coeff := SPG.Physics.Hamiltonian.project_spin s_prime s
78-
79- -- Check eigenstate property (no mixing)
80- let is_eigen :=
81- (s == .x && s_prime 1 == 0 && s_prime 2 == 0 ) ||
82- (s == .y && s_prime 0 == 0 && s_prime 2 == 0 ) ||
83- (s == .z && s_prime 0 == 0 && s_prime 1 == 0 )
84-
85- if is_eigen then
86- val_gk * coeff == val_k
87- else
88- false
89-
90- let kx2_minus_ky2 (k : SPG.Vec3) : ℚ := k 0 * k 0 - k 1 * k 1
91- let kx2_plus_ky2 (k : SPG.Vec3) : ℚ := k 0 * k 0 + k 1 * k 1
92- let kx_ky (k : SPG.Vec3) : ℚ := k 0 * k 1
93-
94- if check_custom kx2_minus_ky2 .z then
24+ IO.println "Invariant k·p Hamiltonians (basis by degree ≤ 2):"
25+
26+ let group := SPG.Data.MagneticGroups.Altermagnet_Group_D4h
27+ let blocks := SPG.Physics.Hamiltonian.invariants_vector_by_degree_solve group 2
28+ for (d, hs) in blocks do
29+ IO.println s! " degree { d} :"
30+ for h in hs do
31+ IO.println s! " { SPG.Physics.Hamiltonian.ham_to_string h} "
32+
33+ IO.println "Invariant complex k·p Hamiltonians (basis by degree ≤ 2):"
34+ let cblocks := SPG.Physics.Hamiltonian.invariants_vector_by_degree_solveC group 2
35+ for (d, hs) in cblocks do
36+ IO.println s! " degree { d} :"
37+ for h in hs do
38+ IO.println s! " { SPG.Physics.Hamiltonian.cham_to_string h} "
39+
40+ let p_dwave : SPG.Physics.Hamiltonian.Poly :=
41+ (SPG.Physics.Hamiltonian.kx * SPG.Physics.Hamiltonian.kx) -
42+ (SPG.Physics.Hamiltonian.ky * SPG.Physics.Hamiltonian.ky)
43+ let p_xy : SPG.Physics.Hamiltonian.Poly :=
44+ SPG.Physics.Hamiltonian.kx * SPG.Physics.Hamiltonian.ky
45+ let p_kin : SPG.Physics.Hamiltonian.Poly :=
46+ (SPG.Physics.Hamiltonian.kx * SPG.Physics.Hamiltonian.kx) +
47+ (SPG.Physics.Hamiltonian.ky * SPG.Physics.Hamiltonian.ky)
48+
49+ if SPG.Physics.Hamiltonian.isInvariantHam group (SPG.Physics.Hamiltonian.singleTerm p_dwave .z) then
9550 IO.println " (kx^2 - ky^2) * σz [d-wave altermagnetism (x^2-y^2 type)]"
9651 else
9752 IO.println " (kx^2 - ky^2) * σz [FORBIDDEN]"
98- -- Analyze why it is forbidden (or allowed)
99- let _ ← SPG.Physics.Hamiltonian.analyze_term_symmetry Demo.Altermagnet.Altermagnet_Group kx2_minus_ky2 .z "(kx^2 - ky^2)" "σz"
10053
101- if check_custom kx_ky .z then
54+ if SPG.Physics.Hamiltonian.isInvariantHam group (SPG.Physics.Hamiltonian.singleTerm p_xy .z) then
10255 IO.println " kx ky * σz [d-wave altermagnetism (xy type)]"
10356 else
10457 IO.println " kx ky * σz [FORBIDDEN]"
105- let _ ← SPG.Physics.Hamiltonian.analyze_term_symmetry Demo.Altermagnet.Altermagnet_Group kx_ky .z "kx ky" "σz"
10658
107- if check_custom kx2_plus_ky2 .I then
59+ if SPG.Physics.Hamiltonian.isInvariantHam group (SPG.Physics.Hamiltonian.singleTerm p_kin .I) then
10860 IO.println " (kx^2 + ky^2) * I [Standard kinetic term]"
10961 else
11062 IO.println " (kx^2 + ky^2) * I [FORBIDDEN]"
111- let _ ← SPG.Physics.Hamiltonian.analyze_term_symmetry Demo.Altermagnet.Altermagnet_Group kx2_plus_ky2 .I "(kx^2 + ky^2)" "I"
0 commit comments