質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

928閲覧

python 応用ルンゲクッタ法

Ackngawe.-

総合スコア27

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/12/24 06:53

編集2021/12/24 07:38

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φ +/+ βc*d^2φ/^2 88という電流iと電圧vのグラフをプロットするために書いたコードです。(ここではφをfai1,/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)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meg_

2021/12/24 07:27

> グラフプロットの際の誤差 計算は合っているのにグラフ化するとおかしくなる、という現象が起きているのでしょうか?
Ackngawe.-

2021/12/24 07:33

申し訳ありません。計算した際の値も表示しているのですが、そこで値がおかしくなっていました。 すぐにタイトルを修正します。
退会済みユーザー

退会済みユーザー

2021/12/25 04:24

あるべき姿(?)を手書きでもよいので画像に加えていただくことはできますか?
Ackngawe.-

2021/12/25 07:22

本来であれば、緑色の点(電流iを増加させたときの点)がi=1.0に到達してから電圧vが発生するので、あるべき姿はグラフ1の赤色の点線のようになるはずです。
melian

2021/12/25 13:05

規格化された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 に到達してから電圧が発生します。
Ackngawe.-

2021/12/26 05:43

確かにcosにすると正しくプロットできていました、、 ですが、ジョセフソン効果で、I=Ic*sinθの関係からそれを用いて規格化しているので、そこをcosに変えてしまうとそもそもがおかしくなってしまわないでしょうか、、?
melian

2021/12/26 05:50

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 ですが)。
Ackngawe.-

2021/12/26 08:07

規格化された通りの式でコードを入力しているつもりなのですが、なぜそのようなズレが生じてしまっているのでしょうか? それとも、コードのどこかでそのズレを生じさせてしまっているということでしょうか?
guest

回答1

0

自己解決

python

1import numpy as np 2import matplotlib.pyplot as plt 3 4def f1(tau,fai2:float): 5 return fai2 6 7def f2(tau,fai1,fai2:float): 8 return (i-np.sin(fai1)-fai2)/BC 9 10i = 1.0 11BC = 4 12 13a = 0 14b = 100 15N = 20000 16h = (b-a)/N 17fai1 = 0.0 18fai2 = 0.0 19s = float() 20v = float() 21 22ln, = plt.plot([], []) 23 24for i in np.arange(0, 2, 0.01): 25 26 for j in range(0, N, 1): 27 tau = j * h 28 k1 = h * f1(tau,fai2) 29 d1 = h * f2(tau,fai1 , fai2) 30 k2 = h * f1(tau,fai2 + d1/2) 31 d2 = h * f2(tau,fai1 + k1/2, fai2 + d1/2) 32 k3 = h * f1(tau,fai2 + d2/2) 33 d3 = h * f2(tau,fai1 + k2/2 , fai2 +d2/2) 34 k4 = h * f1(tau,fai2 + d3) 35 d4 = h * f2(tau,fai1 + k3 , fai2 + d3 ) 36 fai1 += 1/6 * (k1 + 2 * k2 + 2 * k3 + k4) 37 fai2 += 1/6 * (d1 + 2 * d2 + 2 * d3 + d4) 38 39 if j > 10000: 40 s += fai2 41 42 v = s / 10000 43 print(v) 44 print(i) 45 ln.set_xdata(np.append(ln.get_xdata(), v)) 46 ln.set_ydata(np.append(ln.get_ydata(), i)) 47 plt.scatter(v, i, marker='.',color = 'blue') 48 s = 0 49 50for i in np.arange(2, 0, -0.01): 51 52 for j in range(0, N, 1): 53 tau = j * h 54 k1 = h * f1(tau,fai2) 55 d1 = h * f2(tau,fai1 , fai2) 56 k2 = h * f1(tau,fai2 + d1/2) 57 d2 = h * f2(tau,fai1 + k1/2, fai2 + d1/2) 58 k3 = h * f1(tau,fai2 + d2/2) 59 d3 = h * f2(tau,fai1 + k2/2 , fai2 +d2/2) 60 k4 = h * f1(tau,fai2 + d3) 61 d4 = h * f2(tau,fai1 + k3 , fai2 + d3 ) 62 fai1 += 1/6 * (k1 + 2 * k2 + 2 * k3 + k4) 63 fai2 += 1/6 * (d1 + 2 * d2 + 2 * d3 + d4) 64 65 if j > 10000: 66 s += fai2 67 68 v = s / 10000 69 print(v) 70 print(i) 71 ln.set_xdata(np.append(ln.get_xdata(), v)) 72 ln.set_ydata(np.append(ln.get_ydata(), i)) 73 plt.scatter(v, i, marker='.',color = 'green') 74 s = 0 75 76y = ln.get_ydata() 77plt.plot(v,i) 78plt.xlim(0, 1.8) 79plt.ylim(0, 2.0) 80plt.xlabel("v") 81plt.ylabel("i") 82plt.show() 83```配列を使わないコードでなんとかできました。

投稿2021/12/27 03:49

Ackngawe.-

総合スコア27

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/12/28 12:00

解決できて何よりです。手元で動かしましたが計算が遅かったのを覚えています。 参考までに高速化方法を書きます。 from numba import jit として、 @jit() def f2(fai1,fai2): とするとかなり早くなります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問