DSBUS_DV Computes partial derivatives of power injection w.r.t. voltage. The derivatives can be take with respect to polar or cartesian coordinates of voltage, depending on the 3rd argument. [DSBUS_DVA, DSBUS_DVM] = DSBUS_DV(YBUS, V) [DSBUS_DVA, DSBUS_DVM] = DSBUS_DV(YBUS, V, 0) Returns two matrices containing partial derivatives of the complex bus power injections w.r.t voltage angle and voltage magnitude, respectively (for all buses). [DSBUS_DVR, DSBUS_DVI] = DSBUS_DV(YBUS, V, 1) Returns two matrices containing partial derivatives of the complex bus power injections w.r.t the real and imaginary parts of voltage, 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: S = diag(V) * conj(Ibus) = diag(conj(Ibus)) * V Polar coordinates: 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)) Partials of V & Ibus w.r.t. voltage angles dV/dVa = j * diag(V) dI/dVa = Ybus * dV/dVa = Ybus * j * diag(V) 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)) 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)) Cartesian coordinates: Partials of V & Ibus w.r.t. real part of complex voltage dV/dVr = diag(ones(n,1)) dI/dVr = Ybus * dV/dVr = Ybus Partials of V & Ibus w.r.t. imaginary part of complex voltage dV/dVi = j * diag(ones(n,1)) dI/dVi = Ybus * dV/dVi = Ybus * j Partials of S w.r.t. real part of complex voltage dS/dVr = diag(V) * conj(dI/dVr) + diag(conj(Ibus)) * dV/dVr = diag(V) * conj(Ybus) + conj(diag(Ibus)) Partials of S w.r.t. imaginary part of complex voltage dS/dVi = diag(V) * conj(dI/dVi) + diag(conj(Ibus)) * dV/dVi = j * (conj(diag(Ibus)) - diag(V) conj(Ybus)) Examples: [Ybus, Yf, Yt] = makeYbus(baseMVA, bus, branch); [dSbus_dVa, dSbus_dVm] = dSbus_dV(Ybus, V); [dSbus_dVr, dSbus_dVi] = dSbus_dV(Ybus, 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 [dSbus_dV1, dSbus_dV2] = dSbus_dV(Ybus, V, vcart) 0002 %DSBUS_DV Computes partial derivatives of power injection w.r.t. voltage. 0003 % 0004 % The derivatives can be take with respect to polar or cartesian coordinates 0005 % of voltage, depending on the 3rd argument. 0006 % 0007 % [DSBUS_DVA, DSBUS_DVM] = DSBUS_DV(YBUS, V) 0008 % [DSBUS_DVA, DSBUS_DVM] = DSBUS_DV(YBUS, V, 0) 0009 % 0010 % Returns two matrices containing partial derivatives of the complex bus 0011 % power injections w.r.t voltage angle and voltage magnitude, respectively 0012 % (for all buses). 0013 % 0014 % [DSBUS_DVR, DSBUS_DVI] = DSBUS_DV(YBUS, V, 1) 0015 % 0016 % Returns two matrices containing partial derivatives of the complex bus 0017 % power injections w.r.t the real and imaginary parts of voltage, 0018 % respectively (for all buses). 0019 % 0020 % If YBUS is a sparse matrix, the return values will be also. The following 0021 % explains the expressions used to form the matrices: 0022 % 0023 % S = diag(V) * conj(Ibus) = diag(conj(Ibus)) * V 0024 % 0025 % Polar coordinates: 0026 % Partials of V & Ibus w.r.t. voltage magnitudes 0027 % dV/dVm = diag(V./abs(V)) 0028 % dI/dVm = Ybus * dV/dVm = Ybus * diag(V./abs(V)) 0029 % 0030 % Partials of V & Ibus w.r.t. voltage angles 0031 % dV/dVa = j * diag(V) 0032 % dI/dVa = Ybus * dV/dVa = Ybus * j * diag(V) 0033 % 0034 % Partials of S w.r.t. voltage magnitudes 0035 % dS/dVm = diag(V) * conj(dI/dVm) + diag(conj(Ibus)) * dV/dVm 0036 % = diag(V) * conj(Ybus * diag(V./abs(V))) 0037 % + conj(diag(Ibus)) * diag(V./abs(V)) 0038 % 0039 % Partials of S w.r.t. voltage angles 0040 % dS/dVa = diag(V) * conj(dI/dVa) + diag(conj(Ibus)) * dV/dVa 0041 % = diag(V) * conj(Ybus * j * diag(V)) 0042 % + conj(diag(Ibus)) * j * diag(V) 0043 % = -j * diag(V) * conj(Ybus * diag(V)) 0044 % + conj(diag(Ibus)) * j * diag(V) 0045 % = j * diag(V) * conj(diag(Ibus) - Ybus * diag(V)) 0046 % 0047 % Cartesian coordinates: 0048 % Partials of V & Ibus w.r.t. real part of complex voltage 0049 % dV/dVr = diag(ones(n,1)) 0050 % dI/dVr = Ybus * dV/dVr = Ybus 0051 % 0052 % Partials of V & Ibus w.r.t. imaginary part of complex voltage 0053 % dV/dVi = j * diag(ones(n,1)) 0054 % dI/dVi = Ybus * dV/dVi = Ybus * j 0055 % 0056 % Partials of S w.r.t. real part of complex voltage 0057 % dS/dVr = diag(V) * conj(dI/dVr) + diag(conj(Ibus)) * dV/dVr 0058 % = diag(V) * conj(Ybus) + conj(diag(Ibus)) 0059 % 0060 % Partials of S w.r.t. imaginary part of complex voltage 0061 % dS/dVi = diag(V) * conj(dI/dVi) + diag(conj(Ibus)) * dV/dVi 0062 % = j * (conj(diag(Ibus)) - diag(V) conj(Ybus)) 0063 % 0064 % Examples: 0065 % [Ybus, Yf, Yt] = makeYbus(baseMVA, bus, branch); 0066 % [dSbus_dVa, dSbus_dVm] = dSbus_dV(Ybus, V); 0067 % [dSbus_dVr, dSbus_dVi] = dSbus_dV(Ybus, V, 1); 0068 % 0069 % For more details on the derivations behind the derivative code used 0070 % in MATPOWER information, see: 0071 % 0072 % [TN2] R. D. Zimmerman, "AC Power Flows, Generalized OPF Costs and 0073 % their Derivatives using Complex Matrix Notation", MATPOWER 0074 % Technical Note 2, February 2010. [Online]. Available: 0075 % https://matpower.org/docs/TN2-OPF-Derivatives.pdf 0076 % doi: 10.5281/zenodo.3237866 0077 % [TN4] B. Sereeter and R. D. Zimmerman, "AC Power Flows and their 0078 % Derivatives using Complex Matrix Notation and Cartesian 0079 % Coordinate Voltages," MATPOWER Technical Note 4, April 2018. 0080 % [Online]. Available: https://matpower.org/docs/TN4-OPF-Derivatives-Cartesian.pdf 0081 % doi: 10.5281/zenodo.3237909 0082 0083 % MATPOWER 0084 % Copyright (c) 1996-2019, Power Systems Engineering Research Center (PSERC) 0085 % by Ray Zimmerman, PSERC Cornell 0086 % and Baljinnyam Sereeter, Delft University of Technology 0087 % 0088 % This file is part of MATPOWER. 0089 % Covered by the 3-clause BSD License (see LICENSE file for details). 0090 % See https://matpower.org for more info. 0091 0092 %% default input args 0093 if nargin < 3 0094 vcart = 0; %% default to polar coordinates 0095 end 0096 0097 n = length(V); 0098 Ibus = Ybus * V; 0099 0100 if issparse(Ybus) %% sparse version (if Ybus is sparse) 0101 diagV = sparse(1:n, 1:n, V, n, n); 0102 diagIbus = sparse(1:n, 1:n, Ibus, n, n); 0103 if ~vcart 0104 diagVnorm = sparse(1:n, 1:n, V./abs(V), n, n); 0105 end 0106 else %% dense version 0107 diagV = diag(V); 0108 diagIbus = diag(Ibus); 0109 if ~vcart 0110 diagVnorm = diag(V./abs(V)); 0111 end 0112 end 0113 0114 if vcart 0115 dSbus_dV1 = conj(diagIbus) + diagV * conj(Ybus); %% dSbus/dVr 0116 dSbus_dV2 = 1j * (conj(diagIbus) - diagV * conj(Ybus)); %% dSbus/dVi 0117 else 0118 dSbus_dV1 = 1j * diagV * conj(diagIbus - Ybus * diagV); %% dSbus/dVa 0119 dSbus_dV2 = diagV * conj(Ybus * diagVnorm) + conj(diagIbus) * diagVnorm; %% dSbus/dVm 0120 end