


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