e4st-dev / E4ST.jl

Engineering, Economic, and Environmental Electricity Simulation Tool (E4ST)
GNU General Public License v3.0
7 stars 1 forks source link

Result cost of electricity for transmission losses #244

Open sallyrobson opened 1 year ago

sallyrobson commented 1 year ago

copied from the OSW teams channel and modified:

One discrepancy in the welfare is in electricity_revenue (for gen and storage) vs electricity_cost (paid by users). Electricity revenue is determined by electricity generated, which I think is correct. And electricity cost is determined by load served, which I think is also correct. But that means that generators are getting paid for more generation than users are paying for (egen > elserv). I think that the merchandising surplus should be dealing with this issue but the value of the merchandising surplus in our project results doesn't match the difference. I think that since both of those results are calculated correctly (to my knowledge), the best thing would be to include an additional system cost which is the cost of generating electricity for distribution losses. I imagine that the user would pay for that. The downside of having this as an additional term is that it won't get processed with electricity cost in other parts of the results, even though it probably should be treated the same. We could instead calculate it and then add it to the electricity cost formula (possibly having the current version of electricity cost be "electricity_cost_prelim" and then having "electricity_cost" include the distribution, although I'm not sure exactly how that would work with the regions, we will have to assign this additional cost to certain buses). What do you think about this? Has this been handled in a specific way in the past welfare accounting?

Ethan-Russell commented 1 year ago

Hmm, these should be equal. I would expect:

compute_result(data, :gen, :electricity_revenue) + compute_result(data, :storage, :electricity_revenue) == compute_result(data, :bus, :electricity_cost)

Is that not what we are seeing? The LMP seen by users is higher than that earned by generators because of the transmission losses (or at least it should be)

sallyrobson commented 1 year ago

That statement is returning false for me. I also edited my message above because I realized that I think this should be dealt with in merchandising surplus, but the merchandising surplus doesn't equal the difference I'm seeing

sallyrobson commented 1 year ago

Dan says that merchandising surplus deals with the discrepancy in prices between the node of the generator and the node of the load, but doesn't account for transmission losses.

Ethan-Russell commented 1 year ago

How far off is that calculation?

sallyrobson commented 1 year ago

It's off by about 1.5E10

sallyrobson commented 1 year ago

From Dan: [6:08 PM] Shawhan, Daniel For example, suppose you want to calculate user payments for energy using the quantity consumed. You can do that by increasing the prices that consumers pay by the ratio of electricity generated over electricity consumed. They pay a higher price per MWh that reaches them because they have to pay for the energy lost (in transmission and distribution) too. I think this is the way we have done it in the past. Edited​[6:11 PM] Shawhan, Daniel That is not the only way to do it. You could instead increase the quantity of energy that users pay for, so that it includes the amount lost to T&D losses. For that, you would multiply quantity instead of price, by the same ratio mentioned above. Obviously, you get the same result. Edited​[6:14 PM] Shawhan, Daniel I think those are the two best options. I'd probably choose the first one, unless you have a reason that the second one seems better.

Ethan-Russell commented 1 year ago

Ouch! That's a big deal...

With respect to Dan's comment on T&D I believe that the first of the above solutions is already happening. They pay a post-loss LMP. You can confirm that by calculating the national electricity price for bus vs gen table

sallyrobson commented 1 year ago

In looking at the parse_lmp code, it looks like we already do adjust the lmp_elserv when the line_loss_type is "plserv".

# Compensate for line losses for lmp seen by users at buses.
    if config[:line_loss_type] == "plserv"
        line_loss_rate = config[:line_loss_rate]::Float64

        # lmp_elserv is dollars per MWh before losses, so we need to inflate the cost to compensate
        plserv_scalar = 1/(1-line_loss_rate)
        add_table_col!(data, :bus, :lmp_elserv, lmp_elserv .* plserv_scalar, DollarsPerMWhServed,"Locational Marginal Price of Energy Served (scaled up from lmp_elserv_preloss)")
        add_table_col!(data, :bus, :lmp_elserv_preloss, lmp_elserv, DollarsPerMWhServed,"Locational Marginal Price of Energy Served")
    else
        add_table_col!(data, :bus, :lmp_elserv, lmp_elserv, DollarsPerMWhServed,"Locational Marginal Price of Energy Served")
    end
sallyrobson commented 1 year ago

I think that merchandising surplus is getting calculated using the unadjusted lmp_elserv. The result "lmp_elserve" get's set with the adjustment but the actual variable isn't modified and then it gets used later on to calculate merchandising surplus.

Ethan-Russell commented 1 year ago

julia> compute_result(data, :bus, :electricity_cost) + compute_result(data, :storage, :electricity_cost) - compute_result(data, :gen, :electricity_revenue) - compute_result(data, :storage, :electricity_revenue)
7.82511907243269e9

julia> compute_result(data, :bus, :merchandising_surplus_total)
2.008688770768999e10

From the above, it looks like users are over-paying for electricity by 7.8B. However, merchandising surplus is 20B. So after applying the merchandising surplus, the electricity users are paying 12B less than the producers are receiving for electricity.

Note that the merchandising surplus is calculated with the pre-loss LMP and the pre-loss flow. I'm not sure where this discrepancy is coming from.

Ethan-Russell commented 1 year ago

From conversation with Dan:

sallyrobson commented 1 year ago

In looking at the parse_lmp code, it looks like we already do adjust the lmp_elserv when the line_loss_type is "plserv".

# Compensate for line losses for lmp seen by users at buses.
    if config[:line_loss_type] == "plserv"
        line_loss_rate = config[:line_loss_rate]::Float64

        # lmp_elserv is dollars per MWh before losses, so we need to inflate the cost to compensate
        plserv_scalar = 1/(1-line_loss_rate)
        add_table_col!(data, :bus, :lmp_elserv, lmp_elserv .* plserv_scalar, DollarsPerMWhServed,"Locational Marginal Price of Energy Served (scaled up from lmp_elserv_preloss)")
        add_table_col!(data, :bus, :lmp_elserv_preloss, lmp_elserv, DollarsPerMWhServed,"Locational Marginal Price of Energy Served")
    else
        add_table_col!(data, :bus, :lmp_elserv, lmp_elserv, DollarsPerMWhServed,"Locational Marginal Price of Energy Served")
    end

After looking through the code with Ethan, we concluded that this method is actually correct and that we shouldn't be modifying the variable lmp_elserv when using it for merchandising surplus. This is because we are also using the unadjusted pflow in that calculation and so we should match those too (either the lower/unadjusted lmp_elserv and higher/unadjusted pflow, or the higher/adjusted lmp_elserv and the lower/adjusted pflow). Since we are already using unadjusted pflow, we shouldn't modify the lmp_elserve for the merchandising surplus calculation.

Ethan-Russell commented 1 year ago

I've narrowed down the issue to GenerationStandards.

I think that generation standards sometimes cause negative merchandising surpluses, which I thought was impossible. Changing the merchandising surplus calculation to not use an absolute value sign got the test case to pass.