-
Notifications
You must be signed in to change notification settings - Fork 50
/
model_constructors.jl
120 lines (80 loc) · 5.2 KB
/
model_constructors.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
function buildmodel!(sys::PowerSystems.PowerSystem, op_model::PowerOperationModel; args...)
#TODO: Add check model spec vs data functions before trying to build
netinjection = instantiate_network(op_model.transmission, sys)
for category in op_model.generation
constructdevice!(op_model.model, netinjection, category.device, category.formulation, op_model.transmission, sys; args...)
end
if op_model.demand != nothing
for category in op_model.demand
constructdevice!(op_model.model, netinjection, category.device, category.formulation, op_model.transmission, sys; args...)
end
end
#=
for category in op_model.storage
op_model.model = constructdevice!(category.device, network_model, op_model.model, devices_netinjection, sys, category.constraints)
end
=#
if op_model.services != nothing
service_providers = Array{NamedTuple{(:device, :formulation),Tuple{DataType,DataType}}}([])
[push!(service_providers,x) for x in vcat(op_model.generation,op_model.demand,op_model.storage) if x != nothing]
for service in op_model.services
op_model.model = constructservice!(op_model.model, service.service, service.formulation, service_providers, sys; args...)
end
end
constructnetwork!(op_model.model, op_model.branches, netinjection, op_model.transmission, sys; args..., PTDF = op_model.ptdf)
@objective(op_model.model, Min, op_model.model.obj_dict[:objective_function])
return op_model
end
function build_sim_ts(ts_dict::Dict{String,Any}, steps, periods, resolution, date_from, lookahead_periods, lookahead_resolution ; args...)
# exmaple of time series assembly
# TODO: once we refactor PowerSystems, we can improve this process
steps_dict = Dict()
function _subset_ts(ts_dict,start,finish)
return ts_dict[(ts_dict.DateTime .>= start) .& (ts_dict.DateTime .< finish),:]
end
for step in 1:steps
step_stamp = date_from + ((resolution * periods) + (lookahead_periods * lookahead_resolution)) * (step-1)
step_end = step_stamp + (resolution * periods) + (lookahead_periods * lookahead_resolution)
steps_dict[step_stamp] = deepcopy(ts_dict)
steps_dict[step_stamp]["load"] = _subset_ts(steps_dict[step_stamp]["load"],step_stamp,step_end)
for cat in keys(steps_dict[step_stamp]["gen"])
steps_dict[step_stamp]["gen"][cat] = _subset_ts(steps_dict[step_stamp]["gen"][cat],step_stamp,step_end)
end
end
return steps_dict
end
function buildsimulation!(sys::PowerSystems.PowerSystem, op_model::PowerOperationModel, ts_dict::Dict{String,Any}; args...)
name = :name in keys(args) ? args[:name] : "my_simulation"
model = op_model
resolution = :resolution in keys(args) ? args[:resolution] : PowerSystems.getresolution(sys.loads[1].scalingfactor)
date_from = :date_from in keys(args) ? args[:date_from] : minimum(timestamp(sys.loads[1].scalingfactor))
date_to = :date_to in keys(args) ? args[:date_to] : maximum(timestamp(sys.loads[1].scalingfactor))
periods = :periods in keys(args) ? args[:periods] : (resolution < Hour(1) ? 1 : 24)
steps = :steps in keys(args) ? args[:steps] : Int64(floor((length(sys.loads[1].scalingfactor)-1)/periods))
if steps != (length(sys.loads[1].scalingfactor)-1)/periods
@warn "Time series length and simulation definiton inconsistent, simulation may be truncated, simulating $steps steps."
end
lookahead_periods = :lookahead_periods in keys(args) ? args[:lookahead_periods] : 0
lookahead_resolution = :lookahead_resolution in keys(args) ? args[:lookahead_resolution] : resolution
@info "Simulation defined for $steps steps with $periods * $resolution periods per step (plus $lookahead_periods * $lookahead_resolution lookahead periods), from $date_from to $date_to"
dynamic_analysis = false;
timeseries = build_sim_ts(ts_dict, steps, periods, resolution, date_from, lookahead_periods, lookahead_resolution ; args...)
PowerSimulationsModel(name,model, steps, periods, resolution, date_from, date_to,
lookahead_periods, lookahead_resolution, dynamic_analysis, timeseries)
end
function buildsimulation!(sys::PowerSystems.PowerSystem, op_model::PowerOperationModel; args...)
ts_dict = Dict{String,Any}()
ts_dict["load"] = DataFrame(Dict([(l.name,values(l.scalingfactor)) for l in sys.loads]))
ts_dict["load"][:DateTime] = TimeSeries.timestamp(sys.loads[1].scalingfactor)
ts_dict["gen"] = Dict()
if !isa(sys.generators.renewable,Nothing)
# TODO: do a better job of classifying generators in the timeseries dict and reflect that here. For now, i'm just using PV as a placeholder
ts_dict["gen"]["PV"] = DataFrame(Dict([(g.name,values(g.scalingfactor)) for g in sys.generators.renewable]))
ts_dict["gen"]["PV"][:DateTime] = timestamp(sys.generators.renewable[1].scalingfactor)
end
if !isa(sys.generators.hydro,Nothing)
ts_dict["gen"]["Hydro"] = DataFrame(Dict([(g.name,values(g.scalingfactor)) for g in sys.generators.hydro]))
ts_dict["gen"]["Hydro"][:DateTime] = timestamp(sys.generators.hydro[1].scalingfactor)
end
buildsimulation!(sys, op_model, ts_dict; args...)
end