你已经派生过 tem3dfdtd-open
镜像自地址
https://gitee.com/sunhf/tem3dfdtd-open.git
已同步 2025-08-06 04:36:52 +08:00
initial
这个提交包含在:
264
tem3dfdtd/lib/Iteration.f90
普通文件
264
tem3dfdtd/lib/Iteration.f90
普通文件
@@ -0,0 +1,264 @@
|
||||
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn)
|
||||
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com)
|
||||
!Code distribution @ tdem.org or sunhuaifeng.com
|
||||
|
||||
! --------------------------------Subroutine part---------------------------------------------!
|
||||
subroutine Iteration
|
||||
use constantparameters
|
||||
USE CONSTANTPARAMETERS
|
||||
USE ELECTROMAGNETIC_VARIABLES
|
||||
USE RES_MODEL_PARAMETER
|
||||
USE TIME_PARAMETER
|
||||
implicit none
|
||||
real::t1,t2,t !t1 denotes original cpu time at the beginning of each computation fraction, t2 denotes the end cpu time and t=t2-t1
|
||||
REAL*8 CA,CB,DELX1,DELY1,DELZ1 !ca, cb, delx1, dely1, delz1 are all middle variables used in the computation of EM field
|
||||
REAL*8 TEMP_SIG,temp_cacb !Temp_sig and temp_cacb are middle variables used in the computation of EM field
|
||||
REAL*8 DELY2,DELZ2,delx2 !They are all middle variables as above ones.
|
||||
integer num,i,j,k,ii !num is the number of computation fraction
|
||||
real*8,allocatable::Meps_r(:),Mdelt(:),Msource(:),Mcq(:) !They are local substitution of eps_r, delt and cq
|
||||
do num=1,num_fra_com,1 !The outer loop which begins from the first fraction ends at the last fraction
|
||||
call cpu_time(t1) !Record the cpu time at the beginning of each computing fraction
|
||||
allocate(mdelt(0:mstop(num)),meps_r(mstop(num)),mcq(mstop(num)),msource(mstop(num)))
|
||||
! The memory of mdelt, meps_r, mcq and msource are allocated at the begining of fraction
|
||||
do ii=mstart(num),mstart(num)+mstop(num)-1,1
|
||||
mdelt(ii-mstart(num)+1)=delt(ii)
|
||||
meps_r(ii-mstart(num)+1)=eps_r(ii)
|
||||
mcq(ii-mstart(num)+1)=cq(ii)
|
||||
msource(ii-mstart(num)+1)=source(ii) !Link the local value of mdelt, meps_r, mcq and msorce to the global value of delt, eps_r, cq and source array.
|
||||
end do
|
||||
print*,'Now computing fraction:',num
|
||||
mdelt(0)=mdelt(1)
|
||||
!$acc data copy(Ex(1:nx,1:nyb,1:nzb),Ey(1:nxb,1:ny,1:nzb),Ez(1:nxb,1:nyb,1:nz))&
|
||||
!$acc copy(Hx(1:nxb,1:ny,0:nz),Hy(1:nx,1:nyb,0:nz),Hz(1:nx,1:ny,1:nzb)),copyin(cdelx(1:nx))&
|
||||
!$acc copyin(ccsig(1:nx,1:ny,1:nz),mdelt(0:mstop(num)),cdely(1:ny),cdelz(1:nz),mcq(1:mstop(num)),meps_r(1:mstop(num)))&
|
||||
!$acc copyin(is_ex_in_source(1:nx,2:nyb-1),is_ey_in_source(2:nx,1:ny),msource(1:mstop(num)))
|
||||
! OpenACC directive, copy in and out of Ex,Ey,Ez,Hx,Hy,Hz, copy in ccsig, mdelt, cdelz, mcq, meps_r, is_ex_in_source, is_ey_in_source
|
||||
do loop=1,mstop(num),1
|
||||
! --------------------------------update the value of Ex and Ey in source area---------------------------------------!
|
||||
!$acc parallel async(1)
|
||||
!$acc loop gang
|
||||
DO J=2,NYB-1
|
||||
!$acc loop vector
|
||||
DO I=1,NX
|
||||
K=NZ/2+1
|
||||
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
|
||||
DELZ1=CDELZ(NZ/2+1)
|
||||
TEMP_SIG=CCSIG(I,J-1,K-1)*CDELY(J-1)*CDELZ(K-1)&
|
||||
&+CCSIG(I,J-1,K)*CDELY(J-1)*CDELZ(K)&
|
||||
&+CCSIG(I,J,K-1)*CDELY(J)*CDELZ(K-1)&
|
||||
&+CCSIG(I,J,K)*CDELY(J)*CDELZ(K)
|
||||
TEMP_SIG=TEMP_SIG/(4.0D0*DELY1*DELZ1)
|
||||
CA=(2.0D0*Meps_r(loop)-Mdelt(LOOP-1)*TEMP_SIG)/(2.0*Meps_r(loop)+Mdelt(LOOP-1)*TEMP_SIG)
|
||||
CB=(2.0D0*MDELT(LOOP-1))/(2.0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
|
||||
EX(I,J,K)=CA*EX(I,J,K)+CB*((HZ(I,J,K)-HZ(I,J-1,K))/DELY1-(HY(I,J,K)-HY(I,J,K-1))/DELZ1)-cb*Msource(loop)*is_ex_in_source(i,j)
|
||||
ENDDO
|
||||
ENDDO
|
||||
!$acc end parallel
|
||||
! end of updating Ex while k=Nzs+1
|
||||
! update the value of Ey while k=Nzs+1
|
||||
!$acc parallel async(2)
|
||||
!$acc loop gang
|
||||
DO J=1,NY
|
||||
!$acc loop vector
|
||||
DO I=2,NX
|
||||
K=NZ/2+1
|
||||
DELX1=(CDELX(I-1)+CDELX(I))/2.0
|
||||
DELZ1=CDELZ(NZ/2+1)
|
||||
TEMP_SIG=CCSIG(I-1,J,K-1)*CDELX(I-1)*CDELZ(K-1)&
|
||||
&+CCSIG(I-1,J,K)*CDELX(I-1)*CDELZ(K)&
|
||||
&+CCSIG(I,J,K-1)*CDELX(I)*CDELZ(K-1)&
|
||||
&+CCSIG(I,J,K)*CDELX(I)*CDELZ(K)
|
||||
TEMP_SIG=TEMP_SIG/(4.0D0*DELX1*DELZ1)
|
||||
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*TEMP_SIG)/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
|
||||
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
|
||||
EY(I,J,K)=CA*EY(I,J,K)+CB*((HX(I,J,K)-HX(I,J,K-1))/DELZ1-(HZ(I,J,K)-HZ(I-1,J,K))/DELX1)-cb*Msource(loop)*is_ey_in_source(i,j)
|
||||
ENDDO
|
||||
ENDDO
|
||||
!$acc end parallel
|
||||
! end of uptating Ey while k=Nzs+1
|
||||
! ---------------------------------------------------Ex Part-------------------------------------------------------------!
|
||||
!$acc parallel async(3)
|
||||
!$acc loop gang
|
||||
DO K=NZ/2+2,NZ
|
||||
!$acc loop worker
|
||||
DO J=2,NY
|
||||
!$acc loop vector
|
||||
DO I=1,NX
|
||||
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
|
||||
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
|
||||
TEMP_SIG=CCSIG(I,J-1,K-1)*CDELY(J-1)*CDELZ(K-1)&
|
||||
&+CCSIG(I,J-1,K)*CDELY(J-1)*CDELZ(K)&
|
||||
&+CCSIG(I,J,K-1)*CDELY(J)*CDELZ(K-1)&
|
||||
&+CCSIG(I,J,K)*CDELY(J)*CDELZ(K)
|
||||
TEMP_SIG=TEMP_SIG/(4.0D0*DELY1*DELZ1)
|
||||
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*TEMP_SIG)/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
|
||||
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
|
||||
EX(I,J,K)=CA*EX(I,J,K)+CB*((HZ(I,J,K)-HZ(I,J-1,K))/DELY1-(HY(I,J,K)-HY(I,J,K-1))/DELZ1)
|
||||
ENDDO
|
||||
ENDDO
|
||||
ENDDO
|
||||
!$acc end parallel
|
||||
!$acc parallel async(4)
|
||||
!$acc loop gang
|
||||
DO K=2,NZ/2
|
||||
!$acc loop worker
|
||||
DO J=2,NY
|
||||
!$acc loop vector
|
||||
DO I=1,NX
|
||||
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
|
||||
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
|
||||
TEMP_SIG=CCSIG(I,J-1,K-1)*CDELY(J-1)*CDELZ(K-1)&
|
||||
&+CCSIG(I,J-1,K)*CDELY(J-1)*CDELZ(K)&
|
||||
&+CCSIG(I,J,K-1)*CDELY(J)*CDELZ(K-1)&
|
||||
&+CCSIG(I,J,K)*CDELY(J)*CDELZ(K)
|
||||
TEMP_SIG=TEMP_SIG/(4.0D0*DELY1*DELZ1)
|
||||
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*TEMP_SIG)/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
|
||||
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
|
||||
EX(I,J,K)=CA*EX(I,J,K)+CB*((HZ(I,J,K)-HZ(I,J-1,K))/DELY1-(HY(I,J,K)-HY(I,J,K-1))/DELZ1)
|
||||
ENDDO
|
||||
ENDDO
|
||||
ENDDO
|
||||
!$acc end parallel
|
||||
! ================end of updating Ex==================!
|
||||
! -----------------------------------------update the value of Ey--------------------------------!
|
||||
!$acc parallel async(5)
|
||||
!$acc loop gang
|
||||
DO K=NZ/2+2,NZ
|
||||
!$acc loop worker
|
||||
DO J=1,NY
|
||||
!$acc loop vector
|
||||
DO I=2,NX
|
||||
DELX1=(CDELX(I-1)+CDELX(I))/2.0D0
|
||||
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
|
||||
TEMP_SIG=CCSIG(I-1,J,K-1)*CDELX(I-1)*CDELZ(K-1)&
|
||||
&+CCSIG(I-1,J,K)*CDELX(I-1)*CDELZ(K)&
|
||||
&+CCSIG(I,J,K-1)*CDELX(I)*CDELZ(K-1)&
|
||||
&+CCSIG(I,J,K)*CDELX(I)*CDELZ(K)
|
||||
TEMP_SIG=TEMP_SIG/(4.0D0*DELX1*DELZ1)
|
||||
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*TEMP_SIG)/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
|
||||
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
|
||||
EY(I,J,K)=CA*EY(I,J,K)+CB*((HX(I,J,K)-HX(I,J,K-1))/DELZ1-(HZ(I,J,K)-HZ(I-1,J,K))/DELX1)
|
||||
ENDDO
|
||||
ENDDO
|
||||
ENDDO
|
||||
!$acc end parallel
|
||||
!$acc parallel async(6)
|
||||
!$acc loop gang
|
||||
DO K=2,NZ/2
|
||||
!$acc loop worker
|
||||
DO J=1,NY
|
||||
!$acc loop vector
|
||||
DO I=2,NXB-1
|
||||
DELX1=(CDELX(I-1)+CDELX(I))/2.0D0
|
||||
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
|
||||
TEMP_SIG=CCSIG(I-1,J,K-1)*CDELX(I-1)*CDELZ(K-1)&
|
||||
&+CCSIG(I-1,J,K)*CDELX(I-1)*CDELZ(K)&
|
||||
&+CCSIG(I,J,K-1)*CDELX(I)*CDELZ(K-1)&
|
||||
&+CCSIG(I,J,K)*CDELX(I)*CDELZ(K)
|
||||
TEMP_SIG=TEMP_SIG/(4.0D0*DELX1*DELZ1)
|
||||
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*TEMP_SIG)/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
|
||||
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
|
||||
EY(I,J,K)=CA*EY(I,J,K)+CB*((HX(I,J,K)-HX(I,J,K-1))/DELZ1-(HZ(I,J,K)-HZ(I-1,J,K))/DELX1)
|
||||
ENDDO
|
||||
ENDDO
|
||||
ENDDO
|
||||
!$acc end parallel
|
||||
!===============end of updating Ey===================!
|
||||
! -------------------------------------update the value of Ez--------------------------------------!
|
||||
!$acc parallel async(7)
|
||||
!$acc loop gang
|
||||
DO K=1,NZ
|
||||
!$acc loop worker
|
||||
DO J=2,NYB-1
|
||||
!$acc loop vector
|
||||
DO I=2,NXB-1
|
||||
DELX1=(CDELX(I-1)+CDELX(I))/2.0D0
|
||||
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
|
||||
TEMP_SIG=CCSIG(I-1,J-1,K)*CDELX(I-1)*CDELY(J-1)&
|
||||
&+CCSIG(I-1,J,K)*CDELX(I-1)*CDELY(J)&
|
||||
&+CCSIG(I,J-1,K)*CDELX(I)*CDELY(J-1)&
|
||||
&+CCSIG(I,J,K)*CDELX(I)*CDELY(J)
|
||||
TEMP_SIG=TEMP_SIG/(4.0D0*DELX1*DELY1)
|
||||
TEMP_CACB=2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG
|
||||
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*TEMP_SIG)/TEMP_CACB
|
||||
CB=(2.0D0*MDELT(LOOP-1))/TEMP_CACB
|
||||
EZ(I,J,K)=CA*EZ(I,J,K)+CB*((HY(I,J,K)-HY(I-1,J,K))/DELX1-(HX(I,J,K)-HX(I,J-1,K))/DELY1)
|
||||
ENDDO
|
||||
ENDDO
|
||||
ENDDO
|
||||
!$acc end parallel
|
||||
!$acc wait
|
||||
!===============end of updating Ez=========================!
|
||||
! ------------------------------------update the value of Hx-----------------------------------------------!
|
||||
!$acc parallel async(8)
|
||||
!$acc loop gang
|
||||
DO K=1,NZ
|
||||
!$acc loop worker
|
||||
DO J=1,NY
|
||||
!$acc loop vector
|
||||
DO I=1,NXB
|
||||
DELY2=CDELY(J)
|
||||
DELZ2=CDELZ(K)
|
||||
HX(I,J,K)=HX(I,J,K)-MCQ(LOOP)*((EZ(I,J+1,K)-EZ(I,J,K))/DELY2-(EY(I,J,K+1)-EY(I,J,K))/DELZ2)
|
||||
ENDDO
|
||||
ENDDO
|
||||
ENDDO
|
||||
!$acc end parallel
|
||||
!================end of updating Hx=======================!
|
||||
! -------------------------------------update the value of Hy---------------------------------------------!
|
||||
!$acc parallel async(9)
|
||||
!$acc loop gang
|
||||
DO K=1,NZ
|
||||
!$acc loop worker
|
||||
DO J=1,NYB
|
||||
!$acc loop vector
|
||||
DO I=1,NX
|
||||
DELZ2=CDELZ(K)
|
||||
DELX2=CDELX(I)
|
||||
HY(I,J,K)=HY(I,J,K)-MCQ(LOOP)*((EX(I,J,K+1)-EX(I,J,K))/DELZ2-(EZ(I+1,J,K)-EZ(I,J,K))/DELX2)
|
||||
ENDDO
|
||||
ENDDO
|
||||
ENDDO
|
||||
!$acc end parallel
|
||||
!$acc wait
|
||||
!===============end of updating Hy========================!
|
||||
!-------------------------------------update the value of Hz----------------------------------------------!
|
||||
!$acc kernels async(10)
|
||||
DO J=1,NY
|
||||
DO I=1,NX
|
||||
DO K=NZ,NZ/2+1,-1 !NZ,2,-1 !
|
||||
DELX2=CDELX(I)
|
||||
DELY2=CDELY(J)
|
||||
DELZ2=CDELZ(K)
|
||||
HZ(I,J,K)=HZ(I,J,K+1)+DELZ2*((HX(I+1,J,K)-HX(I,J,K))/DELX2+(HY(I,J+1,K)-HY(I,J,K))/DELY2)
|
||||
ENDDO
|
||||
ENDDO
|
||||
ENDDO
|
||||
!$acc end kernels
|
||||
!$acc kernels async(11)
|
||||
DO K=1,NZ/2-1
|
||||
DO J=1,NY
|
||||
DO I=1,NX
|
||||
DELX2=CDELX(I)
|
||||
DELY2=CDELY(J)
|
||||
DELZ2=CDELZ(K)
|
||||
HZ(I,J,K+1)=HZ(I,J,K)-DELZ2*((HX(I+1,J,K)-HX(I,J,K))/DELX2+(HY(I,J+1,K)-HY(I,J,K))/DELY2)
|
||||
ENDDO
|
||||
ENDDO
|
||||
ENDDO
|
||||
!$acc end kernels
|
||||
!$acc wait
|
||||
!===================end of updating Hz==========================!
|
||||
enddo
|
||||
!$acc end data
|
||||
call cpu_time(t2)
|
||||
t=t2-t1
|
||||
print*,'The computing time for this fraction is:', t
|
||||
deallocate(meps_r,mcq,msource,mdelt)
|
||||
call WriteRecFiles(num)
|
||||
write(*,'(1x,e20.10e3,3x,e20.10e3)')Hz(nxs,nys+2,Nzs_air(1)),Hz(Nxs,Nys+2,Nz/2+1)
|
||||
write(*,*)'Now loop is:',mstart(num)+mstop(num)-1
|
||||
print*,mstop(num),'steps have just finished'
|
||||
ENDDO
|
||||
end subroutine Iteration
|
||||
|
在新工单中引用
屏蔽一个用户