Beispiel #1
0
    def initialise_target(self, c, key):
        r"""
        Return a starting value for pressure and enthalpy at inlet.

        Parameters
        ----------
        c : tespy.connections.connection.Connection
            Connection to perform initialisation on.

        key : str
            Fluid property to retrieve.

        Returns
        -------
        val : float
            Starting value for pressure/enthalpy in SI units.

            .. math::

                val = \begin{cases}
                4 \cdot 10^5 & \text{key = 'p'}\\
                h\left(p, 300 \text{K} \right) & \text{key = 'h' at inlet 1}\\
                h\left(p, 220 \text{K} \right) & \text{key = 'h' at outlet 2}
                \end{cases}
        """
        if key == 'p':
            return 50e5
        elif key == 'h':
            if c.target_id == 'in1':
                T = 300 + 273.15
                return h_mix_pT(c.get_flow(), T)
            else:
                T = 220 + 273.15
                return h_mix_pT(c.get_flow(), T)
Beispiel #2
0
    def energy_balance(self):
        r"""
        Calculate the residual in energy balance of the water electrolyzer.

        The residual is the negative to the necessary power input.

        Returns
        -------
        res : float
            Residual value.

            .. math::

                \begin{split}
                res = & \dot{m}_{in,2} \cdot \left( h_{in,2} - h_{in,2,ref}
                \right)\\ & - \dot{m}_{out,3} \cdot e_0\\
                & -\dot{m}_{in,1} \cdot \left( h_{out,1} - h_{in,1} \right)\\
                & - \dot{m}_{out,2} \cdot \left( h_{out,2} - h_{out,2,ref}
                \right)\\
                & - \dot{m}_{out,3} \cdot \left( h_{out,3} - h_{out,3,ref}
                \right)\\
                \end{split}

        Note
        ----
        The temperature for the reference state is set to 20 °C, thus
        the feed water must be liquid as proposed in the calculation of
        the minimum specific energy consumption for electrolysis:
        :func:`tespy.components.reactors.water_electrolyzer.calc_e0`.
        The part of the equation regarding the cooling water is implemented
        with negative sign as the energy for cooling is extracted from the
        reactor.

        - Reference temperature: 293.15 K.
        - Reference pressure: 1 bar.
        """
        T_ref = 293.15
        p_ref = 1e5

        # equations to set a reference point for each h2o, h2 and o2
        h_refh2o = h_mix_pT([1, p_ref, 0, self.inl[1].fluid.val], T_ref)
        h_refh2 = h_mix_pT([1, p_ref, 0, self.outl[2].fluid.val], T_ref)
        h_refo2 = h_mix_pT([1, p_ref, 0, self.outl[1].fluid.val], T_ref)

        val = (self.inl[1].m.val_SI * (self.inl[1].h.val_SI - h_refh2o) -
               self.outl[2].m.val_SI * self.e0 -
               self.inl[0].m.val_SI * (self.outl[0].h.val_SI -
                                       self.inl[0].h.val_SI) -
               self.outl[1].m.val_SI * (self.outl[1].h.val_SI - h_refo2) -
               self.outl[2].m.val_SI * (self.outl[2].h.val_SI - h_refh2))
        return val
Beispiel #3
0
    def initialise_target(self, c, key):
        r"""
        Return a starting value for pressure and enthalpy at inlet.

        Parameters
        ----------
        c : tespy.connections.connection.Connection
            Connection to perform initialisation on.

        key : str
            Fluid property to retrieve.

        Returns
        -------
        val : float
            Starting value for pressure/enthalpy in SI units.

            .. math::

                val = \begin{cases}
                5  \cdot 10^5 & \text{key = 'p'}\\
                h\left(T=293.15, p=5  \cdot 10^5\right) & \text{key = 'h'}
                \end{cases}
        """
        if key == 'p':
            return 5e5
        elif key == 'h':
            flow = c.get_flow()
            T = 20 + 273.15
            return h_mix_pT(flow, T)
Beispiel #4
0
    def initialise_source(self, c, key):
        r"""
        Returns a starting value for pressure and enthalpy at component's
        outlet.

        Parameters
        ----------
        c : tespy.connections.connection
            Connection to perform initialisation on.

        key : str
            Fluid property to retrieve.

        Returns
        -------
        val : float
            Starting value for pressure/enthalpy in SI units.

            .. math::

                val = \begin{cases}
                5  \cdot 10^5 & \text{key = 'p'}\\
                h\left(T=323.15, p=5  \cdot 10^5\right) & \text{key = 'h'}
                \end{cases}
        """
        if key == 'p':
            return 5e5
        elif key == 'h':
            flow = [c.m.val0, 5e5, c.h.val_SI, c.fluid.val]
            T = 50 + 273.15
            return h_mix_pT(flow, T)
Beispiel #5
0
def desuperheat(ude):
    ttd_min = ude.params['ttd_min']
    return (
        ude.conns[0].h.val_SI - ude.conns[1].h.val_SI -
        ude.params['distance'] * (
            ude.conns[0].h.val_SI - h_mix_pT(
                ude.conns[1].get_flow(),
                T_mix_ph(ude.conns[2].get_flow()) + ttd_min)))
Beispiel #6
0
    def energy_balance_func(self):
        r"""
        Calculate the energy balance of the diabatic combustion chamber.

        Returns
        -------
        residual : float
            Residual value of equation.

            .. math::

                \begin{split}
                0 = & \sum_i \dot{m}_{in,i} \cdot
                \left( h_{in,i} - h_{in,i,ref} \right)\\
                & -\dot{m}_{out,2}\cdot\left( h_{out,1}-h_{out,1,ref} \right)\\
                & + LHV_{fuel} \cdot\left(\sum_i\dot{m}_{in,i}\cdot
                x_{fuel,in,i}- \dot{m}_{out,1} \cdot x_{fuel} \right)
                \cdot \eta
                \end{split}\\

                \forall i \in \text{inlets}

        Note
        ----
        The temperature for the reference state is set to 25 °C, thus
        the water may be liquid. In order to make sure, the state is
        referring to the lower heating value, the state of the water in the
        flue gas is fored to gaseous.

        - Reference temperature: 298.15 K.
        - Reference pressure: 1 bar.
        """
        T_ref = 298.15
        p_ref = 1e5

        res = 0
        for i in self.inl:
            res += i.m.val_SI * (i.h.val_SI - h_mix_pT(
                [0, p_ref, 0, i.fluid.val], T_ref, force_gas=True))

        for o in self.outl:
            res -= o.m.val_SI * (o.h.val_SI - h_mix_pT(
                [0, p_ref, 0, o.fluid.val], T_ref, force_gas=True))

        res += self.calc_ti() * self.eta.val
        return res
Beispiel #7
0
    def initialise_source(self, c, key):
        r"""
        Return a starting value for pressure and enthalpy at outlet.

        Parameters
        ----------
        c : tespy.connections.connection
            Connection to perform initialisation on.

        key : str
            Fluid property to retrieve.

        Returns
        -------
        val : float
            Starting value for pressure/enthalpy in SI units.

            .. math::

                val = \begin{cases}
                10 \cdot 10^5 & \text{key = 'p'}\\
                h\left(p, 473.15 \text{K} \right) &
                \text{key = 'h' at outlet 1}\\
                h\left(p, 473.15 \text{K} \right) &
                \text{key = 'h' at outlet 2}\\
                h\left(p, 523.15 \text{K} \right) &
                \text{key = 'h' at outlet 3}
                \end{cases}
        """
        if key == 'p':
            return 10e5
        elif key == 'h':
            flow = c.to_flow()
            if c.source_id == 'out1':
                T = 200 + 273.15
                return h_mix_pT(flow, T)
            elif c.source_id == 'out2':
                T = 200 + 273.15
                return h_mix_pT(flow, T)
            else:
                T = 250 + 273.15
                return h_mix_pT(flow, T)
    def energy_balance_func(self):
        r"""
        Calculate the energy balance of the adiabatic combustion chamber.

        Returns
        -------
        residual : float
            Residual value of equation.

            .. math::

                \begin{split}
                0 = & \sum_i \dot{m}_{in,i} \cdot
                \left( h_{in,i} - h_{in,i,ref} \right)\\
                & -\dot{m}_{out,2}\cdot\left( h_{out,1}-h_{out,1,ref} \right)\\
                & + LHV_{fuel} \cdot\left(\sum_i\dot{m}_{in,i}\cdot
                x_{fuel,in,i}- \dot{m}_{out,1} \cdot x_{fuel} \right)
                \end{split}\\

                \forall i \in \text{inlets}

        Note
        ----
        The temperature for the reference state is set to 100 °C, as the
        custom fluid properties are inacurate at the dew-point of water in
        the flue gas!

        - Reference temperature: 373.15 K.
        - Reference pressure: 1 bar.
        """
        T_ref = 373.15
        p_ref = 1e5

        res = 0
        for i in self.inl:
            res += i.m.val_SI * (
                i.h.val_SI - h_mix_pT([0, p_ref, 0, i.fluid.val], T_ref))
        for o in self.outl:
            res -= o.m.val_SI * (
                o.h.val_SI - h_mix_pT([0, p_ref, 0, o.fluid.val], T_ref))

        return res + self.calc_ti()
Beispiel #9
0
    def energy_balance_deriv(self, increment_filter, k):
        r"""
        Partial derivatives for reactor energy balance.

        Parameters
        ----------
        increment_filter : ndarray
            Matrix for filtering non-changing variables.

        k : int
            Position of derivatives in Jacobian matrix (k-th equation).
        """
        # derivatives determined from calc_P function
        T_ref = 298.15
        p_ref = 1e5
        h_refh2o = h_mix_pT([1, p_ref, 0, self.inl[1].fluid.val], T_ref)
        h_refh2 = h_mix_pT([1, p_ref, 0, self.outl[2].fluid.val], T_ref)
        h_refo2 = h_mix_pT([1, p_ref, 0, self.outl[1].fluid.val], T_ref)

        # derivatives cooling water inlet
        self.jacobian[k, 0, 0] = self.inl[0].h.val_SI - self.outl[0].h.val_SI
        self.jacobian[k, 0, 2] = self.inl[0].m.val_SI

        # derivatives feed water inlet
        self.jacobian[k, 1, 0] = (self.inl[1].h.val_SI - h_refh2o)
        self.jacobian[k, 1, 2] = self.inl[1].m.val_SI

        # derivative cooling water outlet
        self.jacobian[k, 2, 2] = -self.inl[0].m.val_SI

        # derivatives oxygen outlet
        self.jacobian[k, 3, 0] = -(self.outl[1].h.val_SI - h_refo2)
        self.jacobian[k, 3, 2] = -self.outl[1].m.val_SI

        # derivatives hydrogen outlet
        self.jacobian[k, 4, 0] = -(self.outl[2].h.val_SI - h_refh2 + self.e0)
        self.jacobian[k, 4, 2] = -self.outl[2].m.val_SI

        # derivatives for variable P
        if self.P.is_var:
            self.jacobian[k, 5 + self.P.var_pos, 0] = 1
Beispiel #10
0
    def calc_parameters(self):
        r"""Postprocessing parameter calculation."""
        CombustionChamber.calc_parameters(self)

        T_ref = 298.15
        p_ref = 1e5

        res = 0
        for i in self.inl:
            res += i.m.val_SI * (i.h.val_SI - h_mix_pT(
                [0, p_ref, 0, i.fluid.val], T_ref, force_gas=True))

        for o in self.outl:
            res -= o.m.val_SI * (o.h.val_SI - h_mix_pT(
                [0, p_ref, 0, o.fluid.val], T_ref, force_gas=True))

        self.eta.val = -res / self.ti.val
        self.Q_loss.val = -(1 - self.eta.val) * self.ti.val

        if self.inl[1].p.val < self.inl[0].p.val:
            msg = (
                "The pressure at inlet 2 is lower than the pressure at inlet 1 "
                "at component " + self.label + ".")
            logging.warning(msg)
Beispiel #11
0
    def derivatives(self, vec_z):
        r"""
        Calculate partial derivatives for given equations.

        Returns
        -------
        mat_deriv : ndarray
            Matrix of partial derivatives.
        """
        ######################################################################
        # derivatives fluid, mass flow and reactor pressure are static
        k = self.num_nw_fluids * 4 + 5
        ######################################################################
        # derivatives for energy balance equations
        T_ref = 293.15
        p_ref = 1e5
        h_refh2o = h_mix_pT([1, p_ref, 0, self.inl[1].fluid.val], T_ref)
        h_refh2 = h_mix_pT([1, p_ref, 0, self.outl[2].fluid.val], T_ref)
        h_refo2 = h_mix_pT([1, p_ref, 0, self.outl[1].fluid.val], T_ref)

        # derivatives cooling water inlet
        self.mat_deriv[k, 0, 0] = -(
            self.outl[0].h.val_SI - self.inl[0].h.val_SI)
        self.mat_deriv[k, 0, 2] = self.inl[0].m.val_SI

        # derivatives feed water inlet
        self.mat_deriv[k, 1, 0] = (self.inl[1].h.val_SI - h_refh2o)
        self.mat_deriv[k, 1, 2] = self.inl[1].m.val_SI

        # derivative cooling water outlet
        self.mat_deriv[k, 2, 2] = - self.inl[0].m.val_SI

        # derivatives oxygen outlet
        self.mat_deriv[k, 3, 0] = - (self.outl[1].h.val_SI - h_refo2)
        self.mat_deriv[k, 3, 2] = - self.outl[1].m.val_SI

        # derivatives hydrogen outlet
        self.mat_deriv[k, 4, 0] = - self.e0 - (self.outl[2].h.val_SI - h_refh2)
        self.mat_deriv[k, 4, 2] = - self.outl[2].m.val_SI

        # derivatives for variable P
        if self.P.is_var:
            self.mat_deriv[k, 5 + self.P.var_pos, 0] = 1

        k += 1

        ######################################################################
        # derivatives for temperature at gas outlets

        # derivatives for outlet 1
        if not vec_z[3, 1]:
            self.mat_deriv[k, 3, 1] = dT_mix_dph(self.outl[1].to_flow())
        if not vec_z[3, 2]:
            self.mat_deriv[k, 3, 2] = dT_mix_pdh(self.outl[1].to_flow())

        # derivatives for outlet 2
        if not vec_z[4, 1]:
            self.mat_deriv[k, 4, 1] = - dT_mix_dph(self.outl[2].to_flow())
        if not vec_z[4, 2]:
            self.mat_deriv[k, 4, 2] = - dT_mix_pdh(self.outl[2].to_flow())

        k += 1

        ######################################################################
        # derivatives for power vs. hydrogen production
        if self.e.is_set:
            self.mat_deriv[k, 4, 0] = - self.e.val
            # derivatives for variable P
            if self.P.is_var:
                self.mat_deriv[k, 5 + self.P.var_pos, 0] = 1
            # derivatives for variable e
            if self.e.is_var:
                self.mat_deriv[k, 5 + self.e.var_pos, 0] = -(
                    self.outl[2].m.val_SI)
            k += 1

        ######################################################################
        # derivatives for pressure ratio
        if self.pr_c.is_set:
            self.mat_deriv[k, 0, 1] = self.pr_c.val
            self.mat_deriv[k, 2, 1] = - 1
            k += 1

        ######################################################################
        # derivatives for zeta value
        if self.zeta.is_set:
            f = self.zeta_func
            if not vec_z[0, 0]:
                self.mat_deriv[k, 0, 0] = self.numeric_deriv(
                    f, 'm', 0, zeta='zeta')
            if not vec_z[0, 1]:
                self.mat_deriv[k, 0, 1] = self.numeric_deriv(
                    f, 'p', 0, zeta='zeta')
            if not vec_z[0, 2]:
                self.mat_deriv[k, 0, 2] = self.numeric_deriv(
                    f, 'h', 0, zeta='zeta')
            if not vec_z[2, 1]:
                self.mat_deriv[k, 2, 1] = self.numeric_deriv(
                    f, 'p', 2, zeta='zeta')
            if not vec_z[2, 2]:
                self.mat_deriv[k, 2, 2] = self.numeric_deriv(
                    f, 'h', 2, zeta='zeta')

            # derivatives for variable zeta
            if self.zeta.is_var:
                self.mat_deriv[k, 5 + self.zeta.var_pos, 0] = (
                    self.numeric_deriv(
                        f, 'zeta', 5, zeta='zeta'))
            k += 1

        ######################################################################
        # derivatives for heat flow
        if self.Q.is_set:
            self.mat_deriv[k, 0, 0] = -(
                self.inl[0].h.val_SI - self.outl[0].h.val_SI)
            self.mat_deriv[k, 0, 2] = - self.inl[0].m.val_SI
            self.mat_deriv[k, 2, 2] = self.inl[0].m.val_SI
            k += 1

        ######################################################################
        # specified efficiency (efficiency definition: e0 / e)
        if self.eta.is_set:
            self.mat_deriv[k, 4, 0] = - self.e0 / self.eta.val
            # derivatives for variable P
            if self.P.is_var:
                self.mat_deriv[k, 5 + self.P.var_pos, 0] = 1
            k += 1

        ######################################################################
        # specified characteristic line for efficiency
        if self.eta_char.is_set:
            self.mat_deriv[k, 4, 0] = self.numeric_deriv(
                self.eta_char_func, 'm', 4)
            # derivatives for variable P
            if self.P.is_var:
                self.mat_deriv[k, 5 + self.P.var_pos, 0] = 1
            k += 1
Beispiel #12
0
    def derivatives(self):
        r"""
        Calculates matrix of partial derivatives for given equations.

        Returns
        -------
        mat_deriv : ndarray
            Matrix of partial derivatives.
        """
        mat_deriv = []

        ######################################################################
        # derivatives for cooling liquid composition
        deriv = np.zeros((self.num_fl, 5 + self.num_vars, self.num_fl + 3))

        j = 0
        for fluid, x in self.inl[0].fluid.val.items():
            deriv[j, 0, 3 + j] = 1
            deriv[j, 2, 3 + j] = -1
            j += 1

        mat_deriv += deriv.tolist()

        # derivatives to constrain fluids to inlets/outlets
        deriv = np.zeros((3, 5 + self.num_vars, self.num_fl + 3))

        i = 0
        for fluid in self.inl[0].fluid.val.keys():
            if fluid == self.h2o:
                deriv[0, 1, 3 + i] = -1
            elif fluid == self.o2:
                deriv[1, 3, 3 + i] = -1
            elif fluid == self.h2:
                deriv[2, 4, 3 + i] = -1
            i += 1

        mat_deriv += deriv.tolist()

        # derivatives to ban fluids off inlets/outlets
        deriv = np.zeros((3 * len(self.inl[1].fluid.val.keys()) - 3,
                          5 + self.num_vars, self.num_fl + 3))

        i = 0
        j = 0
        for fluid in self.inl[1].fluid.val.keys():
            if fluid != self.h2o:
                deriv[j, 1, 3 + i] = -1
                j += 1
            if fluid != self.o2:
                deriv[j, 3, 3 + i] = -1
                j += 1
            if fluid != self.h2:
                deriv[j, 4, 3 + i] = -1
                j += 1
            i += 1

        mat_deriv += deriv.tolist()

        ######################################################################
        # derivatives for mass balance equations

        # deritatives for mass flow balance in the heat exchanger
        deriv = np.zeros((3, 5 + self.num_vars, self.num_fl + 3))

        deriv[0, 0, 0] = 1
        deriv[0, 2, 0] = -1

        # derivatives for mass flow balance for oxygen output
        o2 = molar_masses[self.o2] / (molar_masses[self.o2] +
                                      2 * molar_masses[self.h2])
        deriv[1, 1, 0] = o2
        deriv[1, 3, 0] = -1

        # derivatives for mass flow balance for hydrogen output
        deriv[2, 1, 0] = (1 - o2)
        deriv[2, 4, 0] = -1

        mat_deriv += deriv.tolist()

        ######################################################################
        # derivatives for pressure equations

        # derivatives for pressure oxygen outlet
        deriv = np.zeros((2, 5 + self.num_vars, self.num_fl + 3))

        deriv[0, 1, 1] = 1
        deriv[0, 3, 1] = -1

        # derivatives for pressure hydrogen outlet
        deriv[1, 1, 1] = 1
        deriv[1, 4, 1] = -1

        mat_deriv += deriv.tolist()

        ######################################################################
        # derivatives for energy balance equations

        deriv = np.zeros((1, 5 + self.num_vars, self.num_fl + 3))

        T_ref = 293.15
        p_ref = 1e5

        h_refh2o = h_mix_pT([1, p_ref, 0, self.inl[1].fluid.val], T_ref)
        h_refh2 = h_mix_pT([1, p_ref, 0, self.outl[2].fluid.val], T_ref)
        h_refo2 = h_mix_pT([1, p_ref, 0, self.outl[1].fluid.val], T_ref)

        # derivatives cooling water inlet
        deriv[0, 0, 0] = - (self.outl[0].h.val_SI - self.inl[0].h.val_SI)
        deriv[0, 0, 2] = self.inl[0].m.val_SI

        # derivatives feed water inlet
        deriv[0, 1, 0] = (self.inl[1].h.val_SI - h_refh2o)
        deriv[0, 1, 2] = self.inl[1].m.val_SI

        # derivative cooling water outlet
        deriv[0, 2, 2] = - self.inl[0].m.val_SI

        # derivatives oxygen outlet
        deriv[0, 3, 0] = - (self.outl[1].h.val_SI - h_refo2)
        deriv[0, 3, 2] = - self.outl[1].m.val_SI

        # derivatives hydrogen outlet
        deriv[0, 4, 0] = - self.e0 - (self.outl[2].h.val_SI - h_refh2)
        deriv[0, 4, 2] = - self.outl[2].m.val_SI

        # derivatives for variable P
        if self.P.is_var:
            deriv[0, 5 + self.P.var_pos, 0] = 1

        mat_deriv += deriv.tolist()

        ######################################################################
        # derivatives for temperature at gas outlets

        deriv = np.zeros((1, 5 + self.num_vars, self.num_fl + 3))

        # derivatives for outlet 1
        deriv[0, 3, 1] = dT_mix_dph(self.outl[1].to_flow())
        deriv[0, 3, 2] = dT_mix_pdh(self.outl[1].to_flow())

        # derivatives for outlet 2
        deriv[0, 4, 1] = - dT_mix_dph(self.outl[2].to_flow())
        deriv[0, 4, 2] = - dT_mix_pdh(self.outl[2].to_flow())

        mat_deriv += deriv.tolist()

        ######################################################################
        # derivatives for power vs. hydrogen production

        if self.e.is_set:
            deriv = np.zeros((1, 5 + self.num_vars, self.num_fl + 3))

            deriv[0, 4, 0] = - self.e.val

            # derivatives for variable P
            if self.P.is_var:
                deriv[0, 5 + self.P.var_pos, 0] = 1

            # derivatives for variable e
            if self.e.is_var:
                deriv[0, 5 + self.e.var_pos, 0] = - self.outl[2].m.val_SI

            mat_deriv += deriv.tolist()

        ######################################################################
        # derivatives for pressure ratio
        if self.pr_c.is_set:

            deriv = np.zeros((1, 5 + self.num_vars, self.num_fl + 3))

            deriv[0, 0, 1] = self.pr_c.val
            deriv[0, 2, 1] = - 1

            mat_deriv += deriv.tolist()

        ######################################################################
        #pr_c.val = pressure ratio Druckverlust (als Faktor vorgegeben)
        # derivatives for zeta value
        if self.zeta.is_set:

            deriv = np.zeros((1, 5 + self.num_vars, self.num_fl + 3))
            deriv[0, 0, 0] = self.numeric_deriv(self.zeta_func, 'm', 0)
            deriv[0, 0, 1] = self.numeric_deriv(self.zeta_func, 'p', 0)
            deriv[0, 0, 2] = self.numeric_deriv(self.zeta_func, 'h', 0)
            deriv[0, 2, 1] = self.numeric_deriv(self.zeta_func, 'p', 2)
            deriv[0, 2, 2] = self.numeric_deriv(self.zeta_func, 'h', 2)

            # derivatives for variable zeta
            if self.zeta.is_var:
                deriv[0, 5 + self.zeta.var_pos, 0] = (
                        self.numeric_deriv(self.zeta_func, 'zeta', 5))

            mat_deriv += deriv.tolist()

        ######################################################################
        # derivatives for heat flow
        if self.Q.is_set:

            deriv = np.zeros((1, 5 + self.num_vars, self.num_fl + 3))

            deriv[0, 0, 0] = - (self.inl[0].h.val_SI - self.outl[0].h.val_SI)
            deriv[0, 0, 2] = - self.inl[0].m.val_SI
            deriv[0, 2, 2] = self.inl[0].m.val_SI

            mat_deriv += deriv.tolist()

        ######################################################################
        # specified efficiency (efficiency definition: e0 / e)
        if self.eta.is_set:

            deriv = np.zeros((1, 5 + self.num_vars, self.num_fl + 3))

            deriv[0, 4, 0] = - self.e0 / self.eta.val

            # derivatives for variable P
            if self.P.is_var:
                deriv[0, 5 + self.P.var_pos, 0] = 1

            mat_deriv += deriv.tolist()

        ######################################################################
        # specified characteristic line for efficiency
        if self.eta_char.is_set:

            mat_deriv += self.eta_char_deriv()

        ######################################################################

        return np.asarray(mat_deriv)