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

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

```
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 [ ]:
```initial_states = list(set([tuple(functools.reduce(operator.add, combination))
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 [ ]:
```final_states = list(set([tuple(functools.reduce(operator.add, combination))
for combination
in itertools.product(possible_states_d3,possible_states_d5)]))
final_states.sort(reverse=True)
len(final_states)

```
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))

```
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
final_state_multiplet_one = [tuple(functools.reduce(operator.add, [state, [1,1,1,1,0,1]]))
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
final_state_multiplet_two = [list(functools.reduce(operator.add, [state, [1,1,1,0,1,1]]))
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
final_state_multiplet_three = [tuple(functools.reduce(operator.add, [state, [1,1,1,1,1,0]]))
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]
final_states_multiplets = [functools.reduce(operator.add, combination)
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
final_states_multiplets = [functools.reduce(operator.add, combination)
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
functools.reduce(operator.add, multiplet_d4_Sz0*2)
initial_states_multiplets = [tuple(functools.reduce(operator.add, combination))
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
final_states_multiplets = [tuple(functools.reduce(operator.add, combination))
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))

```
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
```

```
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)

```
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)

```
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 [ ]:
```

```
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)

```
```

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)

```
```