MATPOWER / matpower

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

multiple generators per bus causes error in Power Summation power flow #210

Closed mj00712 closed 11 months ago

mj00712 commented 12 months ago

Hi Sir,

I hope you are doing well. Sir, when we use this data for the generator matrix, it gets solved using Newton's Power Flow but gives this error:

MATPOWER Version 7.1, 08-Oct-2020 -- AC Power Flow (Power Summation)
Warning: Matrix is singular to working precision.
> In calc_v_pq_sum (line 53)
  In radial_pf (line 63)
  In runpf (line 283)
  In Code (line 118)
Power summation did not converge in 20 iterations when using the Forward-Backward Sweep method. 

I have considered the case33bw distribution network. Shouldn't the Forward-Backward Sweep method be better able to solve this network, considering it is a distribution network? Or is Newton's Power Flow modified to accurately solve radial networks as well? image When the generator matrix has the same bus numbers for new rows (other generators placed on the same bus) it gives an error for the power summation method. However, if we add those P and Q's to the same bus for multiple DG's P and Q and represent it as a single bus then it doesn't give an error.

rdzman commented 11 months ago

When the generator matrix has the same bus numbers for new rows (other generators placed on the same bus) it gives an error for the power summation method. However, if we add those P and Q's to the same bus for multiple DG's P and Q and represent it as a single bus then it doesn't give an error.

I was not able to reproduce this error in the case I tried, where I duplicated the generator representing the substation.

>> mpc = loadcase('case15da');
>> mpc.gen(2, :) = mpc.gen(1, :);
>> mpc.gencost(2, :) = mpc.gencost(1, :);
>> mpopt = mpoption('verbose', 2, 'out.all', 0, 'pf.alg', 'PQSUM');
>> runpf(mpc, mpopt)

MATPOWER Version 8.0b1, 30-May-2023 -- AC Power Flow (Power Summation)

 it    max V mismatch (p.u.)
----  ----------------------
  1         5.545e-02
  2         1.332e-04
  3         4.091e-07
  4         1.273e-09
Power summation converged in 4 iterations.
>> 

Could you provide an example I can use to reproduce the issue?

mj00712 commented 11 months ago

Try this mpc = loadcase('case15da'); mpc.gen(2,:)=mpc.gen(1,:); mpc.gen(3,:)=mpc.gen(1,:); mpc.gen(2,1)=3; mpc.gen(2,2)=0.4; mpc.gen(2,3)=0.5; mpc.gen(3,1)=3; mpc.gen(3,2)=0.7; mpc.gen(3,3)=0.8; mpc.gencost(2, :) = mpc.gencost(1, :); mpc.gencost(3, :) = mpc.gencost(1, :); mpopt = mpoption('verbose', 2, 'out.all', 0, 'pf.alg', 'PQSUM'); runpf(mpc, mpopt) This one works as there are no repeated buses and Ps and Qs are added together for the same bus number. mpc = loadcase('case15da'); mpc.gen(2,:)=mpc.gen(1,:); mpc.gen(2,1)=3; mpc.gen(2,2)=1.1; mpc.gen(2,3)=1.3; mpc.gencost(2, :) = mpc.gencost(1, :); mpopt = mpoption('verbose', 2, 'out.all', 0, 'pf.alg', 'PQSUM'); runpf(mpc, mpopt); But with runpf(mpc) newton method there is no problem.

rdzman commented 11 months ago

Thanks. Just to confirm, in my case the following code (equivalent to your first set above) ...

define_constants;
mpc = loadcase('case15da');
mpc.gen(2,:) = mpc.gen(1,:);
mpc.gen(3,:) = mpc.gen(1,:);
mpc.gencost(2, :) = mpc.gencost(1, :);
mpc.gencost(3, :) = mpc.gencost(1, :);
mpc.gen(2,GEN_BUS)=3;
mpc.gen(2,PG)=0.4;
mpc.gen(2,QG)=0.5;
mpc.gen(3,GEN_BUS)=3;
mpc.gen(3,PG)=0.7;
mpc.gen(3,QG)=0.8;
mpopt = mpoption('verbose', 2, 'out.all', 0, 'pf.alg', 'PQSUM');
runpf(mpc, mpopt)

... does not produce a fatal error, but it fails with the following output ...

>> runpf(mpc, mpopt)    

MATPOWER Version 8.0b1, 30-May-2023 -- AC Power Flow (Power Summation)

 it    max V mismatch (p.u.)
----  ----------------------
  1         4.351e-02
  2               Inf
  3               Inf
  4               Inf
  5               Inf
  6               Inf
  7               Inf
  8               Inf
  9               Inf
 10               Inf
 11               Inf
 12               Inf
 13               Inf
 14               Inf
 15               Inf
 16               Inf
 17               Inf
 18               Inf
 19               Inf
 20               Inf
Power summation did not converge in 20 iterations.

FWIW, the same is true for the Current Summation and Admittance Summation methods (pf.alg set to 'ISUM' and 'YSUM', respectively).

mj00712 commented 11 months ago

Yes, ISUM and YSUM also give the same error.

rdzman commented 11 months ago

The issue is that this code ...

https://github.com/MATPOWER/matpower/blob/fbe9cac672f121997f4b7e7e12e9408744d3646c/lib/calc_v_pq_sum.m#L50-L54

... expects pv to contain only unique indices. Since it contains repeated indices, imag(Zpv) is singular and its inversion results in Inf values. Likewise in (calc_v_i_sum.m and calc_v_y_sum.m).

Not sure if/when I'll get a chance to fix this, so a contributed fix would be greatly appreciated.

rdzman commented 11 months ago

@todorovski-m, any chance this is something you would care to look into?

todorovski-m commented 11 months ago

@rdzman has pinpointed the error source: when there are multiple generators at the same bus, the function make_zpv generates a matrix Zpv with two or more identical rows, rendering the matrix singular. It's evidently a bug. I'll address and fix this issue within the next day or two.

todorovski-m commented 11 months ago

I've updated radial_pf to handle scenarios with multiple generators per bus. You can access the modified file here: radial_pf.m.

To test the updated version, run the following code

clc; clear
define_constants;
mpc = loadcase('case15da');
mpc.gen(2,:) = mpc.gen(1,:);
mpc.gen(3,:) = mpc.gen(1,:);
mpc.gencost(2, :) = mpc.gencost(1, :);
mpc.gencost(3, :) = mpc.gencost(1, :);
mpc.gen(2,GEN_BUS)=3;
mpc.gen(2,PG)=0.4;
mpc.gen(2,QG)=0.5;
mpc.gen(3,GEN_BUS)=3;
mpc.gen(3,PG)=0.7;
mpc.gen(3,QG)=0.8;
mpc.bus(3,BUS_TYPE) = 2;

mpopt = mpoption('verbose', 2, 'out.all', 0, 'pf.alg', 'NR');
mpc1 = runpf(mpc, mpopt);

mpopt = mpoption(mpopt, 'pf.alg', 'PQSUM');
mpc2 = runpf(mpc, mpopt);

V1 = mpc1.bus(:,VM).*exp(1j*mpc1.bus(:,VA)/180*pi);
V2 = mpc2.bus(:,VM).*exp(1j*mpc2.bus(:,VA)/180*pi);
dV = V1-V2

gen1 = mpc1.gen(:, [GEN_BUS PG QG])
gen2 = mpc2.gen(:, [GEN_BUS PG QG])

which solves the test system using solvers NR and PQSUM. It compares complex voltages and generator outputs.

Before finalizing this issue, I need to create tests and provide a comprehensive description of the changes made.

rdzman commented 11 months ago

Thanks @todorovski-m!

If you can create a pull request against the latest master branch, that would be the preferred way to handle this. It makes it easier to review, merge, and track the changes. You can find instructions here to help get you started, if you are unfamiliar.