# # Cavity Antiresonance

# In this example we investigate a system of $N$ closely spaced quantum emitters inside a coherently driven single mode cavity. The model is described in [D. Plankensteiner, et. al., Phys. Rev. Lett. 119, 093601 (2017)](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.119.093601).
# The Hamiltonian of this system is composed of three parts $H = H_c + H_a + H_{\mathrm{int}}$, the driven cavity $H_c$, the dipole-dipole interacting atoms $H_a$ and the atom-cavity interaction $H_\mathrm{int}$:

# ```math
# \begin{align}
# H_\mathrm{c} &= \hbar \Delta_c a^\dagger a + \hbar \eta (a^\dagger + a) \\
# &\\
# H_a &= \hbar \Delta_a \sum\limits_{j} \sigma_j^{22} + \hbar \sum\limits_{i \neq j} \Omega_{ij} \sigma_i^{21} \sigma_j^{12}
# &\\
# H_\mathrm{int} &= \hbar \sum\limits_{j} g_j (a^\dagger \sigma_j^{12} + a \sigma_j^{21})
# \end{align}
# ```

# Additionally the system features two decay channels, the lossy cavity with photon decay rate $\kappa$ and collective atomic emission described by the decay-rate matrix $\Gamma_{ij}$.

# We start by loading the packages.

using QuantumCumulants
using OrdinaryDiffEqTsit5, ModelingToolkitBase
using Plots

# The Hilbert space for this system is given by one cavity mode and $N$ two-level atoms. Here we use symbolic indices, sums and double sums to define the system.
# The parameters $g_j, \, \Gamma_{ij}$ and $\Omega_{ij}$ are defined as indexed variables of atom $i$ and $j$. We will describe the system in first order mean-field.
# Because $\Gamma_{ij}$ and $\Omega_{ij}$ depend on both atom labels, they enter the double sums as index-dependent coefficients; this per-pair dependence is carried through the cumulant expansion and [`evaluate`](@ref) without losing the summation scope.

hc = FockSpace(:cavity) # Hilbert space
ha = NLevelSpace(Symbol(:atom), 2)
h = hc ⊗ ha

@variables N Δc η Δₐ κ # Parameters
g(i) = IndexedVariable(:g, i)
Γ(i, j) = DoubleIndexedVariable(:Γ, i, j)
Ω(i, j) = DoubleIndexedVariable(:Ω, i, j; identical = false)


i = Index(h, :i, N, ha) # Indices
j = Index(h, :j, N, ha)
nothing # hide


# The kwarg ’identical=false’ for the double indexed variable specifies that $\Omega_{ij} = 0$ for $i = j$.
# Now we create the operators on the composite Hilbert space using the $\texttt{IndexedOperator}$ constructor, which assigns each $\texttt{Transition}$ operator an $\texttt{Index}$.

@qnumbers a::Destroy(h)
σ(x, y, k) = IndexedOperator(Transition(h, :σ, x, y), k)
nothing # hide

# We define the Hamiltonian and Liouvillian. For the collective atomic decay we write the corresponding dissipative processes with a double indexed variable $R_{ij}$ and an indexed jump operator $J_j$, such that an operator average $\langle \mathcal{O} \rangle$ follows the equation

# ```math
# \begin{equation}
# \langle \dot{\mathcal{O}} \rangle = \sum_{ij} R_{ij} \left( \langle J_i^\dagger \mathcal{O} J_j \rangle - \frac{1}{2} \langle J_i^\dagger J_j \mathcal{O} \rangle - \frac{1}{2} \langle \mathcal{O} J_i^\dagger J_j \rangle \right).
# \end{equation}
# ```

# The inner dipole-dipole sum excludes the diagonal `i == j` by passing the
# `non_equal` vector `[i]` to the inner `Σ` (SQA v0.5 replaced the old
# `non_equal=true` keyword with this explicit form).
Hc = Δc * a'a + η * (a' + a) # Hamiltonian
Ha = Δₐ * Σ(σ(2, 2, i), i) + Σ(Σ(Ω(i, j) * σ(2, 1, i) * σ(1, 2, j), j, [i]), i)
Hi = Σ(g(i) * (a' * σ(1, 2, i) + a * σ(2, 1, i)), i)
H = Hc + Ha + Hi

J = [a, σ(1, 2, i)] # Jump operators
rates = [κ, Γ(i, j)]
nothing # hide

# We derive the system of equations in first order mean-field.

eqs = meanfield(a, H, J; rates = rates, order = 1)
complete!(eqs)

# To create the equations for a specific number of atoms we use the function [`evaluate`](@ref).

N_ = 2
eqs_ = evaluate(eqs; limits = (N => N_))
sys = mtkcompile(System(eqs_; name = :sys))
nothing # hide

# Finally we need to define the initial state of the system and the numerical parameters. In the end we want to obtain the transmission rate $T$ of our system. For this purpose we calculate the steady state photon number in the cavity $|\langle a \rangle|^2$ for different laser frequencies.

u0 = zeros(ComplexF64, length(eqs_.states))
Γ_ = 1.0 # parameter
d = 2π * 0.08 #0.08λ
θ = π / 2

Ωij(i, j) =
    i == j ? 0 :
    Γ_ * (-3 / 4) * ((1 - (cos(θ))^2) * cos(d) / d - (1 - 3 * (cos(θ))^2) * (sin(d) / (d^2) + (cos(d) / (d^3))))
Γij(i, j) =
    i == j ? Γ_ :
    Γ_ * (3 / 2) * ((1 - (cos(θ))^2) * sin(d) / d + (1 - 3 * (cos(θ))^2) * ((cos(d) / (d^2)) - (sin(d) / (d^3))))

g_ = 2Γ_
κ_ = 20Γ_
Δₐ_ = 0Γ_
Δc_ = 0Γ_
η_ = κ_ / 100

gi_ = [g_ * (-1)^k for k in 1:N_]
Γij_ = [Γij(k, l) for k in 1:N_, l in 1:N_]
Ωij_ = [Ωij(k, l) for k in 1:N_, l in 1:N_]

Δ_ls = [-10:0.05:10;] * Γ_
n_ls = zeros(length(Δ_ls))
for k in eachindex(Δ_ls)
    Δc_i = Δ_ls[k]
    Δₐ_i = Δc_i + Ωij(1, 2)
    p = parameter_map(
        eqs_, Dict(
            Δc => Δc_i, η => η_, Δₐ => Δₐ_i, κ => κ_,
            g(i) => gi_, Γ(i, j) => Γij_, Ω(i, j) => Ωij_,
        )
    )
    prob_ = ODEProblem(sys, merge(initial_values(eqs_, u0), Dict(p)), (0.0, 20.0))
    sol_ = solve(prob_, Tsit5())
    n_ls[k] = abs2(get_solution(sol_, a, eqs_)(sol_.t[end]))
end
nothing # hide

# The transmission rate $T$ with respect to the pump laser detuning is given by the relative steady state intra-cavity photon number $n(\Delta)/n_\mathrm{max}$. We qualitatively reproduce the antiresonance from [D. Plankensteiner, et. al., Phys. Rev. Lett. 119, 093601 (2017)](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.119.093601) for two atoms.

T = n_ls ./ maximum(n_ls)
plot(Δ_ls, T, xlabel = "Δ/Γ", ylabel = "T", legend = false)

# ## Package versions

# These results were obtained using the following versions:

using InteractiveUtils
versioninfo()

using Pkg
Pkg.status(
    ["QuantumCumulants", "OrdinaryDiffEqTsit5", "ModelingToolkitBase", "Plots"],
    mode = PKGMODE_MANIFEST,
)
