quintel / merit

A system for calculating hourly electricity and heat loads with a merit order
MIT License
3 stars 2 forks source link

How to define the price when importing? #107

Closed ChaelKruip closed 10 years ago

ChaelKruip commented 10 years ago

Currently the NL electricity price in the Merit module is set to be the marginal cost of the cheapest inactive plant.

When we introduce virtual power plants to describe the interconnectors (using curves for the price of imported electricity) should we then still take the NL price to be the marginal cost of the next cheapest plant? That is not very realistic (unless the interconnector is almost fully used). It seems more natural to take the price of the curve as the NL price directly.

@AlexanderWirtz please give your 2 cents. @antw @dennisschoenmakers I can imagine that treating the 'marginal cost' of the virtual plant differently than that of a normal plant to determine the NL price complicates the computations in Merit. Do you foresee issues with this?

dennisquintel commented 10 years ago

It seems more natural to take the price of the curve as the NL price directly.

You mean the marginal cost (~='price') curve for the interconnector?

ChaelKruip commented 10 years ago

You mean the marginal cost (~='price') curve for the interconnector?

Kinda. The price of the interconnector is set by the price setting plant in the other country. So, instead of taking the marginal cost of the next cheapest local plant, we should probably be taking the price of interconnector itself.

AlexanderWirtz commented 10 years ago

That is what @ChaelKruip means @dennisschoenmakers . It is more complicated than @ChaelKruip describes, however. This issue highlights a shortcoming (approximation if you will) of the current marginal cost calculation.

Current calculation

The price setting plant is the first inactive plant type, not the first inactive plant. The reason is that the merit module does not distinguish one USC coal-fired power plant from another, for example. In reality, they are all slightly different, or distributed around the average marginal costs for that plant type. This means the price setting plant is often actually the next, slightly more expensive and inactive power plant of the same type rather than the next inactive plant type.

In reality, therefore, until a block (type) of power plants is pretty much fully used, the plants in that block are actually price-setting. Just like we are now requesting for the virtual power plant that is the DE-NL interconnector.

Suggested improvement

If we distributed all large plants (e.g. plant size > 200 MWe) around the average marginal costs, but made them distinct plants as far as the merit calculation is concerned, we could solve the problem described under Current calculation.

This does not solve the issue at hand for the interconnector, being the price setting plant until it is fully utilized, but does show some parallels.

@dennisschoenmakers and @ChaelKruip fire away.

ChaelKruip commented 10 years ago

Also see https://github.com/quintel/merit/issues/59#issuecomment-11989793

ChaelKruip commented 10 years ago

@AlexanderWirtz thanks for writing this up clearly!

This does not solve the issue at hand for the interconnector

I think that for the interconnector we should keep things as simple as possible and just set the price to a constant whenever the interconnector is used, regardless of the 'occupation'.

If we distributed all large plants (e.g. plant size > 200 MWe) around the average marginal costs, but made them distinct plants as far as the merit calculation is concerned

I think this would be a good improvement in principal but treating every plant individually will likely impact the performance of the Merit module quite a bit. Perhaps we can do it as follows:

For a plant type, define a function that describes the marginal cost of the whole 'block' as a function of used capacity of that plant type. This could be a step-function with step-size equal to the capacity of the individual plants. This way, the performance of the Merit module will be hardly affected.

AlexanderWirtz commented 10 years ago

@ChaelKruip that sounds like a good idea. The function for the virtual power plant can be constant then.

dennisquintel commented 10 years ago

Would like to hear @antw 's ideas on this one!

ChaelKruip commented 10 years ago

I have been playing around with two functions to describe the marginal cost of a plant as a function of the used percentage of total installed capacity. The parameters that describe the function are:

The functions:

Here is an example with a mean of 100 EUR / MWh, an installed capacity of 1000 MW and 150 MW plants. The spread is 2% around the mean: figure_1

More exotic distributions are also possible. Normally distributed costs for example. I am struggling with the math here a bit though :blush: You would like to have something like an inverse Normal CDF (cumulative distribution function) that looks something like this: figure_1 It is a pain to calculate, however, and there are some extra parameters that define the widths that have no physical meaning for me at this point.

antw commented 10 years ago

For a plant type, define a function that describes the marginal cost of the whole 'block' as a function of used capacity of that plant type.

I agree, this seems like a good approach and (I'm assuming) less work than having to define individual plants. It should also be much more performant.

I can imagine that treating the 'marginal cost' of the virtual plant differently than that of a normal plant to determine the NL price complicates the computations in Merit. Do you foresee issues with this?

I don't really feel qualified to comment on this yet; profitability and pricing were added to Merit 18-months ago, but I'm not super-familiar with how it works. I need to get to know that code a bit better before I can offer much insight.

Just so I can be clear: the concern is that the interconnect will be priced using the first completely unused producer in the source country (DE), but what you want is to price according to a function applied to the last used producer? (sorry if I'm being dense...)

mo

ChaelKruip commented 10 years ago

(sorry if I'm being dense...)

It's probably my fault for not being clear in my explanations. There are two things going on in this ticket, which are related.

  1. "How to define the price of NL electricity (P(NL)) when there is import going on." This issue arises because normally (currently) we take the marginal cost of the cheapest inactive plant as P(NL). The rationale is that the current active plant would not be making any money if the price were set by its marginal cost so why would it even run right? Now we introduce the Interconnector to Germany: a virtual power plant in the NL merit order with a 'marginal cost' defined as the German price for electricity. That's the problem right there! The Interconnector does not have a real marginal cost put a 'price'. When we import electricity from Germany we should pay that price and not the marginal cost of the next inactive plant in NL.
  2. The second issue is the fact that our current calculation of P(NL) (and P(DE) for that matter) is not realistic. If we would be modelling all power plants individually in the ETM, the price would indeed be defined by the next (inactive) plant but we are describing all plants of the same type as one big plant in the merit order. Therefore, we ignore the variation of marginal cost within the distribution of plants of one type. That results in an overestimate of the money made by plants which can be quite severe.

Hope that helps!

ChaelKruip commented 10 years ago

Part of https://github.com/quintel/merit/issues/104

ChaelKruip commented 10 years ago

I think that the best way to define the price consistently for physical dispatchable plants and virtual supply type interconnector plants is by:

AlexanderWirtz commented 10 years ago

@ChaelKruip

Defining a step-function as proposed in (#107 (comment)) for all plants. For the dispatchable plants, this step function models the distinct units within that 'plant type'. For the virtual supply type interconnector plants, there is only one step so the price is flat.

:+1:

Taking the marginal cost (given by the above step function) of the most expensive plant in use. NOTE: This is not how we do it now. Currently, we take the marginal cost of the next cheapest inactive plant.

I am not sure that makes things more realistic. It works for the interconnector case, but in all other cases it would be wrong. Throwing the baby out with the bathwater. The next most expensive plant inactive will sometimes be considerably more expensive and be price-setting.

antw commented 10 years ago

Taking the marginal cost (given by the above step function) of the most expensive plant in use. NOTE: This is not how we do it now. Currently, we take the marginal cost of the next cheapest inactive plant.

I am not sure that makes things more realistic. It works for the interconnector case, but in all other cases it would be wrong.

If the interconnect provides us with a price, and everything else provides a cost, can we not have the best of both worlds by doing something like this?

if (last_used_participant provides a price)
  set price to last_used_participant.price
else
  set price to cheapest_inactive_participant.cost
ChaelKruip commented 10 years ago

can we not have the best of both worlds by doing something like this?

:+1: :+1:

AlexanderWirtz commented 10 years ago

:+1:

ChaelKruip commented 10 years ago
if (last_used_participant provides a price)
  set price to last_used_participant.price
else
  set price to cheapest_inactive_participant.cost

Thinking a bit more about it there are three cases:

  1. The participant is an interconnector: price is set to the price curve of the interconnector
  2. The participant is a dispatchable plant and it is not using the last 'step' of its marginal cost function (as defined above and in https://github.com/quintel/merit/issues/109): use the next step in the step function to find the price
  3. The participant is a dispatchable plant and it is using the last 'step' of its marginal cost function: take the marginal cost from the (first step) of the marginal cost step function of the next cheapest participant

This is quite ugly in my opinion.

One option to make it less ugly, is to use the step function for all participants (as suggested in the second bullet of https://github.com/quintel/merit/issues/107#issuecomment-48447161) but with this change: instead of the current step, we use the 'next step' (or we scale the steps up by one increment) except for the last step which we set to the marginal cost of the next participant.

The drawback of this approach is, however, that whomever is the 'next participant' can change! So, the last step of the step function would needed to be updated whenever the user touches a slider.

ChaelKruip commented 10 years ago

Another thing to keep in mind: we currently have a uniquely defined merit order (sorted on marginal cost). If plant A has a lower marginal cost than plant B, B will follow A in the merit order.

But what happens if in this new description the highest point of the step function of plant A is actually higher than the lowest point of plant B? This can happen if the difference between the 'mean marginal cost' of the two plants is smaller than the spread around those means.

We could decide to make the spread strictly smaller than the difference between the 'mean marginal costs' of two adjacent plants.

antw commented 10 years ago

Another thing to keep in mind: we currently have a uniquely defined merit order (sorted on marginal cost). If plant A has a lower marginal cost than plant B, B will follow A in the merit order.

But what happens if in this new description the highest point of the step function of plant A is actually higher than the lowest point of plant B?

Marginal costs being anything other than a simple number – such as a curve or function – present us with a performance problem.

Currently, we sort the participants once according to their marginal cost, and then calculate the merit order for the year. If the marginal cost can vary in each point (one point for every hour in the year), then we instead have to sort the participants in every point. Instead of doing it once, we have to sort them 8760 times!

The result of this is an increase in the calculation time from 100ms, to roughly 250ms. This is not a problem for the convergence project where the calculations are done offline, but it is in ETEngine where it represents a 50% increase in the response time.

ChaelKruip commented 10 years ago

If the marginal cost can vary in each point (one point for every hour in the year), then we instead have to sort the participants in every point. Instead of doing it once, we have to sort them 8760 times!

This is not the case! The sorting routine needs to be evaluated only once to determine the merit order. It is just that instead of 1 marginal cost per plant type, we would have a range of marginal costs per plant type with the step function.

We need to make sure, however, that the end of the step function of the cheaper plant (A) is still lower than the beginning of the more expensive plant (B):

                                                              
                                                  +------+    
                                                  |      |    
                                            +-----+      |    
                                            |            |    
                                            |            |    
                                      +-----+            |    
                                      |                  |    
                                      |                  |    
                               +------+                  |    
                       +------++                         |    
                       |      ||                         |    
                 +-----+      ||                         |    
                 |            ||                         |    
                 |            ||                         |    
           +-----+            ||                         |    
           |                  ||                         |    
           |                  ||                         |    
    +------+                  ||                         |    
    |                         ||                         |    
    |                         ||                         |    
    |          A              ||            B            |    
    |                         ||                         |    
    |                         ||                         |    
    |                         ||                         |    
    +-------------------------++-------------------------+    
                                                              
ChaelKruip commented 10 years ago

The only moment where the step function actually comes into play is when the electricity price (and the profitability of the plants) is calculated.

ChaelKruip commented 10 years ago

Part of https://github.com/quintel/merit/issues/104

ChaelKruip commented 10 years ago

Closing this ticket as it has become too big and non-atomic.