594 |
594 |
|
return (Δv .+ w, w, energy) |
595 |
595 |
|
end |
596 |
596 |
|
|
597 |
|
- |
""" |
598 |
|
- |
var_params(α; v = 0.0, w = 0.0, ω = 1.0, N = 1, show_trace = false, verbose = false) |
599 |
|
- |
|
600 |
|
- |
Minimises the multiple phonon mode free energy function for a set of vₚ and wₚ variational parameters at zero-temperature. Similar to `var_params(α, β)` but with `β = Inf`. |
601 |
|
- |
|
602 |
|
- |
# Arguments |
603 |
|
- |
- `α::Vector{Float64}`: is the partial dielectric electron-phonon coupling parameter for the 'jth' phonon mode. |
604 |
|
- |
- `v::Float64, w::Float64`: determines if the function should start with a random initial set of variational parameters (v, w = 0.0) or a given set of variational parameter values. |
605 |
|
- |
- `ω::Union{Float64, Vector{Float64}}`: phonon mode frequencies (2π THz). Predefined as `ω = 1.0` for a single mode in polaron units. |
606 |
|
- |
- `N::Integer`: specifies the number of variational parameter pairs, v_p and w_p, to use in minimising the free energy. |
607 |
|
- |
- `show_trace::Bool`: shows the optimsation trace from `Optim.jl`. |
608 |
|
- |
- `verbose`: is used by `make_polaron()` to specify whether or not to print. Ignore. |
609 |
|
- |
|
610 |
|
- |
See also [`multi_F`](@ref), [`feynmanvw`](@ref), [`var_param`](@ref). |
611 |
|
- |
""" |
612 |
|
- |
function var_params(α; v = 0.0, w = 0.0, ω = 1.0, N = 1, show_trace = false) # N number of v and w params |
613 |
|
- |
|
614 |
|
- |
if N != length(v) != length(w) |
615 |
|
- |
return error("The number of variational parameters v & w must be equal to N.") |
616 |
|
- |
end |
617 |
|
- |
|
618 |
|
- |
# Use a random set of N initial v and w values. |
619 |
|
- |
if v == 0.0 || w == 0.0 |
620 |
|
- |
# Intial guess for v and w parameters. |
621 |
|
- |
initial = [x for x in 1.0:(2.0*N)] # initial guess around 4 and ≥ 1. |
622 |
|
- |
else |
623 |
|
- |
Δv = v .- w |
624 |
|
- |
initial = vcat(Δv .+ 1e-5, w) |
625 |
|
- |
end |
626 |
|
- |
|
627 |
|
- |
# Limits of the optimisation. |
628 |
|
- |
lower = fill(0.0, 2 * N) |
629 |
|
- |
upper = fill(100.0, 2 * N) |
630 |
|
- |
|
631 |
|
- |
# The multiple phonon mode free energy function to minimise. |
632 |
|
- |
f(x) = multi_F([x[2 * n - 1] for n in 1:N] .+ [x[2 * n] for n in 1:N], [x[2 * n] for n in 1:N], α; ω = ω) |
633 |
|
- |
|
634 |
|
- |
# Use Optim to optimise the free energy function w.r.t the set of v and w parameters. |
635 |
|
- |
solution = Optim.optimize( |
636 |
|
- |
Optim.OnceDifferentiable(f, initial; autodiff=:forward), |
637 |
|
- |
lower, |
638 |
|
- |
upper, |
639 |
|
- |
initial, |
640 |
|
- |
Fminbox(BFGS()), |
641 |
|
- |
Optim.Options(show_trace = show_trace), # Set time limit for asymptotic convergence if needed. |
642 |
|
- |
) |
643 |
|
- |
|
644 |
|
- |
# Extract the v and w parameters that minimised the free energy. |
645 |
|
- |
var_params = Optim.minimizer(solution) |
646 |
|
- |
energy = Optim.minimum(solution) |
647 |
|
- |
|
648 |
|
- |
# Separate the v and w parameters into one-dimensional arrays (vectors). |
649 |
|
- |
Δv = [var_params[2*n-1] for n in 1:N] |
650 |
|
- |
w = [var_params[2*n] for n in 1:N] |
651 |
|
- |
|
652 |
|
- |
if Optim.converged(solution) == false |
653 |
|
- |
@warn "Failed to converge T = 0 K variational solution. v = $(Δv .+ w), w = $w." |
654 |
|
- |
end |
655 |
|
- |
|
656 |
|
- |
# Return the variational parameters that minimised the free energy. |
657 |
|
- |
return (Δv .+ w, w, energy) |
658 |
|
- |
end |
659 |
597 |
|
|