You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
powersas.m/internal/hemMachinePFmultiStage.m

396 lines
14 KiB

function [VSol,QSol,sSol,dSol,finalAlpha,alphas,diffRec,t,stateCurve]=hemMachinePFmultiStage(SimData,SysData,SysPara,x,pShare)
% Multi-stage computation of power flow (extended including synchronous generators)
%
% FUNCTION hemMachinePFmultiStage
%
% Author: Rui Yao <ruiyao@ieee.org>
%
% Copyright (C) 2021, UChicago Argonne, LLC. All rights reserved.
%
%
global TaskID TaskNum
setting_func_hemMachinePFmultiStage;
[bus,sw,pv,pq,shunt,line,ind,zip,syn,exc,tg,agc,cac,cluster]=unfoldSysData(SysData);
[nState,idxs]...
=getIndexDyn(SysData);
[V0,Q0,s0,d0,w,eq1,eq2,ed1,ed2,psid,psiq,Pm0,Ef0,Vavrm,Vavrr,Vavrf,Vavrref,tgovg,tgovm,tgovmech,f,dpg,qplt,vg]=unfoldX(x,SysData);
[pqIncr,pvIncr,Rind0,Rind1,Reind0,Reind1,Rzip0,Rzip1,Ytr,~,Ysh0,Ysh1,VspSq2,~,~,~,~,Tmech1,Varref1,Ef1,Pm1,Eq11]=unfoldSysPara(SysPara);
[maxAlpha,segAlpha,dAlpha,nlvl,taylorN,alphaTol,diffTol,diffTolMax,method]=unfoldSimData(SimData);
if isempty(dAlpha)
dAlpha=0.1;
if dAlpha>maxAlpha/10
dAlpha=maxAlpha/10;
end
end
if isfield(SysPara,'nIslands')&&isfield(SysPara,'islands')&&isfield(SysPara,'refs')
nIslands=SysPara.nIslands;islands=SysPara.islands;refs=SysPara.refs;
else
[nIslands,islands,refs]=searchIslands(bus(:,1),line(:,1:2));
end
nbus=size(bus,1);
nline=size(line,1);
pqx=pq;
pvx=pv;
shuntx=shunt;
indx=ind;
zipx=zip;
V0x=V0;
s0x=s0;
Q0x=Q0;
d0x=d0;
Ef0x=Ef0;
Rind0x=Rind0;
Reind0x=Reind0;
Rzip0x=Rzip0;
Ysh0x=Ysh0;
Pm0x=Pm0;
Vsp0x=real(V0.*conj(V0));
alphaConfirm=0;
busType=zeros(nbus,1);
if ~isempty(pv);busType(pv(:,1))=1;end
if ~isempty(sw);busType(sw(:,1))=2;end
Vsp=zeros(nbus,1);
Vsp(busType==2)=sw(:,4).*exp(1j*sw(:,5))-V0(busType==2,1);
vc=zeros(nbus,1);
dc=zeros(size(syn,1),1);
qc=zeros(size(Q0,1),1);
Jc=zeros(size(syn,1),1);
Kc=zeros(size(syn,1),1);
sc=zeros(size(ind,1),1);
dsc=zeros(size(ind,1),1);
dyn=zeros(size(ind,1),1);
alphas=0;
noMove=0;
if exist('TaskID','var')&&exist('TaskNum','var')&&~isempty(TaskID)&&~isempty(TaskNum)
taskTag=num2str(TaskID(1));
else
taskTag='';
end
iden=[datestr(clock,30),'_',taskTag,'K',num2str(randi([100000,899999])),'_init'];
jac=getJacobianMod(nbus,nline,bus,sw,pvx,pqx,shuntx,line,zipx,indx,s0,V0,ones(size(ind,1),1));
initJacCond=condest(jac);
t=zeros(1,0);
stateCurve=zeros(nState,0);
while alphaConfirm<1-alphaTol/1000
alpha=min([1-alphaConfirm,segAlpha]);
alphax=alpha/alphaPreMult;
x=zeros(nState,1);
x(idxs.vIdx)=V0x;x(idxs.sIdx)=s0x;x(idxs.deltaIdx)=d0x;x(idxs.qIdx)=Q0x;x(idxs.efIdx)=Ef0x;x(idxs.pgIdx)=Pm0x;
SysDatax =foldSysData(bus,sw,pvx,pqx,shuntx,line,indx,zipx,syn,exc,tg,agc,cac,cluster);
SysParax =foldSysPara(pqIncr,pvIncr,Rind0x,Rind1,Reind0x,Reind1,Rzip0x,Rzip1,Ytr,[],Ysh0x,Ysh1,[Vsp0x,VspSq2(:,2)],[],[],[],[],[],[],Ef1,Pm1);
SysParax.iden=iden;
if exist([iden,'.mat'],'file')
if ~exist('p_amd','var')
load([iden,'.mat']);
end
SysParax.p_amd=p_amd;
else
SysParax.p_amd=[];
end
SysParax.nIslands=nIslands;
SysParax.islands=islands;
SysParax.refs=refs;
[V,W,Q,s,d,JG,KG]=hemMachinePFSalientcontinueSep(SimData,SysDatax,SysParax,x,pShare,Vsp);
[Va3,Vb3]=getPadeApproxHelm(V,0);
[da3,db3]=getPadeApproxHelm(d,0);
[Qa3,Qb3]=getPadeApproxHelm(Q,find(busType==0));
[Sa3,Sb3]=getPadeApproxHelm(s,0);
ds=s(:,2:end).*repmat(1:(size(s,2)-1),size(s,1),1);
[ds3a,ds3b]=getPadeApproxHelm(ds,0);
idxNanV=find(isnan(Va3(:,1))|isnan(Vb3(:,1)));Va3(idxNanV,:)=0;Vb3(idxNanV,:)=0;Va3(idxNanV,1:3)=V(idxNanV,1:3);
idxNanQ=find(isnan(Qa3(:,1))|isnan(Qb3(:,1)));Qa3(idxNanQ,:)=0;Qb3(idxNanQ,:)=0;Qa3(idxNanQ,1:3)=Q(idxNanQ,1:3);
if ~isempty(ind)
idxNanS=find(isnan(Sa3(:,1))|isnan(Sb3(:,1)));Sa3(idxNanS,:)=0;Sb3(idxNanS,:)=0;Sa3(idxNanS,1:2)=s(idxNanS,1:2);
idxNandS=find(isnan(ds3a(:,1))|isnan(ds3b(:,1)));ds3a(idxNandS,:)=0;ds3b(idxNandS,:)=0;ds3a(idxNandS,1:2)=ds(idxNandS,1:2);
end
if ~isempty(syn)
idxNand=find(isnan(da3(:,1))|isnan(db3(:,1)));da3(idxNand,:)=0;db3(idxNand,:)=0;da3(idxNand,1:2)=d(idxNand,1:2);
end
%Temp: benchmarking with Cxx
% CC=real(V);
% DD=imag(V);
% [CCa3,CCb3]=getPadeApproxHelm(CC,0);
% [DDa3,DDb3]=getPadeApproxHelm(DD,0);
%
% X=[CC;DD;Q;s;d];
% [Xa3,Xb3]=getPadeApproxHelm(X,0);
% Xa=[CCa3;DDa3;Qa3;Sa3;da3];
% Xb=[CCb3;DDb3;Qb3;Sb3;db3];
%
alphaLeft=0;
alphaRight=alpha/alphaPreMult;
% alphax=0.2;
while 1
vc=polyvalVec(Va3(:,end:-1:1),alphax)./polyvalVec([Vb3(:,end:-1:1),ones(size(Vb3,1),1)],alphax);
% CCc=polyvalVec(CCa3(:,end:-1:1),alphax)./polyvalVec([CCb3(:,end:-1:1),ones(size(CCb3,1),1)],alphax);
% CCc(isnan(CCc))=CC(isnan(CCc),1)+alphax*CC(isnan(CCc),2);
%
% DDc=polyvalVec(DDa3(:,end:-1:1),alphax)./polyvalVec([DDb3(:,end:-1:1),ones(size(DDb3,1),1)],alphax);
% DDc(isnan(DDc))=DD(isnan(DDc),1)+alphax*DD(isnan(DDc),2);
% vc=CCc+1j*DDc;
dc=polyvalVec(da3(:,end:-1:1),alphax)./polyvalVec([db3(:,end:-1:1),ones(size(db3,1),1)],alphax);
qc=polyvalVec(Qa3(:,end:-1:1),alphax)./polyvalVec([Qb3(:,end:-1:1),ones(size(Qb3,1),1)],alphax);
qc(busType==0,:)=0;
sc=polyvalVec(Sa3(:,end:-1:1),alphax)./polyvalVec([Sb3(:,end:-1:1),ones(size(Sb3,1),1)],alphax);
dsc=polyvalVec(ds3a(:,end:-1:1),alphax)./polyvalVec([ds3b(:,end:-1:1),ones(size(ds3b,1),1)],alphax);
Y=Ytr+sparse(1:nbus,1:nbus,Ysh0x+Ysh1*alphax,nbus,nbus);
Ef=Ef0x+alphax*Ef1;
Vsp2=Vsp0x+alphax*VspSq2(:,2);
pqxx=pqx;
pqxx(:,[4,5])=pqx(:,[4,5])+alphax*pqIncr;
pvxx=pvx;
if ~isempty(pvx);pvxx(:,4)=pvx(:,4)+alphax*pvIncr;end
zipxx=zipx;
if ~isempty(zipxx)
zipxx(:,5:10)=repmat(Rzip0x+alphax*Rzip1,1,6).*zipx(:,5:10);
end
indxx=indx;
if ~isempty(indx)
indxx(:,13)=indx(:,13)./(Reind0x+alphax*Reind1);
indxx(:,15)=indx(:,15).*(Rind0x+alphax*Rind1);
indxx(:,16)=indx(:,16).*(Rind0x+alphax*Rind1);
indxx(:,17)=indx(:,17).*(Rind0x+alphax*Rind1);
dsc=dsc.*dyn;
end
x=zeros(nState,1);
x(idxs.vIdx)=vc;x(idxs.sIdx)=sc;x(idxs.deltaIdx)=dc;x(idxs.qIdx)=qc;x(idxs.efIdx)=Ef;
dx=zeros(nState,1);
dx(idxs.sIdx)=dsc;
SysDatax=foldSysData(bus,sw,pvxx,pqxx,shunt,line,indxx,zipxx,syn,exc,tg,agc,cac,cluster);
SysParax=foldSysPara([],[],[],[],[],[],[],[],Ytr,[],Ysh0x+Ysh1*alphax,[],[Vsp2,zeros(size(Vsp2))],[],[],[],[]);
diff=checkEquationBalanceSyn(SysDatax,SysParax,x,dx,dyn);
if max(abs(diff))<diffTol&&abs(alphax-alpha/alphaPreMult)<alphaTol/1000
alphaLeft=alphaRight;
else
if max(abs(diff))<diffTol
alphaLeft=alphax;
alphax=(alphaLeft+alphaRight)/2;
else
alphaRight=alphax;
alphax=(alphaLeft+alphaRight)/2;
end
end
if alphaRight-alphaLeft<alphaTol
break;
end
end
diffParadigm=max(abs(diff))+1e-12;
countCheckAlpha=1;
alphax=alphaLeft*alphaPreMult;
if alpha-alphax<alphaTol/10
alphax=alpha;
end
% maxCount=10;
while countCheckAlpha<maxCount
vc=polyvalVec(Va3(:,end:-1:1),alphax)./polyvalVec([Vb3(:,end:-1:1),ones(size(Vb3,1),1)],alphax);
% CCc=polyvalVec(CCa3(:,end:-1:1),alphax)./polyvalVec([CCb3(:,end:-1:1),ones(size(CCb3,1),1)],alphax);
% CCc(isnan(CCc))=CC(isnan(CCc),1)+alphax*CC(isnan(CCc),2);
%
% DDc=polyvalVec(DDa3(:,end:-1:1),alphax)./polyvalVec([DDb3(:,end:-1:1),ones(size(DDb3,1),1)],alphax);
% DDc(isnan(DDc))=DD(isnan(DDc),1)+alphax*DD(isnan(DDc),2);
% vc=CCc+1j*DDc;
dc=polyvalVec(da3(:,end:-1:1),alphax)./polyvalVec([db3(:,end:-1:1),ones(size(db3,1),1)],alphax);
qc=polyvalVec(Qa3(:,end:-1:1),alphax)./polyvalVec([Qb3(:,end:-1:1),ones(size(Qb3,1),1)],alphax);
qc(busType==0,:)=0;
sc=polyvalVec(Sa3(:,end:-1:1),alphax)./polyvalVec([Sb3(:,end:-1:1),ones(size(Sb3,1),1)],alphax);
dsc=polyvalVec(ds3a(:,end:-1:1),alphax)./polyvalVec([ds3b(:,end:-1:1),ones(size(ds3b,1),1)],alphax);
Ef=Ef0x+alphax*Ef1;
Vsp2=Vsp0x+alphax*VspSq2(:,2);
pqxx=pqx;
pqxx(:,[4,5])=pqx(:,[4,5])+alphax*pqIncr;
pvxx=pvx;
if ~isempty(pvx);pvxx(:,4)=pvx(:,4)+alphax*pvIncr;end
zipxx=zipx;
if ~isempty(zipxx)
zipxx(:,5:10)=repmat(Rzip0x+alphax*Rzip1,1,6).*zipx(:,5:10);
end
indxx=indx;
if ~isempty(indx)
indxx(:,13)=indx(:,13)./(Reind0x+alphax*Reind1);
indxx(:,15)=indx(:,15).*(Rind0x+alphax*Rind1);
indxx(:,16)=indx(:,16).*(Rind0x+alphax*Rind1);
indxx(:,17)=indx(:,17).*(Rind0x+alphax*Rind1);
dsc=dsc.*dyn;
end
x=zeros(nState,1);
x(idxs.vIdx)=vc;x(idxs.sIdx)=sc;x(idxs.deltaIdx)=dc;x(idxs.qIdx)=qc;x(idxs.efIdx)=Ef;
dx=zeros(nState,1);
dx(idxs.sIdx)=dsc;
SysDatax=foldSysData(bus,sw,pvxx,pqxx,shunt,line,indxx,zipxx,syn,exc,tg,agc,cac,cluster);
SysParax=foldSysPara([],[],[],[],[],[],[],[],Ytr,[],Ysh0x+Ysh1*alphax,[],[Vsp2,zeros(size(Vsp2))],[],[],[],[]);
diff=checkEquationBalanceSyn(SysDatax,SysParax,x,dx,dyn);
if max(abs(diff))<1.05*diffParadigm
break;
end
alphax=alphax*alphaPreMult;
countCheckAlpha=countCheckAlpha+1;
end
if countCheckAlpha>=maxCount;alphax=alphax/alphaPreMult;end
alpha=alphax;
pqx(:,[4,5])=pqx(:,[4,5])+alpha*pqIncr;
if ~isempty(pvx);pvx(:,4)=pvx(:,4)+alpha*pvIncr;end
Rind0x=Rind0x+alpha*Rind1;
Reind0x=Reind0x+alpha*Reind1;
Rzip0x=Rzip0x+alpha*Rzip1;
Ef0x=Ef0x+alpha*Ef1;
Ysh0x=Ysh0x+alpha*Ysh1;
Vsp0x=Vsp0x+alpha*VspSq2(:,2);
if ~isempty(syn)
nSyn=size(syn,1);
synIdx=syn(:,1);
Efd=zeros(nSyn,1);
Efq=Ef0x;
Rs=syn(:,7);
Xd=syn(:,8);
Xq=syn(:,13);
cosd=cos(dc);
sind=sin(dc);
Cg=real(vc(synIdx));
Dg=imag(vc(synIdx));
Vd=sind.*Cg-cosd.*Dg;
Vq=cosd.*Cg+sind.*Dg;
Id=(Rs.*(Efd-Vd)+Xq.*(Efq-Vq))./(Rs.*Rs+Xq.*Xd);
Iq=(-Xd.*(Efd-Vd)+Rs.*(Efq-Vq))./(Rs.*Rs+Xq.*Xd);
Pm0x=Efq.*Iq+Efd.*Id;
end
alphaConfirm=alphaConfirm+alpha;
addLog(['Step=',num2str(alphaConfirm),', added=',num2str(alpha),', (maxdiff<',num2str(diffTol),').'],'INFO');
if alpha==0
addLog('Step did not move!','INFO');
noMove=noMove+1;
if noMove>=MaxNoMove
zipxx=zipx;
if ~isempty(zipxx)
zipxx(:,5:10)=repmat(Rzip0x,1,6).*zipx(:,5:10);
end
[~,Ytrx,Yshx]=getYMatrix(nbus,line);
[jac,jPIdx,jQIdx,jVIdx,jSIdx,busType]=getJacobianMod(nbus,nline,bus,sw,pvx,pqx,shuntx,line,zipxx,indx,sc,vc,zeros(size(ind,1),1),Ytrx,Yshx*alphaConfirm);
jacCond=condest(jac);
if jacCond>50*initJacCond
[Vx,Dx]=eigs(jac,20,'sm');
dDx=diag(Dx);
[~,iSmall]=min(abs(dDx));
part=Vx(:,iSmall).*conj(Vx(:,iSmall));
partBus=zeros(size(bus,1),1);
partBus(busType~=2)=partBus(busType~=2)+part(jPIdx);
partBus(busType==0)=partBus(busType==0)+part(jQIdx);
addLog('Singular likely!','INFO');
end
addLog('Reached consecutive max no move, exit!','INFO');
break;
end
if diffTol>=diffTolMax
addLog('Max DiffTol reached and not move, exit!','INFO');
break;
end
diffTol=max([diffTol*diffMul,max(abs(diff))]);
if diffTol>diffTolMax
diffTol=diffTolMax;
end
addLog(['Enlarge tol! (Tol=',num2str(diffTol),')'],'INFO');
else
noMove=0;
V0x=vc;
d0x=dc;
Q0x=qc;
s0x=sc;
alphas=[alphas;alpha];
dAlphax=dAlpha;
% if dAlphax>alpha/10
% dAlphax=alpha/10;
% end
alphax=0:dAlphax:alpha;
if alpha-alphax(end)>alphaTol
alphax=[alphax,alpha];
end
nt=size(alphax,2);
vcx=polyvalVec(Va3(:,end:-1:1),alphax)./polyvalVec([Vb3(:,end:-1:1),ones(size(Vb3,1),1)],alphax);
dcx=polyvalVec(da3(:,end:-1:1),alphax)./polyvalVec([db3(:,end:-1:1),ones(size(db3,1),1)],alphax);
qcx=polyvalVec(Qa3(:,end:-1:1),alphax)./polyvalVec([Qb3(:,end:-1:1),ones(size(Qb3,1),1)],alphax);
qcx(busType==0,:)=0;
scx=polyvalVec(Sa3(:,end:-1:1),alphax)./polyvalVec([Sb3(:,end:-1:1),ones(size(Sb3,1),1)],alphax);
if ~isempty(syn);efcx=repmat(Ef0x-alpha*Ef1,1,nt)+Ef1*alphax;else efcx=zeros(0,nt);end
xx=zeros(nState,nt);
xx(idxs.vIdx,:)=vcx;xx(idxs.sIdx,:)=scx;xx(idxs.deltaIdx,:)=dcx;xx(idxs.qIdx,:)=qcx;xx(idxs.efIdx,:)=efcx;
t=[t,alphax+alphaConfirm-alpha];
stateCurve=[stateCurve,xx];
end
end
addLog(['Total Step=',num2str(alphaConfirm),'.'],'INFO');
diffRec=max(abs(diff));
VSol=V0x;
QSol=Q0x;
sSol=s0x;
dSol=d0x;
finalAlpha=alphaConfirm;
if exist([iden,'.mat'],'file')
delete([iden,'.mat']);
end
end