Exercises#

Set up a heat pump model using TESPy with the identical specifications as you have done previously in this exercise. The results in this section should be identical to those in the previous section, however, we should be able to find them much easier.

First, we import the necessary classes from TESPy and create the topology by adding the respective connections to the network instance.

from tespy.components import Compressor, SimpleHeatExchanger, Valve, CycleCloser
from tespy.connections import Connection
from tespy.tools.helpers import UserDefinedEquation
from tespy.networks import Network


nw = Network(T_unit="C", p_unit="bar", h_unit="kJ / kg", iterinfo=False)

cc = CycleCloser("cycle closer")
ev = SimpleHeatExchanger("evaporator")
cp = Compressor("compressor")
cd = SimpleHeatExchanger("condenser")
va = Valve("valve")

c1 = Connection(cc, "out1", ev, "in1", label="1")
c2 = Connection(ev, "out1", cp, "in1", label="2")
c3 = Connection(cp, "out1", cd, "in1", label="3")
c4 = Connection(cd, "out1", va, "in1", label="4")
c0 = Connection(va, "out1", cc, "in1", label="0")

nw.add_conns(c0, c1, c2, c3, c4)

Next we set up the initial parameters.

t_2 = 10
t_4 = 60
heat = -1e6
fluid = "R290"
eta_s = 0.8

c2.set_attr(fluid={fluid: 1}, x=1, T=t_2)
c4.set_attr(x=0, T=t_4)
cp.set_attr(eta_s=eta_s)
ev.set_attr(pr=1)
cd.set_attr(pr=1, Q=heat)

We can solve the model by calling the solve function on our network instance.

nw.solve("design")

The components’ information can be accessed via the val attribute. P is power and Q is heat.

cop = abs(cd.Q.val) / cp.P.val
cop
4.127148602008618

Now fix the compressor power input and remove the heat demand specification.

cp.set_attr(P=0.2e6)
cd.set_attr(Q=None)
nw.solve("design")
cd.Q.val
-825429.7204271422

Fix the heat demand back to the original value and unset the condensation temperature, it will be a result of the calculation.

cd.set_attr(Q=-1e6)
c4.set_attr(T=None)
nw.solve("design")
c4.T.val
52.33872548735076

If topologies get more complex and we do not know the amount of heat and power directly, but we want to achieve a specific COP anyways, we can define our own equations and pass them into our model.

First we define the COP equation:

\[0 = \left(h_2 - h_3 \right) - \text{COP} \cdot \left(h_2 - h_1\right)\]

Then we create the Jacobian for that equation and put it inside a function as well.

\[\begin{split}\begin{align} \frac{\partial}{\partial h_1} = &\;\text{COP}\\ \frac{\partial}{\partial h_2} = &\; 1-\text{COP}\\ \frac{\partial}{\partial h_3} = &\;-1 \end{align}\end{split}\]
def cop_ude(ude):
    c1, c2, c3 = ude.conns
    cop = ude.params["cop"]
    return (c2.h.val_SI - c3.h.val_SI) - cop * (c2.h.val_SI - c1.h.val_SI)


def cop_jacobian(ude):
    c1, c2, c3 = ude.conns
    if c1.h.is_var:
        ude.jacobian[c1.h.J_col] = cop
    if c2.h.is_var:
        ude.jacobian[c2.h.J_col] = 1 - cop
    if c3.h.is_var:
        ude.jacobian[c3.h.J_col] = -1

We can unset the condenser heat specification again and create a UserDefinedEquation with a cop specification of 5.

cd.set_attr(Q=None)


ude = UserDefinedEquation("cop-ude", cop_ude, cop_jacobian, [c2, c3, c4], {"cop": 5})
nw.add_ude(ude)

nw.solve("design")

This should give us a COP of 5.

abs(cd.Q.val) / cp.P.val
5.000000000000051