シュレディンガー方程式の解法(中級偏)yasue/ffn/c8-schrodinger.pdf ·...
TRANSCRIPT
C言語第 8回 [複写/貼り付け]ができます。
Copyright © 1997-2017 Masaki Yasue, Dept. of Phys., Tokai Univ, All rights reserved.
1
シュレディンガー方程式の解法(中級偏)
→ →
【1】量子力学
量子力学は複素数で記述される力学です。基本になる運動方程式を
シュレディンガー方程式
と言い、波動関数を
( )(psi)
,x tyプサイ
と表すと、
( ) ( ) ( ) ( )2
0
0 , 1 ,2
x ax ti i V x x t V x
t m x V x ay
yì >é ù¶ ¶ ïæ ö= - + Ü =ê ú íç ÷¶ ¶ - £è øê ú ïë û î
を満たします。量子の位置 ( )x t と運動量 ( )p t は、
観測毎に値が異なり
平均値しか観測できずに、その値は
( ) ( ) ( )
( ) ( ) ( )
, ,
,,
x t x t x x t dx
x tp t x t i dx
x
y y
yy
¥*
-¥
¥*
-¥
=
¶=
¶
ò
ò
で計算されます。従って、量子の運動は、
( ),x ty がわかればよい
ことになります。とくに、
( ) 2,x ty は、位置 xに粒子がいる確率
になります。全領域( : x -¥® +¥ )に粒子がいる確率は 100%なので
( ) 2, 1x t dxy
-
¥
¥
=ò
になっています。この ( ),x ty を知るには、微分方程式のシュレディンガー方程式を解く必要
があります。
【2】差分方程式
解くべき微分方程式は
1個の量子とポテンシャルの障壁との一次元の衝突をコンピュータでシミュレーションします。角井戸型ポテンシャルを用い、出発時の波束は典型的な量子を記述するガウス型波束を用います。波動関数を各位置すべてにおいてシュレディンガー方程式に従って計算し、入射波束のガウス型波束が角井戸型のポテンシャル障壁に衝突する様子を導きます。(上図のようなグラフィックス化は省きます)
x
y
a- a
0V-
0V
C言語第 8回 [複写/貼り付け]ができます。 2
( ) ( ) ( ) ( ) ( ) ( )22
2
, ,, , ,
2x t x t
i x t V x x t x tt m x
y yy y y
æ ö¶ ¶¢¢ ¢¢= - + =ç ÷
¶ ¶è ø
です。これは、
位置 xの値を固定して tの変化による ( ),x ty を計算する
ことになります。差分に直す微分は、2 種類で、
●( ),x tt
y¶¶
●( ) ( )( )
2
2
,,
x tx t
xy
y¶
¢¢=¶
になります。微分を差分に直すには、テイラー展開をつかいます。テイラー展開は
( ) ( ) ( ) ( ) ( ) ( ) ( )2 3
0 ! 2! 3!
nn
n
a a af x a f x f x a f x f x f xn
¥
=
¢ ¢¢ ¢¢¢+ = = + + + +å
で与えられ、第 1 項と第 2 項に該当する微分があります。差分の数値計算では、
( ) ( ) ( ) ( )
dt t x x x x x xdx xf x f x x x f x tx f x tdt t
Dü ü ü ü- = D = + Dï ï ï ïÞ Þ ÞDý ý ý ý= = = + DD = D ïï ï ï þþDþ þ
次の時刻 現時刻 次の時刻 現時刻
次の時刻 現時刻
のように、
t t tx x x
= + Dìïí = + Dïî
次の時刻 現時刻
次の時刻 現時刻
として次の値を決めていきます。一つ前の値は
t t tx x x
= -Dìïí = -Dïî
現時刻前の時刻
現時刻前の時刻
です。位置 xについての差分方程式は、 x x+ D と x x- D の2つのテイラー展開:
( ) ( ) ( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )
2 3
0
2 3
0
, , , , , ,! 2! 3!
, , , , , ,! 2! 3!
nn
nn
n
n
x x xx x t x t x t x x t x t x tn
x x xx x t x t x t x x t x t x tn
y y y y y y
y y y y y y
¥
=
¥
=
D D D¢ ¢¢ ¢¢¢+ D = = + D + + +
-D D D¢ ¢¢ ¢¢¢- D = = -D + - +
å
å
を利用して、
( ) ( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( )
2 3
2 3
0
2 3
0
2
, , , ,2! 3!
, , 2 , 22!
, ,
,
xx x x
xx x
x t xx xx x t x t x x t x t x
xx x t x x t
t
x t x t
y y
y
y y y y
y y y
DD D D
DD D
D D¢¢ ¢¢¢+ D - = D + + + = D
D+ D + -
¢ ¢
D = + ¢¢ +
≒ にするには、充分小さい をつかう。
とできる。
≒ にするには、充分小さい をつかう。
とできる。
( ) ( )2
, 2 , 22!xx x tt yy ¢¢D
= +
より、
充分小さい xD
C言語第 8回 [複写/貼り付け]ができます。 3
0.010.001
xx
D =
D = Þ計算精度がより良い
など
の時には
( ) ( ) ( )
( ) ( ) ( ) ( )2
, ,
, 2 ,
,
,,
x x t x tx
x x t x t x x tx
x
x t
t
y
y
y y
y y y
+ D -ì=ïï D
í+
¢
D - + -Dï =¢¢ï Dîと差分であらわすことができます。時間の微分は
( ) ( ) ( ), , ,x t x t t x tt t
y y y¶ + D -=
¶ Dになります。
【3】シュレディンガー方程式
微分方程式:
( ) ( ) ( ) ( )2,
, ,2
x ti x t V x x t
t my
y y¶
¢¢= - +¶
は、差分方程式として
( ) ( ) ( ) ( ) ( ) ( ) ( )2
2
, 2 ,, , ,,
2x x t xx t tt x t x x t
i V x x tt m x
y y y y yy
+D - + -D= - +
D D+ D -
になります。この差分方程式は、 0tD ® & 0xD ® で微分方程式に帰着します。これより、
( ) ( ) ( ) ( ) ( ) ( ) ( )2
2
, 2 , ,,
2, ,
tt t
x x t x t x x ti V x x t tm x
x t t x ty y y
y yy+D
+ D - + -Dé ù= - - Dê úDë
+ Dû
時刻
時刻
として次の時刻 t t+ D の値を決めていきます。まず、最初の波動関数は 0t t= で分かっているとし
て与えます。標準な関数として、図 1 のような形状(ガウス型波束と呼ばれる)の
( ) ( )2
0 224
1, exp42
x x i p xx t
DDy
p
é ù-ê ú= - +ê úë û
図 1: 1, 0.035, 0.3, 50D x p p= = = - =
にします。これを用いて、 ( ) ( )0 0, x t p t を計算
( ) ( ) ( )
( ) ( ) ( )
0 0 0
00 0
, ,
,,
x t x t x x t dx
x tp t x t i dx
x
y y
yy
¥*
-¥
¥*
-¥
=
¶=
¶
ò
ò
すると
( )( )
0
0
x t x
p t p
ì =ïí
=ïî
になります。 ( )0,x ty は
時刻 0t に量子を位置 xに見つける確率
( )0,x ty
x
図 1
時刻 t0 の時
C言語第 8回 [複写/貼り付け]ができます。 4
大雑把に x x= の付近の確率が大きい
時刻 0t の量子の位置はだいたい ( )0x x t xÞ =を与えています。また、
無限遠方には量子は存在しないと見なすので、 x = ±¥では、
( ), 0x ty =とする
を仮定します。
波動関数の x方向の値は、
0 1 0 2 1 3 2x x x x x x x x x xÞ = + D Þ = + D Þ = +D Þ
( ) ( ) ( )2
0 0 224
1 , exp 0,1,2,342n n
n
x x i p xt x t n
DDy
p
é ù-ê ú= - + =ê úë û
のように、 0t t= で、 ( )0,x ty の値を 0x から順番に xD づつ増やして計算しておきます。次に、
1 0t t t= + D
で、 ( )0,x ty より、 ( )0,x t ty +D を計算します:
( ) ( ) ( ) ( ) ( ) ( )1 2
0 0 00 0 02
, 2 , ,, , ,
2
tx x t x t x x tix t t x t V x x t t
m xy y y
y y yæ ö + D - + -Dé ùç ÷+ D = - - Dê úç ÷ Dë ûè ø
それを用い、 0x から順番に xD づつ増やして
( ) ( )( ) ( ) ( )
( ) ( )
( ) ( ) ( ) ( ) ( ) ( ) ( )
21 0 0 0 1 0
1 0 0 02
21 0 0 1 0
1
0 0 0
0 0 02
0
, 2 , ,, , , ,
2
, 2 , ,, , , ,
2n nn
nn
nn
x t x t x tix t x t V x t x t tm x
x t x t x tix t x t V x t x t tm x
y y yy y y
y y yy y y
-
+ -
ì é ù- +ï ê ú= + - Dï ê úDï ë ûíï - +é ù
= + - Dï ê úDï ë ûî
各 ( ) 0,1,2,3,nx n = で計算します。次に、時間をすすめ
2 1t t t= + D
にして、 ( )1,x ty より、 ( )2,x ty を計算し、
( ) ( )( ) ( ) ( )
( ) ( )
( ) ( ) ( ) ( ) ( ) ( ) ( )
21 1 0 1 1 1
2 1 1 12
21 1 1 1 1
2
0 0 0
1 1 12
0
, 2 , ,, , , ,
2
, 2 , ,, , , ,
2n nn
nn
nn
x t x t x tix t x t V x t x t tm x
x t x t x tix t x t V x t x t tm x
y y yy y y
y y yy y y
-
+ -
ì é ù- +ï ê ú= + - Dï ê úDï ë ûíï - +é ù
= + - Dï ê úDï ë ûî
のように次々と時間を tD づつ増やして、計算を繰り返します。ここで、
( )10 ,x ty の計算には、 ( )1 0,x ty - も必要
なので、
C言語第 8回 [複写/貼り付け]ができます。 5
( ) ( )2
1 11 0 224
1, exp42
x x i p xx t
DDy
p
- --
é ù-ê ú= - +ê úê úë û
も計算しておきます。従って、
1 0 1 2 3, , , , , x x x x x x-=
の並びで xD づつ増加させ値を決めておきます。
【4】ルンゲ・クッタ法
差分方程式は、
( ) ( ) ( ) ( ) ( ) ( ) ( )2
2
, 2 , ,, , ,
2x x t x t x x tix x t V x t
m xt t x t
y y yy y y
+D - + -Dé ù= - - Dê úDë
Dû
+
より、 nt t= のとき、 t t+ D は
1n nt t t+ = + D
となるので、
( ) ( ) ( ) ( ) ( ) ( ) ( )1
2
2
, 2 , ,, , ,
2n
nnn n
n
x x t x t x x tix x t V x x t tm
tx
y y yy y y+
+ D - + -Dé ù= - - Dê úDë û
と表されます。これはオイラー法の
( )1 ,n n n nx x f x t t+ = + D
に当たります。あるいは ( ) ( ) ( ) ( )0 0 1 1 2 2 3 3, , , , x t x x t x x t x x t x= = = = と対応させると
( ) ( ) ( )( )1 ,n n n nx t x t f x t t t+ = + D
になります。そこで、
( ) ( ),n nx t x ty®
と対応させることができるので、y では ( )( ), ,n nf x t ty を用いて
( ) ( ) ( )( )
( )( ) ( ) ( ) ( ) ( ) ( )
1
2
2
, , , ,
, 2 , ,, , ,
2
n n n n
n n nn n n
x t x t f x t t t
x x t x t x x tif x t t V x x tm x
y y y
y y yy y
+ = + D
+ D - + -Dé ù= - -ê úDë û
と分かります。また、 ( ) ( ) ( ) ( )0 0 1 1 2 2 3 3, , , , x t x x t x x t x x t x= = = = に対して
( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )0 0 1 1 2 2 2 3, , , , , , , , x t x x t x x t x x t xy y y y y y y y= = = =
という関係になります。従って、
C言語第 8回 [複写/貼り付け]ができます。 6
( ) ( ) ( )( )
( )( ) ( ) ( ) ( ) ( ) ( )
1
2
2
,
2,
2
n
n n n n
n n n
t
nn n
x x f x t t
x x x x xif x V x xm x
t
y y y
y y yy y
+ = + D
+ D - + -Dé ù= - -ê úDë û
は無い
と表記できます。実際には、 nt は使われていないです。
ルンゲ・クッタ法では、【第5回 数値シミュレーション:1階の微分方程式(シラバス8・
9回目)】-【4】C言語プログラム:Runge-Kutta 法にてSTEP t®D と読み直して
( )
( )
( )
1
1
12
1 2 3 41 1
23
2 3
,
,2 22 2,
6,
2 2,
n n
k n n
n n n n n n
n n
n n
k f x t
k tk f x t tk k k kx x f x t t x x t
k tk f x t t
k f x k t t t
+ +
=ìï
Dæ öï = + D +ç ÷ï+ + + ï è ø= + D Þ = + D íDæ öï = + D +ç ÷ï è ø
ï= + D + Dïî
を計算します。ここでは、y について解くので、 x y® にすると
( )
( )
1
12
1 2 3 41 1 1
23
2 3
,
,2 22 2
6,
2 2,
n n
n n
n n n n
n n
n n
k f t
k tk f t tk k k kk t t
k tk f t t
k f k t t t
y
yy y y y
y
y
+ +
=ìï
Dæ öï = + D +ç ÷ï+ + + ï è ø= + D Þ = + D íDæ öï = + D +ç ÷ï è ø
ï= + D + Dïî
になります。ところで、y の場合には、各位置 xで計算するので、区別するため xを付け、
( ) ( ) ( )1 1 1,2,3,4 1,2,3,4, , n n n nx x k k xy y y y+ +® ® ®
とします。従って、
( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )1 2 3 41 1 1
2 26n n n n
k x k x k x k xx x k x x x ty y y y+ +
+ + += + Þ = + D
になります。ルンゲ・クッタ法は
( ) ( ) ( ) ( ) ( ) ( )1 2 3 41
2 26n n
k x k x k x k xx x ty y+
+ + += + D
になり、
( ) ( )( ) ( ) ( ) ( ) ( ) ( )2
1 2
2,
2n n n
n n n
x x x x xik x f x t V x xm xy y y
y y+D - + -Dé ù
= = -ê úDë û
C言語第 8回 [複写/貼り付け]ができます。 7
( ) ( ) ( )
( ) ( ) ( ) ( ) ( ) ( )
( ) ( ) ( )
12
1 1 12
2
1
,2 2
22 2 2
2
2
n n
xx x x x
n n n
x
n
k x tk x f x t t
k x x k x k x xx x t x t x x t
im x
k xV x x t
y
y y y
y
+D -D
æ öD= + D +ç ÷
è øé ùê ú+ D -Dæ ö
+ D + D - + D + -D + Dê úç ÷è øê ú
ê ú= Dê úê ú
æ öê ú- + Dç ÷ê úè øë û
( ) ( ) ( )
( ) ( ) ( ) ( ) ( ) ( )
( ) ( ) ( )
( ) ( ) ( )( )
23
2 2 22
2
2
4 3
,2 2
22 2 2
2
2
,
n n
xx x x x
n n n
x
n
n n
k x tk x f x t t
k x x k x k x xx x t x t x x t
im x
k xV x x t
k x f x k x t
y
y y y
y
y
+D -D
æ öD= + D +ç ÷
è øé ùê ú+ D -Dæ ö
+ D + D - + D + -D + Dê úç ÷è øê ú
ê ú= Dê úê ú
æ öê ú- + Dç ÷ê úè øë û
= +
( ) ( ) ( ) ( )( ) ( ) ( )
( ) ( ) ( )( )
23 3 3
2
3
2 2
xx x x x
n n n
x
n
x x k x x t x k x t x x k x x ti
m x
V x x k x t
y y y
y
+D -Dé ùê ú+ D + + D D - + D + - D + - D Dê ú
= Dê úê úê ú- + Dë û
で与えられます。
【5】プログラムの準備
得られた数式をプログラムに合うように整理します。まず、使用する数値は、シッフ著「量子力学
(上) (物理学叢書 (2)、吉岡書店)」にある数値を参考にします。
使用する数値
位置の進み: 0.004xD =
( )max max
max
max maxmax
02 2 max
max max max
5002 2
250 250 0
2 2 2
m mm m i
m mx x x m
x x x m m mm m mx m x m x x m
= Þ- = Þ
ì- D £ £ D =ïïï- D £ £ D Þ Þ = ® =íï æ ö æ ö æ öï = - D Þ - D £ £ -ç ÷ ç ÷ ç ÷ï è ø è ø è øî
時間の進み:2
4xt D
D =
( )max max max0 800 0 800 0t t t n t n t n t n n n£ £ D Þ £ £ D = Þ = D Þ = ® =
シュレディンガー方程式:
C言語第 8回 [複写/貼り付け]ができます。 8
( ) ( ) ( ) ( )22
2
, ,, , 1, 2 1
2x t x t
i V x t x t mt m x
y yy
¶ ¶= - + Ü = =
¶ ¶
ポテンシャル: ( ) ( ) ( )20
0
0 , 70.7 , 0.032 0.064
x aV x t V a
V x ap
ì >ï= Ü = =í- £ïî
幅:
量子の初期(t=0)での波動関数:ガウス型波束:
( ) ( )2
0 224
1, exp 0.035, 0.3, 5042
x x i p xx t D x p
DDy p
p
é ù-ê ú= - + Ü = = - =ê úë û
です。プログラム内では
( ) ( )2
0 224
1, exp cos sin42
x x p x p xx t i
DDy
p
é ù- æ öê ú= - +ç ÷ê ú è øë û
として用います。実部と虚部に分けて用います。
ψn(x)の n について
時間発展は、
( ) : 0 1 2n x n n ny®
= ® = ® = ®時間経過
と nで追跡します。また、位置の変化は
1 0 1 2: , , , , mx x x x x x x-= Þ
とmで追跡するとしましょう。プログラムでは
::m xn tìíî
位置
時間
の添え字を使います。m と nは
1
11
x x mt n
x mt t n
x x m
-D Þ -ìÞìï Þí í + D Þ +îï + D Þ +î
に対応します。
m0 50 100 150 200 250 300 350 400 350 400 450
0n =
C言語第 8回 [複写/貼り付け]ができます。 9
これを踏まえて、ある位置に於ける時間発展を配列(【第2回 C言語の構成要素(シラバス
3・4回目)】-【8】配列)を使います。ここに、
列の添え字は 0 から始まる
に注意しましょう。従って、
1 0 1 2 1: , , , , : 1mx x x x x x x x m- -= Þ Þ = -
の設定は、 1m = - から始まりますが、
1m = - は C 言語の配列の添え字では、使用不可
です。そのため、
( ) ( )( ) ( ) ( )
( ) ( )
01
2 1 10 0 0 0
0 0 0 11 0 0 0
, 2 , ,, , , ,
2
mm
x t x t x tix t x t V x t x tm x
y y yy y y
=
-
=é ùê ú- +ê ú= + -ê úDê úê úë û
より
1
0
1
0
12
m x
m xm x
-= Þ
= Þ
= Þ
の対応になります。
配列は、
( ) [ ][ ]( ) [ ][ ]( ) [ ][ ]( ) [ ]1,2,3,4 1,2,3,4
1
1
n
n
n
x x n m
x n m
x x n m
k x k m
y y
y y
y y
ì + D Þ +ï
Þíï -D Þ -î
Þ
として追跡します。同様に、ポテンシャルは
( ) [ ]V x V mÞ
とします。これに従って、書き換えた表式が、
m0 50 100 150 200 250 300 350 400 350 400 450
300n =
C言語第 8回 [複写/貼り付け]ができます。 10
[ ][ ] [ ][ ] [ ] [ ] [ ] [ ]1 2 3 42 21
6k m k m k m k m
n m n m ty y+ + +
+ = + D
です。ここに、
0m = は 1x- に対応
し、計算は、 1m = から始まり
[ ][ ] [ ][ ] [ ] [ ] [ ] [ ]1 2 3 42 2 11 11
16
1 1k k k kn n ty y
+ + ++ = + D
になります。また、
[ ] [ ][ ] [ ][ ] [ ][ ] [ ] [ ][ ]
[ ]
[ ][ ] [ ] [ ][ ] [ ] [ ][ ] [ ]
[ ] [ ][ ] [ ]
[ ]
[ ][ ] [ ] [ ][ ] [ ] [ ][ ] [ ]
[ ]
2
1 2
1 12
22
1
2 22
23
1
2
2 12
12 1
2 22
2
1
12 1
2 22
11
2
11
2
n m n mik m V m n mm x
k m k mn m t n m t
ik m m xk m
V m n m t
k m k mn m
n m
k mn m t
t n m tik m m
kn t
x
V m
mm
y yy
y y
y
y
y
y
y
y
y
é ù- + -= -ê úDë û
é ùæ ö -- + D + - + Dê úç ÷
è øê úê ú= Dê ú
æ öê ú- + Dç ÷ê úè øë û
æ ö -- + D + -
+
++ + D
++ D+ + D ç ÷
è ø= D
-
[ ][ ] [ ]
[ ][ ][ ] [ ] [ ][ ] [ ]( ) [ ][ ] [ ]
[ ] [ ][ ] [ ]( )
23
3
3
2
32
4
2
2 1 12
1 1
k mn m t
n m k m t n m k m tik m m x
V m n m k m t
n m k m t y y
y
y
ìïïïïïïïïïïï
é ùíê úïê úïê úïê úï æ öê úï + Dç ÷ê úï è øë ûï
ï é ù- + D + - + - Dï ê ú
= Dï ê úï ê ú- + Dë ûî
+ + + D
になり、これがシュレディンガー方程式の解法の主要部分です。プログラムでは、
[ ]1 max: 0k m m m m= ® = のすべての値を計算した後に [ ]2k m を計算する
事になります。 [ ]2,3,4k m についても同様です。また、分子を一括して取り扱えるように
[ ][ ] [ ]
[ ][ ] [ ] [ ]
[ ][ ] [ ] [ ]
[ ][ ] [ ] [ ]
( )[ ][ ]
[ ]
[ ]
[ ]
[ ]
1
:psi2
3
4
1
2
3
4
1
2
3
01
2 21
psi k psi
1
11
12
1
21 1
1
1
k m
k mt n m
k m
k
r
r
k k mn m
k mn m t
k mn m t
n m
k k m
k k m
k k m
rr
rm t mk
y
y
y
y
y
y
ì ìï ïï ïï ïï Þ
+
++ + D
++ + D
+ + + D
=
+ D ´ Þ = +í íï ïï ïï ï
îïî
=
= =
=
= =
=
プサイと書く
と見なして
psi kr t+ D ´
を用います。
C言語第 8回 [複写/貼り付け]ができます。 11
プログラム用変数
プログラムで使用する変数を用意します。C 言語では、
使用する変数はすべて宣言
します。配列は大きさを指定します。ここでは、
配列( [ ][ ]n my )の大きさは、添え字(mや n )の総数で決定
されます。従って、
max
max
1
max max
1
max max
0 1
0 1
m
n
m m m m
n n n n n
m+
+
= ® = Þ = +
= ® = Þ = +
総数:
総数:
の総数
の総数
です。また、
psi
[ ][ ] psi[ ][ ] COMPLEX psi[ ][ ];n mm nn my Þ Þ の の総数総数
1
2
3
4
[ ] k1[ ] COMPLEX k1[ ];
[ ] k2[ ] COMPLEX k2[ ];
[ ] k3[ ] COMPLEX k3[ ];
[ ] k4[ ] COMPLEX k4[ ];
k m m
k m m
k
m
m
mm m
k m mm
Þ Þ
Þ Þ
Þ Þ
Þ Þ
の総数
の総数
の総数
の総数
[ ] dounle V[ ];mV m Þ の総数
更に
無限遠方の x = ±¥では、 ( ), 0x ty =なので、ここでは、
[ ][ ] [ ][ ] [ ][ ] [ ][ ] [ ][ ] [ ][ ]max 1
max 1 max, 0 , , , , ,2 , 1x x
m m
n n mn n mn mny y y y y y+
=-¥ =¥
=
-
の総数
と見なして、
[ ][ ][ ][ ]max
0 0
0
n
n n
y
y
=
=
が条件になります。
使用する数値を、#define を使って、わかりやすい名前で定義します。それらは、 自分で定義した事を思い出すために大文字で記述
しておきます。
3.1415926536 3.1415926536#def Iine P pÜ =
elta
eltD 2Ta
D X
# define
# d
0.004 0.004
(DX*DX/4.0efin
X
T )D4
D
e
x
xt
Ü D =
DÜ D =
C言語第 8回 [複写/貼り付け]ができます。 12
m t
max max
maxtot
o
al
tal
M MAX
M
5002 2
M MAX+
#define
#de 1f TOTi e A 1Ln
m mx x x
m m
Ü - D £ £ D
Ü = +の総数
n tmax
maxtotal
otal
N MAX
N TOT
800 0
N MAX+1
#define
# 1ef e ALd in
t n t
n n
Ü £ £ D
Ü = +の総数
( )
( ) ( ) ( )h
m
slash 22
2
ass
#d e H SLASHfine#defi
1.0 ,MA
,, ,
0.n 2e SS 5x t x t
i V x t x tt m x
y yy
¶ ¶ìÜ = - +í ¶ ¶î
-( ) ( )2
0 224
0.0351 0.3 , exp
42
DX KAKKOP KAKKO PI
#define#define#d 50.0*efine
x i xx t
x pDD
yp
ì é ù-ï ê ú- Ü = - +íê úï ë ûî
( )0
0 0.032,
(70.7* )*(70.7* )#define#define
AV0 PI PI
x aV x t
V x a
ì >ì ïÜ =í í- £î ïî
【5】プログラム
新しいプロジェクト
ryousi(量子)
を作成し、以下の 3 つのプログラムをプロジェクトに追加し、ビルドすること。
1) 以下のプログラムを、[fukusosuu.h]として保存:typedef struct tagCOMPLEX{
double r;double i;
} COMPLEX;
COMPLEX add(COMPLEX z1, COMPLEX z2);COMPLEX subtract(COMPLEX z1, COMPLEX z2);COMPLEX multiply(COMPLEX z1, COMPLEX z2);COMPLEX divide(COMPLEX z1, COMPLEX z2);COMPLEX conjugate(COMPLEX z);double absolute(COMPLEX z);COMPLEX multiply_number(double x, COMPLEX z);COMPLEX cexp(double re, double im);
2) 以下のプログラムを、[fukusosuu.c]として保存:
該当箇所を【第7回 複素数の使用法(シラバス12回目)】のプログ
ラムからコピー可能
#include <stdio.h>#include <math.h>
#include "fukusosuu.h"
// z1+z2
C言語第 8回 [複写/貼り付け]ができます。 13
COMPLEX add(COMPLEX z1, COMPLEX z2){
COMPLEX z;
z.r = z1.r+z2.r;z.i = z1.i+z2.i;
return z;}
// z1-z2COMPLEX subtract(COMPLEX z1, COMPLEX z2){
COMPLEX z;
z.r = z1.r-z2.r;z.i = z1.i-z2.i;
return z;}
// z1*z2COMPLEX multiply(COMPLEX z1, COMPLEX z2){
COMPLEX z;
z.r = z1.r*z2.r - z1.i*z2.i;z.i = z1.r*z2.i + z1.i*z2.r;
return z;}
// z1/z2COMPLEX divide(COMPLEX z1, COMPLEX z2){
COMPLEX z;COMPLEX bunsi;
if((z2.r == 0) && (z2.i == 0)){COMPLEX zero = {0, 0};
printf("エラー:0で割っています\n");
return zero;}
bunsi.r = z1.r*z2.r + z1.i*z2.i;bunsi.i = z1.r*z2.i - z1.i*z2.r;
z.r = bunsi.r/(z2.r*z2.r+z2.i*z2.i);z.i = bunsi.i/(z2.r*z2.r+z2.i*z2.i);
return z;}
// z^*COMPLEX conjugate(COMPLEX z)
C言語第 8回 [複写/貼り付け]ができます。 14
{z.i = -z.i;
return z;}
// |z|double absolute(COMPLEX z){
return sqrt(z.r*z.r + z.i*z.i);}
// x*zCOMPLEX multiply_number(double x, COMPLEX z){
z.r = x*z.r;z.i = x*z.i;
return z;}
// exp(re+i*im)COMPLEX cexp(double re, double im){
COMPLEX z;
z.r = exp(re)*cos(im);z.i = exp(re)*sin(im);
return z;}
3) 以下のプログラムを、[ryousi.c]として保存
COMPLEX calculate_k1(int m, int n)をコピーしてプログラム内に適宜追加すれば
calculate_k2を簡単に作成できる。
COMPLEX calculate_k2(int m, int n)をコピーしてプログラム内の K1 を K2, K3 に
置き換えれば、calculate_k3, calculate_k4 を簡単に作成できる。
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>#include <stdio.h>#include <math.h>#include "fukusosuu.h"
#define PI 3.1415926536#define DX 0.004#define DT DX*DX/4.0#define M_MAX 500#define M_TOTAL M_MAX+1#define N_MAX 800#define N_TOTAL N_MAX+1#define H_SLASH 1#define MASS 0.5#define D 0.035#define X_KAKKO -0.3
C言語第 8回 [複写/貼り付け]ができます。 15
#define P_KAKKO 50.0*PI#define A 0.032#define V0 (70.7*PI)*(70.7*PI)
COMPLEX Psi[N_TOTAL][M_TOTAL];COMPLEX K1[M_TOTAL];COMPLEX K2[M_TOTAL];COMPLEX K3[M_TOTAL];COMPLEX K4[M_TOTAL];double V[M_TOTAL];COMPLEX AI = {0, 1};
double getX(int m){
double x = (m-M_MAX/2.0)*DX;
return x;}
double getT(int n){
double t = n*DT;
return t;}
COMPLEX hasoku(int m){
COMPLEX z;double x = getX(m);double re, im;
re = -(x-X_KAKKO)*(x-X_KAKKO)/4.0/D/D;im = P_KAKKO*x/H_SLASH;
z = cexp(re, im);
z = multiply_number(1.0/pow(2.0*PI*D*D, 1.0/4.0), z);
return z;}
double getV(int m){
double abs_x;double x = getX(m);
abs_x = fabs(x);
if(abs_x > A){return 0.0;
}else{
return -V0;}
}//最初に
C言語第 8回 [複写/貼り付け]ができます。 16
void saishoni(void){
int m, n;COMPLEX c_zero = {0.0, 0.0};
for(n=0; n<=N_MAX; n++){// n=0 n=M_TOTALPsi[n][0] = Psi[n][M_MAX] = c_zero;
}
for(m=1; m<=M_MAX-1; m++){Psi[0][m] = hasoku(m);
}
// m=0からm=M_MAXまでfor(m=0; m<=M_MAX; m++){
V[m] = getV(m);}
}
COMPLEX calculate_k1(int m, int n){
COMPLEX z, w;
z = multiply_number(2.0, Psi[n][m]);z = subtract(Psi[n][m+1], z);z = add(Psi[n][m-1], z);z = multiply_number(H_SLASH*H_SLASH/2.0/MASS/DX/DX, z);
w = multiply_number(V[m], Psi[n][m]);z = subtract(z, w);
z = multiply(AI, z);z = multiply_number(1.0/H_SLASH, z);
return z;}
COMPLEX calculate_psi_plus_k(COMPLEX psi, double r, COMPLEX k){
COMPLEX z;
z = multiply_number(r*DT, k);z = add(psi, z);
return z;}
COMPLEX calculate_k2(int m, int n){
COMPLEX z, w, v;
w = calculate_psi_plus_k(Psi[n][m], 1.0/2.0, K1[m]);v = multiply_number(V[m], w);z = multiply_number(2.0, w);
w = calculate_psi_plus_k(Psi[n][m+1], 1.0/2.0, K1[m+1]);
C言語第 8回 [複写/貼り付け]ができます。 17
z = subtract(w, z);
w = calculate_psi_plus_k(Psi[n][m-1], 1.0/2.0, K1[m-1]);z = add(w, z);
z = multiply_number(H_SLASH*H_SLASH/2.0/MASS/DX/DX, z);z = subtract(z, v);
z = multiply(AI, z);z = multiply_number(1.0/H_SLASH, z);
return z;}
COMPLEX calculate_k3(int m, int n){
COMPLEX z, w, v;
w = calculate_psi_plus_k(Psi[n][m], 1.0/2.0, K2[m]);v = multiply_number(V[m], w);z = multiply_number(2.0, w);
w = calculate_psi_plus_k(Psi[n][m+1], 1.0/2.0, K2[m+1]);z = subtract(w, z);
w = calculate_psi_plus_k(Psi[n][m-1], 1.0/2.0, K2[m-1]);z = add(w, z);
z = multiply_number(H_SLASH*H_SLASH/2.0/MASS/DX/DX, z);z = subtract(z, v);
z = multiply(AI, z);z = multiply_number(1.0/H_SLASH, z);
return z;}
COMPLEX calculate_k4(int m, int n){
COMPLEX z, w, v;
w = calculate_psi_plus_k(Psi[n][m], 1.0, K3[m]);v = multiply_number(V[m], w);z = multiply_number(2.0, w);
w = calculate_psi_plus_k(Psi[n][m+1], 1.0, K3[m+1]);z = subtract(w, z);
w = calculate_psi_plus_k(Psi[n][m-1], 1.0, K3[m-1]);z = add(w, z);
z = multiply_number(H_SLASH*H_SLASH/2.0/MASS/DX/DX, z);z = subtract(z, v);
z =multiply(AI, z);z = multiply_number(1.0/H_SLASH, z);
C言語第 8回 [複写/貼り付け]ができます。 18
return z;}
COMPLEX runge_kutta(int m, int n){
COMPLEX z, w;
w = multiply_number(2.0, K2[m]);z = add(K1[m], w);w = multiply_number(2.0, K3[m]);z = add(z, w);z = add(z, K4[m]);
z = multiply_number(DT/6.0, z);
z = add(Psi[n][m], z);
return z;}
void calculate_psi(int n){
int m;
for(m=1; m<=M_MAX-1; m++){K1[m] = calculate_k1(m,n);
}
for(m=1; m<=M_MAX-1; m++){K2[m] = calculate_k2(m,n);
}
for(m=1; m<=M_MAX-1; m++){K3[m] = calculate_k3(m,n);
}
for(m=1; m<=M_MAX-1; m++){K4[m] = calculate_k4(m,n);
}
for(m=1; m<=M_MAX-1; m++){Psi[n+1][m] = runge_kutta(m,n);
}}
void writetitle(FILE *file_open, int n){
printf(" ,時刻N=%d\n", n);
if(file_open != NULL){fprintf(file_open, " ,時刻N=%d\n", n);
}}
void writedata(FILE *file_open, int m, double x){
printf("%f, %10.3e\n", getX(m), x);
C言語第 8回 [複写/貼り付け]ができます。 19
if(file_open != NULL){fprintf(file_open, "%f, %10.3e\n", getX(m), x);
}}
int main(void){
// 作成ファイル名はryousi.csvなどchar name[] = "ryousi.csv";// ryousi.csvに時刻のマーク追加用char filename[100];// 作成ファイル追尾用変数FILE * file_open = NULL;double x;int m, n, n_out = N_MAX/4;
wsprintf(filename, "%d%s", n_out, name);
// ファイルの作成に失敗すると数値(file_open=NULL)を返すfile_open = fopen(filename, "wt");writetitle(file_open, n_out);
saishoni();
for(n=0; n<=N_MAX-1; n++){calculate_psi(n);
}
n = n_out;
for(m=0; m<=M_MAX; m++){// |ψ(x,t)| x = absolute(Psi[n][m]);// |ψ(x,t)|^2(=x*x) writedata(file_open, m, x*x);
}
// NULLのときにファイル作成失敗if(file_open == NULL){
printf("\n====>ファイル(%s)の作成に失敗しています。\n====>既にファイルが開かれているかもしれません。", filename);
getchar();}else{
HINSTANCE hinst;
fclose(file_open);
hinst = ShellExecute((HWND)0, "open", filename, NULL, NULL, SW_SHOWNORMAL);
if(hinst <= (HINSTANCE)32){printf("\n====>表計算ソフトの自動起動に失敗しました。");
getchar();}
C言語第 8回 [複写/貼り付け]ができます。 20
}
return 0;}
C言語第 8回 [複写/貼り付け]ができます。 21
第8回目レポート
レポートの回数(8回目)、学生証番号と氏名を明記すること
必ず表紙を付け、最後のページ(の添付用)を表紙の次に入れる
(A4レポート用紙使用のこと)
1) 3 つのプログラム(fukusosuu.h, fukusosuu.c, ryousi.c)において、
● 3 つプログラム
● プログラムを実行し、計算結果( ( ),x x ty- )データを出力して、次の n の場合の5つ
グラフ(n_out = N_MAX/4 の箇所を変更します)
n=0
n=N_MAX/4
n=N_MAX/2
n=3*N_MAX/4
n=N_MAX
の7点です。グラフ作成時は、
● 縦軸の最大値を 5 にして表示する。
● [グラフの移動]を”新しいシート”にする。
を実行する事。
2) グラフからは、最初 1 つの波束しかないが、ポテンシャルを通過すると 2 つの波束に分かれてゆく
様子が読み取れる。1つの量子をポテンシャルにぶつけると2つの量子に分裂するという事だろう
か?この結果を説明せよ。
グラフは以下のようになります。
C言語第 8回 [複写/貼り付け]ができます。 22
C言語第 8回 [複写/貼り付け]ができます。 23
提出例(使える表紙は次のページ)
作成する解答など
1ページ目 2ページ目 3ページ目以降
次ページの添付用
コンピュータ物理学演習Ⅱ
第 8回目
月 日
学籍番号
氏名
C言語第 8回 [複写/貼り付け]ができます。 24
コンピュータ物理学演習Ⅱ
第 8 回目
月 日提出
学籍番号
氏名
C言語第 8回 [複写/貼り付け]ができます。 25
第8回目レポート(添付用)1) 3 つのプログラム(fukusosuu.h, fukusosuu.c, ryousi.c)において、
● 3 つプログラムを作成
● プログラムを実行し、計算結果( ( ),x x ty- )データを出力して、次の n の場合の5つ
グラフ(n_out = N_MAX/4 の箇所を変更します)を作成
n=0
n=N_MAX/4
n=N_MAX/2
n=3*N_MAX/4
n=N_MAX
の合計7点です。グラフ作成時は、
● 縦軸の最大値を 10にして表示する。
● [グラフの移動]を”新しいシート”にする。
を実行する事。
2) グラフからは、最初 1 つの波束しかないが、ポテンシャルを通過すると 2 つの波束に分かれてゆく
様子が読み取れる。1つの量子をポテンシャルにぶつけると2つの量子に分裂し、最後は 2 つの
量子が残るという事だろうか?この結果を説明せよ。