예제 #1
0
  /**
   * Returns two matrices containing partial derivatives of the complex bus power injections w.r.t
   * voltage magnitude and voltage angle respectively (for all buses). If YBUS is a sparse matrix,
   * the return values will be also. The following explains the expressions used to form the
   * matrices:
   *
   * <p>S = diag(V) * conj(Ibus) = diag(conj(Ibus)) * V
   *
   * <p>Partials of V & Ibus w.r.t. voltage magnitudes dV/dVm = diag(V./abs(V)) dI/dVm = Ybus *
   * dV/dVm = Ybus * diag(V./abs(V))
   *
   * <p>Partials of V & Ibus w.r.t. voltage angles dV/dVa = j * diag(V) dI/dVa = Ybus * dV/dVa =
   * Ybus * j * diag(V)
   *
   * <p>Partials of S w.r.t. voltage magnitudes dS/dVm = diag(V) * conj(dI/dVm) + diag(conj(Ibus)) *
   * dV/dVm = diag(V) * conj(Ybus * diag(V./abs(V))) + conj(diag(Ibus)) * diag(V./abs(V))
   *
   * <p>Partials of S w.r.t. voltage angles dS/dVa = diag(V) * conj(dI/dVa) + diag(conj(Ibus)) *
   * dV/dVa = diag(V) * conj(Ybus * j * diag(V)) + conj(diag(Ibus)) * j * diag(V) = -j * diag(V) *
   * conj(Ybus * diag(V)) + conj(diag(Ibus)) * j * diag(V) = j * diag(V) * conj(diag(Ibus) - Ybus *
   * diag(V))
   *
   * @param Ybus
   * @param V
   * @return
   */
  @SuppressWarnings("static-access")
  public static DComplexMatrix2D[] jp_dSbus_dV(DComplexMatrix2D Ybus, DComplexMatrix1D V) {
    int n;
    int[] ib;
    DComplexMatrix1D Ibus, absV, Vnorm;
    DComplexMatrix2D[] dSbus_dV;
    SparseRCDComplexMatrix2D diagV, diagIbus, diagVnorm, rhs, dS_dVa, conjInorm, dS_dVm, addend;

    n = (int) V.size();
    ib = Djp_util.irange(n);
    Ibus = Ybus.zMult(V, null);

    diagV = new SparseRCDComplexMatrix2D(n, n, ib, ib, V.toArray(), false, false);
    diagIbus = new SparseRCDComplexMatrix2D(n, n, ib, ib, Ibus.toArray(), false, false);

    absV = V.copy().assign(cfunc.abs);
    Vnorm = V.copy().assign(absV, cfunc.div);
    diagVnorm = new SparseRCDComplexMatrix2D(n, n, ib, ib, Vnorm.toArray(), false, false);

    rhs = (SparseRCDComplexMatrix2D) Ybus.zMult(diagV, null);

    rhs.assign(diagIbus, cfunc.swapArgs(cfunc.minus)).assign(cfunc.conj);
    dS_dVa = (SparseRCDComplexMatrix2D) diagV.zMult(rhs, null);
    dS_dVa.assign(cfunc.mult(new double[] {0, 1}));

    conjInorm = (SparseRCDComplexMatrix2D) Ybus.zMult(diagVnorm, null);
    conjInorm.assign(cfunc.conj);
    dS_dVm = (SparseRCDComplexMatrix2D) diagV.zMult(conjInorm, null);

    diagIbus.assign(cfunc.conj);
    addend = (SparseRCDComplexMatrix2D) diagVnorm.zMult(diagIbus, null);
    dS_dVm.assign(addend, cfunc.plus);

    dSbus_dV = new DComplexMatrix2D[] {dS_dVm, dS_dVa};

    return dSbus_dV;
  }
예제 #2
0
  /**
   * Solves for bus voltages given the full system admittance matrix (for all buses), the complex
   * bus power injection vector (for all buses), the initial vector of complex bus voltages, and
   * column vectors with the lists of bus indices for the swing bus, PV buses, and PQ buses,
   * respectively. The bus voltage vector contains the set point for generator (including ref bus)
   * buses, and the reference angle of the swing bus, as well as an initial guess for remaining
   * magnitudes and angles. JPOPT is a JPOWER options vector which can be used to set the
   * termination tolerance, maximum number of iterations, and output options (see JPOPTION for
   * details). Uses default options if this parameter is not given. Returns the final complex
   * voltages, a flag which indicates whether it converged or not, and the number of iterations
   * performed.
   *
   * @param Ybus
   * @param Sbus
   * @param V0
   * @param ref
   * @param pv
   * @param pq
   * @param jpopt
   * @return
   */
  @SuppressWarnings("static-access")
  public static Object[] jp_newtonpf(
      DComplexMatrix2D Ybus,
      DComplexMatrix1D Sbus,
      DComplexMatrix1D V0,
      int ref,
      int[] pv,
      int[] pq,
      Map<String, Double> jpopt) {
    int i, max_it, verbose, npv, npq, j1, j2, j3, j4, j5, j6;
    int[] pvpq;
    double tol, normF;
    boolean converged;
    DoubleMatrix1D F, dx;
    DoubleMatrix2D J11, J12, J21, J22, J1, J2, J;
    DComplexMatrix1D mis, V, Va, Vm, dxz;
    DComplexMatrix2D dSbus_dVm, dSbus_dVa;
    DComplexMatrix2D[] dSbus_dV;
    SparseRCDoubleMatrix2D JJ;

    /* options */
    tol = jpopt.get("PF_TOL");
    max_it = jpopt.get("PF_MAX_IT").intValue();
    verbose = jpopt.get("VERBOSE").intValue();

    /* initialize */
    pvpq = Djp_util.icat(pv, pq);
    converged = false;
    i = 0;
    V = V0;
    Va = V.copy().assign(cfunc.arg);
    Vm = V.copy().assign(cfunc.abs);

    /* set up indexing for updating V */
    npv = pv.length;
    npq = pq.length;
    j1 = 0;
    j2 = npv; // j1:j2 - V angle of pv buses
    j3 = j2;
    j4 = j2 + npq; // j3:j4 - V angle of pq buses
    j5 = j4;
    j6 = j4 + npq; // j5:j6 - V mag of pq buses

    /* evaluate F(x0) */
    mis = Ybus.zMult(V, null).assign(cfunc.conj);
    mis.assign(V, cfunc.mult).assign(Sbus, cfunc.minus);
    F =
        DoubleFactory1D.sparse.make(
            new DoubleMatrix1D[] {
              mis.viewSelection(pvpq).getRealPart(), mis.viewSelection(pq).getImaginaryPart()
            });

    /* check tolerance */
    normF = DenseDoubleAlgebra.DEFAULT.norm(F, Norm.Infinity);
    if (verbose > 0) System.out.print("(Newton)\n");
    if (verbose > 1) {
      System.out.printf("\n it    max P & Q mismatch (p.u.)");
      System.out.printf("\n----  ---------------------------");
      System.out.printf("\n%3d        %10.3e", i, normF);
    }
    if (normF < tol) {
      converged = true;
      if (verbose > 1) System.out.printf("\nConverged!\n");
    }

    /* do Newton iterations */
    while ((!converged) & (i < max_it)) {
      /* update iteration counter */
      i += 1;

      /* evaluate Jacobian */
      dSbus_dV = Djp_dSbus_dV.jp_dSbus_dV(Ybus, V);
      dSbus_dVm = dSbus_dV[0];
      dSbus_dVa = dSbus_dV[1];

      J11 = dSbus_dVa.getRealPart().viewSelection(pvpq, pvpq).copy();
      J12 = dSbus_dVm.getRealPart().viewSelection(pvpq, pq).copy();
      J21 = dSbus_dVa.getImaginaryPart().viewSelection(pq, pvpq).copy();
      J22 = dSbus_dVm.getImaginaryPart().viewSelection(pq, pq).copy();
      J1 = DoubleFactory2D.sparse.appendColumns(J11, J12);
      J2 = DoubleFactory2D.sparse.appendColumns(J21, J22);
      J = DoubleFactory2D.sparse.appendRows(J1, J2);
      JJ = new SparseRCDoubleMatrix2D(J.rows(), J.columns());
      JJ.assign(J);

      dx = SparseDoubleAlgebra.DEFAULT.solve(JJ, F).assign(dfunc.neg);
      dxz = Djp_util.complex(dx, null);

      /* update voltage */
      if (npv > 0)
        Va.viewSelection(pv).assign(dxz.viewSelection(Djp_util.irange(j1, j2)), cfunc.plus);
      if (npq > 0) {
        Va.viewSelection(pq).assign(dxz.viewSelection(Djp_util.irange(j3, j4)), cfunc.plus);
        Vm.viewSelection(pq).assign(dxz.viewSelection(Djp_util.irange(j5, j6)), cfunc.plus);
      }

      V = Djp_util.polar(Vm.getRealPart(), Va.getRealPart());
      /* update Vm and Va again in case we wrapped around with a negative Vm */
      Va = V.copy().assign(cfunc.arg);
      Vm = V.copy().assign(cfunc.abs);

      /* evalute F(x) */
      mis = Ybus.zMult(V, null).assign(cfunc.conj);
      mis.assign(V, cfunc.mult).assign(Sbus, cfunc.minus);
      F =
          DoubleFactory1D.sparse.make(
              new DoubleMatrix1D[] {
                mis.viewSelection(pvpq).getRealPart(), mis.viewSelection(pq).getImaginaryPart()
              });

      /* check for convergence */
      normF = DenseDoubleAlgebra.DEFAULT.norm(F, Norm.Infinity);
      if (verbose > 1) System.out.printf("\n%3d        %10.3e", i, normF);
      if (normF < tol) {
        converged = true;
        if (verbose > 0)
          System.out.printf("\nNewton's method power flow converged in %d iterations.\n", i);
      }
    }
    if (verbose > 0)
      if (!converged)
        System.out.printf("\nNewton''s method power did not converge in %d iterations.\n", i);

    return new Object[] {V, converged, i};
  }