pypsa-meets-earth / pypsa-earth

PyPSA-Earth: A flexible Python-based open optimisation model to study energy system futures around the world.
https://pypsa-earth.readthedocs.io/en/latest/
230 stars 184 forks source link

Implement csp technology #145

Closed davide-f closed 4 months ago

pz-max commented 2 years ago

This is also needed in PyPSA-Eur-Sec and requires an Atlite expansion. https://github.com/PyPSA/pypsa-eur/issues/225

pz-max commented 2 years ago

@euronion is working on that

pz-max commented 2 years ago

The CSP PR is on the way https://github.com/PyPSA/atlite/pull/194 @euronion do you think we can integrate in the next 10 days a preliminary CSP version into PyPSA-Africa? Or how long you think it takes? Could be smt. we would show in the paper.

pz-max commented 2 years ago

The CSP power plant implementation (design include: solar receiver, thermal storage and power block) for PyPSA-Earth depends on the heat transfer fluid. See more in this report.

euronion commented 2 years ago

Sorry for not finding the time to tackle this. If you want to implement it you can have a look at this code:

All make (general) assumptions on HTF, receiver, field and power block.

pz-max commented 8 months ago

Light to Heat (Link) = Receiver Heat to Store (Link) = Sometimes Heat exchanger, not always necessary Molten Storage Tank (Store) = Hot Molten Salt Store -> Heat (Link) = Sometimes Heat exchanger, not always necessary Heat_salt to Heat_water (Link) = Heat exchanger Heat_water to electricity (Link) = Power block

ekatef commented 8 months ago

@GbotemiB @pz-max, thanks for the great discussion.

As agreed, it makes sense to look into the current implementation of the generation and storage technologies. The following parts could be a good start. 1) Evaluate the renewable potential in build_renewable_profiles: https://github.com/pypsa-meets-earth/pypsa-earth/blob/413e3fe643a4a9903e145a3853a81cb5944d62a5/scripts/build_renewable_profiles.py#L685-L707

2) Attach RES generation: https://github.com/pypsa-meets-earth/pypsa-earth/blob/413e3fe643a4a9903e145a3853a81cb5944d62a5/scripts/add_electricity.py#L309-L317

3) Attach storage as a combination of Stores and Links into attach_wind_and_solar, while it's possible to take a representation concept for storage from add_extra_components: https://github.com/pypsa-meets-earth/pypsa-earth/blob/413e3fe643a4a9903e145a3853a81cb5944d62a5/scripts/add_extra_components.py#L114-L144

to add to a definition for CSP in attach_wind_and_solar, after Generator is added.

GbotemiB commented 8 months ago

Thanks Katia

GbotemiB commented 8 months ago

Here is a block diagram of CSP plant with the main functional elements

image

GbotemiB commented 8 months ago

@ekatef @davide-f @pz-max Here is the block diagram translated into pypsa components. I am open to corrections and review

image

davide-f commented 7 months ago

That's a great detailed draft @GbotemiB :D As a comment, I'd slightly simplify the formulation to hopefully make it faster to compute.

I'd confirm a generator to model the input heat and a store where you placed the first one. I'd instead drop the heat store as it can be combined with the other store energy-wise, boyh connected to a new bus, e.g. csp bus. Then, a link can be used to connect the internal csp bus to the electricity bus.

What fo you think?

GbotemiB commented 7 months ago

Thanks @davide-f,

For clarity, you mean merging the solar bus and the thermal bus into a single bus (CSP internal bus), which will have a generator and a store, which will be connected to the Steam bus (Electricity bus), right?

davide-f commented 7 months ago

Thanks @davide-f,

For clarity, you mean merging the solar bus and the thermal bus into a single bus (CSP internal bus), which will have a generator and a store, which will be connected to the Steam bus (Electricity bus), right?

Yeah, I don't see now the benefit of having the two divided. Happy to disagree :) I saw @pz-max proposed the structure with the two buses. Do you have some idea on how to use the two? To me it seems more stuff to size and parameters which may not be so necessary

pz-max commented 7 months ago

Probably good to write a small PyPSA example to test if everything works @GbotemiB

I would probably do something like this maybe with naming that fits to the PyPSA-Earth/Eur convention: mermaid-diagram-2024-03-05-105735

You can reproduce the above image/ adjust it using Mermaid and copy&paste the below code:

flowchart TD
    A(Receiver - Generator) --> B{Thermal - Bus}
    Y{Storage - Bus} <-->|E.g. Heat Exchanger 
    Charge/Discharge Link|B
    Z(E.g. Salt Tank - Store) --> Y 
    B --> |E.g. Powerblock - Link|C{Electricity Bus}
GbotemiB commented 7 months ago

@pz-max @davide-f This is a simple pypsa example with the block diagram Max drew.

n = pypsa.Network()
n.add("Bus", "storage_bus", carrier="heat")
n.add("Bus", "thermal_bus", carrier="heat")
n.add("Bus", "electricity_bus", carrier="AC")

n.add("Link", "heat_exchanger", bus0="storage_bus", bus1="thermal_bus")
n.add("Link", "power_block", bus0="thermal_bus", bus1="electricity_bus")

n.add("Generator", "receiver", bus="thermal_bus")

n.add("Store", "salt_tank", bus="storage_bus")

n.add("Carrier", "heat")
n.add("Carrier", "AC")
ekatef commented 7 months ago

@pz-max @davide-f This is a simple pypsa example with the block diagram Max drew.

n = pypsa.Network()
n.add("Bus", "storage_bus", carrier="heat")
n.add("Bus", "thermal_bus", carrier="heat")
n.add("Bus", "electricity_bus", carrier="AC")

n.add("Link", "heat_exchanger", bus0="storage_bus", bus1="thermal_bus")
n.add("Link", "power_block", bus0="thermal_bus", bus1="electricity_bus")

n.add("Generator", "receiver", bus="thermal_bus")

n.add("Store", "salt_tank", bus="storage_bus")

n.add("Carrier", "heat")
n.add("Carrier", "AC")

Hello @GbotemiB!

I think @pz-max has intended to demonstrate your a nice way of plotting without any intention to take-over the discussion on the CRS design 🙂

My feeling it's better to go step-by-step. Could you please:

  1. Revise the design to account for the changes on which you have agreed with @davide-f? It would be very handy to keep track of events. (Personally, I'm not completely sure the ideas of your both! 🙃)
  2. Implement this design draft as a minimal working example, according to what @pz-max has suggested.

Keep in mind please that there is also need to keep connection of the implementation with the processes you are trying to reproduce. Imagine that you are telling a story with a diagram, which you need make live with a code implementation. Like: there is some solar power being transferred to a receiver which will be used to feed some load... Would be also great to have some meaningful outputs to check that your example is working. Can you do that?

GbotemiB commented 7 months ago

I got confused earlier. Thanks @ekatef. I have reproduced the design suggested by @davide using Mermaid Mermaid

GbotemiB commented 7 months ago

This is the adjusted sample for pypsa-network

# initialize network
n = pypsa.Network()

# add buses
n.add("Bus", "csp_internal_bus", carrier="heat", v_nom=20.0)
n.add("Bus", "electricity_bus", carrier="AC", v_nom=18.0)

# add links
n.add("Link", "power_block", bus0="csp_internal_bus", bus1="electricity_bus")

# add generator and store
n.add("Generator", "receiver", bus="csp_internal_bus", p_set=100, control="PQ")
n.add("Store", "salt_tank", bus="csp_internal_bus")

# add carriers
n.add("Carrier", "heat")
n.add("Carrier", "AC")

# add load
n.add("Load", "external_load", bus="electricity_bus", p_set=100)

I don't have an idea on how to generate outputs from the code.

I have tried using n.pf() and n.optimize(), but it generates error.

ekatef commented 7 months ago

Hey @GbotemiB!

Great that you have made Mermaid work. It'll be definitely helpful for more advanced stages. However I have an impression that it may be too early to use it on a stage of brainstorming.

Could you please go back to you initial drawing and modify starting from your previous "empiric" draft?

GbotemiB commented 7 months ago

Here is the revised block diagram, what are your thoughts @davide-f @pz-max @ekatef image

ekatef commented 7 months ago

Here is the revised block diagram, what are your thoughts @davide-f @pz-max @ekatef !

Hey @GbotemiB, perfect! My feeling is that it's quite clear now.

I think, we also need to define carriers, which should be heat for the left part of the diagram and electricity for the right part, as you have still defined in the implementation. Apart of that, we also need to set a time-varying input for the receiver (to roughly account for day/night oscillations) and some load. We must also account for some losses in the store and a limited efficiency of heat-to-power transformation (depending on a particular design, that should be something around 0.3..0.6).

To state a problem for a mini-optimisation study, we may assume that the load is fixed, while we need to define a cost-optimal size of a receiver and a storage. What do you think?

You can check pypsa examples for some inspiration on the technical part.

GbotemiB commented 7 months ago

Hi @ekatef @pz-max @davide-f

Here is another revised block diagram for the csp design. Ready for review image

GbotemiB commented 7 months ago

Hello @davide-f @pz-max @ekatef

I have created a simple pypsa example in my repo here for easy review. Here is the notebook with the csp design https://github.com/GbotemiB/csp-design/blob/main/csp.ipynb

davide-f commented 7 months ago

Cool @GbotemiB , good idea!

So:

By doing so, we could represent the csp with an additional bus, 1 generator, 1 store and 1 link. That could be a quite compact formulation :D

What do you all think?

GbotemiB commented 7 months ago

@davide-f, thanks for the review.

image

I have also updated the notebook here

How does it look now?

davide-f commented 7 months ago

That sounds great :D

ekatef commented 7 months ago

Perfect @GbotemiB @davide-f! Look like an elegant solution 😄

I wonder if it would make the model much more computationally expensive, if we keep the second generator in the CSP scheme? Agree that it looks nice and minimalistic without, but:

  1. Link component completely neglects with any operational effects which we may be interested to account for the steam power block. As we discussed before, a steam turbine is quite a sensitive technology in respect to the changes in the input parameters and operation under partial load. There are definitely fine effects which someone may want to consider. For people interested in them, it would look like an over-simplification if we would just exclude by design an option to account for the effects their may be interested in.
  2. From a users perspective, one of the most annoying tasks when analysing model outputs now is extraction of generation for hydro reservoirs. While for all other generators all you need is n.generators, for big hydro you need to remember whether to look into storages or storage units and add an additional procedure to deal with that. I recognise that it sounds rather fussy for modellers, but if we aim for a good software design, that is one of the anti-patterns when a user's is distracted from her/his goal by the need to account for a reach internal world of the software. If I get the current idea properly, it means that a user would need also to remember to extract generation from links. Are we sure that having a slimmer CSP design is worth it?

Could it be probably a good solution to have two representation of CSP: a more elegant and a more detailed?

ekatef commented 7 months ago

Thank you for the great discussion @davide-f and @GbotemiB!

As we discussed, adding a second Generator component would mean double-counting of the energy inputs. We can play around with the configuration like modeling a generator as an electric generator from the very start. However, it feels like quite an over-complication.

The design which was elaborated before (the picture above) seems to be an optimal one. So, let's stick to it 🙂

ekatef commented 7 months ago

Hello @GbotemiB!

A couple of suggestions on how to finalise CSP example: 1) having time-varying inputs may be helpful to get a feeling how does the model work in dynamics; 2) two major components for introducing the time dimensions are network.set_snapshots(index) and a definition of p_max_pu as a time-series; 3) PyPSA examples can be helpful, e.g. BEV charging.

It would be great to finalise the notebook to have CSP implementation documented 👍🏽

As a development goal, we need to integrate the resulted CSP model into the existing workflow, as we discussed above. Happy to support, if needed 🙂

GbotemiB commented 7 months ago

Hi @ekatef, @davide-f, @pz-max

I have included the suggestions into the design implementation here

I have also translated the block diagram into mermaid

ekatef commented 7 months ago

here

Hello @GbotemiB!

Perfect! I think, there is a bit of overshoot to set-up p_max_pu for the link. Agree that there may be some delicate points in how the steam turbine is operating, but in the base generic CSP configuration, we can happily neglect with them. Otherwise, looks good. You can plot time-series of the generation, load and storage to get a feeling on what is going inside (look into PyPSA BEV changing example for inspiration ;) ).

My feeling is that we are ready to start CSP implementation into the PyPSA-Earth codebase 😄