Skip to content

Commit

Permalink
Address output of branch losses mentioned in #234.
Browse files Browse the repository at this point in the history
- Add shunt loss columns (`psh_fr`, `qsh_fr`, `psh_to`, `qsh_to`) to branch data model.
- Separate branch loss summary into series and shunt losses.
- Add series loss columns to branch detail output.

Thanks to Wilson González Vanegas.

Ref: #234
  • Loading branch information
rdzman committed Jun 5, 2024
1 parent a8ae137 commit e7f41f0
Show file tree
Hide file tree
Showing 20 changed files with 577 additions and 380 deletions.
11 changes: 11 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ For change history for [MP-Opt-Model][27], see [mp-opt-model/CHANGES.md](mp-opt-
For change history for [MOST][3], see [most/CHANGES.md](most/CHANGES.md).


since 8.0
---------

#### 6/4/24
- Add shunt loss columns (`psh_fr`, `qsh_fr`, `psh_to`, `qsh_to`) to
branch data model. In pretty-printed output, separate branch loss summary
into series and shunt losses and add series loss columns to branch detail
output.
*Thanks to Wilson González Vanegas.*


Version 8.0 - *May 17, 2024
---------------------------

Expand Down
56 changes: 52 additions & 4 deletions docs/src/MATPOWER-manual/MATPOWER-manual.tex
Original file line number Diff line number Diff line change
Expand Up @@ -8647,11 +8647,61 @@ \subsubsection*{Incompatible Changes}
\end{itemize}


\clearpage
\subsection{Version 8.0.1-dev -- released ??? ??, 202?}
\label{app:v801}

The \href{https://matpower.org/docs/MATPOWER-manual-8.0.1-dev.pdf}{\matpower{} 8.0.1-dev User's Manual} is available online.\footnote{\url{https://matpower.org/docs/MATPOWER-manual-8.0.1-dev.pdf}}

\subsubsection*{New Features}
\begin{itemize}
\item
\item New options:
\begin{itemize}
\item \code{foo.bar}
\end{itemize}
\item New functions/methods:
\begin{itemize}
\item \code{foo}
\end{itemize}
\end{itemize}

\subsubsection*{New Case Files}
\begin{itemize}
\item
\end{itemize}

\subsubsection*{New Documentation}
\begin{itemize}
\item
\end{itemize}

\subsubsection*{Other Improvements}
\begin{itemize}
\item Add shunt loss columns (\code{psh\_fr}, \code{qsh\_fr}, \code{psh\_to}, \code{qsh\_to}) to branch data model. In pretty-printed output, separate branch loss summary into series and shunt losses and add series loss columns to branch detail output.
\emph{Thanks to Wilson Gonz\'alez Vanegas.}
\item Deprecated functions:
\begin{itemize}
\item
\end{itemize}
\end{itemize}

% \pagebreak
\subsubsection*{Bugs Fixed}
\begin{itemize}
\item
\end{itemize}

\subsubsection*{Incompatible Changes}
\begin{itemize}
\item
\end{itemize}

% \clearpage
% \subsection{Version 8.0 -- released ??? ??, 202?}
% \subsection{Version 9.0 -- released ??? ??, 202?}
% \label{app:v80}
%
% The \href{https://matpower.org/docs/MATPOWER-manual-8.0.pdf}{\matpower{} 8.0 User's Manual} is available online.\footnote{\url{https://matpower.org/docs/MATPOWER-manual-8.0.pdf}}
% The \href{https://matpower.org/docs/MATPOWER-manual-9.0.pdf}{\matpower{} 9.0 User's Manual} is available online.\footnote{\url{https://matpower.org/docs/MATPOWER-manual-9.0.pdf}}
%
% \subsubsection*{New Features}
% \begin{itemize}
Expand Down Expand Up @@ -8695,8 +8745,6 @@ \subsubsection*{Incompatible Changes}
% \begin{itemize}
% \item
% \end{itemize}
%
%
\end{appendices}


Expand Down
4 changes: 4 additions & 0 deletions lib/+mp/dmce_branch_mpc2.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
vmap.ql_fr{2} = QF;
vmap.pl_to{2} = PT;
vmap.ql_to{2} = QT;
vmap.psh_fr = {'num', 0}; %% zeros
vmap.qsh_fr = {'num', 0}; %% zeros
vmap.psh_to = {'num', 0}; %% zeros
vmap.qsh_to = {'num', 0}; %% zeros
vmap.mu_flow_fr_ub{2} = MU_SF;
vmap.mu_flow_to_ub{2} = MU_ST;
vmap.mu_vad_lb{2} = MU_ANGMIN;
Expand Down
89 changes: 83 additions & 6 deletions lib/+mp/dme_branch.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
% ``ql_fr`` *double* reactive power injection at "from" end
% ``pl_to`` *double* active power injection at "to" end
% ``ql_to`` *double* reactive power injection at "to" end
% ``psh_fr`` *double* active power shunt losses at "from" end
% ``qsh_fr`` *double* reactive power shunt losses at "from" end
% ``psh_to`` *double* active power shunt losses at "to" end
% ``qsh_to`` *double* reactive power shunt losses at "to" end
% =========== ========= ========================================

% MATPOWER
Expand All @@ -57,6 +61,7 @@
tm % transformer off-nominal turns ratio for branches that are on
ta % xformer phase-shift angle (radians) for branches that are on
rate_a % long term flow limit (p.u.) for branches that are on
loss_tol = 1e-4; % loss values < this are displayed as ``-``
end %% properties

methods
Expand Down Expand Up @@ -92,12 +97,14 @@
'g_to', 'b_to', 'sm_ub_a', 'sm_ub_b', 'sm_ub_c', ...
'cm_ub_a', 'cm_ub_b', 'cm_ub_c', 'vad_lb', 'vad_ub', ...
'tm', 'ta', ... %% remove these when we separate out xformers
'pl_fr', 'ql_fr', 'pl_to', 'ql_to'} );
'pl_fr', 'ql_fr', 'pl_to', 'ql_to', ...
'psh_fr', 'qsh_fr', 'psh_to', 'qsh_to'} );
end

function vars = export_vars(obj)
%
vars = {'pl_fr', 'ql_fr', 'pl_to', 'ql_to'};
vars = {'pl_fr', 'ql_fr', 'pl_to', 'ql_to', ...
'psh_fr', 'qsh_fr', 'psh_to', 'qsh_to'};
end

function s = export_vars_offline_val(obj)
Expand All @@ -108,6 +115,10 @@
s.ql_fr = 0;
s.pl_to = 0;
s.ql_to = 0;
s.psh_fr = 0;
s.qsh_fr = 0;
s.psh_to = 0;
s.qsh_to = 0;
end

function obj = initialize(obj, dm)
Expand Down Expand Up @@ -193,11 +204,43 @@
[email protected]_element(obj, dm, rows, out_e, mpopt, fd, pp_args);

%% print branch summary
fprintf(fd, ' %-29s %12.2f MW', 'Total branch losses', ...
sum(obj.tab.pl_fr(obj.on)) + sum(obj.tab.pl_to(obj.on)) );
p_loss = sum(obj.tab.pl_fr(obj.on)) + sum(obj.tab.pl_to(obj.on));
p_shunt = sum(obj.tab.psh_fr(obj.on)) + sum(obj.tab.psh_to(obj.on));
p_series = p_loss - p_shunt;
if abs(p_series) < obj.loss_tol
p_series_str = '- ';
else
p_series_str = sprintf('%12.2f', p_series);
end
fprintf(fd, ' %-29s %12s MW', 'Total branch series losses', ...
p_series_str);
if mpopt.model(1) ~= 'D' %% AC model
q_loss = sum(obj.tab.ql_fr(obj.on)) + sum(obj.tab.ql_to(obj.on));
q_shunt = sum(obj.tab.qsh_fr(obj.on)) + ...
sum(obj.tab.qsh_to(obj.on));
q_series = q_loss - q_shunt;
if abs(q_series) < obj.loss_tol
q_series_str = '- ';
else
q_series_str = sprintf('%12.2f', q_series);
end
fprintf(fd, ' %12s MVAr', q_series_str);
end
fprintf(fd, '\n');
if abs(p_shunt) < obj.loss_tol
p_shunt_str = '- ';
else
p_shunt_str = sprintf('%12.2f', p_shunt);
end
fprintf(fd, ' %-29s %12s MW', 'Total branch shunt losses', ...
p_shunt_str );
if mpopt.model(1) ~= 'D' %% AC model
fprintf(fd, ' %12.2f MVAr', ...
sum(obj.tab.ql_fr(obj.on)) + sum(obj.tab.ql_to(obj.on)) );
if abs(q_shunt) < obj.loss_tol
q_shunt_str = '- ';
else
q_shunt_str = sprintf('%12.2f', q_shunt);
end
fprintf(fd, ' %12s MVAr', q_shunt_str );
end
fprintf(fd, '\n');
end
Expand All @@ -209,6 +252,33 @@
' ID Bus ID Bus ID Status P (MW) Q (MVAr) P (MW) Q (MVAr)', ...
'-------- -------- -------- ------ -------- -------- -------- --------' } ];
%% 1234567 123456789 123456789 -----1 1234567.90 123456.89 123456.89 123456.89
if mpopt.model(1) ~= 'D' %% AC model
h{end-2} = [h{end-2} ' Series Loss'];
h{end-1} = [h{end-1} ' P (MW) Q (MVAr)'];
h{end} = [h{end} ' -------- --------'];
%% 12345.789 123456.89
%% 12345.789 123456.89
end
end

function f = pp_get_footers_det(obj, dm, out_e, mpopt, pp_args)
%
if mpopt.model(1) == 'D' %% DC model (series losses)
f = {};
else %% AC model
p_loss = sum(obj.tab.pl_fr(obj.on)) + ...
sum(obj.tab.pl_to(obj.on));
p_shunt = sum(obj.tab.psh_fr(obj.on)) + ...
sum(obj.tab.psh_to(obj.on));
p_series = p_loss - p_shunt;
q_loss = sum(obj.tab.ql_fr(obj.on)) + ...
sum(obj.tab.ql_to(obj.on));
q_shunt = sum(obj.tab.qsh_fr(obj.on)) + ...
sum(obj.tab.qsh_to(obj.on));
q_series = q_loss - q_shunt;
f = {' -------- --------',
sprintf('%69s Total:%9.3f %9.2f', '', p_series, q_series)};
end
end

function TorF = pp_have_section_det(obj, mpopt, pp_args)
Expand All @@ -223,6 +293,13 @@
obj.tab.status(k), ...
obj.tab.pl_fr(k), obj.tab.ql_fr(k), ...
obj.tab.pl_to(k), obj.tab.ql_to(k) );
if mpopt.model(1) ~= 'D' %% AC model
str = sprintf('%s %9.3f %9.2f', str, ...
obj.tab.pl_fr(k) + obj.tab.pl_to(k) ...
- obj.tab.psh_fr(k) - obj.tab.psh_to(k), ...
obj.tab.ql_fr(k) + obj.tab.ql_to(k) ...
- obj.tab.qsh_fr(k) - obj.tab.qsh_to(k) );
end
end
end %% methods
end %% classdef
14 changes: 14 additions & 0 deletions lib/+mp/mme_branch_opf_ac.m
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,25 @@
%% shadow prices on angle difference limits
[mu_vad_lb, mu_vad_ub] = obj.ang_diff_prices(mm, nme);

%% branch shunt power losses
v = nme.C' * nm.soln.v;
vm2 = v .* conj(v);
vm2_fr = vm2(1:length(v)/2);
vm2_to = vm2(length(v)/2+1:end);
psh_fr = vm2_fr .* dme.tab.g_fr(dme.on);
qsh_fr = -vm2_fr .* dme.tab.b_fr(dme.on);
psh_to = vm2_to .* dme.tab.g_to(dme.on);
qsh_to = -vm2_to .* dme.tab.b_to(dme.on);

%% update in the data model
dme.tab.pl_fr(dme.on) = real(S_fr) * dm.base_mva;
dme.tab.ql_fr(dme.on) = imag(S_fr) * dm.base_mva;
dme.tab.pl_to(dme.on) = real(S_to) * dm.base_mva;
dme.tab.ql_to(dme.on) = imag(S_to) * dm.base_mva;
dme.tab.psh_fr(dme.on) = psh_fr * dm.base_mva;
dme.tab.qsh_fr(dme.on) = qsh_fr * dm.base_mva;
dme.tab.psh_to(dme.on) = psh_to * dm.base_mva;
dme.tab.qsh_to(dme.on) = qsh_to * dm.base_mva;
dme.tab.mu_flow_fr_ub(dme.on) = mu_flow_fr_ub / dm.base_mva;
dme.tab.mu_flow_to_ub(dme.on) = mu_flow_to_ub / dm.base_mva;
dme.tab.mu_vad_lb(dme.on) = mu_vad_lb * pi/180;
Expand Down
10 changes: 10 additions & 0 deletions lib/+mp/mme_branch_opf_dc.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
pl_fr = nm.soln.gp(pp.i1.branch(1):pp.iN.branch(1));
pl_to = nm.soln.gp(pp.i1.branch(2):pp.iN.branch(2));

%% branch shunt power losses
psh_fr = dme.tab.g_fr(dme.on);
psh_to = dme.tab.g_to(dme.on);

%% shadow prices on branch flow constraints
ibr = mm.userdata.flow_constrained_branch_idx;
mu_flow_fr_ub = zeros(nme.nk, 1);
Expand All @@ -77,7 +81,13 @@

%% update in the data model
dme.tab.pl_fr(dme.on) = pl_fr * dm.base_mva;
dme.tab.ql_fr(dme.on) = 0;
dme.tab.pl_to(dme.on) = pl_to * dm.base_mva;
dme.tab.ql_to(dme.on) = 0;
dme.tab.psh_fr(dme.on) = psh_fr * dm.base_mva;
dme.tab.qsh_fr(dme.on) = 0;
dme.tab.psh_to(dme.on) = psh_to * dm.base_mva;
dme.tab.qsh_to(dme.on) = 0;
dme.tab.mu_flow_fr_ub(dme.on) = mu_flow_fr_ub / dm.base_mva;
dme.tab.mu_flow_to_ub(dme.on) = mu_flow_to_ub / dm.base_mva;
dme.tab.mu_vad_lb(dme.on) = mu_vad_lb * pi/180;
Expand Down
18 changes: 17 additions & 1 deletion lib/+mp/mme_branch_pf_ac.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,33 @@
function obj = data_model_update_on(obj, mm, nm, dm, mpopt)
%

dme = obj.data_model_element(dm);
nme = obj.network_model_element(nm);

%% branch complex power flows
pp = nm.get_idx('port');
S_fr = nm.soln.gs_(pp.i1.branch(1):pp.iN.branch(1));
S_to = nm.soln.gs_(pp.i1.branch(2):pp.iN.branch(2));

%% branch shunt power losses
v = nme.C' * nm.soln.v;
vm2 = v .* conj(v);
vm2_fr = vm2(1:length(v)/2);
vm2_to = vm2(length(v)/2+1:end);
psh_fr = vm2_fr .* dme.tab.g_fr(dme.on);
qsh_fr = -vm2_fr .* dme.tab.b_fr(dme.on);
psh_to = vm2_to .* dme.tab.g_to(dme.on);
qsh_to = -vm2_to .* dme.tab.b_to(dme.on);

%% update in the data model
dme = obj.data_model_element(dm);
dme.tab.pl_fr(dme.on) = real(S_fr) * dm.base_mva;
dme.tab.ql_fr(dme.on) = imag(S_fr) * dm.base_mva;
dme.tab.pl_to(dme.on) = real(S_to) * dm.base_mva;
dme.tab.ql_to(dme.on) = imag(S_to) * dm.base_mva;
dme.tab.psh_fr(dme.on) = psh_fr * dm.base_mva;
dme.tab.qsh_fr(dme.on) = qsh_fr * dm.base_mva;
dme.tab.psh_to(dme.on) = psh_to * dm.base_mva;
dme.tab.qsh_to(dme.on) = qsh_to * dm.base_mva;
end
end %% methods
end %% classdef
11 changes: 10 additions & 1 deletion lib/+mp/mme_branch_pf_dc.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,26 @@
function obj = data_model_update_on(obj, mm, nm, dm, mpopt)
%

dme = obj.data_model_element(dm);

%% branch active power flows
pp = nm.get_idx('port');
pl_fr = nm.soln.gp(pp.i1.branch(1):pp.iN.branch(1));
pl_to = nm.soln.gp(pp.i1.branch(2):pp.iN.branch(2));

%% branch shunt power losses
psh_fr = dme.tab.g_fr(dme.on);
psh_to = dme.tab.g_to(dme.on);

%% update in the data model
dme = obj.data_model_element(dm);
dme.tab.pl_fr(dme.on) = pl_fr * dm.base_mva;
dme.tab.ql_fr(dme.on) = 0;
dme.tab.pl_to(dme.on) = pl_to * dm.base_mva;
dme.tab.ql_to(dme.on) = 0;
dme.tab.psh_fr(dme.on) = psh_fr * dm.base_mva;
dme.tab.qsh_fr(dme.on) = 0;
dme.tab.psh_to(dme.on) = psh_to * dm.base_mva;
dme.tab.qsh_to(dme.on) = 0;
end
end %% methods
end %% classdef
Loading

0 comments on commit e7f41f0

Please sign in to comment.