power_flow_process_visualizer.htmlは、潮流計算アルゴリズムの各計算ステップを段階的に可視化する教育特化型ツールです。初学者が潮流計算の流れを理解できるよう、計算過程を分解して表示し、各段階での数値変化を詳細に観察できます。
┌─────────────────────────────────────────────────┐
│ 現在のステップ: [3/6] Jacobian行列構築 │
├─────────────────────────────────────────────────┤
│ ◯ 1. 初期化完了 ◯ 2. ミスマッチ計算完了 │
│ ● 3. Jacobian構築中 ◯ 4. 線形方程式求解 │
│ ◯ 5. 電圧更新 ◯ 6. 収束判定 │
├─────────────────────────────────────────────────┤
│ [前のステップ] [次のステップ] [自動実行] [リセット] │
└─────────────────────────────────────────────────┘
現在の電圧 (反復2回目)
┌─────┬──────────┬──────────┬──────────┐
│母線 │ 電圧大きさ │ 位相角 │ミスマッチ │
├─────┼──────────┼──────────┼──────────┤
│ 1 │ 1.060 │ 0.00° │ 0.000 │
│ 2 │ 1.043 │ -4.25° │ -0.086 │
│ 3 │ 1.011 │ -12.35° │ 0.034 │
└─────┴──────────┴──────────┴──────────┘
Jacobian行列 (4×4)
┌─────────────────────────────────────┐
│ 15.2 -5.1 2.3 -0.8 │ ∂P/∂θ │
│ -5.1 12.7 -3.2 1.1 │ │
│ ├─────────────────────────┤ │
│ 2.1 -0.9 8.4 -2.3 │ ∂Q/∂θ │
│ -0.7 1.2 -2.1 6.8 │ │
└─────────────────────────────────────┘
∂P/∂θ ∂Q/∂V
class ProcessController {
constructor() {
this.currentStep = 0;
this.maxSteps = 6;
this.stepData = {};
this.isRunning = false;
this.autoMode = false;
}
nextStep() {
if (this.currentStep < this.maxSteps) {
this.executeStep(this.currentStep + 1);
this.currentStep++;
this.updateDisplay();
}
}
executeStep(stepNumber) {
switch(stepNumber) {
case 1: this.initializeSystem(); break;
case 2: this.calculateMismatch(); break;
case 3: this.buildJacobian(); break;
case 4: this.solveLinearSystem(); break;
case 5: this.updateVoltages(); break;
case 6: this.checkConvergence(); break;
}
}
// 各ステップの詳細実装...
}
initializeSystem() {
// 初期電圧設定
this.voltages = this.busData.map(bus => {
if (bus.type === 'slack') {
return {magnitude: bus.V, angle: 0};
} else if (bus.type === 'PV') {
return {magnitude: bus.V, angle: 0};
} else {
return {magnitude: 1.0, angle: 0};
}
});
// アドミタンス行列構築
this.Ybus = this.buildAdmittanceMatrix();
// 表示更新
this.displayVoltages();
this.displayYbusMatrix();
this.highlightCurrentOperation("システム初期化完了");
}
calculateMismatch() {
const mismatch = [];
this.busData.forEach((bus, i) => {
if (bus.type !== 'slack') {
// 計算電力
const S_calc = this.calculatePowerInjection(i);
// 指定電力
const S_spec = {P: bus.PG - bus.PD, Q: bus.QG - bus.QD};
// ミスマッチ
const deltaP = S_spec.P - S_calc.P;
const deltaQ = S_spec.Q - S_calc.Q;
mismatch.push({bus: i+1, deltaP, deltaQ});
}
});
this.mismatchData = mismatch;
this.displayMismatch();
this.highlightMismatchBuses();
}
buildJacobian() {
const n = this.busData.length;
const J = new Array(2*n).fill(0).map(() => new Array(2*n).fill(0));
// 各要素を順次計算・表示
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
// ∂P/∂θ 要素
J[i][j] = this.calculateDPDtheta(i, j);
this.animateJacobianElement(i, j, J[i][j]);
// ∂P/∂V 要素
J[i][j+n] = this.calculateDPDV(i, j);
this.animateJacobianElement(i, j+n, J[i][j+n]);
// ∂Q/∂θ 要素
J[i+n][j] = this.calculateDQDtheta(i, j);
this.animateJacobianElement(i+n, j, J[i+n][j]);
// ∂Q/∂V 要素
J[i+n][j+n] = this.calculateDQDV(i, j);
this.animateJacobianElement(i+n, j+n, J[i+n][j+n]);
}
}
this.jacobianMatrix = J;
this.displayJacobianStructure();
}
class EquationDisplay {
showCurrentEquation(stepNumber) {
const equations = {
1: "V₀ = 1.0∠0° (初期電圧)",
2: "ΔP = P_spec - P_calc = P_spec - Re(V*·(YV)*)",
3: "J = [∂P/∂θ ∂P/∂|V|]\n [∂Q/∂θ ∂Q/∂|V|]",
4: "J·Δx = -f(x) → LU分解 → 前進後進代入",
5: "θ_new = θ_old + Δθ\n|V|_new = |V|_old + Δ|V|",
6: "max|f(x)| < ε ? 収束 : 次反復"
};
this.displayEquation(equations[stepNumber]);
}
displayEquation(latexString) {
// MathJax または独自レンダラーで数式表示
const mathElement = document.getElementById('current-equation');
mathElement.innerHTML = this.renderLatex(latexString);
}
}
class AnimationController {
animateVoltageUpdate(busIndex, oldV, newV) {
const duration = 1000; // 1秒
const steps = 50;
const stepDuration = duration / steps;
for (let step = 0; step <= steps; step++) {
setTimeout(() => {
const ratio = step / steps;
const currentV = this.interpolateVoltage(oldV, newV, ratio);
this.updateBusDisplay(busIndex, currentV);
}, step * stepDuration);
}
}
highlightMatrixElement(row, col, value) {
const cell = document.getElementById(`matrix-${row}-${col}`);
cell.classList.add('highlight');
cell.textContent = value.toFixed(4);
setTimeout(() => {
cell.classList.remove('highlight');
}, 1500);
}
}
反復1回目:
ステップ2: ミスマッチ計算
┌─────────────────────────────┐
│ 母線2: ΔP = -0.086 MW │
│ 母線3: ΔP = 0.034 MW │
│ 母線2: ΔQ = -0.023 MVAR │
│ 母線3: ΔQ = 0.012 MVAR │
│ 最大誤差: 0.086 MW │
└─────────────────────────────┘
ステップ3: Jacobian構築中...
[∂P₂/∂θ₂] = -12.35 ←計算中
[∂P₂/∂θ₃] = 4.21
[∂P₂/∂V₂] = 8.94
[∂P₂/∂V₃] = -2.18
反復前: 反復後:
┌─[1]─┐ ┌─[1]─┐
│1.06∠0°│ │1.06∠0°│
└─────┘ └─────┘
│ │
┌─[2]─┐ ┌─[2]─┐
│1.00∠0°│ → 更新 → │1.04∠-4°│
└─────┘ └─────┘
│ │
┌─[3]─┐ ┌─[3]─┐
│1.00∠0°│ │1.01∠-12°│
└─────┘ └─────┘
色分け: 緑=収束, 黄=更新中, 赤=大誤差
const displayLevels = {
beginner: {
showEquations: false, // 数式非表示
showMatrix: false, // 行列詳細非表示
animationSpeed: 'slow', // ゆっくり
explanationLevel: 'detailed' // 詳細説明
},
intermediate: {
showEquations: true, // 数式表示
showMatrix: true, // 行列構造表示
animationSpeed: 'medium', // 中速
explanationLevel: 'moderate' // 適度説明
},
advanced: {
showEquations: true, // 完全数式
showMatrix: true, // 全行列要素
animationSpeed: 'fast', // 高速
explanationLevel: 'minimal' // 最小説明
}
};
function generateQuiz(currentStep) {
const quizzes = {
2: "次のミスマッチが最も大きい母線は?",
3: "Jacobian行列の(2,3)要素は何を表す?",
4: "LU分解を使う理由は?",
5: "電圧位相角の更新量が負の意味は?"
};
return {
question: quizzes[currentStep],
options: generateOptions(currentStep),
correctAnswer: calculateCorrectAnswer(currentStep)
};
}
function provideHint(stepNumber, difficulty) {
const hints = {
beginner: "この段階では電力の不足分を計算しています",
intermediate: "ΔP = P指定 - P計算 = P指定 - Re(V*・(Y・V)*)",
advanced: "ミスマッチベクトルf(x) = [ΔP; ΔQ]の構築"
};
return hints[difficulty];
}
ファイル: power_flow_process_visualizer.html
作成日: 2024年12月30日
更新日: 2024年12月30日
バージョン: 1.5