ngspiceってのがある。結果の表示をPySpiceってやつでもちっとうまいことでるんやないか。って試み。
前回、シミュレーションすることができた。ついに(ってほどじゃないやろ)、値を変更しながらのシミュレーションで結果を重ね書きってのをやる。で、
-
import math
-
import numpy as np
-
import matplotlib.pyplot as plt
-
import PySpice.Logging.Logging as Logging
-
logger = Logging.setup_logging()
-
from PySpice.Plot.BodeDiagram import bode_diagram
-
from PySpice.Spice.Netlist import Circuit
-
def ngspice_simulation(cvalue):
-
circuit = Circuit('Low-Pass RC Filter')
-
circuit.SinusoidalVoltageSource('input', 'vin', circuit.gnd, amplitude=1)
-
R1 = circuit.R(1, 'vin', 'vout', 1e3)
-
C1 = circuit.C(1, 'vout', circuit.gnd, cvalue)
-
break_frequency = 1 / (2 * math.pi * float(R1.resistance * C1.capacitance))
-
print("Break frequency = {:.1f} Hz".format(break_frequency))
-
simulator = circuit.simulator(temperature=25, nominal_temperature=25)
-
analysis = simulator.ac(start_frequency=1, stop_frequency=1e6, number_of_points=10, variation='dec')
-
freqs=np.array(analysis.frequency)
-
vout=np.array(analysis.vout)
-
return freqs,vout
-
freqs,vout1=ngspice_simulation(1e-6)
-
freqs,vout2=ngspice_simulation(0.1e-6)
-
freqs,vout3=ngspice_simulation(0.01e-6)
-
fig = plt.figure()
-
ax1=plt.subplot(2,1,1)
-
ax1.grid(True)
-
ax1.plot(freqs,20*np.log10(np.absolute(vout1)), 'b-')
-
ax1.plot(freqs,20*np.log10(np.absolute(vout2)), 'g-')
-
ax1.plot(freqs,20*np.log10(np.absolute(vout3)), 'r-')
-
ax1.set_ylabel('Amplitude [dB]')
-
plt.xscale('log')
-
ax2=plt.subplot(2,1,2)
-
ax2.grid(True)
-
ax2.plot(freqs,np.angle(vout1), 'b-')
-
ax2.plot(freqs,np.angle(vout2), 'g-')
-
ax2.plot(freqs,np.angle(vout3), 'r-')
-
ax2.set_xlabel('frequency [Hz]')
-
ax2.set_ylabel('Phase [rad.]')
-
plt.xscale('log')
-
fig.tight_layout()
-
plt.show()
シミュレーション部分を関数化しているけど、どういう感じで関数化するのかはセンスが問われるところ。引数とか、戻り値とか。今回は必要な分だけ対象にしている(最も手抜きシンプル)。
で、結果、
はい。うまくいった。
ngspiceの機能を補うとともにpythonでの特殊な計算の実装の可能性もあるpyspice。まぁまぁいいね。(pythonではahkabって回路シミュレーターも選択肢なんだけど、ahkabは非線形素子の計算がゲロクソ遅いとか問題がある。状況に応じて使い分けるのが良いと思われる。)
コメントをお書きください