電力系統モデル作成に関する解説は「一連の解析実行例ページ」 でも行っています。そちらのページと本ページではどちらも3母線の電力系統モデルという同規模のモデルを作成していますが、こちらのページで解説する定義方法の方がやや上級者向けとなっています。
- 「一連の解析実行例」ページの構築方法
各母線・機器・ブランチ毎に1つずつ定義を行い系統モデルを構築していく
※GUILDAのソースコードにあるnetwork_sample3bus
はこちらの方法で書かれています。 - 本ページの構築方法
各母線・機器・ブランチの情報をテーブルとしてまとめておき、そのデータからfor文による繰り返し処理によって自動的に系統モデルを構築していく
※GUILDAのソースコードにあるnetwork_IEEE68bus
はこちらの方法で書かれています。
前者の場合、仮に何百もの母線で構成される系統モデルを構築する際、その分、大量の行数のコードを書く必要が出てきます。一方後者の場合、系統を構成する母線の数が増えようとcsvデータが大きくなるだけでコードを変化させる必要はないため、汎用性に優れていると言えます。
後者の定義方法を自身で考えて書けるようになるには、for文の中でどんな関数を繰り返し処理し、どの部分を一般項にすれば良いのか考えられるようにならなければいけません。そのためには、前者の定義方法のように各母線・機器・ブランチの定義方法を理解している必要があります。
2つの解説ページでは重複している部分も多くありますが、どちらも参考にしてみて下さい。
¶
【解説】¶
ネットワークの定義¶
今回はネットワークの情報をnet
と名付けた変数に定義していきます。初めに以下のように電力系統クラスを定義します。電力系統モデルはpower_network
クラスを用いて実装されます。
net = power_network(); % 何も定義されていないネットワーク
これで、電力系統モデルのクラスの準備が出来ました。しかし、このままでは構成要素の無い系統モデルの状態です。以下では、ブランチモデル、母線モデル、機器モデルを順に定義し、このpower_networkクラスのクラス変数に格納していきます。
ブランチの定義¶
母線をつなぐ送電網の情報を一度、table
型のデータで格納します。
例えば今回構成する3busモデルでは「母線1と母線2」と「母線2と母線3」を繋ぐ2本の送電網があるため、テーブルは以下のようになります。
9×7 table
bus_from bus_to x_real x_imag y tap phase
________ ______ ______ ______ ______ ___ _____
1 2 0 0.0576 0 1 0
3 2 0 0.0625 0 1 0
- bus_from 接続元のバスの番号
- bus_to 接続先のバスの番号
- x_real , x_imag
ブランチ上のインピーダンスの実部と虚部の値
この値の逆数がアドミタンスになります。 - y 対地静電容量の値
- tap , phase 位相調整変圧器のパラメータ
branchを定義する際のサンプルコード¶
ではブランチの情報を定義したtable型のデータから、各行毎に順に値を取得し、先ほど定義したpower_networkクラス内のa_branchというクラス変数内に格納していきます。
% データの数字のみを行列の形で代入
branch_array = [ここにデータを入れる];
% `branch_array`に変数名を追加して`table`型に
branch = array2table(branch_array, 'VariableNames', ...
{'bus_from', 'bus_to', 'x_real', 'x_imag', 'y', 'tap', 'phase'}...
);
for i = 1:size(branch, 1)
if branch{i, 'tap'} == 0
br = branch_pi(branch{i, 'bus_from'}, branch{i, 'bus_to'},...
branch{i, {'x_real', 'x_imag'}}, branch{i, 'y'});
else
br = branch_pi_transformer(branch{i, 'bus_from'}, branch{i, 'bus_to'},...
branch{i, {'x_real', 'x_imag'}}, branch{i, 'y'},...
branch{i, 'tap'}, branch{i, 'phase'});
end
net.add_branch(br);
end
上記のコードはpower_networkクラスをnet
という変数名で保存している場合のコードですので、net3bus
などとしている場合は、それに合わせて、最後から2行目の部分を
net3bus.ad_branch(br)
などと変更してください。
母線の変数¶
母線のパラメータ変数として以下の6つのものが考えられます。
これについては、電力システムの構成要素に関する解説ページを参考にしてください。
- : 有効電力
- : 無効電力
- : 電圧の絶対値
- : 電圧の位相角
- : 地面に繋がっているシャント抵抗のアドミタンス
以下の3種の母線はのうち2つの変数とシャント抵抗の値を指定します.
母線の定義¶
母線の情報はnet
のa_bus
というフィールドに格納されます。
母線のクラスには「PV母線、PQ母線、slack母線」の3種類があります。各母線の種類毎に、対応するクラスのインスタンスを定義し、net
のa_bus
フィールドにcell配列として格納していきます。
% slack母線のとき
b = bus_slack(…);
% PV母線のとき
b = bus_PV(…);
% PQ母線のとき
b = bus_PQ(…);
上記のコード例では、母線を定義する際、bus_slack,bus_PV,bus_PQ
の引数を...
と省略していますが、実行する際はここにパラメータを代入する必要があります。
・slack bus¶
電力ネットワーク内の発電機バスは基本全てPVバスに分類されますが、一つだけ電圧の位相を指定し基準として機能するような特殊なバスが存在します。それがslackバスです。
slackバスでは電圧の絶対値と位相角を指定します。そのため、slackバスの定義は以下のようにV_abs,V_angle
を引数としています。
b = bus_slack(V_abs, V_angle, [G_shunt, B_shunt]);
- 入力引数
- V_abs 電圧.
- V_angle 位相角。通常0となる.
- [G_shunt, B_shunt] 地面に繋がっているシャント抵抗のインピーダンスの実部と虚部.
・PV bus¶
PVバスには、slackバスを除いた全ての発電機バスが分類されます。
このバスでは、その名の通り有効電力Pと電圧の絶対値|V|を指定します。
b = bus_PV(P_gen, V_abs, [G_shunt, B_shunt]);
- 入力引数
- P_gen 有効電力
- V_abs 電圧
- [G_shunt, B_shunt] 地面に繋がっているシャント抵抗のインピーダンスの実部と虚部.
・PQ bus¶
PQバスは基本的に負荷バスが分類されるバスです。
このバスでは、有効電力Pと有効電力Qを指定します。
b = bus_PQ(-Pload, -Qload, [G_shunt, B_shunt]);
- 入力引数
- Pload 有効電力.
- Qload 無効電力.
- [G_shunt, B_shunt] 地面に繋がっているシャント抵抗のインピーダンスの実部と虚部.
機器の定義¶
上記で母線のクラスのインスタンスを作成することまで完了しました。母線クラスを定義した変数b
をpower_networkのフィールドに格納する前に、各母線クラスに接続する機器モデルをcomponent
フィールドに格納します。
機器の定義の方法の流れとしては、
- 変数
component
を機器のクラスのインスタンスとする - そのcomponent変数をそれぞれの母線を表すクラス変数
b
にset_component
関数を用いて代入する といった流れです。
それでは各componentの定義を行っていきます。
componentの例として以下の2種類のクラスについて解説を行います。
- generator_1axis
- load_impedance
発電機の定義¶
発電機の定義にはgenerator_1axis
という関数を用います。この関数は同期発電機のモデルを各パラメータを引数として得ることで定義する関数です。
下のコードの場合、component
は1軸発電機のインスタンスとなります。
component = generator_1axis(omega0, mac);
基準角周波数のことです。 ・mac
発電機のパラメーターに当たります。
実際には、8個のフィールドをもつtable
となります.以下その例です。branch
のパラメータの設定のときと同様にmac
もtable
型で各列の変数は以下のようになっている必要があります。
table
型の変数の定義法に浮いてはbranch
の節で参考になるコードを上げていますので、mac
用に適宜変えてください。
mac =
1×8 table
No_machine No_bus Xd Xd_prime Xq T M D
____________ _________ _________ __________ _______ ______ ___ ___
1 3 1.569 0.324 1.548 5.14 100 2
No_machine
発電機の番号No_bus
何番目の母線につながっているかXd, Xd_prime, Xq
d軸、q軸回りの同期リアクタンスT
d軸回りの回路時定数M
慣性定数D
制動係数
ここまでで、任意のパラメータを持つ1軸発電機の変数を作ることができました。
しかし、現実の発電機にはAVRやPSSと呼ばれる、応答を好ましいものにするための制御器がかかっていることが一般的です。
そこで、次のように発電機のインスタンスにAVRやPSSの情報も加えることができます。
component.set_avr(avr_sadamoto2019(exc));
component.set_pss(pss(p))
avr_sadamoto2019
はAVRのモデルの1つで、GUILDAにある既存のクラスになります。
引数の情報は次のようになります。
・exc,p
exc
がAVRに関するパラメータで、p
がPSSに関するパラメータです。
以下それぞれの具体的な構成です.
exc =
1×3 table
No_bus Ka Te
________ _____ ______
1 2 0.05
p =
1×6 table
No_bus Kpss Tpss TL1p TL1 TL2p TL2
_________ ____ ____ ____ _____ ____ ___
1 0 10 0.05 0.015 0.08 0.01
しつこいようですが、変数mac
は発電機のパラメータであったのに対し、このexc
,p
のパラメータはAVRやPSSの制御器のパラメータです。
負荷の定義¶
負荷の定義にはload_impedance
という関数を用います。この関数は以下の様に定義します。
component = load_impedance();
機器モデルを母線クラスへ付加¶
母線クラスのset_component
というメソッドを用いることで機器モデルを格納します。本解説ページでは、
- 母線クラスを変数
b
として定義 - 機器モデルを定義した変数
component
をb
に格納 power_network
クラスにb
を格納
という手順を行なっています。この場合は、以下のようなコマンドを実行することになります。
b.set_component(component);
net.add_bus(b);
一方で、
- 母線クラスを変数
b
として定義 power_network
クラスにb
を格納power_network
クラスに格納された母線クラスに機器モデルを定義した変数component
を格納
とする場合は、以下のようになります。
net.add_bus(b);
net.a_bus{i}.set_component(component);
power_networkクラスのメソッドadd_bus
では指定された母線クラスをa_bus
というフィールドに格納します。このとき、気をつけるべきポイントはフィールドa_bus
には代入された順番に母線が定義されます。つまり最初にnet.add_bus(b)
された母線クラスが「母線1」という扱いになるわけです。上のコードの
net.a_bus{i}.set_component(component);
でのi
に関しては、1行前にadd_bus
した母線がi番目に代入された母線であるということと対応します。そのため後者の手順だと、「今、代入した母線が何番目の母線か?」ということを調べる必要が出てきてしまいます。その点、前者では先に母線クラスに機器モデルを格納してからpower_network
クラスに格納しているため、その手間が必要ありません。
ただ、例えば5番目の母線に付加されている機器モデルを定インピーダンス負荷に後から変更したくなったという場合は、
component = load_impedance();
net.a_bus{5}.set_component(component);
と実行するのが有効的ですね。
以上で電力系統の定義が完了しました。 ここまでのコードを最後にまとめておきます。
function net = network_3bus_1axis()
omega0 = 60*2*pi;
net = power_network();
bus_array = [1 1.00 0 0.60 0 0 0 0 0 2;
2 1.00 0 5.45 0 1.0 1.0 0 0 3;
3 1.00 0 1.00 2 0 0 0 0 1];
bus = array2table(bus_array, 'VariableNames', ...
{'No', 'V_abs', 'V_angle', 'P_gen', 'Q_gen', 'P_load', 'Q_load', 'G_shunt', 'B_shunt', 'type'} ...
);
branch_array = [...
1 2 0 1/12.56041 0 1 0;...
3 2 0 1/13.65107 0 1 0;];
branch = array2table(branch_array, 'VariableNames', ...
{'bus_from', 'bus_to', 'x_real', 'x_imag', 'y', 'tap', 'phase'}...
);
mac_array = [1, 1, 0.1, 0.031, 0.069, 10.2, 84, 4;
2, 3, 0.295, 0.0697, 0.282, 6.56, 60.4, 9.75];
mac_data = array2table(mac_array, 'VariableNames', ...
{'No_machine', 'No_bus', 'Xd', 'Xd_prime', 'Xq', 'T', 'M', 'D'} ...
);
exc_array = [1 0 0.05;
3 0 0.05];
exc_data = array2table(exc_array, 'VariableNames', ...
{'No_bus', 'Ka', 'Te'} ...
);
pss_array = [1 0 10 0.05 0.015 0.08 0.01;
3 0 10 0.05 0.015 0.08 0.01];
pss_data = array2table(pss_array, 'VariableNames', ...
{'No_bus', 'Kpss', 'Tpss', 'TL1p', 'TL1', 'TL2p', 'TL2'} ...
);
for i = 1:size(bus, 1)
shunt = bus{i, {'G_shunt', 'B_shunt'}};
switch bus{i, 'type'}
case 1
V_abs = bus{i, 'V_abs'};
V_angle = bus{i, 'V_angle'};
b = bus_slack(V_abs, V_angle, shunt);
b.set_component(get_generator(i, machinery, excitation, pss_data, omega0));
case 2
V_abs = bus{i, 'V_abs'};
P = bus{i, 'P_gen'};
b = bus_PV(P, V_abs, shunt);
b.set_component(get_generator(i, machinery, excitation, pss_data, omega0));
case 3
P = bus{i, 'P_load'};
Q = bus{i, 'Q_load'};
b = bus_PQ(-P, -Q, shunt);
if P~=0 || Q~=0
load = load_impedance();
b.set_component(load);
end
end
net.add_bus(b);
end
for i = 1:size(branch, 1)
if branch{i, 'tap'} == 0
br = branch_pi(branch{i, 'bus_from'}, branch{i, 'bus_to'},...
branch{i, {'x_real', 'x_imag'}}, branch{i, 'y'});
else
br = branch_pi_transformer(branch{i, 'bus_from'}, branch{i, 'bus_to'},...
branch{i, {'x_real', 'x_imag'}}, branch{i, 'y'},...
branch{i, 'tap'}, branch{i, 'phase'});
end
net.add_branch(br);
end
net.initialize();
end
function g = get_generator(i, mac_data, exc_data, pss_data, omega0)
idx = mac_data{:, 'No_bus'} == i;
if sum(idx) ~= 0
g = generator_1axis(omega0, mac_data(idx, :));
exc = exc_data(exc_data{:, 'No_bus'}==i, :);
g.set_avr(avr_sadamoto2019(exc));
p = pss_data(pss_data{:, 'No_bus'}==i, :);
g.set_pss(pss(p));
end
end
今回は3母線の電力ネットワークを例として実装しています。ただ上のコードでは、パラメータを定義するテーブル(bus_array,branch_array,mac_array,...)を変えさえすれば、任意のネットワーク形状や機器を実装することができます。
これで電力ネットワークの定義が一通り終わりました。 作成した電力系統に対して状態方程式を求めたり、数値シミュレーションを行うなどの解析を行うことができます。また、作成した電力系統モデルに制御器を付加して解析を行いたい場合は次のパートの制御器設計編に進んでください。