# Transitions of a $d^4$ system

We calculate the possible transitions of the type $d^4d^4\rightarrow d^3d^5$, applying some knowledge regarding the ground state of the CRO system.

To recapitulate, the representation is as follows: each level/orbital is composed of two elements of an array, one for each spin (up, down). In a low spin d4 system, we have only the t2g orbitals (xy yz xz) active leading to a 6 elements representation for a site. Two neighboring states involved in a transition are contiguous in a list, thus consisting of 12 elements.

First we generate all possible states for a single site with 3, 4, and 5 electrons.



In [ ]:

import numpy as np
import itertools
import functools
import operator




In [ ]:

def generate_states(electrons, states):
seed = [1 if position < electrons else 0 for position in range(states)]
generated_states = list(set(itertools.permutations(seed)))
generated_states.sort(reverse=True)
return generated_states




In [ ]:

states_d3 = generate_states(3,6)
states_d4 = generate_states(4,6)
states_d5 = generate_states(5,6)
states_d4



Not all generated states are relevant for the problem, and we can reduce the amount of states beforehand.

From all the $d^4$ states, we consider only those with a full $d_{xy}$ orbital and those which distribute the other two electrons in different orbitals as possible initial states as those are the possible ground states. In our representations, this means only the states that have a 1 in the first two entires. Also, we do not need those states with double occupancy in zx or yz orbital.



In [ ]:

possible_states_d4 = [state for state in states_d4
if state[0]==1 and state[1]==1  #  dxy orbital double occupancy
and state[2] is not state[3]]       # dzx/dyz orbital single occupancy
possible_states_d4



Regarding the $d^3$ states, we want at least those which keep one electron in the $d_{xy}$ orbital since we know that the others states are not reachable with one movement.



In [ ]:

possible_states_d3 = [state for state in states_d3 if state[0]==1 or state[1]==1]
possible_states_d3



In the case of the $d^5$ states, since our ground state has a doule occupied $d_{xy}$ orbital then it has to stay occupied.



In [ ]:

possible_states_d5 = [list(state) for state in states_d5 if state[0]==1 and state[1]==1]
possible_states_d5



Now we generate all possible initial $d^4d^4$



In [ ]:

for combination
in itertools.combinations_with_replacement(possible_states_d4,2)]))
initial_states



and the $d^3d^5$ final states printing out the amount of them.



In [ ]:

for combination
in itertools.product(possible_states_d3,possible_states_d5)]))
final_states.sort(reverse=True)
len(final_states)



Now we check if the transition from each initial state to each final state and print out those that are allowed.



In [ ]:

def is_allowed(jump):
if np.unique(np.remainder(np.nonzero(jump),2)).size == 1:
return 1
return 0

for initial_state in initial_states:
for final_state in final_states:
jump = np.logical_xor(initial_state,final_state)
allowed = is_allowed(jump)
if allowed:
print("From initial state {} to final state {} is allowed.".format(initial_state, final_state))



Now we test what happens for the actual transitions. First at low temperatures we only have $S_z=\pm1$ states in the ground state in AFM ordering.



In [ ]:

#                                i      '     j
#
AFM_ground_state_multiplet    = [1,1,1,0,1,0,1,1,0,1,0,1] # d4d4 AFM state
final_state_multiplet_d3_one  = [[1,0,1,0,0,1],[1,0,0,1,1,0],[0,1,1,0,1,0]]  # 4A2 S=1/2 d3 multiplet

for state
in final_state_multiplet_d3_one]

for state in final_state_multiplet_one:
jump = np.logical_xor(AFM_ground_state_multiplet, state)
allowed = is_allowed(jump)
print(allowed)




In [ ]:

AFM_ground_state_multiplet    = [1,1,0,1,0,1,1,1,1,0,1,0] # d4d4 AFM state
final_state_multiplet_d3_two  = [[1,0,0,1,0,1],[0,1,1,0,0,1],[0,1,0,1,1,0]]  # 4A2 S=1/2 d3 multiplet
for state
in final_state_multiplet_d3_two]
for state in final_state_multiplet_two:
jump = np.logical_xor(AFM_ground_state_multiplet,state)
allowed = is_allowed(jump)
print(allowed)



From the $d^4_{\downarrow}d^4_{\uparrow}$ AFM state to the $d3d5$ $^4A_2$ $S=\frac{1}{2}$ there is only one allowed term. Comparing the ground state and the final multiplet we can see that the transition is $t_{xy,xz}/\sqrt{3}$. Unfortunatelly, this way of testing transitions is somewhat cumbersome, particularly given that we already calculated all possible combinations.

Now we check for the $d^4_{\uparrow}d^4_{\uparrow}$ FM state to the $d3d5$ $^4A_2$ $S=\frac{3}{2}$.



In [ ]:

FM_ground_state_multiplet     = [1,1,1,0,1,0,1,1,1,0,1,0] # d4d4 AFM state
final_state_multiplet_d3_three  = [[1,0,1,0,1,0]]  # 4A2 S=3/2 d3 multiplet

for state
in final_state_multiplet_d3_three]

for state in final_state_multiplet_three:
jump = np.logical_xor(FM_ground_state_multiplet, state)
allowed = is_allowed(jump)
print(allowed)



The result obtained is the same as easily calculculated by hand, where the transition is allowed and has a matrix element of $t_{xy,xz}$.

We create now all possible $^4A_2$ multiplets with $S=3/2$. These are composed by the $S_z=3/2$ and the $S_z=1/2$ states.

First for $S_z=3/2$ we have



In [ ]:

multiplet_d3 = [[1,0,1,0,1,0],[0,1,0,1,0,1]] # 4A2 S=3/2 d3 multiplet, both spins
possible_states_d5 = [list(state) for state in possible_states_d5]
for combination
in itertools.product(list(multiplet_d3),list(possible_states_d5))]
final_states_multiplets.sort(reverse=True)
print("From initial state {}".format(AFM_ground_state_multiplet))
for state in final_states_multiplets:
jump = np.logical_xor(AFM_ground_state_multiplet,state)
allowed = is_allowed(jump)
if allowed:
print("       final state {} is allowed.".format(state))



From this multiplet, we cannot reach any final $d^5$ state.

Doing the same for the $d^3$ $S_z=1/2$ states we obtain



In [ ]:

multiplet_d3_down  = [[1,0,1,0,0,1],[1,0,0,1,1,0],[0,1,1,0,1,0]]  # 4A2 Sz=1/2 d3 multiplet one spin down
multiplet_d3_up  = [[1,0,0,1,0,1],[0,1,1,0,0,1],[0,1,0,1,1,0]]  # 4A2 Sz=1/2 d3 multiplet one spin up
for combination
in itertools.product(multiplet_d3_down+multiplet_d3_up,possible_states_d5)]
final_states_multiplets.sort(reverse=True)
print("From initial state {}".format(AFM_ground_state_multiplet))
for state in final_states_multiplets:
jump = np.logical_xor(AFM_ground_state_multiplet,state)
allowed = is_allowed(jump)
if allowed:
print("       final state {} is allowed.".format(state))



Given the antiferromagnetic $d^4_\downarrow d^4_\uparrow$ state as the initial one, only transitions from the $d_{xy}$ orbital to the $d_{xz}$ or $d_{yz}$ orbitals are allowed with transition matrix element $t_{xy,xz}/\sqrt{3}$ and $t_{xy,yz}/\sqrt{3}$, respectivelly.

Now, we are interested in the $S_z=0$ $d^4$ state into account.



In [ ]:

multiplet_d4_Sz0 = [[1,1,1,0,0,1],[1,1,0,1,1,0]]  # Sz=0 d4 multiplet
list(itertools.product(multiplet_d4_Sz0,multiplet_d4_Sz0))




In [ ]:

multiplet_d4_Sz0 = [[1,1,1,0,0,1],[1,1,0,1,1,0]]  # Sz=0 d4 multiplet
for combination
in itertools.product(multiplet_d4_Sz0,multiplet_d4_Sz0)]
initial_states_multiplets




In [ ]:

multiplet_d3_down  = [[1,0,1,0,0,1],[1,0,0,1,1,0],[0,1,1,0,1,0]]  # 4A2 Sz=1/2 d3 multiplet one spin down
multiplet_d3_up  = [[1,0,0,1,0,1],[0,1,1,0,0,1],[0,1,0,1,1,0]]  # 4A2 Sz=1/2 d3 multiplet one spin up
for combination
in itertools.product(multiplet_d3_down+multiplet_d3_up,possible_states_d5)]
final_states_multiplets.sort(reverse=True)
for istate in initial_states_multiplets:
print("From initial state {}".format(istate))
for state in final_states_multiplets:
print(istate,state)
jump = np.logical_xor(istate,state)
allowed = is_allowed(jump)
if allowed:
print("       final state {} is allowed {}.".format(state, allowed))




In [ ]:

len(final_states_multiplets)




In [ ]:

multiplet_d3_down+multiplet_d3_up




In [ ]:

possible_states_d5




In [ ]:

list(itertools.product(multiplet_d3_down+multiplet_d3_up,possible_states_d5))




In [ ]:

test_state = (1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0)

for state in final_states:
jump = np.logical_xor(test_state,state)
allowed = is_allowed(jump)
if allowed:
print("From initial state {}".format(test_state))
print("       final state {} is allowed.\n".format(state))



We have an overestimation of allowed transitions, from the six ones showed only 4 are proper ones. The other two have two extra changes!

When taking those out, we obtain the transitions



In [ ]:

test_state = (1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1)

for state in final_states:
jump = np.logical_xor(test_state,state)
allowed = is_allowed(jump)
if allowed:
print("From initial state {}".format(test_state))
print("       final state {} is allowed.\n".format(state))



Now, we want to extract the amplitudes in a smart way. Considering the $S_z=\pm1,0$ we have four possible initial states: $d^\uparrow_4d^\uparrow_4$, $d^\uparrow_4d^\downarrow_4$, $d^\uparrow_4d^0_4$, $d^0_4d^0_4$. Then, we are interested in the $d_3d_5$ sectors given by a $|^4A_2,3/2>$, $|^4A_2,1/2>$, $|^4A_2,3/2>$, $|^2E,a>$, $|^2E,b>$ multiplets (as given by Zang202017), combined with a $d_5$ state.

# Final code!



In [ ]:

from typing import List

def transition(initial: List, final: List[List[int]], debug = False):
"""This function takes the list representation of an initial state and a list of
final d3 states. Then, it computes if the transition from the initial state to the
compounded d3d5 final state is possible.
"""
# multiplet_d3 = [[1,0,1,0,1,0],[0,1,0,1,0,1]] # 4A2 S=3/2 d3 multiplet, both spins
#     possible_states_d5 = [list(state) for state in possible_states_d5]

# Producing all the possible final states. This has to be read from bottom to top.
final_states = [
functools.reduce(operator.add, combination) #  3) the single site representations are combined into one single two-site representation
for combination  # 2) we iterate over all the d3d5 combinations produced
in itertools.product(list(final), list(possible_states_d5))  # 1) make the product of the given d3 final states and possible d5 states.
]

final_states.sort(reverse=True)

if debug:
print(final_states)

print("From initial state {}".format(initial))
for state in final_states:
jump = np.logical_xor(initial,state)
allowed = is_allowed(jump)
if allowed:
print("       final state {} is allowed.".format(state))




In [ ]:

transition(initial=[1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0], final=[[1,0,1,0,1,0],[0,1,0,1,0,1]])




In [ ]:

possible_states_d4



## Case: $^4A_2$ and $S=\pm1$

Starting with the pure $S=\pm1$ initial states, meaning $d^\uparrow_4d^\uparrow_4$ and $d^\uparrow_4d^\downarrow_4$, we have the following representations:



In [ ]:

AFM_down = [1,1,0,1,0,1,1,1,1,0,1,0]
FM_down  = [1,1,0,1,0,1,1,1,0,1,0,1]

AFM_up = [1,1,1,0,1,0,1,1,0,1,0,1]
FM_up  = [1,1,1,0,1,0,1,1,1,0,1,0]



Then, the representation for a $|^4A_2,3/2>$ multiplet is given by



In [ ]:

A2_32 = [[1,0,1,0,1,0]]
transition(AFM, A2_32)
transition(FM, A2_32)



As expected, this transition has no weigth.

Continuing with $|^4A_2,1/2>$



In [ ]:

A2_12 = [[1,0,0,1,0,1],[0,1,1,0,0,1],[0,1,0,1,1,0]]  # 4A2 Sz=1/2 d3 multiplet one spin up
transition(AFM, A2_12)
transition(FM, A2_12)



Going now into the more challenging $S=0$ states, we start with the $d^\uparrow_4d^0_4$ initial state. For this, we will split thw $d^0_4$ in the two parts.



In [ ]:

S0_1 = [1, 1, 1, 0, 0, 1]
S0_2 = [1, 1, 0, 1, 1, 0]



For the $|^4A_2,3/2>$ $d_3$ multiplet



In [ ]:

transition(S0_1 + [1, 1, 1, 0, 1, 0], A2_32)
transition(S0_2 + [1, 1, 1, 0, 1, 0], A2_32)



For the $|^4A_2,1/2>$ $d_3$ multiplet



In [ ]:

transition(S0_1 + [1, 1, 0, 1, 0, 1], A2_12)
transition(S0_2 + [1, 1, 0, 1, 0, 1], A2_12)



Continuing with the $d^0_4d^0_4$



In [ ]:

transition(S0_1 + S0_2, A2_32)
transition(S0_1 + S0_2, A2_12)



## E multiplets

We first do $S=\pm1$ initial states.



In [ ]:

Ea = [[0,1,1,0,1,0],[1,0,0,1,1,0],[1,0,1,0,0,1]]  # 2Ea
transition(AFM, Ea)
transition(FM, Ea)




In [ ]:

Eb = [[1,0,1,0,0,1],[1,0,0,1,1,0]]  # 2Eb
transition(AFM, Eb)
transition(FM, Eb)




In [ ]:

possible_states_d5




In [ ]:



## $|^2T1>$

First we encode the $|^2T1>$ multiplet



In [28]:

T1 = [[1,0,0,0,1,1],[1,0,1,1,0,0]]
transition(AFM_down, T1)
transition(AFM_up, T1)
transition(FM_down, T1)
transition(FM_up, T1)




From initial state [1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0]
From initial state [1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1]
From initial state [1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1]
From initial state [1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0]



This multiplet has no transitions from the $S_z0\pm1$ initial states.

Now, checking the $S_0$ states we obtain:



In [29]:

transition(S0_1 + S0_1, T1)
transition(S0_1 + S0_2, T1)
transition(S0_2 + S0_1, T1)
transition(S0_2 + S0_2, T1)




From initial state [1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1]
final state [1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1] is allowed.
From initial state [1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0]
final state [1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1] is allowed.
From initial state [1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1]
final state [1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1] is allowed.
From initial state [1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0]
final state [1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1] is allowed.