@@ -355,76 +355,75 @@ function _steadystate_fourier(
355355 tol:: R = 1e-8 ,
356356 kwargs... ,
357357) where {R<: Real }
358- T1 = eltype (L_0)
359- T2 = eltype (L_p)
360- T3 = eltype (L_m)
361- T = promote_type (T1, T2, T3)
358+ # Get matrix data and promote types
359+ L0_mat = get_data (L_0)
360+ Lp_mat = get_data (L_p)
361+ Lm_mat = get_data (L_m)
362+ T = promote_type (eltype (L0_mat), eltype (Lp_mat), eltype (Lm_mat))
362363
363- L_0_mat = get_data (L_0)
364- L_p_mat = get_data (L_p)
365- L_m_mat = get_data (L_m)
366-
367- N = size (L_0_mat, 1 )
364+ N = size (L0_mat, 1 )
368365 Ns = isqrt (N)
369366 n_fourier = 2 * n_max + 1
370367 n_list = (- n_max): n_max
371368
369+ # Create stabilization matrix Mn
372370 weight = one (T)
373- rows = ones (Int, Ns)
374- cols = [Ns * (j - 1 ) + j for j in 1 : Ns]
375- vals = fill (weight, Ns)
376- Mn = _sparse_similar (L_0_mat, rows, cols, vals, N, N)
377- L = L_0_mat + Mn
378-
379- M = _sparse_similar (L_0_mat, n_fourier * N, n_fourier * N)
380- for i in 1 : (n_fourier- 1 )
381- M_block = _sparse_similar (L_0_mat, N, N)
382- copyto! (M_block, L_p_mat)
383- M[(i* N+ 1 ): ((i+ 1 )* N), ((i- 1 )* N+ 1 ): (i* N)] = M_block
384- M_block = _sparse_similar (L_0_mat, N, N)
385- copyto! (M_block, L_m_mat)
386- M[((i- 1 )* N+ 1 ): (i* N), (i* N+ 1 ): ((i+ 1 )* N)] = M_block
387- end
371+ diag_indices = Ns * (0 : (Ns- 1 )) .+ (1 : Ns)
372+ Mn = _sparse_similar (L0_mat, ones (Int, Ns), diag_indices, fill (weight, Ns), N, N)
388373
389- for i in 1 : n_fourier
390- n = n_list[i]
391- M_block = _sparse_similar (L_0_mat, N, N)
392- copyto! (M_block, L)
393- M_block -= 1im * ωd * n * sparse (I, N, N )
394- M[((i - 1 ) * N + 1 ) : (i * N), ((i - 1 )* N + 1 ) : (i * N)] = M_block
395- end
374+ # Base Liouvillian
375+ L = L0_mat + Mn
376+
377+ # Build off-diagonal blocks
378+ Kp = _sparse_similar (L0_mat, spdiagm ( - 1 => ones (T, n_fourier - 1 )) )
379+ Km = _sparse_similar (L0_mat, spdiagm ( 1 => ones (T, n_fourier - 1 )))
380+ M = kron (Kp, Lm_mat) + kron (Km, Lp_mat)
396381
397- v0 = similar (L_0_mat, n_fourier * N)
398- fill! (v0, zero (T))
399- target_idx = n_max* N + 1
400- QuantumToolbox. allowed_setindex! (v0, weight, target_idx)
382+ # Build diagonal blocks
383+ n_vals = - 1im * ωd * T .(n_list)
384+ diag_blocks = [L + n * sparse (I, N, N) for n in n_vals]
385+ block_diag = blockdiag (diag_blocks... )
386+ M += block_diag
401387
388+ # Initialize RHS vector
389+ v0 = zeros (T, n_fourier * N)
390+ v0[n_max* N+ 1 ] = weight
391+
392+ # Preconditioners setup
402393 (haskey (kwargs, :Pl ) || haskey (kwargs, :Pr )) && error (" The use of preconditioners must be defined in the solver." )
403394 if ! isnothing (solver. Pl)
404- kwargs = merge (( ; kwargs... ), ( Pl = solver. Pl (M), ))
395+ kwargs = ( ; kwargs... , Pl = solver. Pl (M))
405396 elseif isa (M, SparseMatrixCSC)
406- kwargs = merge ((; kwargs... ), (Pl = ilu (M, τ = 0.01 ),))
397+ kwargs = (; kwargs... , Pl = ilu (M, τ = 0.01 ))
398+ end
399+ if ! isnothing (solver. Pr)
400+ kwargs = (; kwargs... , Pr = solver. Pr (M))
401+ end
402+ if ! haskey (kwargs, :abstol )
403+ kwargs = (; kwargs... , abstol = tol)
404+ end
405+ if ! haskey (kwargs, :reltol )
406+ kwargs = (; kwargs... , reltol = tol)
407407 end
408- ! isnothing (solver. Pr) && (kwargs = merge ((; kwargs... ), (Pr = solver. Pr (M),)))
409- ! haskey (kwargs, :abstol ) && (kwargs = merge ((; kwargs... ), (abstol = tol,)))
410- ! haskey (kwargs, :reltol ) && (kwargs = merge ((; kwargs... ), (reltol = tol,)))
411408
409+ # Solve linear system
412410 prob = LinearProblem (M, v0)
413411 ρtot = solve (prob, solver. alg; kwargs... ). u
414412
413+ # Extract ρ0 and normalize
415414 offset1 = n_max * N
416415 offset2 = (n_max + 1 ) * N
417- ρ0 = reshape (ρtot[(offset1+ 1 ): offset2], Ns, Ns)
416+ ρ0 = Matrix ( reshape (ρtot[(offset1+ 1 ): offset2], Ns, Ns)) # Explicitly convert to Matrix
418417 ρ0_tr = tr (ρ0)
419- ρ0 = ρ0 / ρ0_tr
418+ ρ0 ./= ρ0_tr
420419 ρ0 = QuantumObject ((ρ0 + ρ0' ) / 2 , type = Operator (), dims = L_0. dimensions)
421- ρtot = ρtot / ρ0_tr
422420
421+ # Collect higher-order Fourier components
423422 ρ_list = [ρ0]
424423 for i in 0 : (n_max- 1 )
425- ρi_m = reshape (ρtot[( offset1- (i+ 1 )* N+ 1 ): (offset1- i* N)], Ns, Ns )
426- ρi_m = QuantumObject (ρi_m, type = Operator (), dims = L_0 . dimensions)
427- push! (ρ_list, ρi_m)
424+ idx_range = ( offset1- (i+ 1 )* N+ 1 ): (offset1- i* N)
425+ ρi_m = Matrix ( reshape (ρtot[idx_range], Ns, Ns)) # Explicitly convert to Matrix
426+ push! (ρ_list, QuantumObject ( ρi_m, type = Operator (), dims = L_0 . dimensions) )
428427 end
429428
430429 return ρ_list
0 commit comments