0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

spiceの数値計算をPythonコードで

Posted at

✅ 数値シミュレーション手法一覧表(陰的法・DAE中心)

分類 手法名 主な特徴 用途・備考
数値積分法 後退オイラー法 一次精度・陰的・安定性が高い 硬い問題に適用しやすく、SPICEの基本手法
台形公式(Trapezoidal Rule) 二次精度・平均化を利用・比較的高精度 高精度解析向けだが振動的になることがある
Gear法(BDF法) 多段・陰的・L-安定性・非常に硬い問題に有効 電気回路(SPICE)で頻繁に使われる
DAEソルバ IDA(SUNDIALS) Index-1対応・陰的法・ヤコビ評価に柔軟 汎用DAEソルバ、工学的モデリングツールで広く利用
DASSL Fortran由来・古典的DAE解法 数値計算書で頻出
反復法 ニュートン・ラフソン法 非線形方程式用・局所二次収束 ヤコビ行列が必要、初期値依存が大
修正ニュートン法 ヤコビ行列を固定・反復回数節約 大規模系で計算軽減に有効
ステップ制御 予測子-修正子方式 誤差推定 → ステップ幅調整 Gear法やSPICEで標準的に採用
行列解法 LU分解 線形系の直接解法・安定 一度分解すれば多回代入に向いている
ガウス消去法 線形方程式の基本解法 小規模システムに有効
応用系 MNA法 電気回路→Index-1 DAEへ導出 SPICEの基礎理論
DCOP解析 静的状態から初期条件決定 DAE整合初期値生成として不可欠

# Program Name: first_order_compare_error.py
# Creation Date: 20250609
# Overview: Compare 3 integration methods for RC circuit including error analysis
# Usage: Run to see method comparison, absolute error plots, and dt-dependence

!pip install numpy matplotlib

import numpy as np
import matplotlib.pyplot as plt

# --- Simulation parameters / パラメータ ---
R = 1.0
C = 1.0
tau = R * C
T_end = 5.0
V_in = 1.0
V0 = 0.0

# --- 固定ステップでの誤差評価 ---
dt = 0.1
time = np.arange(0, T_end + dt, dt)
N = len(time)

# 初期化 / Initialize
V_be = np.zeros(N)
V_tp = np.zeros(N)
V_gear = np.zeros(N)
V_ana = V_in * (1 - np.exp(-time / tau))
V_be[0] = V_tp[0] = V_gear[0] = V0
V_gear[1] = (V0 + dt / tau * V_in) / (1 + dt / tau)

# Backward Euler
for n in range(1, N):
    V_be[n] = (V_be[n-1] + dt / tau * V_in) / (1 + dt / tau)

# Trapezoidal
for n in range(1, N):
    a = (1 - dt / (2 * tau))
    b = dt / tau
    V_tp[n] = (a * V_tp[n-1] + b * V_in) / (1 + dt / (2 * tau))

# Gear BDF2
for n in range(2, N):
    alpha0, alpha1, alpha2 = 3/2, -2, 1/2
    beta = dt * V_in / tau
    V_gear[n] = (-alpha1 * V_gear[n-1] - alpha2 * V_gear[n-2] + beta) / alpha0

# --- 絶対誤差のプロット / Plot absolute errors ---
plt.plot(time, np.abs(V_be - V_ana), label='Error: Backward Euler')
plt.plot(time, np.abs(V_tp - V_ana), label='Error: Trapezoidal')
plt.plot(time, np.abs(V_gear - V_ana), label='Error: Gear BDF2')
plt.title('Absolute Error vs Time')
plt.xlabel('Time [s]')
plt.ylabel('Absolute Error [V]')
plt.legend()
plt.grid(True)
plt.show()

# --- ステップ幅と誤差の関係 / dt vs error plot ---
dt_list = [0.4, 0.2, 0.1, 0.05, 0.01]
err_be = []
err_tp = []
err_gear = []

for dt in dt_list:
    time = np.arange(0, T_end + dt, dt)
    N = len(time)
    V_ana = V_in * (1 - np.exp(-time / tau))
    V_be = np.zeros(N)
    V_tp = np.zeros(N)
    V_gear = np.zeros(N)
    V_be[0] = V_tp[0] = V_gear[0] = V0
    if N > 1:
        V_gear[1] = (V0 + dt / tau * V_in) / (1 + dt / tau)

    for n in range(1, N):
        V_be[n] = (V_be[n-1] + dt / tau * V_in) / (1 + dt / tau)
        a = (1 - dt / (2 * tau))
        b = dt / tau
        V_tp[n] = (a * V_tp[n-1] + b * V_in) / (1 + dt / (2 * tau))

    for n in range(2, N):
        alpha0, alpha1, alpha2 = 3/2, -2, 1/2
        beta = dt * V_in / tau
        V_gear[n] = (-alpha1 * V_gear[n-1] - alpha2 * V_gear[n-2] + beta) / alpha0

    err_be.append(np.abs(V_be - V_ana).max())
    err_tp.append(np.abs(V_tp - V_ana).max())
    err_gear.append(np.abs(V_gear - V_ana).max())

# --- プロット(対数軸) / Error vs dt ---
plt.loglog(dt_list, err_be, 'o-', label='Backward Euler')
plt.loglog(dt_list, err_tp, 's--', label='Trapezoidal')
plt.loglog(dt_list, err_gear, 'x-.', label='Gear BDF2')
plt.title('Max Error vs Time Step')
plt.xlabel('Time Step Δt [s]')
plt.ylabel('Max Absolute Error [V]')
plt.grid(True, which='both')
plt.legend()
plt.show()

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?