python
1import numpy as np 2import matplotlib.pyplot as plt 3from numpy.lib.type_check import isrealobj 4 5#関数の定義 6def f1(fai2): 7 return fai2 8 9def f2(fai1,fai2): 10 return (i-np.sin(fai1)-fai2)/bc 11 12#初期値 13a = 0 14b = 100 15N = 20000 16h = (b-a)/N 17 18bc = 4 19 20#配列 21fai1 = np.empty(N) 22fai2 = np.empty(N) 23fai1_0 = 0 24fai2_0 = 0 25fai1[0] = fai1_0 26fai2[0] = fai2_0 27 28for i in np.linspace(0, 2, 201): 29 30 for j in range (0, N-2, 1): 31 k1 = h * f1(fai2[j]) 32 d1 = h * f2(fai1[j] , fai2[j]) 33 k2 = h * f1(fai2[j] + d1/2) 34 d2 = h * f2(fai1[j] + k1/2, fai2[j] + d1/2) 35 k3 = h * f1(fai2[j] + d2/2) 36 d3 = h * f2(fai1[j] + k2/2, fai2[j] +d2/2) 37 k4 = h * f1(fai2[j] + d3) 38 d4 = h * f2(fai1[j] + k3 , fai2[j] + d3) 39 fai1[j+1] = fai1[j] + 1/6 * (k1 + 2 * k2 + 2 * k3 + k4) 40 fai2[j+1] = fai2[j] + 1/6 * (d1 + 2 * d2 + 2 * d3 + d4) 41 42 if j == N-1: 43 break 44 45 #6000以降のfai2の合計の平均 46 v = np.average(fai2[10000:]) 47 print(v) 48 print(i) 49 plt.scatter(v, i, marker='.',color = "green") 50 51fai2_0 = fai2[19999] 52fai1_0 = fai1[19999] 53 54 55for i in np.linspace(2, 0, 201): 56 57 for j in range (N-2, 0, -1): 58 k1 = h * f1(fai2[j]) 59 d1 = h * f2(fai1[j] , fai2[j]) 60 k2 = h * f1(fai2[j] + d1/2) 61 d2 = h * f2(fai1[j] + k1/2, fai2[j] + d1/2) 62 k3 = h * f1(fai2[j] + d2/2) 63 d3 = h * f2(fai1[j] + k2/2, fai2[j] +d2/2) 64 k4 = h * f1(fai2[j] + d3) 65 d4 = h * f2(fai1[j] + k3 , fai2[j] + d3) 66 fai1[j-1] = fai1[j] + 1/6 * (k1 + 2 * k2 + 2 * k3 + k4) 67 fai2[j-1] = fai2[j] + 1/6 * (d1 + 2 * d2 + 2 * d3 + d4) 68 69 if j == 0: 70 break 71 72 #6000以降のfai2の合計の平均 73 v = np.average(fai2[:10000]) 74 75 print(v) 76 print(i) 77 plt.scatter(v, i, marker='.',color = 'blue') 78 79#plot 80plt.plot(v,i) 81plt.xlim(0, 1.8) 82plt.ylim(0, 2.0) 83plt.xlabel("v") 84plt.ylabel("i") 85plt.show() 86``` このコードは、規格化されたRCSJモデル 87 i = sinφ + dφ/dτ + βc*d^2φ/dτ^2 88という電流iと電圧vのグラフをプロットするために書いたコードです。(ここではφをfai1,dφ/dτをfai2とおいています) 89 電流を0から2まで増やしていったあと、そのまま電流を2から0まで減らしていくと以下のグラフ1のように帰ってくる値が0ではなく、与えたβcの値によって変わるヒステリシスという現象が起こります。このコードをルンゲクッタ法を用いて書いていきます。 90 本来であれば、電流iは規格化されているので臨界電流としてi=1.0となるまでは電圧vはグラフのようにほぼ0の値をとり続けるのですが、実際にコードを回してみると、なぜかi=1.0に行く前に電圧が発生しているグラフがプロットされます。結果の数値を表示すると、i=0.94でvの値が大きくなってしまっていました(グラフ2) 91それ以前の問題だと思い、φ2とτのグラフを確認してみたところ、それらのグラフはきちんとプロットされていたので、vとiのグラフをプロットした途端に正しく出ないのはおかしいと思いました。 92 どこかコードがおかしいのでしょうか。それとも、小数点以下の誤差なので、どこかループでの誤差の影響なのでしょうか。アドバイスを頂けたらと思います。 93 94グラフ1![イメージ説明](7f5eb9303100c07a76838b9c3867e472.png) 95 96グラフ2![イメージ説明](b7d983fd26d34267deba8efc111ecb7f.png)
> グラフプロットの際の誤差
計算は合っているのにグラフ化するとおかしくなる、という現象が起きているのでしょうか?
申し訳ありません。計算した際の値も表示しているのですが、そこで値がおかしくなっていました。
すぐにタイトルを修正します。
あるべき姿(?)を手書きでもよいので画像に加えていただくことはできますか?
本来であれば、緑色の点(電流iを増加させたときの点)がi=1.0に到達してから電圧vが発生するので、あるべき姿はグラフ1の赤色の点線のようになるはずです。
規格化されたRCSJモデルに関する資料(ジョセフソン接合関連)を2本程斜め読みしたのですが、f2 関数内の計算式にある np.sin(fai1) は np.cos(fai1) じゃないかな、と。
def f2(fai1,fai2):
##return (i-np.sin(fai1)-fai2)/bc
return (i-np.cos(fai1)-fai2)/bc
np.cos に変更して実行すると i=0 に到達してから電圧が発生します。
確かにcosにすると正しくプロットできていました、、
ですが、ジョセフソン効果で、I=Ic*sinθの関係からそれを用いて規格化しているので、そこをcosに変えてしまうとそもそもがおかしくなってしまわないでしょうか、、?
v の平均値に影響はなく、位相が π/2 ずれるだけかと思います。ズレがどのくらいかと言うと、bc * i_tick * (cos(0) - sin(0)) です。i_tick は for i in np.linspace(0, 2, 201) としているので 0.01 です。つまり、 4 * 0.01 * 1 = 0.04 ずれるので 0.96 で電流が発生してしまう事になります(実際には 0.94 ですが)。
規格化された通りの式でコードを入力しているつもりなのですが、なぜそのようなズレが生じてしまっているのでしょうか?
それとも、コードのどこかでそのズレを生じさせてしまっているということでしょうか?
回答1件
あなたの回答
tips
プレビュー