DIBR_DV Computes partial derivatives of branch currents w.r.t. voltage. The derivatives can be take with respect to polar or cartesian coordinates of voltage, depending on the 5th argument. [DIF_DVA, DIF_DVM, DIT_DVA, DIT_DVM, IF, IT] = DIBR_DV(BRANCH, YF, YT, V) [DIF_DVA, DIF_DVM, DIT_DVA, DIT_DVM, IF, IT] = DIBR_DV(BRANCH, YF, YT, V, 0) Returns four matrices containing partial derivatives of the complex branch currents at "from" and "to" ends of each branch w.r.t voltage magnitude and voltage angle, respectively (for all buses). [DIF_DVR, DIF_DVI, DIT_DVR, DIT_DVI, IF, IT] = DIBR_DV(BRANCH, YF, YT, V, 1) Returns four matrices containing partial derivatives of the complex branch currents 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 currents themselves. The following explains the expressions used to form the matrices: If = Yf * V; 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)) 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 Derivations for "to" bus are similar. Example: [Ybus, Yf, Yt] = makeYbus(baseMVA, bus, branch); [dIf_dVa, dIf_dVm, dIt_dVa, dIt_dVm, If, It] = ... dIbr_dV(branch, Yf, Yt, V); [dIf_dVr, dIf_dVi, dIt_dVr, dIt_dVi, If, It] = ... dIbr_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
0001 function [dIf_dV1, dIf_dV2, dIt_dV1, dIt_dV2, If, It] = dIbr_dV(branch, Yf, Yt, V, vcart) 0002 %DIBR_DV Computes partial derivatives of branch currents 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 % [DIF_DVA, DIF_DVM, DIT_DVA, DIT_DVM, IF, IT] = DIBR_DV(BRANCH, YF, YT, V) 0008 % [DIF_DVA, DIF_DVM, DIT_DVA, DIT_DVM, IF, IT] = DIBR_DV(BRANCH, YF, YT, V, 0) 0009 % 0010 % Returns four matrices containing partial derivatives of the complex 0011 % branch currents at "from" and "to" ends of each branch w.r.t voltage 0012 % magnitude and voltage angle, respectively (for all buses). 0013 % 0014 % [DIF_DVR, DIF_DVI, DIT_DVR, DIT_DVI, IF, IT] = DIBR_DV(BRANCH, YF, YT, V, 1) 0015 % 0016 % Returns four matrices containing partial derivatives of the complex 0017 % branch currents 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 currents themselves. The 0022 % following explains the expressions used to form the matrices: 0023 % 0024 % If = Yf * V; 0025 % 0026 % Polar coordinates: 0027 % Partials of V, Vf & If w.r.t. voltage angles 0028 % dV/dVa = j * diag(V) 0029 % dVf/dVa = sparse(1:nl, f, j * V(f)) = j * sparse(1:nl, f, V(f)) 0030 % dIf/dVa = Yf * dV/dVa = Yf * j * diag(V) 0031 % 0032 % Partials of V, Vf & If w.r.t. voltage magnitudes 0033 % dV/dVm = diag(V./abs(V)) 0034 % dVf/dVm = sparse(1:nl, f, V(f)./abs(V(f)) 0035 % dIf/dVm = Yf * dV/dVm = Yf * diag(V./abs(V)) 0036 % 0037 % Cartesian coordinates: 0038 % Partials of V, Vf & If w.r.t. real part of complex voltage 0039 % dV/dVr = diag(ones(n,1)) 0040 % dVf/dVr = Cf 0041 % dIf/dVr = Yf 0042 % where Cf is the connection matrix for line & from buses 0043 % 0044 % Partials of V, Vf & If w.r.t. imaginary part of complex voltage 0045 % dV/dVi = j * diag(ones(n,1)) 0046 % dVf/dVi = j * Cf 0047 % dIf/dVi = j * Yf 0048 % 0049 % Derivations for "to" bus are similar. 0050 % 0051 % Example: 0052 % [Ybus, Yf, Yt] = makeYbus(baseMVA, bus, branch); 0053 % [dIf_dVa, dIf_dVm, dIt_dVa, dIt_dVm, If, It] = ... 0054 % dIbr_dV(branch, Yf, Yt, V); 0055 % [dIf_dVr, dIf_dVi, dIt_dVr, dIt_dVi, If, It] = ... 0056 % dIbr_dV(branch, Yf, Yt, V, 1); 0057 % 0058 % For more details on the derivations behind the derivative code used 0059 % in MATPOWER information, see: 0060 % 0061 % [TN2] R. D. Zimmerman, "AC Power Flows, Generalized OPF Costs and 0062 % their Derivatives using Complex Matrix Notation", MATPOWER 0063 % Technical Note 2, February 2010. [Online]. Available: 0064 % https://matpower.org/docs/TN2-OPF-Derivatives.pdf 0065 % doi: 10.5281/zenodo.3237866 0066 % [TN4] B. Sereeter and R. D. Zimmerman, "AC Power Flows and their 0067 % Derivatives using Complex Matrix Notation and Cartesian 0068 % Coordinate Voltages," MATPOWER Technical Note 4, April 2018. 0069 % [Online]. Available: https://matpower.org/docs/TN4-OPF-Derivatives-Cartesian.pdf 0070 % doi: 10.5281/zenodo.3237909 0071 0072 % MATPOWER 0073 % Copyright (c) 1996-2019, Power Systems Engineering Research Center (PSERC) 0074 % by Ray Zimmerman, PSERC Cornell 0075 % 0076 % This file is part of MATPOWER. 0077 % Covered by the 3-clause BSD License (see LICENSE file for details). 0078 % See https://matpower.org for more info. 0079 0080 %% default input args 0081 if nargin < 5 0082 vcart = 0; %% default to polar coordinates 0083 end 0084 0085 %% define 0086 nb = length(V); 0087 0088 if vcart 0089 dIf_dV1 = Yf; %% dIf_dVr 0090 dIf_dV2 = 1j * Yf; %% dIf_dVi 0091 dIt_dV1 = Yt; %% dIt_dVr 0092 dIt_dV2 = 1j * Yt; %% dIt_dVi 0093 else 0094 Vnorm = V ./ abs(V); 0095 if issparse(Yf) %% sparse version (if Yf is sparse) 0096 diagV = sparse(1:nb, 1:nb, V, nb, nb); 0097 diagVnorm = sparse(1:nb, 1:nb, Vnorm, nb, nb); 0098 else %% dense version 0099 diagV = diag(V); 0100 diagVnorm = diag(Vnorm); 0101 end 0102 dIf_dV1 = Yf * 1j * diagV; %% dIf_dVa 0103 dIf_dV2 = Yf * diagVnorm; %% dIf_dVm 0104 dIt_dV1 = Yt * 1j * diagV; %% dIt_dVa 0105 dIt_dV2 = Yt * diagVnorm; %% dIt_dVm 0106 end 0107 0108 %% compute currents 0109 if nargout > 4 0110 If = Yf * V; 0111 It = Yt * V; 0112 end