Beispiel #1
0
def first_time_step(system):
    """Compute the first time step"""
    settings = system.TDS
    if not system.DAE.n:
        freq = 1.0
    elif system.DAE.n == 1:
        B = matrix(system.DAE.Gx)
        linsolve(system.DAE.Gy, B)
        As = system.DAE.Fx - system.DAE.Fy * B
        freq = abs(As[0, 0])
    else:
        freq = 20.0

    if freq > system.Settings.freq:
        freq = float(system.Settings.freq)

    tspan = abs(settings.tf - settings.t0)
    tcycle = 1 / freq
    settings.deltatmax = min(5 * tcycle, tspan / 100.0)
    settings.deltat = min(tcycle, tspan / 100.0)
    settings.deltatmin = min(tcycle / 64, settings.deltatmax / 20)

    if settings.fixt:
        if settings.tstep <= 0:
            system.Log.warning('Fixed time step is negative or zero')
            system.Log.warning('Switching to automatic time step')
            settings.fixt = False
        else:
            settings.deltat = settings.tstep
            if settings.tstep < settings.deltatmin:
                system.Log.warning(
                    'Fixed time step is below the estimated minimum')
    return settings.deltat
Beispiel #2
0
    def linsolve(self, A, b):
        """
        Solve linear equation set ``Ax = b`` and returns the solutions in a 1-D array.

        This function performs both symbolic and numeric factorizations every time, and can be slower than
        ``Solver.solve``.

        Parameters
        ----------
        A
            Sparse matrix

        b
            RHS of the equation

        Returns
        -------
        The solution in a 1-D np array.
        """
        if self.sparselib == 'umfpack':
            try:
                umfpack.linsolve(A, b)
            except ArithmeticError:
                logger.error('Singular matrix. Case is not solvable')
            return np.ravel(b)

        elif self.sparselib == 'klu':
            try:
                klu.linsolve(A, b)
            except ArithmeticError:
                logger.error('Singular matrix. Case is not solvable')
            return np.ravel(b)

        elif self.sparselib in ('spsolve', 'cupy'):
            ccs = A.CCS
            size = A.size
            data = np.array(ccs[2]).reshape((-1, ))
            indices = np.array(ccs[1]).reshape((-1, ))
            indptr = np.array(ccs[0]).reshape((-1, ))

            A = csc_matrix((data, indices, indptr), shape=size)

            if self.sparselib == 'spsolve':
                x = spsolve(A, b)
                return np.ravel(x)

            elif self.sparselib == 'cupy':
                # delayed import for startup speed
                import cupy as cp  # NOQA
                from cupyx.scipy.sparse import csc_matrix as csc_cu  # NOQA
                from cupyx.scipy.sparse.linalg.solve import lsqr as cu_lsqr  # NOQA

                cu_A = csc_cu(A)
                cu_b = cp.array(np.array(b).reshape((-1, )))
                x = cu_lsqr(cu_A, cu_b)

                return np.ravel(cp.asnumpy(x[0]))
Beispiel #3
0
def klu_linsolve(A, b):
    """
    KLU wrapper function for linear system solve A x = b
    :param A: System matrix
    :param b: right hand side
    :return: solution
    """
    A2 = A.tocoo()
    A_cvxopt = cvxopt.spmatrix(A2.data, A2.row, A2.col, A2.shape, 'd')
    x = cvxopt.matrix(b)
    klu.linsolve(A_cvxopt, x)
    return np.array(x)[:, 0]
Beispiel #4
0
    def linsolve(self, A, b):
        """
        Solve linear equation set ``Ax = b`` and store the solutions in ``b``.

        Parameters
        ----------
        A
            Sparse matrix

        b
            RHS of the equation

        Returns
        -------
        None
        """
        if self.sparselib == 'umfpack':
            umfpack.linsolve(A, b)
            return b

        elif self.sparselib == 'klu':
            klu.linsolve(A, b)
            return b

        elif self.sparselib in ('spsolve', 'cupy'):
            ccs = A.CCS
            size = A.size
            data = np.array(ccs[2]).reshape((-1, ))
            indices = np.array(ccs[1]).reshape((-1, ))
            indptr = np.array(ccs[0]).reshape((-1, ))

            A = csc_matrix((data, indices, indptr), shape=size)

            if self.sparselib == 'spsolve':
                x = spsolve(A, b)
                return matrix(x)

            elif self.sparselib == 'cupy':
                # delayed import for startup speed
                import cupy as cp  # NOQA
                from cupyx.scipy.sparse import csc_matrix as csc_cu  # NOQA
                from cupyx.scipy.sparse.linalg.solve import lsqr as cu_lsqr  # NOQA

                cu_A = csc_cu(A)
                cu_b = cp.array(np.array(b).reshape((-1, )))
                x = cu_lsqr(cu_A, cu_b)

                return matrix(cp.asnumpy(x[0]))
Beispiel #5
0
    def linsolve(self, A, b):
        """
        Solve linear equation set ``Ax = b`` and store the solutions in ``b``.

        Parameters
        ----------
        A
            Sparse matrix

        b
            RHS of the equation

        Returns
        -------
        None
        """
        if self.sparselib == 'umfpack':
            return umfpack.linsolve(A, b)

        elif self.sparselib == 'klu':
            return klu.linsolve(A, b)
Beispiel #6
0
    def init1(self, dae):
        """New initialization function"""
        self.servcall(dae)
        retval = True

        mva = self.system.mva
        self.p0 = mul(self.p0, self.gammap)
        self.q0 = mul(self.q0, self.gammaq)

        dae.y[self.vsd] = mul(dae.y[self.v], -sin(dae.y[self.a]))
        dae.y[self.vsq] = mul(dae.y[self.v], cos(dae.y[self.a]))

        rs = matrix(self.rs)
        rr = matrix(self.rr)
        xmu = matrix(self.xmu)
        x1 = matrix(self.xs) + xmu
        x2 = matrix(self.xr) + xmu
        Pg = matrix(self.p0)
        Qg = matrix(self.q0)
        Vc = dae.y[self.v]
        vsq = dae.y[self.vsq]
        vsd = dae.y[self.vsd]

        toSn = div(mva, self.Sn)  # to machine base
        toSb = self.Sn / mva  # to system base

        # rotor speed
        omega = 1 * (ageb(mva * Pg, self.Sn)) + \
            mul(0.5 + 0.5 * mul(Pg, toSn),
                aandb(agtb(Pg, 0), altb(mva * Pg, self.Sn))) + \
            0.5 * (aleb(mva * Pg, 0))

        slip = 1 - omega
        theta = mul(self.Kp, mround(1000 * (omega - 1)) / 1000)
        theta = mmax(theta, 0)

        # prepare for the iterations

        irq = mul(-x1, toSb, (2 * omega - 1), div(1, Vc), div(1, xmu),
                  div(1, omega))
        isd = zeros(*irq.size)
        isq = zeros(*irq.size)

        # obtain ird isd isq
        for i in range(self.n):
            A = sparse([[-rs[i], vsq[i]], [x1[i], -vsd[i]]])
            B = matrix([vsd[i] - xmu[i] * irq[i], Qg[i]])
            linsolve(A, B)
            isd[i] = B[0]
            isq[i] = B[1]
        ird = -div(vsq + mul(rs, isq) + mul(x1, isd), xmu)
        vrd = -mul(rr, ird) + mul(
            slip,
            mul(x2, irq) + mul(xmu, isq))  # todo: check x1 or x2
        vrq = -mul(rr, irq) - mul(slip, mul(x2, ird) + mul(xmu, isd))

        # main iterations
        for i in range(self.n):
            mis = ones(6, 1)
            rows = [0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5]
            cols = [0, 1, 3, 0, 1, 2, 2, 4, 3, 5, 0, 1, 2]

            x = matrix([isd[i], isq[i], ird[i], irq[i], vrd[i], vrq[i]])
            # vals = [-rs, x1, xmu, -x1, -rs, -xmu, -rr,
            #         -1, -rr, -1, vsd, vsq, -xmu * Vc / x1]

            vals = [
                -rs[i], x1[i], xmu[i], -x1[i], -rs[i], -xmu[i], -rr[i], -1,
                -rr[i], -1, vsd[i], vsq[i], -xmu[i] * Vc[i] / x1[i]
            ]
            jac0 = spmatrix(vals, rows, cols, (6, 6), 'd')
            niter = 0

            while max(abs(mis)) > self.system.tds.config.tol:
                if niter > 20:
                    logger.error('Initialization of DFIG <{}> failed.'.format(
                        self.name[i]))
                    retval = False
                    break

                mis[0] = -rs[i] * x[0] + x1[i] * x[1] + xmu[i] * x[3] - vsd[i]
                mis[1] = -rs[i] * x[1] - x1[i] * x[0] - xmu[i] * x[2] - vsq[i]
                mis[2] = -rr[i] * x[2] + slip[i] * (x2[i] * x[3] +
                                                    xmu[i] * x[1]) - x[4]
                mis[3] = -rr[i] * x[3] - slip[i] * (x2[i] * x[2] +
                                                    xmu[i] * x[0]) - x[5]
                mis[4] = vsd[i] * x[0] + vsq[i] * x[1] + x[4] * x[2] + \
                    x[5] * x[3] - Pg[i]
                mis[5] = -xmu[i] * Vc[i] * x[2] / x1[i] - \
                    Vc[i] * Vc[i] / x1[i] - Qg[i]

                rows = [2, 2, 3, 3, 4, 4, 4, 4]
                cols = [1, 3, 0, 2, 2, 3, 4, 5]
                vals = [
                    slip[i] * xmu[i], slip[i] * x2[i], -slip[i] * xmu[i],
                    -slip[i] * x2[i], x[4], x[5], x[2], x[3]
                ]

                jac = jac0 + spmatrix(vals, rows, cols, (6, 6), 'd')

                linsolve(jac, mis)

                x -= mis
                niter += 1

            isd[i] = x[0]
            isq[i] = x[1]
            ird[i] = x[2]
            irq[i] = x[3]
            vrd[i] = x[4]
            vrq[i] = x[5]

        dae.x[self.ird] = mul(self.u0, ird)
        dae.x[self.irq] = mul(self.u0, irq)
        dae.y[self.isd] = isd
        dae.y[self.isq] = isq
        dae.y[self.vrd] = vrd
        dae.y[self.vrq] = vrq

        dae.x[self.omega_m] = mul(self.u0, omega)
        dae.x[self.theta_p] = mul(self.u0, theta)
        dae.y[self.pwa] = mmax(mmin(2 * dae.x[self.omega_m] - 1, 1), 0)

        self.vref0 = mul(aneb(self.KV, 0),
                         Vc - div(ird + div(Vc, xmu), self.KV))
        dae.y[self.vref] = self.vref0
        k = mul(div(x1, Vc, xmu, omega), toSb)

        self.irq_off = -mul(k, mmax(mmin(2 * omega - 1, 1), 0)) - irq

        # electrical torque in pu
        te = mul(
            xmu,
            mul(dae.x[self.irq], dae.y[self.isd]) -
            mul(dae.x[self.ird], dae.y[self.isq]))

        for i in range(self.n):
            if te[i] < 0:
                logger.error(
                    'Pe < 0 on bus <{}>. Wind speed initialize failed.'.format(
                        self.bus[i]))
                retval = False

        # wind power in pu
        pw = mul(te, omega)
        dae.y[self.pw] = pw

        # wind speed initialization loop

        R = 4 * pi * self.system.freq * mul(self.R, self.ngb, div(
            1, self.npole))
        AA = pi * self.R**2
        vw = 0.9 * self.Vwn

        for i in range(self.n):
            mis = 1
            niter = 0
            while abs(mis) > self.system.tds.config.tol:
                if niter > 50:
                    logger.error(
                        'Wind <{}> init failed. '
                        'Try increasing the nominal wind speed.'.format(
                            self.wind[i]))
                    retval = False
                    break

                pw_iter, jac = self.windpower(self.ngen[i], self.rho[i], vw[i],
                                              AA[i], R[i], omega[i], theta[i])

                mis = pw_iter - pw[i]
                inc = -mis / jac[1]
                vw[i] += inc
                niter += 1

        # set wind speed
        dae.x[self.vw] = div(vw, self.Vwn)

        lamb = div(omega, vw, div(1, R))
        ilamb = div(1,
                    (div(1, lamb + 0.08 * theta) - div(0.035, theta**3 + 1)))
        cp = 0.22 * mul(
            div(116, ilamb) - 0.4 * theta - 5, exp(div(-12.5, ilamb)))

        dae.y[self.lamb] = lamb
        dae.y[self.ilamb] = ilamb
        dae.y[self.cp] = cp

        self.system.rmgen(self.gen)

        if not retval:
            logger.error('DFIG initialization failed')

        return retval
Beispiel #7
0
    def init1(self, dae):
        self.servcall(dae)
        mva = self.system.mva
        self.p0 = mul(self.p0, 1)
        self.v120 = self.v12

        self.toMb = div(mva, self.Sn)  # to machine base
        self.toSb = self.Sn / mva  # to system base
        rs = matrix(self.rs)
        xd = matrix(self.xd)
        xq = matrix(self.xq)
        psip = matrix(self.psip)
        Pg = matrix(self.p0)

        # rotor speed
        omega = 1 * (ageb(mva * Pg, self.Sn)) + \
            mul(0.5 + 0.5 * mul(Pg, self.toMb),
                aandb(agtb(Pg, 0), altb(mva * Pg, self.Sn))) + \
            0.5 * (aleb(mva * Pg, 0))

        theta = mul(self.Kp, mround(1000 * (omega - 1)) / 1000)
        theta = mmax(theta, 0)

        # variables to initialize iteratively: vsd, vsq, isd, isq

        vsd = matrix(0.8, (self.n, 1))
        vsq = matrix(0.6, (self.n, 1))
        isd = matrix(self.p0 / 2)
        isq = matrix(self.p0 / 2)

        for i in range(self.n):
            # vsd = 0.5
            # vsq = self.psip[i]
            # isd = Pg / 2
            # isq = Pg / 2
            x = matrix([vsd[i], vsq[i], isd[i], isq[i]])

            mis = ones(4, 1)
            jac = sparse(matrix(0, (4, 4), 'd'))
            iter = 0
            while (max(abs(mis))) > self.system.tds.config.tol:
                if iter > 40:
                    logger.error(
                        'Initialization of WTG4DC <{}> failed.'.format(
                            self.name[i]))
                    break
                mis[0] = x[0] * x[2] + x[1] * x[3] - Pg[i]
                # mis[1] = omega[i]*x[3] * (psip[i] + (xq[i] - xd[i]) * x[2])\
                #     - Pg[i]
                mis[1] = omega[i] * x[3] * (psip[i] - xd[i] * x[2]) - Pg[i]
                mis[2] = -x[0] - rs[i] * x[2] + omega[i] * xq[i] * x[3]
                mis[3] = x[1] + rs[i] * x[3] + omega[i] * xd[i] * x[2] - \
                    omega[i] * psip[i]

                jac[0, 0] = x[2]
                jac[0, 1] = x[3]
                jac[0, 2] = x[0]
                jac[0, 3] = x[1]

                jac[1, 2] = omega[i] * x[3] * (-xd[i])
                jac[1, 3] = omega[i] * (psip[i] + (-xd[i]) * x[2])

                jac[2, 0] = -1
                jac[2, 2] = -rs[i]
                jac[2, 3] = omega[i] * xq[i]
                jac[3, 1] = 1
                jac[3, 2] = omega[i] * xd[i]
                jac[3, 3] = rs[i]

                linsolve(jac, mis)
                x -= mis
                iter += 1

            vsd[i] = x[0]
            vsq[i] = x[1]
            isd[i] = x[2]
            isq[i] = x[3]

        dae.y[self.isd] = isd
        dae.y[self.vsd] = vsd
        dae.y[self.vsq] = vsq

        dae.x[self.isq] = isq
        dae.x[self.omega_m] = mul(self.u0, omega)
        dae.x[self.theta_p] = mul(self.u0, theta)
        dae.y[self.pwa] = mmax(mmin(2 * dae.x[self.omega_m] - 1, 1), 0)

        self.ps0 = mul(vsd, isd) + mul(vsq, isq)
        self.qs0 = mul(vsq, isd) - mul(vsd, isq)
        self.te0 = mul(isq, psip + mul(xq - xd, isd))
        dae.y[self.te] = self.te0
        dae.y[self.ps] = self.ps0

        MPPT.init1(self, dae)
        Turbine.init1(self, dae)

        self.system.rmgen(self.dcgen)
Beispiel #8
0
def state_matrix(system):
    """Return state matrix"""
    Gyx = matrix(system.DAE.Gx)
    linsolve(system.DAE.Gy, Gyx)
    return matrix(system.DAE.Fx - system.DAE.Fy*Gyx)