Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Hessian of lineflow #111

Merged
merged 1 commit into from
Feb 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion src/Polar/Constraints/line_flow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function flow_constraints_grad!(polar::PolarForm, cons_grad, buffer, weights)
fill!(cons_grad, 0)
adj_vmag = @view cons_grad[1:nbus]
adj_vang = @view cons_grad[nbus+1:2*nbus]
ev = adj_branch_flow_kernel!(polar.device)(weights, buffer.vmag, adj_vmag,
ev = adj_branch_flow_kernel!(polar.device)(weights, buffer.vmag, adj_vmag,
buffer.vang, adj_vang,
PT.yff_re, PT.yft_re, PT.ytf_re, PT.ytt_re,
PT.yff_im, PT.yft_im, PT.ytf_im, PT.ytt_im,
Expand All @@ -49,6 +49,31 @@ function bounds(polar::PolarForm{T, IT, VT, MT}, ::typeof(flow_constraints)) whe
return convert(VT, [f_min; f_min]), convert(VT, [f_max; f_max])
end

function adjoint!(
polar::PolarForm,
::typeof(flow_constraints),
cons, ∂cons,
vm, ∂vm,
va, ∂va,
pinj, ∂pinj,
qinj, ∂qinj,
)
nlines = PS.get(polar.network, PS.NumberOfLines())
nbus = PS.get(polar.network, PS.NumberOfBuses())
top = polar.topology

ev = adj_branch_flow_kernel!(polar.device)(
∂cons,
vm, ∂vm,
va, ∂va,
top.yff_re, top.yft_re, top.ytf_re, top.ytt_re,
top.yff_im, top.yft_im, top.ytf_im, top.ytt_im,
top.f_buses, top.t_buses, nlines,
ndrange = nlines
)
wait(ev)
end

# Jacobian-transpose vector product
function jtprod(
polar::PolarForm,
Expand Down
23 changes: 14 additions & 9 deletions src/Polar/kernels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,14 @@ function residual_polar!(F, vm, va, pinj, qinj,
wait(ev)
end

KA.@kernel function adj_residual_edge_kernel!(F, adj_F, vm, adj_vm, va, adj_va,
colptr, rowval,
ybus_re_nzval, ybus_im_nzval,
edge_vm_from, edge_vm_to,
edge_va_from, edge_va_to,
pinj, adj_pinj, qinj, pv, pq)
KA.@kernel function adj_residual_edge_kernel!(
F, adj_F, vm, adj_vm, va, adj_va,
colptr, rowval,
ybus_re_nzval, ybus_im_nzval,
edge_vm_from, edge_vm_to,
edge_va_from, edge_va_to,
pinj, adj_pinj, qinj, pv, pq
)

npv = size(pv, 1)
npq = size(pq, 1)
Expand Down Expand Up @@ -202,9 +204,11 @@ KA.@kernel function adj_residual_node_kernel!(F, adj_F, vm, adj_vm, va, adj_va,
end
end

function adj_residual_polar!(F, adj_F, vm, adj_vm, va, adj_va,
ybus_re, ybus_im,
pinj, adj_pinj, qinj, pv, pq, nbus)
function adj_residual_polar!(
F, adj_F, vm, adj_vm, va, adj_va,
ybus_re, ybus_im,
pinj, adj_pinj, qinj, pv, pq, nbus
)
npv = length(pv)
npq = length(pq)
nvbus = length(vm)
Expand Down Expand Up @@ -813,3 +817,4 @@ KA.@kernel function adj_branch_flow_kernel!(
adj_vang[fr_bus] += adj_Δθ
adj_vang[to_bus] -= adj_Δθ
end

1 change: 1 addition & 0 deletions test/Polar/autodiff.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
for cons in [
ExaPF.power_balance,
ExaPF.reactive_power_constraints,
ExaPF.flow_constraints,
]
m = ExaPF.size_constraint(polar, cons)
λ = rand(m)
Expand Down
25 changes: 25 additions & 0 deletions test/Polar/hessian.jl
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,31 @@ const PS = PowerSystem
∂₂Q.xu ∂₂Q.uu
]
@test isapprox(projp, H * tgt)


# Line-flow
hess_lineflow = AutoDiff.Hessian(polar, ExaPF.flow_constraints)
ncons = ExaPF.size_constraint(polar, ExaPF.flow_constraints)
μ = rand(ncons)
function flow_jac_x(z)
x_ = z[1:nx]
u_ = z[1+nx:end]
# Transfer control
ExaPF.transfer!(polar, cache, u_)
# Transfer state (manually)
cache.vang[pv] .= x_[1:npv]
cache.vang[pq] .= x_[npv+1:npv+npq]
cache.vmag[pq] .= x_[npv+npq+1:end]
V = cache.vmag .* exp.(im .* cache.vang)
Jx = ExaPF.matpower_jacobian(polar, State(), ExaPF.flow_constraints, V)
Ju = ExaPF.matpower_jacobian(polar, Control(), ExaPF.flow_constraints, V)
return [Jx Ju]' * μ
end

H_fd = FiniteDiff.finite_difference_jacobian(flow_jac_x, [x; u])
tgt = rand(nx + nu)
projp = AutoDiff.adj_hessian_prod!(polar, hess_lineflow, cache, μ, tgt)
@test isapprox(projp, H_fd * tgt, rtol=1e-5)
end
end