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

Rh/psy methods New script for simple CEM #10

Closed
Closed
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
88 changes: 74 additions & 14 deletions scripts/portfolio_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
const PSY = PowerSystems
const PSIP = PowerSystemsInvestmentsPortfolios

data = PSY._create_system_data_from_kwargs()
#data = PSY._create_system_data_from_kwargs()

#bus = ACBus(nothing)
#discount_rate = 0.07
Expand All @@ -29,17 +29,23 @@
)

t_th_ext = t_th.ext
t_th_ext["capital_cost"] = 50.0
t_th_ext["capital_cost"] = [50.0, 125.0]
t_th_ext["operations_cost"] = [5.0, 2.5]
t_th_ext["variable_cost"] = [1.0, 1.0]
t_th_ext["investment_periods"] = [2030, 2040]
# one option is to repeat these for each investment
t_th_ext["operational_periods"] = [1, 2, 3]
t_th_ext["operational_periods_2"] = [
1, 2, 3, # first investment period

Check warning on line 39 in scripts/portfolio_test.jl

View workflow job for this annotation

GitHub Actions / build (1, x86, ubuntu-latest)

[JuliaFormatter] reported by reviewdog 🐶 Raw Output: scripts/portfolio_test.jl:39:- 1, 2, 3, # first investment period scripts/portfolio_test.jl:40:- 4, 5, 6 # second investment period scripts/portfolio_test.jl:39:+ 1, scripts/portfolio_test.jl:40:+ 2, scripts/portfolio_test.jl:41:+ 3, # first investment period scripts/portfolio_test.jl:42:+ 4, scripts/portfolio_test.jl:43:+ 5, scripts/portfolio_test.jl:44:+ 6, # second investment period
4, 5, 6 # second investment period
]
t_th_ext["investment_operational_periods_map"] = Dict(
2030 => [1, 2, 3],
2040 => [4, 5, 6],
1 => 2030,
2 => 2030,
3 => 2030,
4 => 2040,
5 => 2040,
6 => 2040,
)
t_th_ext["initial_capacity"] = 200.0 # Data in MW
t_th_ext["maximum_capacity"] = 10000.0
Expand All @@ -56,9 +62,30 @@
)

t_th_exp_ext = t_th_exp.ext
t_th_exp_ext["capital_cost"] = 150.0
t_th_exp_ext["capital_cost"] = [150.0, 100.0]
t_th_exp_ext["operations_cost"] = [15.0, 10.0]
t_th_exp_ext["variable_cost"] = [1.0, 1.0]
t_th_exp_ext["investment_periods"] = [2030, 2040]
# one option is to repeat these for each investment
t_th_exp_ext["operational_periods"] = [1, 2, 3]
t_th_exp_ext["operational_periods_2"] = [
1, 2, 3, # first investment period
4, 5, 6 # second investment period
]
t_th_exp_ext["investment_operational_periods_map"] = Dict(
1 => 2030,
2 => 2030,
3 => 2030,
4 => 2040,
5 => 2040,
6 => 2040,
)
t_th_exp_ext["initial_capacity"] = 200.0 # Data in MW
t_th_exp_ext["maximum_capacity"] = 10000.0
t_th_exp_ext["minimum_required_capacity"] = [0.0, 0.0]


# Initial Capacity
# Renewable Technology

t_re = SupplyTechnology{RenewableDispatch}(
name="renewable_tech",
Expand All @@ -71,21 +98,54 @@
)

t_re_ext = t_re.ext
t_re_ext["capital_cost"] = 100.0
t_re_ext["variable_capacity_factor"] = [0.8, 0.6, 0.3]
t_re_ext["capital_cost"] = [100.0, 75.0]
t_re_ext["operations_cost"] = [10.0, 6.5]
t_re_ext["variable_cost"] = [0, 0]
t_re_ext["variable_capacity_factor"] = [0.8, 0.6, 0.3, 0.5, 0.9, 0.4]
t_re_ext["investment_periods"] = [2030, 2040]
# one option is to repeat these for each investment
t_re_ext["operational_periods"] = [1, 2, 3]
t_re_ext["operational_periods_2"] = [
1, 2, 3, # first investment period
4, 5, 6 # second investment period
]
t_re_ext["investment_operational_periods_map"] = Dict(
1 => 2030,
2 => 2030,
3 => 2030,
4 => 2040,
5 => 2040,
6 => 2040,
)
t_re_ext["initial_capacity"] = 200.0 # Data in MW
t_re_ext["maximum_capacity"] = 10000.0
t_re_ext["minimum_required_capacity"] = [0.0, 0.0]


# Demand side technologies
d_1 = DemandSideTechnology{ElectricLoad}(
name="demand",
available=true,
capital_cost
)


PSIP.add_technology!(p, t_th)
PSIP.add_technology!(p, t_re)
PSIP.add_technology!(p, t_th_exp)


IS.serialize(t)
IS.serialize(t_th)
IS.serialize(t_re)
IS.serialize(t_th_exp)
IS.serialize(p)

get_technologies(x -> (!get_available(x)), SupplyTechnology{ThermalStandard}, p)
#get_technologies(x -> (!get_available(x)), SupplyTechnology{ThermalStandard}, p)

get_technologies(SupplyTechnology{ThermalStandard}, p)
PSIP.remove_technology!(SupplyTechnology{ThermalStandard}, p, "thermal_tech")
#get_technologies(SupplyTechnology{ThermalStandard}, p)
#PSIP.remove_technology!(SupplyTechnology{ThermalStandard}, p, "thermal_tech")

get_available(t)
IS.deserialize(p)
#get_available(t_th)
#get_available(t_re)
#get_available(t_th_exp)
#IS.deserialize(p)
243 changes: 243 additions & 0 deletions scripts/simple_cem.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
using HiGHS
using JuMP

abstract type GenTech end
abstract type InvestmentModel end
abstract type OperationModel end
abstract type RegionalModel end
abstract type OptimizationModel end
#mutable struct ThermalGen <: GenTech end

# Include simplified portfolio
include("portfolio_test.jl")

#struct to define basic capacity expansion model, broken down into operation and InvestmentModel
struct SimpleInvest <: InvestmentModel end
struct SimpleOp <: OperationModel end

#Defining Model types
inv = SimpleInvest()
op = SimpleOp()

# Defining empty dictionaries for constraints, expressions, variables, etc. How is this done in Sienna?

# investment definitions
build = Dict()
capacity = Dict()
build_nonneg = Dict()
cap_bounds = Dict()
capital_costs = Dict()
fom_costs = Dict()

# operations definitions
dispatch = Dict()
dispatch_lb = Dict()
dispatch_ub = Dict()
dispatch_limit = Dict()
demand_matching = Dict()
vom_costs = Dict()

##################
# Investment variables
##################

function add_variables!(model, T::SupplyTechnology{ThermalStandard}, U::SimpleInvest)
print("Thermal investment variables called \n")
for t in T.ext["investment_periods"]

i = findfirst(==(t), T.ext["investment_periods"])

# Build and capacity variables
build[T.name, t] = JuMP.@variable(model)
capacity[T.name, t] = JuMP.@expression(model, (T.ext["initial_capacity"] + sum( build[T.name,t_p] for t_p in T.ext["investment_periods"] if t_p <= t)))

# Investment and FOM cost calculations
capital_costs[T.name, t] = JuMP.@expression(model, T.ext["capital_cost"][i]*build[T.name, t])
fom_costs[T.name, t] = JuMP.@expression(model, T.ext["operations_cost"][i]*capacity[T.name, t])

end

end

function add_variables!(model, T::SupplyTechnology{RenewableDispatch}, U::SimpleInvest)
print("Renewable investment variables called \n")
for t in T.ext["investment_periods"]

i = findfirst(==(t), T.ext["investment_periods"])

# Build and capacity variables
build[T.name, t] = JuMP.@variable(model)
capacity[T.name, t] = JuMP.@expression(model, (T.ext["initial_capacity"] + sum( build[T.name,t_p] for t_p in T.ext["investment_periods"] if t_p <= t)))

# Investment and FOM cost calculations
capital_costs[T.name, t] = JuMP.@expression(model, T.ext["capital_cost"][i]*build[T.name, t])
fom_costs[T.name, t] = JuMP.@expression(model, T.ext["operations_cost"][i]*capacity[T.name, t])

end

end

############
# Operations variables
############

function add_variables!(model, T::SupplyTechnology{ThermalStandard}, U::SimpleOp)
print("Thermal operation variable called \n")
for t in T.ext["operational_periods_2"]

i = findfirst(==(t), T.ext["operational_periods_2"])

i_mapper = findfirst(==(t_th.ext["investment_operational_periods_map"][t]), t_th.ext["investment_periods"])

#Dispatch Variable
dispatch[T.name, t] = JuMP.@variable(model)

#VOM costs
vom_costs[T.name, t] = JuMP.@expression(model, dispatch[T.name, t]*T.ext["variable_cost"][i_mapper])

end

end

function add_variables!(model, T::SupplyTechnology{RenewableDispatch}, U::SimpleOp)
print("Renewable operation variable called\n")
for t in T.ext["operational_periods_2"]

i = findfirst(==(t), T.ext["operational_periods_2"])

i_mapper = findfirst(==(t_th.ext["investment_operational_periods_map"][t]), t_th.ext["investment_periods"])

#Dispatch Variable
dispatch[T.name, t] = JuMP.@variable(model)

#VOM costs
vom_costs[T.name, t] = JuMP.@expression(model, dispatch[T.name, t]*T.ext["variable_cost"][i_mapper])

end

end

############
# Investment constraints
############

function add_constraints!(model, T::SupplyTechnology{ThermalStandard}, U::SimpleInvest)
print("Thermal investment constraints called\n")
for t in T.ext["investment_periods"]

i = findfirst(==(t), T.ext["investment_periods"])

# Build and capacity variable bounds
build_nonneg[T.name, t] = JuMP.@constraint(model, 0 <= build[T.name, t])
cap_bounds[T.name, t] = JuMP.@constraint(model, T.ext["minimum_required_capacity"][i] <= capacity[T.name, t] <= T.ext["maximum_capacity"])

end

end

function add_constraints!(model, T::SupplyTechnology{RenewableDispatch}, U::SimpleInvest)
print("Renewable investment constraints called\n")
for t in T.ext["investment_periods"]

i = findfirst(==(t), T.ext["investment_periods"])

# Build and capacity variable bounds
build_nonneg[T.name, t] = JuMP.@constraint(model, 0 <= build[T.name, t])
cap_bounds[T.name, t] = JuMP.@constraint(model, T.ext["minimum_required_capacity"][i] <= capacity[T.name, t] <= T.ext["maximum_capacity"])

end

end

###########
# Operations Constraints
###########

function add_constraints!(model, T::SupplyTechnology{ThermalStandard}, U::SimpleOp)
print("Thermal operations constraints called\n")
for t in T.ext["operational_periods_2"]

i = findfirst(==(t), T.ext["operational_periods_2"])

i_mapper = findfirst(==(t_th.ext["investment_operational_periods_map"][t]), t_th.ext["investment_periods"])

# Dispatch Variable
dispatch_lb[T.name, t] = JuMP.@constraint(model, 0 <= dispatch[T.name, t])
dispatch_ub[T.name, t] = JuMP.@constraint(model, dispatch[T.name, t] <=
T.capacity_factor*capacity[T.name, T.ext["investment_operational_periods_map"][t]])

end

end

function add_constraints!(model, T::SupplyTechnology{RenewableDispatch}, U::SimpleOp)
print("Renewable operations constraints called\n")
for t in T.ext["operational_periods_2"]

i = findfirst(==(t), T.ext["operational_periods_2"])

i_mapper = findfirst(==(t_th.ext["investment_operational_periods_map"][t]), t_th.ext["investment_periods"])

# Dispatch Variable
dispatch_lb[T.name, t] = JuMP.@constraint(model, 0 <= dispatch[T.name, t])
dispatch_ub[T.name, t] = JuMP.@constraint(model, dispatch[T.name, t] <=
T.ext["variable_capacity_factor"][i]*T.capacity_factor*capacity[T.name, T.ext["investment_operational_periods_map"][t]])

end

end

function add_constraints!(model, U::SimpleOp)
print("system operations constraints called\n")
for t in T_o

demand_matching[t] = JuMP.@constraint(model, loads[t] <= sum(dispatch[g,t] for g in gens))

end

end

#############
# Objective function
#############

function add_objective_function!(model)
JuMP.@objective(model, Min, sum(capital_costs[g, t]+fom_costs[g, t] for g in gens for t in T_i)+weights[t]*sum(vom_costs[g, t] for g in gens for t in T_o))
end

##################
# Running the optimization model
##################

#defining toy data for writing model
loads = Dict(1 => 100, 2 => 150, 3 => 175, 4 => 80, 5=>300, 6=>120)
weights = Dict(1 => 12, 2 => 12, 3 => 12, 4 => 12, 5=>12, 6=>12)

# initialize model
model = JuMP.Model(HiGHS.Optimizer)

# Calling investment variables
add_variables!(model, t_th, inv)
add_variables!(model, t_th_exp, inv)
add_variables!(model, t_re, inv)

# Calling investment constraints
add_constraints!(model, t_th, inv)
add_constraints!(model, t_th_exp, inv)
add_constraints!(model, t_re, inv)

# Calling operation variable definitions
add_variables!(model, t_th, op)
add_variables!(model, t_th_exp, op)
add_variables!(model, t_re, op)

# Calling operation constraint definitions
add_constraints!(model, t_th, op)
add_constraints!(model, t_th_exp, op)
add_constraints!(model, t_re, op)

# Calling demand matching constraints
add_constraints!(model, op)

# Calling objective function
add_objective_function!(model)
Loading