This tutorial will introduce the user into the pandapipes datastructure and how to create networks through the pandapipes API. The following minimal example contains the most common elements that are supported by the pandapipes format.
The datastructure of the pandapipes framework is based on the Python library pandas. A pandapipes network consist of separate tables for each component type that is used in the network and each table holds the elements of its component type. Each row is indexed and represents a single element. The parameters are organized in columns.
By executing the follwing code cells you generate the different component tables. You can find detailed descriptions about each parameter in the pandapipes documentation under bulletpoint "Datastructure and Components".
First, we import pandapipes and create an empty network: We have to state the name of the fluid for the network. In pandapipes, some fluids are already pre-defined, e.g. hgas, lgas (high and low calorific natural gas), hydrogen, water, and air, but you can also create your own fluid if you prefer (tutorial in preparation).
In this example, we will create a medium pressure gas network and choose lgas from the predefined fluids in pandapipes.
import pandapipes as pp
net = pp.create_empty_network(fluid="lgas") # create an empty network
This network does not hold any elements yet. It serves as a container for the component tables and network specific parameters.
We will now use the create functions to create elements. They will be automatically added to the respective tables.
We now create 6 junctions with an intital pressure for the pipeflow calculation of 1.0 bar. For improved readability, we add names (optional).
junction1 = pp.create_junction(net, pn_bar=1.0, tfluid_k=293.15, name="Connection to External Grid") junction2 = pp.create_junction(net, pn_bar=1.0, tfluid_k=293.15, name="Junction 2") junction3 = pp.create_junction(net, pn_bar=1.0, tfluid_k=293.15, name="Junction 3") junction4 = pp.create_junction(net, pn_bar=1.0, tfluid_k=293.15, name="Junction 4") junction5 = pp.create_junction(net, pn_bar=1.0, tfluid_k=293.15, name="Junction 5") junction6 = pp.create_junction(net, pn_bar=1.0, tfluid_k=293.15, name="Junction 6")
The junctions are now in the net and can be called. Some parameters were filled with default values.
net.junction # show junction table
All create functions return the pandapipes index of the element that was created, for example the variable junction1 is now equal to the index of the junction with the name "Connection to External Grid" (which is 0):
We use these variables for creating bus and branch elements in the following.
We now create a medium pressure external grid connection that serves as slack node for the pipe flow calculation. The pressure is set to 1.1 bar:
medium_pressure_grid = pp.create_ext_grid(net, junction=junction1, p_bar=1.1, t_k=293.15, name="Grid Connection") net.ext_grid # show external grid table
The network includes 5 pipes between two junctions each. The junctions and pipes lengths are defined in the network diagram:
For all pipes we want a diameter of 300 mm.
pipe1 = pp.create_pipe_from_parameters(net, from_junction=junction1, to_junction=junction2, length_km=10, diameter_m=0.3, name="Pipe 1") pipe2 = pp.create_pipe_from_parameters(net, from_junction=junction2, to_junction=junction3, length_km=2, diameter_m=0.3, name="Pipe 2") pipe3 = pp.create_pipe_from_parameters(net, from_junction=junction2, to_junction=junction4, length_km=2.5, diameter_m=0.3, name="Pipe 3") pipe4 = pp.create_pipe_from_parameters(net, from_junction=junction3, to_junction=junction5, length_km=1, diameter_m=0.3, name="Pipe 4") pipe5 = pp.create_pipe_from_parameters(net, from_junction=junction4, to_junction=junction6, length_km=1, diameter_m=0.3, name="Pipe 5")
The full pipe table looks like this:
net.pipe # show pipe table
The parameters from_junction and to_junction define the orientation of the pipe. If the fluid streams in fact from the from_junction to to_junction, the resulting fluid velocity is positive. If the fluid stream direction is opposite, the resulting velocity is negative.
There is one valve between Junction 5 and Juncion 6. It is open so that the gas can circulate.
valve = pp.create_valve(net, from_junction=junction5, to_junction=junction6, diameter_m=0.3, opened=True)
As we see in the valve table below the default value for the loss_coefficient of the valve is zero. Also, all valves have a length of 0 meter, because we consider ideal valves. However, if needed you can change the loss_coefficient parameter.
net.valve # show valve table
The sink element is used to model by default a constant consumption. We create here a gas consumption sink with a mass flow of 545 gramm per second. Sinks and sources always have to be assigned to a particular junction. The sign of the mass flow is positive.
sink = pp.create_sink(net, junction=junction4, mdot_kg_per_s=0.545, name="Sink 1") net.sink
The source element is used to model a generation of heat or gas. It could be for example a biogas plant that is directly connected to the gas network or a combined heat and power plant. In this example, we assume that a biogas plant is directly feeding into the gas grid with a constant value of 234 gramm per second. The sign of the mass flow is also positive.
source = pp.create_source(net, junction=junction3, mdot_kg_per_s=0.234, name="Source 1")
We are done. Now, the net includes all the elements from the picture.
Finally, the gas flow can be calculated with the
The results are written to
res_... tables. They were added to the
net # result tables have been added to the net
net.res_junction # calculated pressure and temperature at junctions
net.res_pipe # velocities, mass flows through pipes and other results