Home > matpower7.1 > lib > dSbr_dV.m

dSbr_dV

PURPOSE ^

DSBR_DV Computes partial derivatives of branch power flows w.r.t. voltage.

SYNOPSIS ^

function [dSf_dV1, dSf_dV2, dSt_dV1, dSt_dV2, Sf, St] = dSbr_dV(branch, Yf, Yt, V, vcart)

DESCRIPTION ^

DSBR_DV   Computes partial derivatives of branch power flows w.r.t. voltage.

   The derivatives can be take with respect to polar or cartesian coordinates
   of voltage, depending on the 5th argument.

   [DSF_DVA, DSF_DVM, DST_DVA, DST_DVM, SF, ST] = DSBR_DV(BRANCH, YF, YT, V)
   [DSF_DVA, DSF_DVM, DST_DVA, DST_DVM, SF, ST] = DSBR_DV(BRANCH, YF, YT, V, 0)

   Returns four matrices containing partial derivatives of the complex
   branch power flows at "from" and "to" ends of each branch w.r.t voltage
   magnitude and voltage angle, respectively (for all buses).

   [DSF_DVR, DSF_DVI, DST_DVR, DST_DVI, SF, ST] = DSBR_DV(BRANCH, YF, YT, V, 1)

   Returns four matrices containing partial derivatives of the complex
   branch power flows at "from" and "to" ends of each branch w.r.t real and
   imaginary parts of voltage, respectively (for all buses).

   If YF is a sparse matrix, the partial derivative matrices will be as well.
   Optionally returns vectors containing the power flows themselves. The
   following explains the expressions used to form the matrices:

   If = Yf * V;
   Sf = diag(Vf) * conj(If) = diag(conj(If)) * Vf

   Polar coordinates:
     Partials of V, Vf & If w.r.t. voltage angles
       dV/dVa  = j * diag(V)
       dVf/dVa = sparse(1:nl, f, j * V(f)) = j * sparse(1:nl, f, V(f))
       dIf/dVa = Yf * dV/dVa = Yf * j * diag(V)

     Partials of V, Vf & If w.r.t. voltage magnitudes
       dV/dVm  = diag(V./abs(V))
       dVf/dVm = sparse(1:nl, f, V(f)./abs(V(f))
       dIf/dVm = Yf * dV/dVm = Yf * diag(V./abs(V))

     Partials of Sf w.r.t. voltage angles
       dSf/dVa = diag(Vf) * conj(dIf/dVa)
                       + diag(conj(If)) * dVf/dVa
               = diag(Vf) * conj(Yf * j * diag(V))
                       + conj(diag(If)) * j * sparse(1:nl, f, V(f))
               = -j * diag(Vf) * conj(Yf * diag(V))
                       + j * conj(diag(If)) * sparse(1:nl, f, V(f))
               = j * (conj(diag(If)) * sparse(1:nl, f, V(f))
                       - diag(Vf) * conj(Yf * diag(V)))

     Partials of Sf w.r.t. voltage magnitudes
       dSf/dVm = diag(Vf) * conj(dIf/dVm)
                       + diag(conj(If)) * dVf/dVm
               = diag(Vf) * conj(Yf * diag(V./abs(V)))
                       + conj(diag(If)) * sparse(1:nl, f, V(f)./abs(V(f)))

   Cartesian coordinates:
     Partials of V, Vf & If w.r.t. real part of complex voltage
       dV/dVr  = diag(ones(n,1))
       dVf/dVr = Cf
       dIf/dVr = Yf
     where Cf is the connection matrix for line & from buses

     Partials of V, Vf & If w.r.t. imaginary part of complex voltage
       dV/dVi  = j * diag(ones(n,1))
       dVf/dVi = j * Cf
       dIf/dVi = j * Yf

     Partials of Sf w.r.t. real part of complex voltage
       dSf/dVr = conj(diag(If)) * Cf + diag(Vf) * conj(Yf)

     Partials of Sf w.r.t. imaginary part of complex voltage
       dSf/dVi = j * (conj(diag(If)) * Cf - diag(Vf) * conj(Yf))

   Derivations for "to" bus are similar.

   Examples:
       [Ybus, Yf, Yt] = makeYbus(baseMVA, bus, branch);
       [dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St] = ...
           dSbr_dV(branch, Yf, Yt, V);
       [dSf_dVr, dSf_dVi, dSt_dVr, dSt_dVi, Sf, St] = ...
           dSbr_dV(branch, Yf, Yt, V, 1);

   For more details on the derivations behind the derivative code used
   in MATPOWER information, see:

   [TN2]  R. D. Zimmerman, "AC Power Flows, Generalized OPF Costs and
          their Derivatives using Complex Matrix Notation", MATPOWER
          Technical Note 2, February 2010. [Online]. Available:
          https://matpower.org/docs/TN2-OPF-Derivatives.pdf
          doi: 10.5281/zenodo.3237866
   [TN4]  B. Sereeter and R. D. Zimmerman, "AC Power Flows and their
          Derivatives using Complex Matrix Notation and Cartesian
          Coordinate Voltages," MATPOWER Technical Note 4, April 2018.
          [Online]. Available: https://matpower.org/docs/TN4-OPF-Derivatives-Cartesian.pdf
          doi: 10.5281/zenodo.3237909

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [dSf_dV1, dSf_dV2, dSt_dV1, dSt_dV2, Sf, St] = dSbr_dV(branch, Yf, Yt, V, vcart)
0002 %DSBR_DV   Computes partial derivatives of branch power flows w.r.t. voltage.
0003 %
0004 %   The derivatives can be take with respect to polar or cartesian coordinates
0005 %   of voltage, depending on the 5th argument.
0006 %
0007 %   [DSF_DVA, DSF_DVM, DST_DVA, DST_DVM, SF, ST] = DSBR_DV(BRANCH, YF, YT, V)
0008 %   [DSF_DVA, DSF_DVM, DST_DVA, DST_DVM, SF, ST] = DSBR_DV(BRANCH, YF, YT, V, 0)
0009 %
0010 %   Returns four matrices containing partial derivatives of the complex
0011 %   branch power flows at "from" and "to" ends of each branch w.r.t voltage
0012 %   magnitude and voltage angle, respectively (for all buses).
0013 %
0014 %   [DSF_DVR, DSF_DVI, DST_DVR, DST_DVI, SF, ST] = DSBR_DV(BRANCH, YF, YT, V, 1)
0015 %
0016 %   Returns four matrices containing partial derivatives of the complex
0017 %   branch power flows at "from" and "to" ends of each branch w.r.t real and
0018 %   imaginary parts of voltage, respectively (for all buses).
0019 %
0020 %   If YF is a sparse matrix, the partial derivative matrices will be as well.
0021 %   Optionally returns vectors containing the power flows themselves. The
0022 %   following explains the expressions used to form the matrices:
0023 %
0024 %   If = Yf * V;
0025 %   Sf = diag(Vf) * conj(If) = diag(conj(If)) * Vf
0026 %
0027 %   Polar coordinates:
0028 %     Partials of V, Vf & If w.r.t. voltage angles
0029 %       dV/dVa  = j * diag(V)
0030 %       dVf/dVa = sparse(1:nl, f, j * V(f)) = j * sparse(1:nl, f, V(f))
0031 %       dIf/dVa = Yf * dV/dVa = Yf * j * diag(V)
0032 %
0033 %     Partials of V, Vf & If w.r.t. voltage magnitudes
0034 %       dV/dVm  = diag(V./abs(V))
0035 %       dVf/dVm = sparse(1:nl, f, V(f)./abs(V(f))
0036 %       dIf/dVm = Yf * dV/dVm = Yf * diag(V./abs(V))
0037 %
0038 %     Partials of Sf w.r.t. voltage angles
0039 %       dSf/dVa = diag(Vf) * conj(dIf/dVa)
0040 %                       + diag(conj(If)) * dVf/dVa
0041 %               = diag(Vf) * conj(Yf * j * diag(V))
0042 %                       + conj(diag(If)) * j * sparse(1:nl, f, V(f))
0043 %               = -j * diag(Vf) * conj(Yf * diag(V))
0044 %                       + j * conj(diag(If)) * sparse(1:nl, f, V(f))
0045 %               = j * (conj(diag(If)) * sparse(1:nl, f, V(f))
0046 %                       - diag(Vf) * conj(Yf * diag(V)))
0047 %
0048 %     Partials of Sf w.r.t. voltage magnitudes
0049 %       dSf/dVm = diag(Vf) * conj(dIf/dVm)
0050 %                       + diag(conj(If)) * dVf/dVm
0051 %               = diag(Vf) * conj(Yf * diag(V./abs(V)))
0052 %                       + conj(diag(If)) * sparse(1:nl, f, V(f)./abs(V(f)))
0053 %
0054 %   Cartesian coordinates:
0055 %     Partials of V, Vf & If w.r.t. real part of complex voltage
0056 %       dV/dVr  = diag(ones(n,1))
0057 %       dVf/dVr = Cf
0058 %       dIf/dVr = Yf
0059 %     where Cf is the connection matrix for line & from buses
0060 %
0061 %     Partials of V, Vf & If w.r.t. imaginary part of complex voltage
0062 %       dV/dVi  = j * diag(ones(n,1))
0063 %       dVf/dVi = j * Cf
0064 %       dIf/dVi = j * Yf
0065 %
0066 %     Partials of Sf w.r.t. real part of complex voltage
0067 %       dSf/dVr = conj(diag(If)) * Cf + diag(Vf) * conj(Yf)
0068 %
0069 %     Partials of Sf w.r.t. imaginary part of complex voltage
0070 %       dSf/dVi = j * (conj(diag(If)) * Cf - diag(Vf) * conj(Yf))
0071 %
0072 %   Derivations for "to" bus are similar.
0073 %
0074 %   Examples:
0075 %       [Ybus, Yf, Yt] = makeYbus(baseMVA, bus, branch);
0076 %       [dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St] = ...
0077 %           dSbr_dV(branch, Yf, Yt, V);
0078 %       [dSf_dVr, dSf_dVi, dSt_dVr, dSt_dVi, Sf, St] = ...
0079 %           dSbr_dV(branch, Yf, Yt, V, 1);
0080 %
0081 %   For more details on the derivations behind the derivative code used
0082 %   in MATPOWER information, see:
0083 %
0084 %   [TN2]  R. D. Zimmerman, "AC Power Flows, Generalized OPF Costs and
0085 %          their Derivatives using Complex Matrix Notation", MATPOWER
0086 %          Technical Note 2, February 2010. [Online]. Available:
0087 %          https://matpower.org/docs/TN2-OPF-Derivatives.pdf
0088 %          doi: 10.5281/zenodo.3237866
0089 %   [TN4]  B. Sereeter and R. D. Zimmerman, "AC Power Flows and their
0090 %          Derivatives using Complex Matrix Notation and Cartesian
0091 %          Coordinate Voltages," MATPOWER Technical Note 4, April 2018.
0092 %          [Online]. Available: https://matpower.org/docs/TN4-OPF-Derivatives-Cartesian.pdf
0093 %          doi: 10.5281/zenodo.3237909
0094 
0095 %   MATPOWER
0096 %   Copyright (c) 1996-2019, Power Systems Engineering Research Center (PSERC)
0097 %   by Ray Zimmerman, PSERC Cornell
0098 %   and Baljinnyam Sereeter, Delft University of Technology
0099 %
0100 %   This file is part of MATPOWER.
0101 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0102 %   See https://matpower.org for more info.
0103 
0104 %% define named indices into bus, gen, branch matrices
0105 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0106     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0107     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0108 
0109 %% default input args
0110 if nargin < 5
0111     vcart = 0;      %% default to polar coordinates
0112 end
0113 
0114 %% define
0115 f = branch(:, F_BUS);       %% list of "from" buses
0116 t = branch(:, T_BUS);       %% list of "to" buses
0117 nl = length(f);
0118 nb = length(V);
0119 
0120 %% compute intermediate values
0121 Yfc = conj(Yf);
0122 Ytc = conj(Yt);
0123 Vc = conj(V);
0124 Ifc = Yfc * Vc;     %% conjugate of "from" current
0125 Itc = Ytc * Vc;     %% conjugate of "to" current
0126 
0127 if issparse(Yf)             %% sparse version (if Yf is sparse)
0128     diagVf  = sparse(1:nl, 1:nl, V(f), nl, nl);
0129     diagVt  = sparse(1:nl, 1:nl, V(t), nl, nl);
0130     diagIfc = sparse(1:nl, 1:nl, Ifc, nl, nl);
0131     diagItc = sparse(1:nl, 1:nl, Itc, nl, nl);
0132     if ~vcart
0133         Vnorm       = V ./ abs(V);
0134         diagVc      = sparse(1:nb, 1:nb, Vc, nb, nb);
0135         diagVnorm   = sparse(1:nb, 1:nb, Vnorm, nb, nb);
0136         CVf  = sparse(1:nl, f, V(f), nl, nb);
0137         CVnf = sparse(1:nl, f, Vnorm(f), nl, nb);
0138         CVt  = sparse(1:nl, t, V(t), nl, nb);
0139         CVnt = sparse(1:nl, t, Vnorm(t), nl, nb);
0140     end
0141 else                        %% dense version
0142     diagVf  = diag(V(f));
0143     diagVt  = diag(V(t));
0144     diagIfc = diag(Ifc);
0145     diagItc = diag(Itc);
0146     if ~vcart
0147         Vnorm       = V ./ abs(V);
0148         diagVc      = diag(Vc);
0149         diagVnorm   = diag(Vnorm);
0150 %         CVf        = zeros(nl, nb);    CVf(sub2ind([nl,nb], (1:nl)', f)) = V(f);
0151 %         CVnf       = zeros(nl, nb);    CVnf(sub2ind([nl,nb], (1:nl)', f)) = Vnorm(f);
0152 %         CVt        = zeros(nl, nb);    CVt(sub2ind([nl,nb], (1:nl)', t)) = V(t);
0153 %         CVnt       = zeros(nl, nb);    CVnt(sub2ind([nl,nb], (1:nl)', t)) = Vnorm(t);
0154         CVf  = full(sparse(1:nl, f, V(f), nl, nb));
0155         CVnf = full(sparse(1:nl, f, Vnorm(f), nl, nb));
0156         CVt  = full(sparse(1:nl, t, V(t), nl, nb));
0157         CVnt = full(sparse(1:nl, t, Vnorm(t), nl, nb));
0158     end
0159 end
0160 if vcart
0161     Cf = sparse(1:nl, f, ones(nl, 1), nl, nb);      %% connection matrix for line & from buses
0162     Ct = sparse(1:nl, t, ones(nl, 1), nl, nb);      %% connection matrix for line & to buses
0163     Af = diagIfc * Cf;
0164     Bf = diagVf * Yfc;
0165     At = diagItc * Ct;
0166     Bt = diagVt * Ytc;
0167 
0168     dSf_dV1 = Af + Bf;          %% dSf_dVr
0169     dSf_dV2 = 1j * (Af - Bf);   %% dSf_dVi
0170     dSt_dV1 = At + Bt;          %% dSt_dVr
0171     dSt_dV2 = 1j * (At - Bt);   %% dSt_dVi
0172 else
0173     dSf_dV1 = 1j * (diagIfc * CVf - diagVf * Yfc * diagVc);     %% dSf_dVa
0174     dSf_dV2 = diagVf * conj(Yf * diagVnorm) + diagIfc * CVnf;   %% dSf_dVm
0175     dSt_dV1 = 1j * (diagItc * CVt - diagVt * Ytc * diagVc);     %% dSt_dVa
0176     dSt_dV2 = diagVt * conj(Yt * diagVnorm) + diagItc * CVnt;   %% dSt_dVm
0177 end
0178 
0179 if nargout > 4
0180     Sf = V(f) .* Ifc;
0181     St = V(t) .* Itc;
0182 end

Generated on Fri 09-Oct-2020 11:21:31 by m2html © 2005