📄 fm_cluster.m
字号:
function fm_cluster(flag)% FM_CLUSTER define Cluster Controllers%% FM_CLUSTER(FLAG)% FLAG = 0 -> initialization% FLAG = 1 -> algebraic equations% FLAG = 2 -> algebraic Jacobians% FLAG = 3 -> differential equations% FLAG = 4 -> state Jacobians% FLAG = 5 -> non-windup limiters)%%Author: Federico Milano%Date: 11-Nov-2002%Version: 1.0.0%%E-mail: fmilano@thunderbox.uwaterloo.ca%Web-site: http://thunderbox.uwaterloo.ca/~fmilano%% Copyright (C) 2002-2006 Federico Milanoglobal Cluster DAE Bus Exc Svc Syn Cac%Data Format Cluster.con:% col #1: Central Area Control number% col #2: AVR or SVC number% col #3: type (1) AVR, (2) SVC% col #4: T Integral time constant [Second]% col #5: Xtg None [None]% col #6: Xeq None [None]% col #7: Qgr None [None]% col #8: Vs_max% col #9: Vs_maxVs = DAE.x(Cluster.Vs);T = Cluster.con(:,4);Xtg = Cluster.con(:,5);Xeq = Cluster.con(:,6);Qgr = Cluster.con(:,7);Vs_max = Cluster.con(:,8);Vs_min = Cluster.con(:,9);switch flag case 0 % initialization % check time constants idx = find(T == 0); if idx clusterwarn(idx, ['Time constant T cannot be zero. T = 0.001 s ' ... 'will be used.']) end Cluster.con(idx,5) = 0.001; % variable initialization DAE.x(Cluster.Vs) = 0; Vs = DAE.x(Cluster.Vs); % set reactive power references % (the CAC signal q is q = 1 at the steady state e.q.) Qg = zeros(Cluster.n,1); if Cluster.exc Qg(Cluster.exc) = -Syn.Qg(Syn.cluster); end if Cluster.svc Qg(Cluster.svc) = getq(Svc,Svc.cluster); end Cluster.con(:,7) = Qg; Cluster.dVsdQ = (Xtg+Xeq)./T; Cluster.u = ones(Cluster.n,1); % check limits idx = find(Vs > Vs_max); if idx clusterwarn(idx, [' State variable Vs is over its maximum ' ... 'limit.']) end idx = find(Vs < Vs_min); if idx clusterwarn(idx, [' State variable Vs is under its minimum ' ... 'limit.']) end fm_disp('Initialization of Cluster''s completed.') case 1 % algebraic equations case 2 % algebraic Jacobians case 3 % differential equations Qg = zeros(Cluster.n,1); if Cluster.exc Qg(Cluster.exc) = -Syn.Qg(Syn.cluster); end if Cluster.svc Qg(Cluster.svc) = getq(Svc,Svc.cluster); end q = Cac.q(Cluster.cac); DAE.f(Cluster.Vs) = ((Qgr.*q-Qg).*(Xtg+Xeq))./T; % non-windup limits idx = find(Vs >= Vs_max & DAE.f(Cluster.Vs) > 0); if idx, DAE.f(Cluster.Vs(idx)) = 0; end DAE.x(Cluster.Vs) = min(Vs,Vs_max); idx = find(Vs <= Vs_min & DAE.f(Cluster.Vs) < 0); if idx, DAE.f(Cluster.Vs(idx)) = 0; end DAE.x(Cluster.Vs) = max(Vs,Vs_min); Cluster.u = Vs <= Vs_max & Vs >= Vs_min; case 4 % state variable Jacobians q1 = DAE.x(Cac.q1(Cluster.cac)); KP = Cac.con(Cluster.cac,7); q1_max = Cac.con(Cluster.cac,8); q1_min = Cac.con(Cluster.cac,9); idx = find((q1 >= q1_max | q1 <= q1_min) & DAE.f(Cac.q1) == 0); if idx DAE.Fx = DAE.Fx + ... sparse(Cluster.Vs(idx),Cac.q1(Cluster.cac(idx)), ... Qgr(idx).*(Xtg(idx)+Xeq(idx))./T(idx),DAE.n,DAE.n); end DAE.Fy = DAE.Fy + sparse(Cluster.Vs,Cac.bus(Cluster.cac)+Bus.n, ... -KP.*Qgr.*(Xtg+Xeq)./T,DAE.n,2*Bus.n); type = Cluster.con(:,3); idx = find(Cluster.u); for i = 1:length(idx) switch type(idx(i)) case 1 % the Cluster is connected to an AVR j = Cluster.bus(idx(i)); k = Cluster.Vs(idx(i)); h = Exc.cluster(idx(i)); m = Syn.cluster(idx(i)); % update Jacobians of Synchronous Machines & AVRs type_exc = Exc.con(h,2); switch type_exc case 1 DAE.Fx(Exc.vr1(h),k) = -DAE.Fx(Exc.vr1(h), Exc.vm(h)); DAE.Fx(Exc.vr2(h),k) = -DAE.Fx(Exc.vr2(h), Exc.vm(h)); case 2 DAE.Fx(Exc.vr1(h),k) = -DAE.Fx(Exc.vr1(h), Exc.vm(h)); case 3 vrmax = Exc.con(h,3); vrmin = Exc.con(h,4); if Syn.vf(m) < vrmax & Syn.vf(m) > vrmin Td10 = Syn.con(m,11); Td20 = Syn.con(m,12); Taa = Syn.con(m,24); xd = Syn.con(m,8); x1d = Syn.con(m,9); xL = Syn.con(m,6); ord = Syn.con(m,5); vm3 = DAE.x(Exc.vm(h)); Kr = Exc.con(h,5); T2r = Exc.con(h,6); T1r = Exc.con(h,7); Kr1 = Kr*T1r/T2r; v0 = Exc.con(h,9); k1 = -Kr1*vm3/v0; switch ord case 3, DAE.Fx(Syn.e1q(m),k) = -k1/Td10; case 4, DAE.Fx(Syn.e1q(m),k) = -k1/Td10; case 5.1, DAE.Fx(Syn.e1q(m),k) = -k1/Td10; case 5.3, DAE.Fx(Syn.e1q(m),k) = -k1*(xd+xl)/(x1d+xL)/Td10; otherwise, DAE.Fx(Syn.e1q(m),k) = -k1*(1-Taa/Td10)/Td10; DAE.Fx(Syn.e2q(m),k) = -k1*Taa/Td10/Td20; end end DAE.Fx(Exc.vr3(h),k) = -DAE.Fx(Exc.vr3(h), Exc.vm(h)); end alpha = Cluster.dVsdQ(idx(i)); % Cluster Control Jacobian of algebraic variables % (ineherited from synchronous machines) DAE.Fy(k,j) = alpha*Syn.J21(m); DAE.Fy(k,j+Bus.n) = alpha*Syn.J22(m); % Cluster Jacobian of state variables % (inherited from synchronous machines) DAE.Fx(k,Syn.delta(m)) = alpha*Syn.Gq(m,1); type_syn = Syn.con(Syn.cluster(idx(i)),5); switch type_syn case 3 DAE.Fx(k,Syn.e1q(m)) = alpha*Syn.Gq(m,3); case 4 DAE.Fx(k,Syn.e1q(m)) = alpha*Syn.Gq(m,3); DAE.Fx(k,Syn.e1d(m)) = alpha*Syn.Gq(m,4); case 5.1 DAE.Fx(k,Syn.e1q(m)) = alpha*Syn.Gq(m,3); DAE.Fx(k,Syn.e2d(m)) = alpha*Syn.Gq(m,4); case 5.2 DAE.Fx(k,Syn.e2q(m)) = alpha*Syn.Gq(m,3); DAE.Fx(k,Syn.e2d(m)) = alpha*Syn.Gq(m,4); case 5.3 DAE.Fx(k,Syn.e1q(m)) = alpha*Syn.Gq(m,3); DAE.Fx(k,Syn.psiq(m)) = alpha*Syn.Gq(m,7); DAE.Fx(k,Syn.psid(m)) = alpha*Syn.Gq(m,8); case 6 DAE.Fx(k,Syn.e2q(m)) = alpha*Syn.Gq(m,3); DAE.Fx(k,Syn.e2d(m)) = alpha*Syn.Gq(m,4); case 8 DAE.Fx(k,Syn.e2q(m)) = alpha*Syn.Gq(m,5); DAE.Fx(k,Syn.e2d(m)) = alpha*Syn.Gq(m,6); DAE.Fx(k,Syn.psiq(m)) = alpha*Syn.Gq(m,7); DAE.Fx(k,Syn.psid(m)) = alpha*Syn.Gq(m,8); end end end case 5 % non-windup limiters fm_windup(Cluster.Vs,Cluster.con(:,8),Cluster.con(:,9)) end% -------------------------------------------------------------------% function for creating warning messagesfunction clusterwarn(idx, msg)fm_disp(strcat('Warning: CLUSTER #',int2str(idx),msg))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -