-
Notifications
You must be signed in to change notification settings - Fork 1
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
Simultaneous charge and discharge #214
Comments
I'm thinking this might be a good question for Ray if we want to reach out, I don't think we've used up our time for him. |
A brain dump. If we say that storage is on the generator side: power discharged should be added to pgen_bus That is theoretically what is happening in line 456-457 of Storage.jl Ok. Let's find an example of when things are messed up. julia> out_path = raw"L:\Project-Gurobi\Workspace3\E4ST_Output\baseline_testing\bar_hom\230906_140425427"
julia> data = read_processed_results(out_path)
julia> pdischarge = get_raw_result(data, :pdischarge_stor);
julia> pcharge = get_raw_result(data, :pcharge_stor);
julia> p = pdischarge .* pcharge;
julia> count(>(1), p)
1254 # This means there are 1254 times for which there is simultaneous charging & discharging
julia> findmax(p)
(1.1764705813597874e6, CartesianIndex(209, 1, 43))
julia> day = get_table_col(data, :hours, :e4st_day)[43]
12
julia> hr_idxs = get_hour_idxs(data, :e4st_day=>day)
2-element Vector{Int64}:
43
44
julia> pcharge[209, 1, hr_idxs]
2-element Vector{Float64}:
1176.4705851141678
9.690407329034632e-7
julia> pdischarge[209, 1, hr_idxs]
2-element Vector{Float64}:
999.9999968087767
1.3619506173416022e-6
julia> 999.9999968087767 / 1176.4705851141678
0.849999999542474 # Round trip storage efficiency of 85%
# Yup, we are charging a lot here. First thing to check is LMP's
julia> get_table_col(data, :storage, :lmp_e)[209][ 1, hr_idxs]
2-element Vector{Float64}:
45.72981667241463
19.777874344097867
# Just to make sure we're getting the correct LMP here:
julia> get_table_col(data, :bus, :lmp_elserv_preloss)[get_table_col(data, :storage, :bus_idx)[209]][1, hr_idxs]
2-element Vector{Float64}:
45.72981667241463
19.777874344097867
# Rats. Positive LMP means that increasing the power served would increase the objective, so I don't know why we're seeing this.
# Maybe let's take a look at the `pgen_bus` value
julia> pgen_bus[get_table_col(data, :storage, :bus_idx)[209], 1, hr_idxs]
2-element Vector{Float64}:
1999.2075872742473
8.155446399178975e-7
julia> gen_idxs = get_table_row_idxs(data, :gen, :bus_idx=>stor_bus_idx)
5-element Vector{Int64}:
8227
10024
18493
20760
20761
julia> pgen_gen[gen_idxs, 1, hr_idxs]
5×2 Matrix{Float64}:
4.18739e-8 3.86825e-7
2175.68 0.0
8.4827e-8 4.22689e-9
1.18931e-8 1.34263e-8
1.56859e-8 1.81568e-8
# Ah, all the generation is from a single generator, 10024. Let's check out its cost of operation:
julia> obj_coef = get_raw_result(data, :obj_coef);
julia> obj_pgen_gen = obj_coef[:pgen_gen];
julia> obj_pgen_gen_unweighted = unweight_hourly(data, obj_pgen_gen)
julia> obj_pgen_gen_unweighted[10024, 1, hr_idxs]
julia> obj_pgen_gen_unweighted[10024, 1, hr_idxs]
2-element Vector{Float64}:
-22.38
-22.38
# That looks like an IRA ptc value.
julia> gen.pcap[10024]
1-element view(::Matrix{Float64}, 1, :) with eltype Float64:
2999.9999999493302
julia> gen.af[10024][hr_idxs]
2-element Vector{Float64}:
0.725226058959961
0.0
julia> gen.pcap[10024] .* 0.725226058959961
1-element Vector{Float64}:
2175.6781768431356
# Ah. So there is a generator with maxed out capacity and generation with negative gen cost
# Let's check and see why we wouldn't be discharging after - could be that e0 is maxed out
julia> e0 = get_raw_result(data, :e0_stor)
julia> e0[stor_idx,1]
3999.9999976746653
# Yup. Seems like our yearly e0 is hurting us a bit.
julia> sum(weight_hourly(data, pdischarge) .* (pdischarge .* pcharge .> 1))
1.950544207651207e7
julia> sum(weight_hourly(data, pdischarge))
7.695451029947007e7 So in conclusion, our initial stored energy in the battery, |
Ok so we need the following:
|
After making those two changes, we are still seeing simultaneous charging and discharging, albeit less frequently. Let's take a look at another case julia> data = read_processed_results("L:/Project-Gurobi/Workspace3/E4ST_Output/baseline_testing/bar_hom\\230914_162839691");
julia> pcharge = get_raw_result(data, :pcharge_stor);
julia> pdischarge = get_raw_result(data, :pdischarge_stor);
julia> p = pdischarge .* pcharge;
julia> count(>(10), p)
790
julia> findmax(p)
(345261.40185765864, CartesianIndex(218, 1, 36))
julia> stor_idx = 218
218
julia> hr_idxs^C
julia> day = get_table_col(data, :hours, :e4st_day)[36]
8
julia> hr_idxs = get_hour_idxs(data, :e4st_day=>day)
2-element Vector{Int64}:
35
36
julia> get_table(data, :hours, hr_idxs)
2×14 SubDataFrame
Row │ hour_id src_file description hours year month day hour season e4st_day hrs_per_day hr_idx e4st_day_hour_duration ozone_season
│ String3 String String Float64 Int64 Int64 Int64 Int64 String7 Int64 Int64 Int64 Int64 Int64
─────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ h35 L:\\Project-Gurobi\\Workspace3\\… us-can: load weighted average of… 76.9171 2008 8 6 17 summer 8 2 35 4 1
2 │ h36 L:\\Project-Gurobi\\Workspace3\\… us-can: load weighted average of… 76.9171 2008 8 6 13 summer 8 2 36 4 1
julia> pcharge[stor_idx, 1, hr_idxs]
2-element Vector{Float64}:
656.072149189513
615.7875374234399
julia> pdischarge[stor_idx, 1, hr_idxs]
2-element Vector{Float64}:
520.398061636471
560.6826719850344
julia> pdischarge[stor_idx,:, hr_idxs] .+ pcharge[stor_idx, :, hr_idxs]
1×2 Matrix{Float64}:
1176.47 1176.47
# Ok, so our new constraint is not being violated here, and we're seeing some slight differences in the amount of charge/discharge in each hour
julia> sum(pdischarge[stor_idx, 1, hr_idxs]) / sum(pcharge[stor_idx, 1, hr_idxs])
0.8500000000003894 # No violation of our efficiency constraint
julia> pcharge[stor_idx,1, hr_idxs] .- pdischarge[stor_idx, 1, hr_idxs]
2-element Vector{Float64}:
135.674087553042
55.104865438405454
# A bit more load added to the grid in the first hour than in the 2nd hour. Let's dig into the LMP.
julia> get_table_col(data, :bus, :lmp_elserv_preloss)[get_table_col(data, :storage, :bus_idx)[stor_idx]][1, hr_idxs]
2-element Vector{Float64}:
0.08949863770090605
0.08949863774134087
julia> stor_bus_idx = get_table_col(data, :storage, :bus_idx)[stor_idx]
218
julia> pgen_bus = get_raw_result(data, :pgen_bus); pgen_gen = get_raw_result(data, :pgen_gen);
julia> pgen_bus[stor_bus_idx, 1, hr_idxs]
2-element Vector{Float64}:
-135.67405792881732
-55.10483585548184
julia> stor_bus_idx = get_table_col(data, :storage, :bus_idx)[stor_idx]
218
julia> pgen_bus = get_raw_result(data, :pgen_bus); pgen_gen = get_raw_result(data, :pgen_gen);
julia> pgen_bus[stor_bus_idx, 1, hr_idxs]
2-element Vector{Float64}:
-135.67405792881732
-55.10483585548184
julia> gen_idxs = get_table_row_idxs(data, :gen, :bus_idx=>stor_bus_idx);
julia> pgen_gen[gen_idxs, 1, hr_idxs]
23×2 Matrix{Float64}:
2.3553e-8 2.39795e-8
2.91271e-5 2.90053e-5
2.37537e-8 2.4189e-8
0.0 0.0
3.55872e-8 3.59832e-8
1.77827e-8 1.80557e-8
2.41219e-8 2.45704e-8
3.66558e-8 3.76026e-8
0.0 0.0
2.09853e-8 2.13719e-8
1.77358e-8 1.80055e-8
2.05869e-8 2.09049e-8
3.51248e-8 3.5477e-8
1.98514e-8 1.99209e-8
2.07689e-8 2.11016e-8
2.16953e-8 2.20374e-8
3.59679e-8 3.62593e-8
4.77814e-8 4.93427e-8
3.39119e-8 1.02346e-7
3.81812e-8 3.85238e-8
0.0 4.70806e-9
1.15352e-8 1.16289e-8
1.15328e-8 1.1627e-8
# Huh, no generation at this bus. But very small LMP.
# Just to keep track of how much discharging is happening while there is charging happening too, I will come up with a metric:
julia> sum(weight_hourly(data, pdischarge) .* (pdischarge .* pcharge .> 1))
1.0157812171984944e7
julia> sum(weight_hourly(data, pdischarge))
7.739219724255703e7
# That's about 10 million TWh out of 77 million TWh of total battery discharge.
|
I think I'd like to add a small VOM to our storage to see if that significantly reduces the problem |
I am still seeing simultaneous charging and discharging with the full size grid. Need to get creative with a way to limit this with LP hopefully without changing the objective.
The text was updated successfully, but these errors were encountered: