Exciter model.

        Based on Exciter.m from MatDyn by Stijn Cole, developed at Katholieke
        Universiteit Leuven. See U{http://www.esat.kuleuven.be/electa/teaching/
        matdyn/} for more information.

def exciter(self, Xexc, Pexc, Vexc):
        """ Exciter model.

        Based on Exciter.m from MatDyn by Stijn Cole, developed at Katholieke
        Universiteit Leuven. See U{http://www.esat.kuleuven.be/electa/teaching/
        matdyn/} for more information.
        """
        exciters = self.exciters

        F = zeros(Xexc.shape)

        typ1 = [e.generator._i for e in exciters if e.model ==CONST_EXCITATION]
        typ2 = [e.generator._i for e in exciters if e.model == IEEE_DC1A]

        # Exciter type 1: constant excitation
        F[typ1, :] = 0.0

        # Exciter type 2: IEEE DC1A
        Efd = Xexc[typ2, 0]
        Uf = Xexc[typ2, 1]
        Ur = Xexc[typ2, 2]

        Ka = Pexc[typ2, 0]
        Ta = Pexc[typ2, 1]
        Ke = Pexc[typ2, 2]
        Te = Pexc[typ2, 3]
        Kf = Pexc[typ2, 4]
        Tf = Pexc[typ2, 5]
        Aex = Pexc[typ2, 6]
        Bex = Pexc[typ2, 7]
        Ur_min = Pexc[typ2, 8]
        Ur_max = Pexc[typ2, 9]
        Uref = Pexc[typ2, 10]
        Uref2 = Pexc[typ2, 11]

        U = Vexc[typ2, 1]

        Ux = Aex * exp(Bex * Efd)
        dUr = 1 / Ta * (Ka * (Uref - U + Uref2 - Uf) - Ur)
        dUf = 1 / Tf * (Kf / Te * (Ur - Ux - Ke * Efd) - Uf)

        if sum(flatnonzero(Ur > Ur_max)) >= 1:
            Ur2 = Ur_max
        elif sum(flatnonzero(Ur < Ur_max)) >= 1:
            Ur2 = Ur_min
        else:
            Ur2 = Ur

        dEfd = 1 / Te * (Ur2 - Ux - Ke * Efd)
        F[typ2, :] = c_[dEfd, dUf, dUr]

        # Exciter type 3:

        # Exciter type 4:

        return F