diff --git a/src/PowerFlowData.jl b/src/PowerFlowData.jl index 2fdfae9c..c22ca912 100644 --- a/src/PowerFlowData.jl +++ b/src/PowerFlowData.jl @@ -157,7 +157,7 @@ NOTE: use it for AC power flow computations. WARNING: functions for the evaluation of the multi-period AC PF still to be implemented. """ function PowerFlowData( - ::ACPowerFlow{<: ACPowerFlowSolverType}, + ::ACPowerFlow{<:ACPowerFlowSolverType}, sys::PSY.System; time_steps::Int = 1, timestep_names::Vector{String} = String[], @@ -440,7 +440,11 @@ Create an appropriate `PowerFlowContainer` for the given `PowerFlowEvaluationMod """ function make_power_flow_container end -make_power_flow_container(pfem::ACPowerFlow{<: ACPowerFlowSolverType}, sys::PSY.System; kwargs...) = +make_power_flow_container( + pfem::ACPowerFlow{<:ACPowerFlowSolverType}, + sys::PSY.System; + kwargs..., +) = PowerFlowData(pfem, sys; kwargs...) make_power_flow_container(pfem::DCPowerFlow, sys::PSY.System; kwargs...) = diff --git a/src/newton_ac_powerflow.jl b/src/newton_ac_powerflow.jl index a909edb5..e44d9aa6 100644 --- a/src/newton_ac_powerflow.jl +++ b/src/newton_ac_powerflow.jl @@ -31,7 +31,7 @@ solve_ac_powerflow!(sys, method=:newton) ``` """ function solve_ac_powerflow!( - pf::ACPowerFlow{<: ACPowerFlowSolverType}, + pf::ACPowerFlow{<:ACPowerFlowSolverType}, system::PSY.System; kwargs..., ) @@ -72,7 +72,7 @@ res = solve_powerflow(sys, method=:newton) ``` """ function solve_powerflow( - pf::ACPowerFlow{<: ACPowerFlowSolverType}, + pf::ACPowerFlow{<:ACPowerFlowSolverType}, system::PSY.System; kwargs..., ) @@ -128,7 +128,7 @@ function _check_q_limit_bounds!(data::ACPowerFlowData, zero::Vector{Float64}) end function _solve_powerflow!( - pf::ACPowerFlow{<: ACPowerFlowSolverType}, + pf::ACPowerFlow{<:ACPowerFlowSolverType}, data::ACPowerFlowData, check_reactive_power_limits; nlsolve_kwargs..., @@ -160,12 +160,18 @@ function _newton_powerflow( df = NLsolve.OnceDifferentiable(pf, J, pf.x0, pf.residual, J.Jv) res = NLsolve.nlsolve(df, pf.x0; nlsolve_kwargs...) if !res.f_converged - @error("The powerflow solver NLSolve did not converge (returned convergence = $(res.f_converged))") + @error( + "The powerflow solver NLSolve did not converge (returned convergence = $(res.f_converged))" + ) end return res.f_converged, res.zero end -function _newton_powerflow(pf::ACPowerFlow{KLUACPowerFlow}, data::ACPowerFlowData; nlsolve_kwargs...) +function _newton_powerflow( + pf::ACPowerFlow{KLUACPowerFlow}, + data::ACPowerFlowData; + nlsolve_kwargs..., +) # Fetch maxIter and tol from kwargs, or use defaults if not provided maxIter = get(nlsolve_kwargs, :maxIter, DEFAULT_NR_MAX_ITER) tol = get(nlsolve_kwargs, :tol, DEFAULT_NR_TOL) @@ -180,7 +186,7 @@ function _newton_powerflow(pf::ACPowerFlow{KLUACPowerFlow}, data::ACPowerFlowDat Vm = data.bus_magnitude[:] # prevent unfeasible starting values for Vm; for pv and ref buses we cannot do this: - Vm[pq] = clamp.(Vm[pq], 0.9, 1.1) + Vm[pq] = clamp.(Vm[pq], 0.9, 1.1) Va = data.bus_angles[:] V = Vm .* exp.(1im * Va) diff --git a/src/post_processing.jl b/src/post_processing.jl index 8ae1d687..c8229201 100644 --- a/src/post_processing.jl +++ b/src/post_processing.jl @@ -608,7 +608,7 @@ dictionary will therefore feature just one key linked to one DataFrame. vector containing the reults for one single time-period. """ function write_results( - ::ACPowerFlow{<: ACPowerFlowSolverType}, + ::ACPowerFlow{<:ACPowerFlowSolverType}, sys::PSY.System, data::ACPowerFlowData, result::Vector{Float64}, diff --git a/src/powerflow_types.jl b/src/powerflow_types.jl index cc0c5c20..fa9a1ae0 100644 --- a/src/powerflow_types.jl +++ b/src/powerflow_types.jl @@ -1,16 +1,19 @@ abstract type PowerFlowEvaluationModel end abstract type ACPowerFlowSolverType end - struct KLUACPowerFlow <: ACPowerFlowSolverType end struct NLSolveACPowerFlow <: ACPowerFlowSolverType end -Base.@kwdef struct ACPowerFlow{ACSolver <: ACPowerFlowSolverType} <: PowerFlowEvaluationModel +Base.@kwdef struct ACPowerFlow{ACSolver <: ACPowerFlowSolverType} <: + PowerFlowEvaluationModel check_reactive_power_limits::Bool = false end # Create a constructor that defaults to KLUACPowerFlow -function ACPowerFlow(; check_reactive_power_limits::Bool = false, ACSolver::Type{<:ACPowerFlowSolverType} = KLUACPowerFlow) +function ACPowerFlow(; + check_reactive_power_limits::Bool = false, + ACSolver::Type{<:ACPowerFlowSolverType} = KLUACPowerFlow, +) return ACPowerFlow{ACSolver}(check_reactive_power_limits) end diff --git a/test/test_powerflow_data.jl b/test/test_powerflow_data.jl index 1f4152ad..2d45a148 100644 --- a/test/test_powerflow_data.jl +++ b/test/test_powerflow_data.jl @@ -18,7 +18,8 @@ end PF.vPTDFPowerFlowData end -@testset "System <-> PowerFlowData round trip" for ACSolver in (NLSolveACPowerFlow, KLUACPowerFlow) +@testset "System <-> PowerFlowData round trip" for ACSolver in + (NLSolveACPowerFlow, KLUACPowerFlow) # TODO currently only tested with ACPowerFlow # TODO test that update_system! errors if the PowerFlowData doesn't correspond to the system @@ -57,6 +58,9 @@ end sys_modify_updated = deepcopy(sys_original) PF.update_system!(sys_modify_updated, data_modified) sys_mod_redist = deepcopy(sys_modified) - PF.update_system!(sys_mod_redist, PowerFlowData(ACPowerFlow{ACSolver}(), sys_mod_redist)) + PF.update_system!( + sys_mod_redist, + PowerFlowData(ACPowerFlow{ACSolver}(), sys_mod_redist), + ) @test IS.compare_values(powerflow_match_fn, sys_modify_updated, sys_mod_redist) end diff --git a/test/test_psse_export.jl b/test/test_psse_export.jl index 58fe743c..802eee3f 100644 --- a/test/test_psse_export.jl +++ b/test/test_psse_export.jl @@ -222,7 +222,12 @@ function compare_systems_loosely(sys1::PSY.System, sys2::PSY.System; return result end -function test_power_flow(pf::ACPowerFlow{<:ACPowerFlowSolverType}, sys1::System, sys2::System; exclude_reactive_flow = false) +function test_power_flow( + pf::ACPowerFlow{<:ACPowerFlowSolverType}, + sys1::System, + sys2::System; + exclude_reactive_flow = false, +) result1 = solve_powerflow(pf, sys1) result2 = solve_powerflow(pf, sys2) reactive_power_tol = @@ -319,7 +324,10 @@ end @test compare_systems_loosely(sys, deepcopy(sys)) end -@testset "PSSE Exporter with system_240[32].json, v33" for (ACSolver, folder_name) in ((NLSolveACPowerFlow, "system_240_NLSolve"), (KLUACPowerFlow, "system_240_KLU")) +@testset "PSSE Exporter with system_240[32].json, v33" for (ACSolver, folder_name) in ( + (NLSolveACPowerFlow, "system_240_NLSolve"), + (KLUACPowerFlow, "system_240_KLU"), +) sys = load_test_system() pf = ACPowerFlow{ACSolver}() isnothing(sys) && return @@ -365,7 +373,10 @@ end test_power_flow(pf, sys2, reread_sys2; exclude_reactive_flow = true) # TODO why is reactive flow not matching? end -@testset "PSSE Exporter with RTS_GMLC_DA_sys, v33" for (ACSolver, folder_name) in ((NLSolveACPowerFlow, "rts_gmlc_NLSolve"), (KLUACPowerFlow, "rts_gmlc_KLU")) +@testset "PSSE Exporter with RTS_GMLC_DA_sys, v33" for (ACSolver, folder_name) in ( + (NLSolveACPowerFlow, "rts_gmlc_NLSolve"), + (KLUACPowerFlow, "rts_gmlc_KLU"), +) sys = create_pf_friendly_rts_gmlc() pf = ACPowerFlow{ACSolver}() set_units_base_system!(sys, UnitSystem.SYSTEM_BASE)