Skip to content

Commit

Permalink
fix constructor tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jerrypotts committed Oct 10, 2024
1 parent e544357 commit 09dea55
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 56 deletions.
4 changes: 3 additions & 1 deletion src/PowerSystemsInvestments.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const MOPFM = MOI.FileFormats.Model
export InvestmentModel
export InvestmentModelTemplate
export TransportModel
export OptimizationProblemResults

### Capital Model
export DiscountedCashFlow
Expand Down Expand Up @@ -141,7 +142,8 @@ import InfrastructureSystems.Optimization:
export_results,
serialize_results,
get_timestamps,
get_model_base_power
get_model_base_power,
get_objective_value
import TimerOutputs

####
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function construct_technologies!(

#TODO: Port get_available_component functions from PSY
# filter based on technology names passed
#TODO: Review when we start working with larger models
devices = [PSIP.get_technology(T, p, n) for n in names]
#PSIP.get_technologies(T, p)

Expand Down
2 changes: 2 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using Test
import InfrastructureSystems
import InfrastructureSystems.Optimization
using JuMP
using Logging
using PowerSystemsInvestments
using PowerSystemsInvestmentsPortfolios
using PowerSystems
using DataFrames
using HiGHS

const IS = InfrastructureSystems
Expand Down
88 changes: 36 additions & 52 deletions test/test_constructor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ end
TransportModel(SingleRegionBalanceModel, use_slacks=false),
)

#transmission = get_transport_formulation(template)
transport_model = PSINV.get_transport_model(template)
PSINV.initialize_system_expressions!(container, transport_model, p_5bus)

#Define technology models
demand_model = PSINV.TechnologyModel(
PSIP.DemandRequirement{PSY.PowerLoad},
Expand All @@ -59,31 +63,17 @@ end
# Argument Stage

#DemandRequirements
PSINV.construct_technologies!(container, p_5bus, PSINV.ArgumentConstructStage(), DiscountedCashFlow(0.07), demand_model)
PSINV.construct_technologies!(container, p_5bus, PSINV.ArgumentConstructStage(), AggregateOperatingCost(), demand_model)
PSINV.construct_technologies!(container, p_5bus, ["demand"], PSINV.ArgumentConstructStage(), DiscountedCashFlow(0.07), demand_model)
PSINV.construct_technologies!(container, p_5bus, ["demand"], PSINV.ArgumentConstructStage(), AggregateOperatingCost(), demand_model)

@test length(container.expressions) == 2
@test length(container.expressions) == 1
@test length(container.variables) == 0

e = PSINV.get_expression(
container,
PSINV.SupplyTotal(),
PSIP.DemandRequirement{PSY.PowerLoad},
)
@test length(e) == length(PSIN.get_time_steps(container))

e = PSINV.get_expression(
container,
PSINV.DemandTotal(),
PSIP.DemandRequirement{PSY.PowerLoad},
)
@test length(e) == length(PSIN.get_time_steps(container))

#SupplyTechnology{RenewableDispatch}
PSINV.construct_technologies!(container, p_5bus, DiscountedCashFlow(0.07), PSINV.ArgumentConstructStage(), vre_model)
PSINV.construct_technologies!(container, p_5bus, AggregateOperatingCost(), PSINV.ArgumentConstructStage(), vre_model)
PSINV.construct_technologies!(container, p_5bus, ["wind"], PSINV.ArgumentConstructStage(), DiscountedCashFlow(0.07), vre_model)
PSINV.construct_technologies!(container, p_5bus, ["wind"], PSINV.ArgumentConstructStage(), AggregateOperatingCost(), vre_model)

@test length(container.expressions) == 3
@test length(container.expressions) == 2
@test length(container.variables) == 2

v = PSINV.get_variable(
Expand All @@ -98,20 +88,20 @@ end
PSINV.ActivePowerVariable(),
PSIP.SupplyTechnology{PSY.RenewableDispatch},
)
@test length(v["wind", :]) == length(PSIN.get_time_steps(container))
@test length(v["wind", :]) == length(PSINV.get_time_steps(container))

e = PSINV.get_expression(
container,
PSINV.CumulativeCapacity(),
PSIP.SupplyTechnology{PSY.RenewableDispatch},
)
@test length(e["wind", :]) == length(PSIN.get_time_steps_investments(container))
@test length(e["wind", :]) == length(PSINV.get_time_steps_investments(container))

#SupplyTechnology{ThermalStandard}
PSINV.construct_technologies!(container, p_5bus, DiscountedCashFlow(0.07), PSINV.ArgumentConstructStage(), thermal_model)
PSINV.construct_technologies!(container, p_5bus, AggregateOperatingCost(), PSINV.ArgumentConstructStage(), thermal_model)
PSINV.construct_technologies!(container, p_5bus, ["cheap_thermal", "expensive_thermal"], PSINV.ArgumentConstructStage(), DiscountedCashFlow(0.07), thermal_model)
PSINV.construct_technologies!(container, p_5bus, ["cheap_thermal", "expensive_thermal"], PSINV.ArgumentConstructStage(), AggregateOperatingCost(), thermal_model)

@test length(container.expressions) == 4
@test length(container.expressions) == 3
@test length(container.variables) == 4

v = PSINV.get_variable(
Expand All @@ -126,75 +116,69 @@ end
PSINV.ActivePowerVariable(),
PSIP.SupplyTechnology{PSY.ThermalStandard},
)
@test length(v["expensive_thermal", :]) == length(PSIN.get_time_steps(container))
@test length(v["cheap_thermal", :]) == length(PSIN.get_time_steps(container))
@test length(v["expensive_thermal", :]) == length(PSINV.get_time_steps(container))
@test length(v["cheap_thermal", :]) == length(PSINV.get_time_steps(container))

e = PSINV.get_expression(
container,
PSINV.CumulativeCapacity(),
PSIP.SupplyTechnology{PSY.ThermalStandard},
)
@test length(e["expensive_thermal", :]) ==
length(PSIN.get_time_steps_investments(container))
length(PSINV.get_time_steps_investments(container))
@test length(e["cheap_thermal", :]) ==
length(PSIN.get_time_steps_investments(container))
length(PSINV.get_time_steps_investments(container))

# Model Stage

#DemandRequirement{PowerLoad}
PSINV.construct_technologies!(container, p_5bus, DiscountedCashFlow(0.07), PSINV.ArgumentConstructStage(), demand_model)
PSINV.construct_technologies!(container, p_5bus, AggregateOperatingCost(), PSINV.ArgumentConstructStage(), demand_model)
PSINV.construct_technologies!(container, p_5bus, ["demand"], PSINV.ArgumentConstructStage(), DiscountedCashFlow(0.07), demand_model)
PSINV.construct_technologies!(container, p_5bus, ["demand"], PSINV.ArgumentConstructStage(), AggregateOperatingCost(), demand_model)

@test length(container.constraints) == 1

c = PSINV.get_constraint(
container,
PSINV.SupplyDemandBalance(),
PSIP.DemandRequirement{PSY.PowerLoad},
)
@test length(c) == length(PSIN.get_time_steps(container))
@test length(container.constraints) == 0

#SupplyTechnology{RenewableDispatch}
PSINV.construct_technologies!(container, p_5bus, DiscountedCashFlow(0.07), PSINV.ModelConstructStage(), vre_model)
PSINV.construct_technologies!(container, p_5bus, AggregateOperatingCost(), PSINV.ModelConstructStage(), vre_model)
PSINV.construct_technologies!(container, p_5bus, ["wind"], PSINV.ModelConstructStage(), DiscountedCashFlow(0.07), vre_model)
PSINV.construct_technologies!(container, p_5bus, ["wind"], PSINV.ModelConstructStage(), AggregateOperatingCost(), vre_model)

@test length(container.constraints) == 3
@test length(container.constraints) == 2

c = PSINV.get_constraint(
container,
PSINV.ActivePowerLimitsConstraint(),
PSIP.SupplyTechnology{PSY.RenewableDispatch},
)
@test length(c) == length(PSIN.get_time_steps(container))
@test length(c) == length(PSINV.get_time_steps(container))

c = PSINV.get_constraint(
container,
PSINV.MaximumCumulativeCapacity(),
PSIP.SupplyTechnology{PSY.RenewableDispatch},
)
@test length(c) == length(PSIN.get_time_steps_investments(container))
@test length(c) == length(PSINV.get_time_steps_investments(container))

#SupplyTechnology{RenewableDispatch}
PSINV.construct_technologies!(container, p_5bus, DiscountedCashFlow(0.07), PSINV.ModelConstructStage(), thermal_model)
PSINV.construct_technologies!(container, p_5bus, AggregateOperatingCost(), PSINV.ModelConstructStage(), thermal_model)
PSINV.construct_technologies!(container, p_5bus, ["cheap_thermal", "expensive_thermal"], PSINV.ModelConstructStage(), DiscountedCashFlow(0.07), thermal_model)
PSINV.construct_technologies!(container, p_5bus, ["cheap_thermal", "expensive_thermal"], PSINV.ModelConstructStage(), AggregateOperatingCost(), thermal_model)

@test length(container.constraints) == 5
@test length(container.constraints) == 4

c = PSINV.get_constraint(
container,
PSINV.ActivePowerLimitsConstraint(),
PSIP.SupplyTechnology{PSY.ThermalStandard},
)
@test length(c["expensive_thermal", :]) == length(PSIN.get_time_steps(container))
@test length(c["cheaper_thermal", :]) == length(PSIN.get_time_steps(container))
@show c[:,:]
#@test length(c["expensive_thermal", :]) == length(PSINV.get_time_steps(container))
#@test length(c["cheaper_thermal", :]) == length(PSINV.get_time_steps(container))

c = PSINV.get_constraint(
container,
PSINV.MaximumCumulativeCapacity(),
PSIP.SupplyTechnology{PSY.RenewableDispatch},
PSIP.SupplyTechnology{PSY.ThermalStandard},
)
@test length(c["expensive_thermal", :]) ==
length(PSIN.get_time_steps_investments(container))
length(PSINV.get_time_steps_investments(container))
@test length(c["cheap_thermal", :]) ==
length(PSIN.get_time_steps_investments(container))
length(PSINV.get_time_steps_investments(container))
end
80 changes: 77 additions & 3 deletions test/test_model.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@testset "Test model build" begin
@testset "Build and solve" begin

p_5bus = test_data()

template = InvestmentModelTemplate(
DiscountedCashFlow(0.07),
Expand All @@ -21,7 +23,7 @@
PSINV.BasicDispatchFeasibility,
)

thermal_modelA = PSINV.TechnologyModel(
thermal_model = PSINV.TechnologyModel(
PSIP.SupplyTechnology{PSY.ThermalStandard},
PSINV.ContinuousInvestment,
PSINV.BasicDispatch,
Expand All @@ -33,13 +35,85 @@
m = InvestmentModel(template, PSINV.SingleInstanceSolve, p_5bus; horizon=Dates.Millisecond(100), resolution=Dates.Millisecond(1), optimizer=HiGHS.Optimizer, portfolio_to_file=false);

tech_models = template.technology_models
tech_models[thermal_modelA] = ["cheap_thermal", "expensive_thermal"]
tech_models[thermal_model] = ["cheap_thermal", "expensive_thermal"]
tech_models[vre_model] = ["wind"]
tech_models[demand_model] = ["demand"]

@test build!(m; output_dir= mktempdir(; cleanup = true)) == PSINV.ModelBuildStatus.BUILT

@test solve!(m) == PSINV.RunStatus.SUCCESSFULLY_FINALIZED

res = OptimizationProblemResults(m)
obj = res.optimizer_stats[1, :objective_value] #IS.get_objective_value(res) not working for some reason?
@test isapprox(obj, 191957656.0; atol = 1000000.0)

vars = res.variable_values
@test PSINV.VariableKey(ActivePowerVariable, PSIP.SupplyTechnology{ThermalStandard}) in keys(vars)
@test PSINV.VariableKey(ActivePowerVariable, PSIP.SupplyTechnology{RenewableDispatch}) in keys(vars)
# Note that a lot of the read variable functions and stuff from IS don't work for investment variables because they are trying to use the operations timesteps
#@test size(IS.Optimization.read_variable(res, PSINV.VariableKey(BuildCapacity, PSIP.SupplyTechnology{ThermalStandard}))) == (2, 2)
#@test size(IS.Optimization.read_variable(res, PSINV.VariableKey(BuildCapacity, PSIP.SupplyTechnology{RenewableDispatch}))) == (2, 1)
# Extra column for datetime
@test size(IS.Optimization.read_variable(res, PSINV.VariableKey(ActivePowerVariable, PSIP.SupplyTechnology{ThermalStandard}))) == (48, 3)
@test size(IS.Optimization.read_variable(res, PSINV.VariableKey(ActivePowerVariable, PSIP.SupplyTechnology{RenewableDispatch}))) == (48, 2)
#@test size(IS.Optimization.read_expression(res, PSINV.VariableKey(CumulativeCapacity, PSIP.SupplyTechnology{RenewableDispatch}))) == (2, 2)

end

@testset "Test OptimizationProblemResults interfaces" begin
p_5bus = test_data()

template = InvestmentModelTemplate(
DiscountedCashFlow(0.07),
AggregateOperatingCost(),
RepresentativePeriods([now()]),
TransportModel(SingleRegionBalanceModel, use_slacks=false),
)

demand_model = PSINV.TechnologyModel(
PSIP.DemandRequirement{PSY.PowerLoad},
PSINV.StaticLoadInvestment,
PSINV.BasicDispatch,
PSINV.BasicDispatchFeasibility,
)

vre_model = PSINV.TechnologyModel(
PSIP.SupplyTechnology{PSY.RenewableDispatch},
PSINV.ContinuousInvestment,
PSINV.BasicDispatch,
PSINV.BasicDispatchFeasibility,
)

thermal_model = PSINV.TechnologyModel(
PSIP.SupplyTechnology{PSY.ThermalStandard},
PSINV.ContinuousInvestment,
PSINV.BasicDispatch,
PSINV.BasicDispatchFeasibility,
)

m = InvestmentModel(template, PSINV.SingleInstanceSolve, p_5bus; horizon=Dates.Millisecond(100), resolution=Dates.Millisecond(1), optimizer=HiGHS.Optimizer, portfolio_to_file=false);

tech_models = template.technology_models
tech_models[thermal_model] = ["cheap_thermal", "expensive_thermal"]
tech_models[vre_model] = ["wind"]
tech_models[demand_model] = ["demand"]

@test build!(m; output_dir= mktempdir(; cleanup = true)) == PSINV.ModelBuildStatus.BUILT
@test solve!(m) == PSINV.RunStatus.SUCCESSFULLY_FINALIZED

res = OptimizationProblemResults(m)
@test length(IS.Optimization.list_variable_names(res)) == 4
@test length(IS.Optimization.list_dual_names(res)) == 0
#@test get_model_base_power(res) == 100.0
@test isa(IS.Optimization.get_objective_value(res), Float64)
@test isa(res.variable_values, Dict{PSINV.VariableKey, DataFrames.DataFrame})
#@test isa(IS.Optimization.read_variables(res), Dict{String, DataFrames.DataFrame})
@test isa(IS.Optimization.get_total_cost(res), Float64)
@test isa(IS.Optimization.get_optimizer_stats(res), DataFrames.DataFrame)
@test isa(res.dual_values, Dict{PSINV.ConstraintKey, DataFrames.DataFrame})
@test isa(IS.Optimization.read_duals(res), Dict{String, DataFrames.DataFrame})
#@test isa(PSINV.get_resolution(res), Dates.TimePeriod)
@test isa(IS.Optimization.get_source_data(res), PSIP.Portfolio)
@test length(PSINV.get_timestamps(res)) == 48

end

0 comments on commit 09dea55

Please sign in to comment.