2022-11-17 02:50:48 +01:00
|
|
|
using Dates
|
|
|
|
using Serialization
|
|
|
|
using Logging
|
|
|
|
|
|
|
|
import JuMP
|
|
|
|
|
|
|
|
function get_solution(model)
|
|
|
|
λ = JuMP.value(model[:λ])
|
|
|
|
Q = real.(sqrt(JuMP.value.(model[:P])))
|
|
|
|
solution = Dict(:λ => λ, :Q => Q)
|
|
|
|
return solution
|
|
|
|
end
|
|
|
|
|
2023-04-11 10:32:24 +02:00
|
|
|
function get_solution(model, wd, varP, eps = 1e-10)
|
2022-11-17 02:50:48 +01:00
|
|
|
λ = JuMP.value(model[:λ])
|
|
|
|
|
2023-04-11 10:32:24 +02:00
|
|
|
@info "reconstructing the solution"
|
|
|
|
Q = @time let wd = wd, Ps = [JuMP.value.(P) for P in varP], eps = eps
|
|
|
|
PropertyT.__droptol!.(Ps, 100eps)
|
|
|
|
Qs = real.(sqrt.(Ps))
|
|
|
|
PropertyT.__droptol!.(Qs, eps)
|
|
|
|
PropertyT.reconstruct(Qs, wd)
|
|
|
|
end
|
|
|
|
|
2022-11-17 02:50:48 +01:00
|
|
|
solution = Dict(:λ => λ, :Q => Q)
|
2023-03-20 01:40:40 +01:00
|
|
|
|
2022-11-17 02:50:48 +01:00
|
|
|
return solution
|
|
|
|
end
|
|
|
|
|
|
|
|
function solve_in_loop(model::JuMP.Model, args...; logdir, optimizer, data)
|
|
|
|
@info "logging to $logdir"
|
|
|
|
status = JuMP.UNKNOWN_RESULT_STATUS
|
|
|
|
warm = try
|
|
|
|
solution = deserialize(joinpath(logdir, "solution.sjl"))
|
|
|
|
warm = solution[:warm]
|
|
|
|
@info "trying to warm-start model with λ=$(solution[:λ])..."
|
|
|
|
warm
|
|
|
|
catch
|
|
|
|
nothing
|
|
|
|
end
|
|
|
|
old_lambda = 0.0
|
|
|
|
while status != JuMP.OPTIMAL
|
|
|
|
date = now()
|
|
|
|
log_file = joinpath(logdir, "solver_$date.log")
|
|
|
|
@info "Current logfile is $log_file."
|
|
|
|
isdir(dirname(log_file)) || mkpath(dirname(log_file))
|
|
|
|
|
|
|
|
λ, flag, certified_λ = let
|
|
|
|
# logstream = current_logger().logger.stream
|
|
|
|
# v = @ccall setvbuf(logstream.handle::Ptr{Cvoid}, C_NULL::Ptr{Cvoid}, 1::Cint, 0::Cint)::Cint
|
|
|
|
# @warn v
|
2023-03-20 01:40:40 +01:00
|
|
|
status, warm =
|
|
|
|
@time PropertyT.solve(log_file, model, optimizer, warm)
|
2022-11-17 02:50:48 +01:00
|
|
|
|
2023-03-20 01:40:40 +01:00
|
|
|
solution = get_solution(model, args...)
|
2022-11-17 02:50:48 +01:00
|
|
|
serialize(joinpath(logdir, "solution_$date.sjl"), solution)
|
|
|
|
serialize(joinpath(logdir, "solution.sjl"), solution)
|
|
|
|
|
2023-03-20 01:40:40 +01:00
|
|
|
solution[:warm] = warm
|
|
|
|
|
|
|
|
flag, λ_cert = open(log_file; append = true) do io
|
2022-11-17 02:50:48 +01:00
|
|
|
with_logger(SimpleLogger(io)) do
|
2023-03-20 01:40:40 +01:00
|
|
|
return PropertyT.certify_solution(
|
2022-11-17 02:50:48 +01:00
|
|
|
data.elt,
|
|
|
|
data.unit,
|
|
|
|
solution[:λ],
|
2023-03-20 01:40:40 +01:00
|
|
|
solution[:Q];
|
|
|
|
halfradius = data.halfradius,
|
2022-11-17 02:50:48 +01:00
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
solution[:λ], flag, λ_cert
|
|
|
|
end
|
|
|
|
|
|
|
|
if flag == true && certified_λ ≥ 0
|
2023-03-20 02:29:19 +01:00
|
|
|
@info "Certification done with λ = $certified_λ" certified_λ rel_change status
|
2022-11-17 02:50:48 +01:00
|
|
|
return certified_λ
|
|
|
|
else
|
2023-03-20 01:40:40 +01:00
|
|
|
rel_change =
|
|
|
|
abs(certified_λ - old_lambda) /
|
|
|
|
(abs(certified_λ) + abs(old_lambda))
|
2023-03-20 02:29:19 +01:00
|
|
|
@info "Certification failed with λ = $λ" certified_λ rel_change status
|
2023-04-13 01:00:22 +02:00
|
|
|
if rel_change < 1e-9
|
|
|
|
@info "No progress detected, breaking" certified_λ rel_change status
|
|
|
|
break
|
|
|
|
end
|
2022-11-17 02:50:48 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
old_lambda = certified_λ
|
|
|
|
end
|
|
|
|
|
|
|
|
return status == JuMP.OPTIMAL ? old_lambda : NaN
|
|
|
|
end
|