EnergySystemsModellingLab / MUSE_OS

Welcome to the MUSE-OS repository
https://muse-os.readthedocs.io/en/latest/
GNU General Public License v3.0
22 stars 9 forks source link

[BUG] LOCE calculation is incorrect when more than one time slice is present #246

Closed ahawkes closed 4 months ago

ahawkes commented 7 months ago

Describe the bug

A clear and concise description of what the bug is, including error messages.

Email from Sara G: "to calculate the lcoe, all the costs are calculated and then allocated to the timeslices. Installation-related capital, fixed, and variable costs are therefore distributed over the timeslices. The costs are summed up and then divided over the energy produced by timeslice. When there is zero production in a timeslice, to avoid zero division in the algorithm, a very small epsilon amount is used. This can cause the big number in the output."

This is an error because a zero output in a time slice is a common situation. E.g. solar power at night.

The "big number" result should only happen when total output over the whole year approaches zero.

To Reproduce

Steps to reproduce the behavior. Attache any input file that might be required.

Add a technology with zero output in a time slice. There needs to be more than one time slice.

Expected behavior

A clear and concise description of what you expected to happen.

The correct approach here is (I think - please feel free to pursue workable alterantives):

1) calculate variable cost (fuel, variable O&M, CO2, etc) in each time slice 2) calculate non-variable parts of cost (installation and fixed costs) and distribute across time slices in proportion to output. Note that if a time slice has zero output, none of these costs will be distributed to that time slice. 3) divide resulting value for each time slice by the output in that time slice (except where output is zero, to avoid a divide by zero error - if it's zero then set LCOE to zero for that time slice)

In the above we would also need to check what happens for cases where output is very very small but not zero - could be unstable.

Screenshots

If applicable, add screenshots to help explain your problem.

Context

Please, complete the following to better understand the system you are using to run MUSE.

dalonsoa commented 5 months ago
  1. calculate variable cost (fuel, variable O&M, CO2, etc) in each time slice
  2. calculate non-variable parts of cost (installation and fixed costs) and distribute across time slices in proportion to output. Note that if a time slice has zero output, none of these costs will be distributed to that time slice.
  3. divide resulting value for each time slice by the output in that time slice (except where output is zero, to avoid a divide by zero error - if it's zero then set LCOE to zero for that time slice)

@ahawkes , I've tried to do this, but I'm afraid the result is not what you were expecting. If we set the LCOE for a particular timeslice to zero, the investing algorithm concludes it is super cheap to invest into that technology and will try to install it. Naturally, when calculating how much extra capacity needs to be installed to match the demand, the result is infinite as there is no production during that timeslice, hitting the following error:

muse.errors.GrowthOfCapacityTooConstrained: Error during the investment process. 
The capacity was not allowed to grow sufficiently in order to match the demand. 
Consider increating the MaxCapacityAddition and/or the MaxCapacityGrowth in the technodata.

The main problem I can see is that we are calculating the maximum capacity required to fulfill the demand on a timeslice basis, and then using NREL formula where the utilisation factor (or capacity factor, as they call it) is meant to be an average value over a whole year. An utilisation factor for such a granular timeslice does not makes sense in the light of this calculation, as far as I can tell.

Indeed, calculating the LCOE at the timeslice level seems odd. It is a magnitude used to measure the cost of a technology over its lifetime, so it is not surprising that if calculated at a short enough timescale levels, the results are nonesense.

I wonder if the LCOE should be timeslice independent and if we should be averaging the values (utilisation factor and production) over the whole year, using appropriate weightings based on the timeslices, in order to calculate the results.

What do you think, @ahawkes ?

ahawkes commented 5 months ago

@dalonsoa right - yes the time slice level LCOE is indeed nonsense (though see side-note on this below). LCOE is calculated over the lifetime of the asset. So if we look at a single year, we should figure out utilisation by (a) calculating the output of the technology over all time slices, (b) dividing this by the maximum annual output (which is determined by its capacity). So yes, I think your proposed solution is correct.

The side-note is this: I believe LCOE is (or can) be used to calculate time-sliced commodity prices. In this case, it does make sense to calculate LCOE at time slice level, but it has to be done using the method I set out above (which avoids divide by zero errors, and does not distribute non-variable costs to time slices that do not have output).

dalonsoa commented 5 months ago

OK, I'll implement the solution I suggest for now and see what we get.

About the side note, I'm not entirely sure what you mean. Keeping aside mathematical errors, which are avoided with your method, having an LCOE equal to zero in a time slice will be somewhat misleading to calculate commodity prices in that time slice. Thinking on solar energy, it is not the case that it costs nothing at night, is that there's no energy to buy!

ahawkes commented 5 months ago

Thanks. That's a good point, and could be an issue in some circumstances.

The price calculation is important to determine internal commodity prices, which are then used in calculation of investment-related LCOE (and other objectives) of assets that consume those commodities, and so-on. The issue you describe would only be an issue where no commodity is produced by any technology in a time slice - which is very unlikely in a standard systems model - but could be an issue if the framework is used in unexpected ways (which is entirely possible).

For asset investment LCOE calculation, the change proposed here will make the LCOE just a single value that depends on annual utilisation (so essentially its the same in every time slice).

For the commodity price calculation (which presumably happens elsewhere in MUSE), where the commodity price is assumed to be based on LCOE (I think there are options here, it's either LCOE-based or marginal price based, where marginal price is variable costs only), there are a few defensible ways to do this. One could (a) use the output-weighted average LCOE of every asset contributing in the time slice, or (b) use the highest LCOE of all assets contributing in a time slice. Then we come to your question - if all assets have zero output of the commodity in a time slice, what do we do? I think we would need to break that down into a few cases, (1) where all of the available assets (including all possible new assets) have an upper bound of output in that time slice of zero, then price should be infinite because there's simply no way to get that commodity in that time slice, and (2) where there are available assets that could produce the commodity in that time slice (but aren't doing so yet), it perhaps should the LCOE or marginal cost of the cheapest one (though this is debateable - actual price will depend on which asset is actually chosen). Anyway, it seems like this price issue is not the one you're dealing with in relation to this bug - rather you are looking at the asset investment - and have found a serious issue there. Should a new issue be raised for this price calculation problem?

dalonsoa commented 5 months ago

I think this should be doable. The LCOE used for investment is done in here, while the one used for calculating commodity prices is done in this other place, so it should be possible to implement the logic you indicate. It will be useful to do it in two separate issues, yes, so we have the chance to properly asses the code changes related to one of the changes.

Indeed, we should start with the second one, changing the commodity prices calculation so it uses a more robust logic when the utilization factor is zero for one or more timeslice, and then change the investment part. Otherwise, we might end up with the situation commented above of having preferred technologies to invest because of its low price in a timeslice that have no production in that timeslice.

Update: second issue is #288

ahawkes commented 5 months ago

Thanks Diego,

Actually the investment part is a higher priority, as every model out there right now is making serious mistakes. The commodity price issue is important, but would only apply in outlier cases I think. Can we deal with the investment part ASAP, check it, and do a release to fix for users?

Also can we check if any other investment objectives are calculated for each time slice when they should be annual?

Note if there is a release there is knock on impact for @Bland, @.***> work - as presumably examples will change - with knock on updates needed for documentation and OU course. Hmmm, not sure what to do about that - as there will be further releases with further knock on changes.

P.S. perhaps there’s also a further issue with investment in that one does not know dispatch when objectives are being calculated? Can you let me know what is assumed in this regard? Does it assume upper bound of output in each time slice when calculating utilisation, or does it somehow use actual dispatch (and if so, how is this known at the point objectives are calculated)? Note this is an issue that I think the approach in MUSE 2.0 will largely solve, but still we need a defensible approach in MUSE 1.x


From: Diego Alonso Álvarez @.> Sent: Friday, May 3, 2024 10:56:26 AM To: EnergySystemsModellingLab/MUSE_OS @.> Cc: Hawkes, Adam D @.>; Mention @.> Subject: Re: [EnergySystemsModellingLab/MUSE_OS] [BUG] LOCE calculation is incorrect when more than one time slice is present (Issue #246)

This email from @.*** originates from outside Imperial. Do not click on links and attachments unless you recognise the sender. If you trust the sender, add them to your safe senders listhttps://spam.ic.ac.uk/SpamConsole/Senders.aspx to disable email stamping for this address.

I think this should be doable. The LCOE used for investment is done in here, while the one used for calculating commodity prices is done in this other place, so it should be possible to implement the logic you indicate. It will be useful to do it in two separate issues, yes, so we have the chance to properly asses the code changes related to one of the changes.

Indeed, we should start with the second one, changing the commodity prices calculation so it uses a more robust logic when the utilization factor is zero for one or more timeslice, and then change the investment part. Otherwise, we might end up with the situation commented above of having preferred technologies to invest because of its low price in a timeslice that have no production in that timeslice.

— Reply to this email directly, view it on GitHubhttps://github.com/EnergySystemsModellingLab/MUSE_OS/issues/246#issuecomment-2092496081, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AC37JLNN4OT2NNDAKWBOC5LZAM7KVAVCNFSM6AAAAABD5VPHZ2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJSGQ4TMMBYGE. You are receiving this because you were mentioned.Message ID: @.***>

dalonsoa commented 5 months ago

As far as I can tell, most - if not all - of the objectives are timeslice dependent and have always been that way checking the commit history. LCOE, NPV, NPC, EAC... all are provided as a function of the timeslices.

On the dispatch, that is indeed not known. The way this is done (and the NPV does the same) is to calculate what the minimum capacity would be if the maximum demand were to be fulfilled by a particular technology on each timeslice. This capacity is then used to calculate the production and all the other costs:

The LCOE is then calculated as sum(all_costs)/production. As capacity and production are timeslice dependent, so is the LCOE.

It will be useful if you could review the existing code in the links above to make sure that we are addressing the right problem - the dependence on the timeslices - and that there's nothing else going on. As I said above this part of MUSE was coded over 4 years ago by Mayeul and has not been touched ever since, so I'm a bit surprised that an incorrect behavior here has not been flagged a long time ago since this is used by every single model that uses the LCOE.

What I'm trying to do, now, is to calculate yearly averaged values over timeslices of the capacity and the production, so the LCOE becomes timeslice independent.

dalonsoa commented 5 months ago

I've made the change and get the LCOE timeslice independent, but I also hit the error I pointed out above during the investment process, GrowthOfCapacityTooConstrained. This is not surprising if the objective (LCOE) for the problematic technology (windturbine in the tests I'm running) is favourable but there is no production for some timeslices. It just will not be possible to meet the demand with the most favourable technology based on a timeslice-independent LCOE.

I'll keep trying next week, but we might need a dedicated technical meeting (not the regular meeting) to discuss how to tackle this.

ahawkes commented 4 months ago

Thanks Diego, I think we need a meeting about this. But for now: LCOE and other objectives would need time slice information to be calculated correctly (even if dispatch is not known at the time they are calculated). If dispatch is not known, one approach would be to figure out LCOE by assuming maximum dispatch (where maximum dispatch in any time slice is given by input data - and might be zero in some time slices). This LCOE should be independent of the capacity ultimately installed. Another approach would be to look at the demand profile to be served, and then figure out maximum demand served in each time slice (function of input data which limits tech output in a time slice, and flexibility of that output, but also function of how much demand there is remaining in each time slice) - which would give utilisation, from which we can calculate LCOE.

Growth constraints could be reached as you’ve seen. But in those cases the model would need to have access to another technology to fill the gaps that the one with lower LCOE cannot serve.

It would also be good to know how the model was working previously. Did Mayuel calculate LCOE for each time slice and then take a weighted average to get overall annual LCOE (which is wrong but not super wrong)? Or did he somehow use LCOE for a single time slice (which is super wrong) - and if he did this how did he decide which time slice LCOE to use?

Thanks!


From: Diego Alonso Álvarez @.> Sent: Friday, May 3, 2024 4:51:16 PM To: EnergySystemsModellingLab/MUSE_OS @.> Cc: Hawkes, Adam D @.>; Mention @.> Subject: Re: [EnergySystemsModellingLab/MUSE_OS] [BUG] LOCE calculation is incorrect when more than one time slice is present (Issue #246)

This email from @.*** originates from outside Imperial. Do not click on links and attachments unless you recognise the sender. If you trust the sender, add them to your safe senders listhttps://spam.ic.ac.uk/SpamConsole/Senders.aspx to disable email stamping for this address.

I've made the change and get the LCOE timeslice independent, but I also hit the error I pointed out above during the investment process, GrowthOfCapacityTooConstrained. This is not surprising if the objective (LCOE) for the problematic technology (windturbine in the tests I'm running) is favourable but there is no production for some timeslices. It just will not be possible to meet the demand with the most favourable technology based on a timeslice-independent LCOE.

I'll keep trying next week, but we might need a dedicated technical meeting (not the regular meeting) to discuss how to tackle this.

— Reply to this email directly, view it on GitHubhttps://github.com/EnergySystemsModellingLab/MUSE_OS/issues/246#issuecomment-2093065285, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AC37JLL76TXYT7TLUCQGOY3ZAOI5JAVCNFSM6AAAAABD5VPHZ2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJTGA3DKMRYGU. You are receiving this because you were mentioned.Message ID: @.***>