電子動力学法の雛形プログラムの公開

 投稿者:mike  投稿日:2017年 2月 1日(水)09時39分23秒
   電子動力学法の雛形プログラムを公開します。
電子動力学法は、ポテンシャル中の電子の波動関数psi(x,t)とポテンシャルV(x)からdt時間後のpsi(x,t+dt)を求めます。
これを繰り返して時間発展させていきます。この波動関数から、電子の存在確率やエネルギーなどが解ります。
電子波束の波動関数は複素関数になるのですが、波束の移動に伴い、複素平面で回転しながら
進行方向に巻き付くように巻き付くように進んでいく様子は興味深いものがあります。
この雛形プログラムでは、ポテンシャルが平らなところでは波束は拡がっていってくので、
なるべく波束の形が崩れにくい放物線型のポテンシャルにしています。
normは波動関数の絶対値で初期に1に規格化されていますが、時間経過とともに1から少しづつずれていきます。
全エネルギーも保存されるはずですが誤差がありわずかに揺らぎます。

表示の説明:
黒の曲線は電子の感じるポテンシャルV(x)で、赤の線は電子の存在確率です。
青色の線は波動関数を表します。y軸に実部Re(psi),z軸に虚部Im(psi)をとると、
3次元空間内の曲線になりますが、曲線がどうも解り難いです。

試験環境:
本プログラムは十進BASIC 0.6.6.0 / macOS 10.7.5と
十進BASIC Ver 7.7.8 / windows 10でテストしました。

!
! ========= Quantum Electron Dynamics 1D ==========
!
! wavePacketQED1D.bas
!
! Mitsuru Ikeuchi (C) Copyleft
!
! ver 0.0.1   2017.01.31  created
!
OPTION ARITHMETIC NATIVE
DECLARE EXTERNAL SUB qed1d.setInitialCondition,qed1d.evolveWave,qed1d.drawWave
DECLARE EXTERNAL FUNCTION qed1d.systemTime,qed1d.norm
!
CALL setInitialCondition(1) !(menu)
!
FOR it=1 TO 1000
   FOR i=1 TO 10
      CALL evolveWave
   NEXT i
   CALL drawWave
   !IF (MOD(it,10)=0) THEN
   !   PRINT USING "time =#####.## (au)  norm =#.###############":systemTime,norm
   !END IF
NEXT it
!
END

! ---------- QED1D module (QED: Quantum Electron Dynamics) ----------
!
! - time dependent Schrodinger equation: i(d/dt)psi(r,t) = H psi(r,t)
! - time evolution
!    psi(r,t+dt) = exp(-i dt H) psi(r,t),  (H:Hamiltonian of the system)
!      H = -delta/2 + V(r), delta = d^2/dx^2 + d^2/dy^2 + d^2/dz^2
!    psi(r,t+dt) = exp(-i dt H) psi(r,t) nearly=
!      {exp(-i(dt/2)V} {exp(i dt(delta/2)} {exp(-i(dt/2)V} psi(r,t)
! - algorism: {exp(i dt(delta/2)}
!      QED: Watanabe's algorism (semi-implicit method)
!      Naoki Watanabe, Masaru Tsukada; arXiv:physics/0011068v1
!      (Published from Physical Review E. 62, 2914, (2000).)
!
MODULE qed1d
MODULE OPTION ARITHMETIC NATIVE
OPTION BASE 0
PUBLIC SUB setInitialCondition, evolveWave, drawWave
PUBLIC FUNCTION systemTime, norm
SHARE NUMERIC NNx,sysTime, dt, dx, auLength, auTime, auEnergy
SHARE NUMERIC phRe(500),phIm(500) ! wave function
SHARE NUMERIC vv(500)             ! external potential
SHARE NUMERIC bRe(500),bIm(500)   ! b vector in kxStep
SHARE NUMERIC uRe(500),uIm(500)   ! u vector in kxStep
LET NNx = 400                     ! max number of phRe(),phIm(),..
LET sysTime = 0.0                 ! (au) au : atomic unit (hbar=1, me=1, e=1)
LET dx = 0.5                      ! (au) x division
LET dt = 1.0*dx*dx                ! (au) time division  dt/(dx*dx)>3 ~ unstable?
LET auLength = 5.29177e-11        ! (m) 1(au) = auLength (m)
LET auTime = 2.41888e-17          ! (s) 1(au) = auTime (s)
LET auEnergy = 4.38975e-18        ! (J) 1(au) = auEnergy (J) (= 27.2114 eV)
!
! ----- set initial condition
!
EXTERNAL SUB setInitialCondition(menu)   !public
   DECLARE EXTERNAL SUB setGaussianWave,setparabolicPotential
   LET sysTime = 0.0
   IF menu=1 THEN
      CALL setGaussianWave(50.0,10.0,0.0) !(wavePos,waveWidth,momentum)
      CALL setparabolicPotential(0.5*(NNx-1)*dx,0.0001) ! v(x)=k*(x-x0)^2
   ELSEIF menu=2 THEN
      CALL setGaussianWave(50.0,10.0,1.0) !(wavePos,waveWidth,momentum)
      CALL setparabolicPotential(0.5*(NNx-1)*dx,0.0) ! v(x)=k*(x-x0)^2
   END IF
   ! set window
   LET w = NNx*dx
   LET b = 20
   SET WINDOW -b,w+b,-b,w+b
END SUB
!
EXTERNAL SUB setGaussianWave(wavePos,waveWidth,momentum)
   DECLARE EXTERNAL SUB normalize
   FOR i=1 TO NNx-2
      LET x = i*dx
      LET phAb = EXP(-((x-wavePos)/(2.0*waveWidth))^2)
      LET phPh = momentum*x
      LET phRe(i) = phAb*cos(phPh)
      LET phIm(i) = phAb*sin(phPh)
   NEXT i
   LET phRe(0) = 0.0
   LET phIm(0) = 0.0
   LET phRe(NNx-1) = 0.0
   LET phIm(NNx-1) = 0.0
   CALL normalize
END SUB
!
EXTERNAL SUB setparabolicPotential(x0,k)   ! v(x)=k*(x-x0)^2
   FOR i=0 TO NNx-1
      LET x = i*dx
      LET vv(i) = k*(x-x0)^2
   NEXT i
END SUB
!
! ----- evolve Wave
!
EXTERNAL SUB evolveWave   !public
   DECLARE EXTERNAL SUB phaseStep,kxStep
   CALL phaseStep
   CALL kxStep
   CALL phaseStep
   LET sysTime = sysTime + dt
END SUB
!
EXTERNAL SUB kxStep   !{exp(i dt(delta/2)} semi-implicit method
   LET ai = 4*dx*dx/dt
   LET aaAb = 4+ai*ai
   FOR i=1 TO NNx-2  !set b-vector
      LET bRe(i) = 2*phRe(i)-ai*phIm(i) - phRe(i+1) - phRe(i-1)
      LET bIm(i) = 2*phIm(i)+ai*phRe(i) - phIm(i+1) - phIm(i-1)
   NEXT i
   ! forward elimination
   LET uRe(1) = -2/aaAb
   LET uIm(1) = -ai/aaAb
   LET phRe(1) = bRe(1)*uRe(1) - bIm(1)*uIm(1)
   LET phIm(1) = bIm(1)*uRe(1) + bRe(1)*uIm(1)
   FOR i=2 TO NNx-2
      LET auAb = (-2-uRe(i-1))*(-2-uRe(i-1))+(ai-uIm(i-1))*(ai-uIm(i-1))
      LET uRe(i) = (-2-uRe(i-1))/auAb
      LET uIm(i) = -(ai-uIm(i-1))/auAb
      LET phRe(i) = (bRe(i)-phRe(i-1))*uRe(i) - (bIm(i)-phIm(i-1))*uIm(i)
      LET phIm(i) = (bRe(i)-phRe(i-1))*uIm(i) + (bIm(i)-phIm(i-1))*uRe(i)
   NEXT i
   ! backward substitution
   FOR i=NNx-3 TO 1 STEP -1
      LET phRe(i) = phRe(i) - (phRe(i+1)*uRe(i) - phIm(i+1)*uIm(i))
      LET phIm(i) = phIm(i) - (phRe(i+1)*uIm(i) + phIm(i+1)*uRe(i))
   NEXT i
END SUB
!
EXTERNAL SUB phaseStep   !{exp(-i(dt/2)V} evolve 0.5dt
   FOR i=1 TO NNx-2
      LET th = 0.5*dt*vv(i)
      LET cs = COS(th)
      LET sn = SIN(th)
      LET phr = phRe(i)
      LET phi = phIm(i)
      LET phRe(i) =  cs*phr+sn*phi
      LET phIm(i) = -sn*phr+cs*phi
   NEXT i
END SUB
!
! ----- utility
!
EXTERNAL FUNCTION systemTime   !public
   LET systemTime = sysTime
END FUNCTION
!
EXTERNAL SUB normalize
   LET a = norm !public function
   FOR i=1 TO NNx-2
      LET phRe(i) = phRe(i)/a
      LET phIm(i) = phIm(i)/a
   NEXT i
END SUB
!
EXTERNAL FUNCTION norm   !public  SQR(<psi|psi>)
!LOCAL i,a2
   LET a2 = 0.0
   FOR i=1 TO NNx-2
      LET a2 = a2 + (phRe(i)*phRe(i)+phIm(i)*phIm(i))*dx
   NEXT i
   LET norm = SQR(a2)
END FUNCTION
!
EXTERNAL FUNCTION kineticEnergy !<psi| d^2/dx^2 |psi>
   LET s = 0.0
   FOR i=1 TO NNx-2
      LET hphRe = (2.0*phRe(i)-phRe(i+1)-phRe(i-1))/(2.0*dx*dx)
      LET hphIm = (2.0*phIm(i)-phIm(i+1)-phIm(i-1))/(2.0*dx*dx)
      LET s = s + (phRe(i)*hphRe + phIm(i)*hphIm)*dx
   NEXT i
   LET kineticEnergy = s
END FUNCTION
!
EXTERNAL FUNCTION potentialEnergy !<psi| V(x) |psi>
   LET s = 0.0
   FOR i=1 TO NNx-2
      LET s = s + vv(i)*(phRe(i)*phRe(i)+phIm(i)*phIm(i))*dx
   NEXT i
   LET potentialEnergy = s
END FUNCTION
!
! ----- draw wave
!
EXTERNAL SUB drawWave
   DECLARE EXTERNAL FUNCTION kineticEnergy,potentialEnergy
   LET yh = (NNx*dx+40)*0.4
   LET sth = SIN(PI/12)

   SET DRAW MODE HIDDEN
   CLEAR
   !---plot V(x),<psi|psi>,|psi>
   SET LINE COLOR 1 ! black : PLOT potential V(x);
   FOR i=0 TO NNx-1
      PLOT LINES: dx*i,  vv(i)*100+yh;
   NEXT i
   PLOT LINES
   SET LINE COLOR 4 ! red : plot probability <psi|psi>
   FOR i=0 TO NNx-1
      LET ph2 = (phRe(i)*phRe(i)+phIm(i)*phIm(i))*dx
      PLOT LINES: dx*i, ph2*1000+yh;
   NEXT i
   PLOT LINES
   FOR i=0 TO NNx-1 !plot wave function |psi(x,t)>
      LET x = i*dx
      LET y = phRe(i)*50
      LET z = phIm(i)*50
      IF phIm(i)>=0 THEN SET LINE COLOR 2 ELSE SET LINE COLOR 10
      PLOT LINES: x-sth*z, y+yh;
      !PLOT LINES: dx*i-sth*phIm(i)*50, phRe(i)*50+yh;
   NEXT i
   PLOT LINES
   SET TEXT COLOR 1 ! black
   PLOT TEXT, AT 0, yh+22 :"potential V(x)"
   SET TEXT COLOR 4 ! red
   PLOT TEXT, AT 0, yh+6 :"<psi|psi>"
   SET TEXT COLOR 2 ! blue
   PLOT TEXT, AT 0, yh-10 :"|psi(x,t)>"
   !---caption
   LET ke = kineticEnergy
   LET pe = potentialEnergy
   SET TEXT HEIGHT 5
   SET TEXT COLOR 1 ! black
   PLOT TEXT, AT 0,48 ,USING "time =#####.## (au) =####.#### (femto s)":sysTime,sysTime*auTime*1e15
   PLOT TEXT, AT 0,40 ,USING "norm of wave function =#.###############":norm
   PLOT TEXT, AT 0,32 ,USING "kinetic energy   =#.###### (au) =##.### (eV)":ke,ke*27.2114
   PLOT TEXT, AT 0,24 ,USING "potential energy =#.###### (au) =##.### (eV)":pe,pe*27.2114
   PLOT TEXT, AT 0,16 ,USING "total energy     =#.###### (au) =##.### (eV)":ke+pe,(ke+pe)*27.2114
   PLOT TEXT, AT 0, 8 ,USING "xLength =####.# (au) =###.### (nm)":NNx*dx,NNx*dx*auLength*1e9
   PLOT TEXT, AT 0, 0 :"wave packet - quantum electron dynamics 1D"
   SET DRAW MODE EXPLICIT
END SUB
!
END MODULE
 

Re: 電子動力学法の雛形プログラムの公開

 投稿者:SECOND  投稿日:2017年 2月 1日(水)14時25分23秒
  > No.4249[元記事へ]

mikeさんへのお返事です。

ほんとに、ざっと、ですが、
手でドラッグして、x軸を、画面垂直まで回せるものを、用意しました、
見てみますか? 細かい所は、触ってませんので後は御自身で・・
 

Re: 電子動力学法の雛形プログラムの公開

 投稿者:mike  投稿日:2017年 2月 1日(水)15時56分53秒
  > No.4250[元記事へ]

SECONDさんへのお返事です。

SECONDさん、お世話になります。

ぜひ、掲示板への掲載をお願いします。
複素数の扱いに堪能なSECONDさんでしたら、
複素関数の部分もエレガントなコードに変身するのではと思います。
よろしくお願いします。


> mikeさんへのお返事です。
>
> ほんとに、ざっと、ですが、
> 手でドラッグして、x軸を、画面垂直まで回せるものを、用意しました、
> 見てみますか? 細かい所は、触ってませんので後は御自身で・・
>
 

Re: 電子動力学法の雛形プログラムの公開

 投稿者:SECOND  投稿日:2017年 2月 1日(水)16時13分26秒
  > No.4251[元記事へ]

mikeさんへのお返事です。

2進モードで、今度は見やすいです。
走り書きに近く、どこか壊れているかも知れませんので、点検して下さい。
とりあえず、波動関数の、らせん形が、見えます。

! ========= Quantum Electron Dynamics 1D ==========
!
! wavePacketQED1D.bas
!
! Mitsuru Ikeuchi (C) Copyleft
!
! ver 0.0.1   2017.01.31  created
!
OPTION ARITHMETIC NATIVE
OPTION BASE 0
DECLARE FUNCTION systemTime,norm
DECLARE FUNCTION kineticEnergy,potentialEnergy
!
! ---------- QED1D module (QED: Quantum Electron Dynamics) ----------
!
! - time dependent Schrodinger equation: i(d/dt)psi(r,t) = H psi(r,t)
! - time evolution
!    psi(r,t+dt) = exp(-i dt H) psi(r,t),  (H:Hamiltonian of the system)
!      H = -delta/2 + V(r), delta = d^2/dx^2 + d^2/dy^2 + d^2/dz^2
!    psi(r,t+dt) = exp(-i dt H) psi(r,t) nearly=
!      {exp(-i(dt/2)V} {exp(i dt(delta/2)} {exp(-i(dt/2)V} psi(r,t)
! - algorism: {exp(i dt(delta/2)}
!      QED: Watanabe's algorism (semi-implicit method)
!      Naoki Watanabe, Masaru Tsukada; arXiv:physics/0011068v1
!      (Published from Physical Review E. 62, 2914, (2000).)
!
!--------------
DIM pV(1 TO 4),Axys(1 TO 4,1 TO 4),P3D(1 TO 4,1 TO 4)
DIM rotx(1 TO 4,1 TO 4),shxyz(1 TO 4,1 TO 4),shres(1 TO 4,1 TO 4)
MAT Axys=IDN
MAT rotx=IDN
MAT shxyz=IDN
MAT shres=IDN
LET pV(4)=1
!
LET Sx=1
LET Sy=1
LET Sz=1
LET Ax=0                                 !開始のz軸方向( 画面垂直0度からx軸回転成分)
LET Ay=0                                 !  〃 〃  (    〃 〃  y軸回転成分)
LET Az=0                                 !z軸回転成分
!
DIM phRe(500),phIm(500) ! wave function
DIM vv(500)             ! external potential
DIM bRe(500),bIm(500)   ! b vector in kxStep
DIM uRe(500),uIm(500)   ! u vector in kxStep
LET NNx = 400                     ! max number of phRe(),phIm(),..
LET sysTime = 0.0                 ! (au) au : atomic unit (hbar=1, me=1, e=1)
LET dx = 0.5                      ! (au) x division
LET dt = 1.0*dx*dx                ! (au) time division  dt/(dx*dx)>3 ~ unstable?
LET auLength = 5.29177e-11        ! (m) 1(au) = auLength (m)
LET auTime = 2.41888e-17          ! (s) 1(au) = auTime (s)
LET auEnergy = 4.38975e-18        ! (J) 1(au) = auEnergy (J) (= 27.2114 eV)
!
CALL setInitialCondition(1) !(menu)
!
FOR it=1 TO 1000
   FOR i9=1 TO 10
      IF mlb=0 THEN CALL evolveWave
   NEXT i9
   CALL drawWave
   !IF (MOD(it,10)=0) THEN
   !   PRINT USING "time =#####.## (au)  norm =#.###############":systemTime,norm
   !END IF
   mouse poll mx,my,mlb,mrb
   IF mrb=1 THEN EXIT FOR
   ! LET Ay=Ay+1e-2        !trim. y軸で、自動で回す場合
NEXT it

! ----- set initial condition
!
SUB setInitialCondition(menu)   !public
   LET sysTime = 0.0
   IF menu=1 THEN
      CALL setGaussianWave(50.0,10.0,0.0) !(wavePos,waveWidth,momentum)
      CALL setparabolicPotential(0.5*(NNx-1)*dx,0.0001) ! v(x)=k*(x-x0)^2
   ELSEIF menu=2 THEN
      CALL setGaussianWave(50.0,10.0,1.0) !(wavePos,waveWidth,momentum)
      CALL setparabolicPotential(0.5*(NNx-1)*dx,0.0) ! v(x)=k*(x-x0)^2
   END IF
   ! set window
   LET w = NNx*dx
   LET b = 20
   SET WINDOW -b,w+b,-b,w+b
   !--
   CALL mat_shxyz(shxyz,-w/2,-w/2, 0)  !画面中心を原点へ移動する行列 shxyz 作成
   CALL mat_shxyz(shres, w/2, w/2, 0)  !画面中心を原点から元へ戻す行列 shres 作成
END SUB

SUB setGaussianWave(wavePos,waveWidth,momentum)
   FOR i=1 TO NNx-2
      LET x = i*dx
      LET phAb = EXP(-((x-wavePos)/(2.0*waveWidth))^2)
      LET phPh = momentum*x
      LET phRe(i) = phAb*cos(phPh)
      LET phIm(i) = phAb*sin(phPh)
   NEXT i
   LET phRe(0) = 0.0
   LET phIm(0) = 0.0
   LET phRe(NNx-1) = 0.0
   LET phIm(NNx-1) = 0.0
   CALL normalize
END SUB

SUB setparabolicPotential(x0,k)   ! v(x)=k*(x-x0)^2
   FOR i=0 TO NNx-1
      LET x = i*dx
      LET vv(i) = k*(x-x0)^2
   NEXT i
END SUB

! ----- evolve Wave
!
SUB evolveWave   !public
   DECLARE EXTERNAL SUB phaseStep,kxStep
   CALL phaseStep
   CALL kxStep
   CALL phaseStep
   LET sysTime = sysTime + dt
END SUB

SUB kxStep   !{exp(i dt(delta/2)} semi-implicit method
   LET ai = 4*dx*dx/dt
   LET aaAb = 4+ai*ai
   FOR i=1 TO NNx-2  !set b-vector
      LET bRe(i) = 2*phRe(i)-ai*phIm(i) - phRe(i+1) - phRe(i-1)
      LET bIm(i) = 2*phIm(i)+ai*phRe(i) - phIm(i+1) - phIm(i-1)
   NEXT i
   ! forward elimination
   LET uRe(1) = -2/aaAb
   LET uIm(1) = -ai/aaAb
   LET phRe(1) = bRe(1)*uRe(1) - bIm(1)*uIm(1)
   LET phIm(1) = bIm(1)*uRe(1) + bRe(1)*uIm(1)
   FOR i=2 TO NNx-2
      LET auAb = (-2-uRe(i-1))*(-2-uRe(i-1))+(ai-uIm(i-1))*(ai-uIm(i-1))
      LET uRe(i) = (-2-uRe(i-1))/auAb
      LET uIm(i) = -(ai-uIm(i-1))/auAb
      LET phRe(i) = (bRe(i)-phRe(i-1))*uRe(i) - (bIm(i)-phIm(i-1))*uIm(i)
      LET phIm(i) = (bRe(i)-phRe(i-1))*uIm(i) + (bIm(i)-phIm(i-1))*uRe(i)
   NEXT i
   ! backward substitution
   FOR i=NNx-3 TO 1 STEP -1
      LET phRe(i) = phRe(i) - (phRe(i+1)*uRe(i) - phIm(i+1)*uIm(i))
      LET phIm(i) = phIm(i) - (phRe(i+1)*uIm(i) + phIm(i+1)*uRe(i))
   NEXT i
END SUB

SUB phaseStep   !{exp(-i(dt/2)V} evolve 0.5dt
   FOR i=1 TO NNx-2
      LET th = 0.5*dt*vv(i)
      LET cs = COS(th)
      LET sn = SIN(th)
      LET phr = phRe(i)
      LET phi = phIm(i)
      LET phRe(i) =  cs*phr+sn*phi
      LET phIm(i) = -sn*phr+cs*phi
   NEXT i
END SUB

! ----- utility
!
FUNCTION systemTime
   LET systemTime = sysTime
END FUNCTION

SUB normalize
   LET a = norm
   FOR i=1 TO NNx-2
      LET phRe(i) = phRe(i)/a
      LET phIm(i) = phIm(i)/a
   NEXT i
END SUB

FUNCTION norm   !public  SQR(<psi|psi>)
   LOCAL i,a2
   LET a2 = 0.0
   FOR i=1 TO NNx-2
      LET a2 = a2 + (phRe(i)*phRe(i)+phIm(i)*phIm(i))*dx
   NEXT i
   LET norm = SQR(a2)
END FUNCTION

FUNCTION kineticEnergy !<psi| d^2/dx^2 |psi>
   LET s = 0.0
   FOR i=1 TO NNx-2
      LET hphRe = (2.0*phRe(i)-phRe(i+1)-phRe(i-1))/(2.0*dx*dx)
      LET hphIm = (2.0*phIm(i)-phIm(i+1)-phIm(i-1))/(2.0*dx*dx)
      LET s = s + (phRe(i)*hphRe + phIm(i)*hphIm)*dx
   NEXT i
   LET kineticEnergy = s
END FUNCTION

FUNCTION potentialEnergy !<psi| V(x) |psi>
   LET s = 0.0
   FOR i=1 TO NNx-2
      LET s = s + vv(i)*(phRe(i)*phRe(i)+phIm(i)*phIm(i))*dx
   NEXT i
   LET potentialEnergy = s
END FUNCTION

! ----- draw wave
!
SUB drawWave
   LET yh = (NNx*dx+40)*0.4
   LET sth = SIN(PI/12)
   !
   SET DRAW MODE HIDDEN
   CLEAR
   CALL control_
   !---plot V(x),<psi|psi>,|psi>
   SET LINE COLOR 1 ! black : PLOT potential V(x);
   FOR i=0 TO NNx-1
      CALL line3D(dx*i, vv(i)*100+yh, 0)   !PLOT LINES: dx*i,  vv(i)*100+yh;
   NEXT i
   PLOT LINES
   !--
   SET LINE COLOR 4 ! red : plot probability <psi|psi>
   FOR i=0 TO NNx-1
      LET ph2 = (phRe(i)*phRe(i)+phIm(i)*phIm(i))*dx
      CALL line3D( dx*i, ph2*1000+yh, 0)   !PLOT LINES: dx*i, ph2*1000+yh;
   NEXT i
   PLOT LINES
   !--
   FOR i=0 TO NNx-1 !plot wave function |psi(x,t)>
      LET x = i*dx
      LET y = phRe(i)*50
      LET z = phIm(i)*50
      IF phIm(i)>=0 THEN SET LINE COLOR 2 ELSE SET LINE COLOR 10
      CALL line3D( x, y+yh, z)       !PLOT LINES: x-sth*z, y+yh;
      !PLOT LINES: dx*i-sth*phIm(i)*50, phRe(i)*50+yh;
   NEXT i
   PLOT LINES
   !--
   SET TEXT COLOR 1                            ! black
   PLOT TEXT, AT 0, yh+22 :"potential V(x)"
   SET TEXT COLOR 4                            ! red
   PLOT TEXT, AT 0, yh+6  :"<psi|psi>"
   SET TEXT COLOR 2                            ! blue
   PLOT TEXT, AT 0, yh-10 :"|psi(x,t)>"
   !---caption
   LET ke = kineticEnergy
   LET pe = potentialEnergy
   SET TEXT HEIGHT 5
   SET TEXT COLOR 1 ! black
   PLOT TEXT, AT 0,48 ,USING "time =#####.## (au) =####.#### (femto s)":sysTime,sysTime*auTime*1e15
   PLOT TEXT, AT 0,40 ,USING "norm of wave function =#.###############":norm
   PLOT TEXT, AT 0,32 ,USING "kinetic energy   =#.###### (au) =##.### (eV)":ke,ke*27.2114
   PLOT TEXT, AT 0,24 ,USING "potential energy =#.###### (au) =##.### (eV)":pe,pe*27.2114
   PLOT TEXT, AT 0,16 ,USING "total energy     =#.###### (au) =##.### (eV)":ke+pe,(ke+pe)*27.2114
   PLOT TEXT, AT 0, 8 ,USING "xLength =####.# (au) =###.### (nm)":NNx*dx,NNx*dx*auLength*1e9
   PLOT TEXT, AT 0, 0 :"wave packet - quantum electron dynamics 1D"
   SET DRAW MODE EXPLICIT
END SUB

SUB control_
   PLOT label,AT 20, 210:"左 click 一時停止、drag 手動回転。右 click 終了。"
   !-----click_drag-----
   IF mlb=1 THEN
   !!LET Ax= -(my-mybak)*PI/100    !※Y軸回転のみにする。  !ドラッグ方向から、軸方向と回転量
      LET Ay= +(mx-mxbak)*PI/100
   END IF
   LET mxbak=mx
   LET mybak=my
   !-----
   LET ar0=SQR(Ax^2+Ay^2)                !回転の角度(∝マウス・ドラッグの長さ)
   IF ar0<>0 THEN
      LET DIRar0=ANGLE(Ax,Ay)            !軸の角度
      CALL mat_rotx(rotx, ar0)
      MAT Axys=Axys*ROTATE(-DIRar0)*rotx*ROTATE(DIRar0)  !ドラッグ累積 (方向,回転)
      LET Ax=0
      LET Ay=0
   END IF
   MAT P3D=shxyz*ROTATE(Az)*Axys*shres
END SUB

SUB axes3D(x1,y1,z1, x2,y2,z2, a$ )
   CALL line3D(x1,y1,z1)
   CALL line3D(x2,y2,z2)
   PLOT TEXT,AT pV(1),pV(2) :a$ ! PEN-off
END SUB

SUB line3D(x,y,z)
   LET pV(1)=x*Sx           !描画目盛は、全方向等しくないと、回転で、形が保てない。
   LET pV(2)=y*Sy           !スケール Sx,Sy,Sz の違いは、入力の倍率として、行なう。
   LET pV(3)=z*Sz           !入力 z 座標は 出力 x,y に反映。出力zは 描画不可。
   LET pV(4)=1              ! shxyzM …shxyzP で必要。
   MAT pV=pV*P3D
   PLOT LINES: pV(1),pV(2); ! PEN-on
END SUB

!---------------------------------
! x軸で 回転する行列 → 配列引数
!(x,y,z,1)| 1,      0,      0, 0 |
!         | 0, cos(a), sin(a), 0 |
!         | 0,-sin(a), cos(a), 0 |
!         | 0,      0,      0, 1 |
!---------------------------------
SUB mat_rotx(m(,), a)
   LET m(2,2)=COS(a)
   LET m(3,2)=-SIN(a)
   LET m(2,3)=SIN(a)
   LET m(3,3)=COS(a)               !他の要素は、呼出し側で管理
END SUB

!-----------------------------
! 平行移動。(sx,sy,sz)
!(x,y,z,1)|  1,  0,  0, 0 |
!         |  0,  1,  0, 0 |
!         |  0,  0,  1, 0 |
!         | sx, sy, sz, 1 |
!-----------------------------
SUB mat_shxyz(m(,), sx,sy,sz)
   LET m(4,1)=sx
   LET m(4,2)=sy
   LET m(4,3)=sz                   !他の要素は、呼出し側で管理
END SUB

END
 

Re: 電子動力学法の雛形プログラムの公開

 投稿者:mike  投稿日:2017年 2月 1日(水)18時02分50秒
  > No.4252[元記事へ]

SECONDさんへのお返事です。

SECONDさん、プログラムの投稿ありがとうございます。

プログラムを実行すると、波動関数がぐるぐると巻きながら進む様子が見えました。
マウスドラッグできると実態があるように感じますね。

3Dグラフィックの使い方については、プログラムを熟読させていただきます。

ありがとうございました。

> mikeさんへのお返事です。
>
> 2進モードで、今度は見やすいです。
> 走り書きに近く、どこか壊れているかも知れませんので、点検して下さい。
> とりあえず、波動関数の、らせん形が、見えます。
 

Re: 電子動力学法の雛形プログラムの公開

 投稿者:SECOND  投稿日:2017年 2月 1日(水)18時22分47秒
  > No.4253[元記事へ]

mikeさんへのお返事です。

速度が落ちて、早く終了する。バグを、作っていました。すみません。
外部副プログラムが、原則、全ローカル変数なので、内側に移すときに、
重なっているのに気が付きませんでした。

メインの、FOR i=1 TO 10 の、iを、 FOR i9=1 TO 10 の様に変えないと・・、

   FOR i=1 TO 10
      IF mlb=0 THEN CALL evolveWave
   NEXT i

     ↓

   FOR i9=1 TO 10
      IF mlb=0 THEN CALL evolveWave
   NEXT i9
 

Re: 電子動力学法の雛形プログラムの公開

 投稿者:mike  投稿日:2017年 2月 2日(木)09時09分20秒
  > No.4254[元記事へ]

SECONDさんへのお返事です。

SECONDさん、連絡ありがとうございます。
さっそく、修正しました。

1カ所、修正があります。(下記の!****************の部分)
なんとか3Dのように見えるようx-->x-sth*zにして、少し斜めから見る効果をだしたつもりでした。
正確にはCALL line3D( x, y+yh, z)とすべきと思います。


SUB drawWave
   LET yh = (NNx*dx+40)*0.4
   LET sth = SIN(PI/12)
   !
   SET DRAW MODE HIDDEN
   CLEAR
   CALL control_
   !---plot V(x),<psi|psi>,|psi>
   SET LINE COLOR 1 ! black : PLOT potential V(x);
   FOR i=0 TO NNx-1
      CALL line3D(dx*i, vv(i)*100+yh, 0)   !PLOT LINES: dx*i,  vv(i)*100+yh;
   NEXT i
   PLOT LINES
   !--
   SET LINE COLOR 4 ! red : plot probability <psi|psi>
   FOR i=0 TO NNx-1
      LET ph2 = (phRe(i)*phRe(i)+phIm(i)*phIm(i))*dx
      CALL line3D( dx*i, ph2*1000+yh, 0)   !PLOT LINES: dx*i, ph2*1000+yh;
   NEXT i
   PLOT LINES
   !--
   FOR i=0 TO NNx-1 !plot wave function |psi(x,t)>
      LET x = i*dx
      LET y = phRe(i)*50
      LET z = phIm(i)*50
      IF phIm(i)>=0 THEN SET LINE COLOR 2 ELSE SET LINE COLOR 10
      !CALL line3D( x-sth*z, y+yh, z)       !PLOT LINES: x-sth*z, y+yh; !****************
      CALL line3D( x, y+yh, z)       !PLOT LINES: x-sth*z, y+yh;  !************
      !PLOT LINES: dx*i-sth*phIm(i)*50, phRe(i)*50+yh;
   NEXT i
   PLOT LINES


> mikeさんへのお返事です。
>
> 速度が落ちて、早く終了する。バグを、作っていました。すみません。
> 外部副プログラムが、原則、全ローカル変数なので、内側に移すときに、
> 重なっているのに気が付きませんでした。
>
> メインの、FOR i=1 TO 10 の、iを、 FOR i9=1 TO 10 の様に変えないと・・、
>
>    FOR i=1 TO 10
>       IF mlb=0 THEN CALL evolveWave
>    NEXT i
>
>      ↓
>
>    FOR i9=1 TO 10
>       IF mlb=0 THEN CALL evolveWave
>    NEXT i9
>  
 

Re: 電子動力学法の雛形プログラムの公開

 投稿者:SECOND  投稿日:2017年 2月 2日(木)13時35分50秒
  > No.4255[元記事へ]

mikeさんへのお返事です。

修正しておきました。
速度Verlet法 の方も、修正しておきます。
当時、気が付きませんでした。
速度の2項目を、先に更新する事で、位置計算の3項目を、見事に省略されてますね。

後の、修正は、もう一度、ご自身で、再公開して頂ければ、助かります。
よけいな事は、気にしないで、組込んでください。

SECOND が書いたものは、あくまで素材として、使えるものがあれば、ご利用ください。
他の投稿、スレッド Amusement_Program 複数ページ長編プログラム なども、
SECOND になっているもの全て、権利など、放棄されています。連絡不要。

3Dが、煩雑なのは、見え隠れの処理のためです。(3D-VRAM なら無用かと?)
単に3Dを、2D配置するだけなら、行列写像後の、Z座標を捨てるだけで、
draw ~ with や、変形指示MAT文 の、直接描画でよいのですが、
見え隠れの描画順序を、入れ替えるまでは、実描画できず、配列にプロットし、
その、Z座標で、ソートし、配列から、xyだけの2Dプロットを行なう順序です。

複素数を用いる理由は、xyの2変数が、1変数に減らせる。z座標も虚数にする事で、
空間距離が、ABS( ABS(Pxy)+Pz ) などで済み、2乗和、開平などから開放。
2変数を、1つとして、BASIC が、同時処理するので、どのモードより速くなる。
などです。
小型のプログラムでの外部副プログラムを、避けるのも、プロセッサの負担を、
軽くするためです。外部副プログラムでは、原則、全ローカル変数になるため、
PUSH POP のレジスター・セーブ・リストアが、増えているでしょう。

WAIT DELAY が、PI制御になっているのは、私のノートより世間のノートが、
20倍程速いと思われ、動画スピードの共有が、できないからです。
 6dB/oct 1次のループですから、発振はしないはずです。

返信は、なかなか大変で、時間も食うので、控えて頂ければ、助かります。
 

戻る