diff --git a/README.md b/README.md index 866b6449..93ab7726 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ and [Y.-T. Huang](https://github.com/ytdHuang). - **Quantum State and Operator Manipulation:** Easily handle quantum states and operators with a rich set of tools, with the same functionalities as `QuTiP`. - **Dynamical Evolution:** Advanced solvers for time evolution of quantum systems, thanks to the powerful [`DifferentialEquations.jl`](https://github.com/SciML/DifferentialEquations.jl) package. - **GPU Computing:** Leverage GPU resources for high-performance computing. Simulate quantum dynamics directly on the GPU with the same syntax as the CPU case. -- **Distributed Computing:** Distribute the computation over multiple nodes (e.g., a cluster). For example, you can run hundreds of quantum trajectories in parallel on a cluster, with, again, the same syntax as the simple case. See [this tutorial](https://qutip.org/QuantumToolbox.jl/stable/tutorials/cluster) for more information. +- **Distributed Computing:** Distribute the computation over multiple nodes (e.g., a cluster). For example, you can run hundreds of quantum trajectories in parallel on a cluster, with, again, the same syntax as the simple case. See [here](https://qutip.org/QuantumToolbox.jl/stable/users_guide/cluster) for more information. - **Easy Extension:** Easily extend the package, taking advantage of the `Julia` language features, like multiple dispatch and metaprogramming. ## Installation diff --git a/docs/make.jl b/docs/make.jl index f49590d5..0aec9e28 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -36,6 +36,7 @@ const PAGES = [ "Brief Example" => "getting_started/brief_example.md", "Key differences from QuTiP" => "getting_started/qutip_differences.md", "The Importance of Type-Stability" => "getting_started/type_stability.md", + "Example: Create QuantumToolbox.jl Logo" => "getting_started/logo.md", # "Cite QuantumToolbox.jl" => "getting_started/cite.md", ], "Users Guide" => [ @@ -54,6 +55,7 @@ const PAGES = [ "Stochastic Solver" => "users_guide/time_evolution/stochastic.md", "Solving Problems with Time-dependent Hamiltonians" => "users_guide/time_evolution/time_dependent.md", ], + "Intensive parallelization on a Cluster" => "users_guide/cluster.md", "Hierarchical Equations of Motion" => "users_guide/HEOM.md", "Solving for Steady-State Solutions" => "users_guide/steadystate.md", "Two-time correlation functions" => "users_guide/two_time_corr_func.md", @@ -62,15 +64,6 @@ const PAGES = [ "users_guide/extensions/cairomakie.md", ], ], - "Tutorials" => [ - "Time Evolution" => [ - "Low Rank Master Equation" => "tutorials/lowrank.md", - ], - "Miscellaneous Tutorials" => [ - "tutorials/logo.md", - "tutorials/cluster.md", - ], - ], "Resources" => [ "API" => "resources/api.md", "Bibliography" => "resources/bibliography.md", diff --git a/docs/src/.vitepress/config.mts b/docs/src/.vitepress/config.mts index bad15a5a..9a0732bb 100644 --- a/docs/src/.vitepress/config.mts +++ b/docs/src/.vitepress/config.mts @@ -13,6 +13,7 @@ const navTemp = { const nav = [ ...navTemp.nav, + { text: 'Tutorials', link: 'https://qutip.org/qutip-julia-tutorials/' }, { text: 'Benchmarks', link: 'https://qutip.org/QuantumToolbox.jl/benchmarks/' }, { component: 'VersionPicker' diff --git a/docs/src/tutorials/logo.md b/docs/src/getting_started/logo.md similarity index 88% rename from docs/src/tutorials/logo.md rename to docs/src/getting_started/logo.md index 12be5156..587e732f 100644 --- a/docs/src/tutorials/logo.md +++ b/docs/src/getting_started/logo.md @@ -1,8 +1,8 @@ -# [Create QuantumToolbox.jl logo](@id doc-tutor:Create-QuantumToolbox.jl-logo) +# [Example: Create QuantumToolbox.jl logo](@id doc:Create-QuantumToolbox.jl-logo) ## Introduction -In this tutorial, we will demonstrate how to create the logo for the **QuantumToolbox.jl** package. The logo represents the Wigner function of the triangular cat state, which is a linear superposition of three coherent states. The resulting Wigner function has a triangular shape that resembles the Julia logo. We will also define a custom colormap that varies based on the value of the Wigner function and the spatial coordinates, such that the three blobs corresponding to the coherent states have different colors (matching the colors of the Julia logo). +In this example, we will demonstrate how to create the logo for the **QuantumToolbox.jl** package. The logo represents the Wigner function of the triangular cat state, which is a linear superposition of three coherent states. The resulting Wigner function has a triangular shape that resembles the Julia logo. We will also define a custom colormap that varies based on the value of the Wigner function and the spatial coordinates, such that the three blobs corresponding to the coherent states have different colors (matching the colors of the Julia logo). ### Triangular Cat State @@ -196,4 +196,4 @@ fig ## Conclusion -This tutorial demonstrates how to generate the [QuantumToolbox.jl](https://github.com/qutip/QuantumToolbox.jl) logo using the package itself and [Makie.jl](https://github.com/MakieOrg/Makie.jl) for visualization. The logo is a visualization of the Wigner function of a triangular cat state, with a custom colormap that highlights the different coherent states with colors matching the Julia logo. +This example demonstrates how to generate the [QuantumToolbox.jl](https://github.com/qutip/QuantumToolbox.jl) logo using the package itself and [Makie.jl](https://github.com/MakieOrg/Makie.jl) for visualization. The logo is a visualization of the Wigner function of a triangular cat state, with a custom colormap that highlights the different coherent states with colors matching the Julia logo. diff --git a/docs/src/index.md b/docs/src/index.md index bf4d70b1..148d2932 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -17,11 +17,14 @@ hero: text: Users Guide link: /users_guide/QuantumObject/QuantumObject - theme: alt - text: View on Github - link: https://github.com/qutip/QuantumToolbox.jl + text: Tutorials + link: https://qutip.org/qutip-julia-tutorials/ - theme: alt text: API link: /resources/api + - theme: alt + text: View on Github + link: https://github.com/qutip/QuantumToolbox.jl - theme: alt text: Visit QuTiP.org link: https://qutip.org/ @@ -39,7 +42,7 @@ features: - icon: title: Distributed Computing details: Distribute the computation over multiple nodes (e.g., a cluster). Simulate hundreds of quantum trajectories in parallel on a cluster, with, again, the same syntax as the simple case. - link: /tutorials/cluster + link: /users_guide/cluster --- ``` diff --git a/docs/src/tutorials/lowrank.md b/docs/src/tutorials/lowrank.md deleted file mode 100644 index d7084600..00000000 --- a/docs/src/tutorials/lowrank.md +++ /dev/null @@ -1,177 +0,0 @@ -# [Low rank master equation](@id doc-tutor:Low-rank-master-equation) - -In this tutorial, we will show how to solve the master equation using the low-rank method. For a detailed explanation of the method, we recommend to read the article [gravina2024adaptive](@cite). - -As a test, we will consider the dissipative Ising model with a transverse field. The Hamiltonian is given by - -```math -\hat{H} = \frac{J_x}{2} \sum_{\langle i,j \rangle} \sigma_i^x \sigma_j^x + \frac{J_y}{2} \sum_{\langle i,j \rangle} \sigma_i^y \sigma_j^y + \frac{J_z}{2} \sum_{\langle i,j \rangle} \sigma_i^z \sigma_j^z - \sum_i h_i \sigma_i^z + h_x \sum_i \sigma_i^x + h_y \sum_i \sigma_i^y + h_z \sum_i \sigma_i^z, -``` - -where the sums are over nearest neighbors, and the collapse operators are given by - -```math -c_i = \sqrt{\gamma} \sigma_i^-. -``` - -We start by importing the packages - -```@example lowrank -using QuantumToolbox -using CairoMakie -CairoMakie.enable_only_mime!(MIME"image/svg+xml"()) -``` - -Define lattice - -```@example lowrank -Nx, Ny = 2, 3 -latt = Lattice(Nx = Nx, Ny = Ny) -``` - -Define lr-space dimensions - -```@example lowrank -N_cut = 2 # Number of states of each mode -N_modes = latt.N # Number of modes -N = N_cut^N_modes # Total number of states -M = latt.N + 1 # Number of states in the LR basis -``` - -Define lr states. Take as initial state all spins up. All other N states are taken as those with miniman Hamming distance to the initial state. - -```@example lowrank -ϕ = Vector{QuantumObject{Vector{ComplexF64},KetQuantumObject,M-1}}(undef, M) -ϕ[1] = kron(fill(basis(2, 1), N_modes)...) - -i = 1 -for j in 1:N_modes - global i += 1 - i <= M && (ϕ[i] = MultiSiteOperator(latt, j=>sigmap()) * ϕ[1]) -end -for k in 1:N_modes-1 - for l in k+1:N_modes - global i += 1 - i <= M && (ϕ[i] = MultiSiteOperator(latt, k=>sigmap(), l=>sigmap()) * ϕ[1]) - end -end -for i in i+1:M - ϕ[i] = QuantumObject(rand(ComplexF64, size(ϕ[1])[1]), dims = ϕ[1].dims) - normalize!(ϕ[i]) -end -nothing # hide -``` - -Define the initial state - -```@example lowrank -z = hcat(get_data.(ϕ)...) -B = Matrix(Diagonal([1 + 0im; zeros(M - 1)])) -S = z' * z # Overlap matrix -B = B / tr(S * B) # Normalize B - -ρ = QuantumObject(z * B * z', dims = ntuple(i->N_cut, Val(N_modes))); # Full density matrix -``` - -Define the Hamiltonian and collapse operators - -```@example lowrank -# Define Hamiltonian and collapse operators -Jx = 0.9 -Jy = 1.04 -Jz = 1.0 -hx = 0.0 -hy = 0.0 -hz = 0.0 -γ = 1 - -Sx = mapreduce(i->MultiSiteOperator(latt, i=>sigmax()), +, 1:latt.N) -Sy = mapreduce(i->MultiSiteOperator(latt, i=>sigmay()), +, 1:latt.N) -Sz = mapreduce(i->MultiSiteOperator(latt, i=>sigmaz()), +, 1:latt.N) - -H, c_ops = DissipativeIsing(Jx, Jy, Jz, hx, hy, hz, γ, latt; boundary_condition = Val(:periodic_bc), order = 1) -e_ops = (Sx, Sy, Sz) - -tl = range(0, 10, 100) -nothing # hide -``` - -### Full evolution - -```@example lowrank -sol_me = mesolve(H, ρ, tl, c_ops; e_ops = [e_ops...]); -Strue = entropy_vn(sol_me.states[end], base=2) / latt.N -``` - -### Low Rank evolution - -Define functions to be evaluated during the low-rank evolution - -```@example lowrank -function f_purity(p, z, B) - N = p.N - M = p.M - S = p.S - T = p.temp_MM - - mul!(T, S, B) - return tr(T^2) -end - -function f_trace(p, z, B) - N = p.N - M = p.M - S = p.S - T = p.temp_MM - - mul!(T, S, B) - return tr(T) -end - -function f_entropy(p, z, B) - C = p.A0 - σ = p.Bi - - mul!(C, z, sqrt(B)) - mul!(σ, C', C) - return entropy_vn(Qobj(Hermitian(σ), type=Operator), base=2) -end -``` - -Define the options for the low-rank evolution - -```@example lowrank -opt = (err_max = 1e-3, p0 = 0.0, atol_inv = 1e-6, adj_condition = "variational", Δt = 0.0); - -sol_lr = lr_mesolve(H, z, B, tl, c_ops; e_ops = e_ops, f_ops = (f_purity, f_entropy, f_trace), opt = opt); -``` - -Plot the results - -```@example lowrank -m_me = real(sol_me.expect[3, :]) / Nx / Ny -m_lr = real(sol_lr.expect[3, :]) / Nx / Ny - -fig = Figure(size = (500, 350), fontsize = 15) -ax = Axis(fig[1, 1], xlabel = L"\gamma t", ylabel = L"M_{z}", xlabelsize = 20, ylabelsize = 20) -lines!(ax, tl, m_lr, label = L"LR $[M=M(t)]$", linewidth = 2) -lines!(ax, tl, m_me, label = "Fock", linewidth = 2, linestyle = :dash) -axislegend(ax, position = :rb) - -ax2 = Axis(fig[1, 2], xlabel = L"\gamma t", ylabel = "Value", xlabelsize = 20, ylabelsize = 20) -lines!(ax2, tl, 1 .- real(sol_lr.fexpect[1, :]), label = L"$1-P$", linewidth = 2) -lines!( - ax2, - tl, - 1 .- real(sol_lr.fexpect[3, :]), - label = L"$1-\mathrm{Tr}(\rho)$", - linewidth = 2, - linestyle = :dash, - color = :orange, -) -lines!(ax2, tl, real(sol_lr.fexpect[2, :]) / Nx / Ny, color = :blue, label = L"S", linewidth = 2) -hlines!(ax2, [Strue], color = :blue, linestyle = :dash, linewidth = 2, label = L"S^{\,\mathrm{true}}_{\mathrm{ss}}") -axislegend(ax2, position = :rb) - -fig -``` diff --git a/docs/src/tutorials/cluster.md b/docs/src/users_guide/cluster.md similarity index 80% rename from docs/src/tutorials/cluster.md rename to docs/src/users_guide/cluster.md index 5bd752b9..3e1726ff 100644 --- a/docs/src/tutorials/cluster.md +++ b/docs/src/users_guide/cluster.md @@ -1,33 +1,16 @@ -# [Intensive parallelization on a Cluster](@id doc-tutor:Intensive-parallelization-on-a-Cluster) +# [Intensive parallelization on a Cluster](@id doc:Intensive-parallelization-on-a-Cluster) ## Introduction -In this tutorial, we will demonstrate how to seamlessly perform intensive parallelization on a cluster using the **QuantumToolbox.jl** package. Indeed, thanks to the [**Distributed.jl**](https://docs.julialang.org/en/v1/manual/distributed-computing/) and [**ClusterManagers.jl**](https://github.com/JuliaParallel/ClusterManagers.jl) packages, it is possible to parallelize on a cluster with minimal effort. The following examples are applied to a cluster with the [SLURM](https://slurm.schedmd.com/documentation.html) workload manager, but the same principles can be applied to other workload managers, as the [**ClusterManagers.jl**](https://github.com/JuliaParallel/ClusterManagers.jl) package is very versatile. +In this example, we will demonstrate how to seamlessly perform intensive parallelization on a cluster using the **QuantumToolbox.jl** package. Indeed, thanks to the [**Distributed.jl**](https://docs.julialang.org/en/v1/manual/distributed-computing/) and [**ClusterManagers.jl**](https://github.com/JuliaParallel/ClusterManagers.jl) packages, it is possible to parallelize on a cluster with minimal effort. The following examples are applied to a cluster with the [SLURM](https://slurm.schedmd.com/documentation.html) workload manager, but the same principles can be applied to other workload managers, as the [**ClusterManagers.jl**](https://github.com/JuliaParallel/ClusterManagers.jl) package is very versatile. -We will consider two examples: +## SLURM batch script -1. **Parallelization of a Monte Carlo quantum trajectories** -2. **Parallelization of a Master Equation by sweeping over parameters** - -### Monte Carlo Quantum Trajectories - -Let's consider a 2-dimensional transverse field Ising model with 4x3 spins. The Hamiltonian is given by - -```math -\hat{H} = \frac{J_z}{2} \sum_{\langle i,j \rangle} \hat{\sigma}_i^z \hat{\sigma}_j^z + h_x \sum_i \hat{\sigma}_i^x \, , -``` - -where the sums are over nearest neighbors, and the collapse operators are given by - -```math -\hat{c}_i = \sqrt{\gamma} \hat{\sigma}_i^- \, . -``` - -We start by creating a file named `run.batch` with the following content: +To submit a batch script to [SLURM](https://slurm.schedmd.com/documentation.html), we start by creating a file named `run.batch` with the following content: ```bash #!/bin/bash -#SBATCH --job-name=tutorial +#SBATCH --job-name=example #SBATCH --output=output.out #SBATCH --account=your_account #SBATCH --nodes=10 @@ -44,9 +27,34 @@ export PATH=/home/username/.juliaup/bin:$PATH julia --project script.jl ``` -where we have to replace `your_account` with the name of your account. This script will be used to submit the job to the cluster. Here, we are requesting 10 nodes with 72 threads each (720 parallel jobs). The `--time` flag specifies the maximum time that the job can run. To see all the available options, you can check the [SLURM documentation](https://slurm.schedmd.com/documentation.html). We also export the path to the custom Julia installation, which is necessary to run the script (replace `username` with your username). Finally, we run the script `script.jl` with the command `julia --project script.jl`. +where we have to replace `your_account` with the name of your account. This script will be used to submit the job to the cluster by using the following command in terminal: + +```shell +sbatch run.batch +``` + +Here, we are requesting `10` nodes with `72` threads each (`720` parallel jobs). The `--time` flag specifies the maximum time that the job can run. To see all the available options, you can check the [SLURM documentation](https://slurm.schedmd.com/documentation.html). We also export the path to the custom Julia installation, which is necessary to run the script (replace `username` with your username). Finally, we run the script `script.jl` with the command `julia --project script.jl`. + +In the following, we will consider two examples: + +1. **Parallelization of a Monte Carlo quantum trajectories** +2. **Parallelization of a Master Equation by sweeping over parameters** + +## Monte Carlo Quantum Trajectories + +Let's consider a `2`-dimensional transverse field Ising model with `4x3` spins. The Hamiltonian is given by + +```math +\hat{H} = \frac{J_z}{2} \sum_{\langle i,j \rangle} \hat{\sigma}_i^z \hat{\sigma}_j^z + h_x \sum_i \hat{\sigma}_i^x \, , +``` + +where the sums are over nearest neighbors, and the collapse operators are given by + +```math +\hat{c}_i = \sqrt{\gamma} \hat{\sigma}_i^- \, . +``` -The `script.jl` contains the following content: +In this case, the `script.jl` contains the following content: ```julia using Distributed @@ -121,7 +129,7 @@ With the println("Hello! You have $(nworkers()) workers with $(remotecall_fetch(Threads.nthreads, 2)) threads each.") ``` -command, we test that the distributed network is correctly initialized. The `remotecall_fetch(Threads.nthreads, 2)` command returns the number of threads of the worker with ID 2. +command, we test that the distributed network is correctly initialized. The `remotecall_fetch(Threads.nthreads, 2)` command returns the number of threads of the worker with ID `2`. We then write the main part of the script, where we define the lattice through the [`Lattice`](@ref) function. We set the parameters and define the Hamiltonian and collapse operators with the [`DissipativeIsing`](@ref) function. We also define the expectation operators `e_ops` and the initial state `ψ0`. Finally, we perform the Monte Carlo quantum trajectories with the [`mcsolve`](@ref) function. The `ensemble_method=EnsembleSplitThreads()` argument is used to parallelize the Monte Carlo quantum trajectories, by splitting the ensemble of trajectories among the workers. For a more detailed explanation of the different ensemble methods, you can check the [official documentation](https://docs.sciml.ai/DiffEqDocs/stable/features/ensemble/) of the [**DifferentialEquations.jl**](https://github.com/SciML/DifferentialEquations.jl/) package. Finally, the `rmprocs(workers())` command is used to remove the workers after the computation is finished. @@ -140,7 +148,7 @@ FINISH! where we can see that the computation **lasted only 21 seconds**. -### Master Equation by Sweeping Over Parameters +## Master Equation by Sweeping Over Parameters In this example, we will consider a driven Jaynes-Cummings model, describing a two-level atom interacting with a driven cavity mode. The Hamiltonian is given by @@ -154,7 +162,7 @@ and the collapse operators are given by \hat{c}_1 = \sqrt{\gamma} \hat{a} \, , \quad \hat{c}_2 = \sqrt{\gamma} \hat{\sigma}_- \, . ``` -The SLURM file is the same as before, but the `script.jl` file now contains the following content: +The SLURM batch script file is the same as before, but the `script.jl` file now contains the following content: ```julia using Distributed