MATPOWER / matpower

MATPOWER – steady state power flow simulation and optimization for MATLAB and Octave
https://matpower.org
Other
428 stars 151 forks source link

Branch losses for pretty-printed results in flexible Matpower framework #234

Closed WilsonGV closed 5 months ago

WilsonGV commented 5 months ago

I found differences in the pretty-printed results of the branch summary between legacy and flexible Matpower's frameworks. In particular, the total reactive power brach losses printed while using the flexible Matpower framework is not consistent with the result of the Matpower's function get_losses (used in the legacy Matpower framework)

This happens because in the method pp_data_sum of subclass dme_branch the total losses are calculated from the port injections which also includes reactive power of shunt admitances of the pi-model. I implemmented the following code to show the issue:

clear; close all; clc

mpc = 'case300'; 

%% Flexible framework
mpopt = mpoption('verbose', 0);
mpopt.out.all = 0;  
task = mp.task_pf();
res_flex = task.run(mpc, mpopt);
% mpopt.out.all = -1; res_flex.print_soln(mpopt);

%% Legacy framework
res_lega = runpf(mpc, mpopt);
% mpopt.out.all = -1; printpf(res_lega, mpopt);

%% Current computation of branch losses
% Legacy framework (benchmark)
bl_lega = sum(get_losses(res_lega));
Plega = real(bl_lega);
Qlega = imag(bl_lega);

% Flexible framework
obj = res_flex.dm.elements.branch;
Pflex = sum(obj.tab.pl_fr(obj.on)) + sum(obj.tab.pl_to(obj.on));   %% line  197 of mp.dme_branch
Qflex = sum(obj.tab.ql_fr(obj.on)) + sum(obj.tab.ql_to(obj.on));   %% line  200 of mp.dme_branch

%% Suggested computation for flexible framework
dme_bus = res_flex.dm.elements.bus;
obj.tab.bc = res_flex.dm.source.branch(:,5);   %  BR_B column
[~, id_fr] = ismember(obj.tab.bus_fr, dme_bus.tab.uid);
[~, id_to] = ismember(obj.tab.bus_to, dme_bus.tab.uid);
obj.tab.qsh_fr = (dme_bus.tab.vm(id_fr).^2) .* (obj.tab.bc ./ 2) * res_flex.dm.base_mva;
obj.tab.qsh_to = (dme_bus.tab.vm(id_to).^2) .* (obj.tab.bc ./ 2) * res_flex.dm.base_mva;

Q = sum(obj.tab.ql_fr(obj.on)) + sum(obj.tab.qsh_fr(obj.on)) + ...
    sum(obj.tab.ql_to(obj.on)) + sum(obj.tab.qsh_to(obj.on));

%% Print results
fprintf('\n         Legacy                   Flexible                   Suggested         ')
fprintf('\n  ---------------------      ---------------------      ---------------------  ')
fprintf('\n    P(MW)      Q(MVAr)         P(MW)      Q(MVAr)         P(MW)      Q(MVAr)   ')
fprintf('\n   %7.3f     %7.3f       %7.3f    %7.3f        %7.3f      %7.3f\n',...
              Plega,   Qlega,      Pflex,    Qflex,        Pflex,          Q)

The suggested computation for the total branch series reactive losses employs two new columns, qsh_fr and qsh_to, added to the table of branches which hold the reactive power related to shunts admitances at from and to sides.

Notice that the computation of obj.tab.qsh_fr and obj.tab.qsh_to could be included in the method data_model_update_on of subclass mme_branch_pf_ac such that they could be used in line 200 of subclass dme_brach

rdzman commented 5 months ago

Thanks for pointing this out @WilsonGV. I knew it wasn't completely consistent with the legacy output, but I hadn't gotten around to splitting the line losses into the series and shunt parts yet.

I must say I'm gratified to know that someone was able to understand the new code well enough to make such detailed suggestions. Thank you!

I believe I've addressed the issues you raise in #235, along with a few more. Let me know what you think.

(And give my greetings to Carlos.) 👋

WilsonGV commented 5 months ago

Thanks for your rapid response @rdzman.

A much clearer solution using the C matrix for branches over the node voltages at the network model solution rather than using dme_bus.tab.uid. Note: I hadn't noticed the existence of tab.g_fr in the main data table of branches. Since that column has zero values, do you see a potential application for the shunt conductance in a flexible branch modeling?

rdzman commented 5 months ago

I put it in there as a step toward a more general branch model. In fact, it is possible to update those values in the data model after loading it (and rebuilding the branch data model element) and the computations will all be handled correctly. It's just not handled in the current version of the MATPOWER case format.

rdzman commented 5 months ago

Closed via #235 with commit e7f41f0.