0

以下は、入門的な研究作業のために今週末に作成した 1D ハイドロ コード (変数 p と q を展開するための Strang 分割によるハミルトニアン法を使用) からのものです。

    do
       if(num==1) then
          p2   = p(i) - (dt/2.)*q(i)/abs(q(i))   ! half step in P
          q(i) = q(i) + dt*p2                    ! full step in Q
          p(i) = p2 - (dt/2.)*q(i)/abs(q(i))     ! half step in P
          num=2
       elseif(num==2) then
          q2   = q(i) + (dt/2.)*p(i)             ! half step in Q
          p(i) = p(i) - dt*q2/abs(q2)            ! full step in P
          q(i) = q(i) + (dt/2.)*p(i)             ! half step in Q
          num=1
       endif
       t = t+dt
       if(t >= tend) exit
    enddo

ここにあるものよりも、2 つのアルゴリズム (スプリアス データを減らすために必要) を切り替える効率的な方法はありますか? 重要な場合、p と q にはそれぞれ約 100,000 個のセルがあります (コードは並列化されています)。

編集:doコードの部分だけではなく、ループ部分を追加しましたif-elseif。の後にファイルへの書き込み部分もありますがendif、潜在的な最適化には必要ないと思います。

4

1 に答える 1

2

を完全に削除するようにコードを書き直しますif/then/else

integer :: num_steps, k
logical :: one_more

num_steps = tend/dt
one_more = (mod(num_steps,2) /= 0)

do k = 1,num_steps/2
   p2   = p(i) - (dt/2.)*q(i)/abs(q(i))   ! half step in P
   q(i) = q(i) + dt*p2                    ! full step in Q
   p(i) = p2 - (dt/2.)*q(i)/abs(q(i))     ! half step in P
   ! output
   q2   = q(i) + (dt/2.)*p(i)             ! half step in Q
   p(i) = p(i) - dt*q2/abs(q2)            ! full step in P
   q(i) = q(i) + (dt/2.)*p(i)             ! half step in Q
   ! output
enddo

if (one_more) then
   p2   = p(i) - (dt/2.)*q(i)/abs(q(i))   ! half step in P
   q(i) = q(i) + dt*p2                    ! full step in Q
   p(i) = p2 - (dt/2.)*q(i)/abs(q(i))     ! half step in P
   ! output
endif

t = t+dt出力操作の現在の時間が必要な場合は、ループ内の各ステップの後にステートメントを含めることができます。

于 2012-12-03T17:06:12.987 に答える