! $Id$ ! ! DuFort-Frankel time stepping routine. As is well known, this proceedure ! has disadvantages, but it is well suited to deal with the time step constrain ! near the center in spherical polar coordinates. ! module Timestep ! use Cparam use Cdata ! implicit none ! private ! public :: time_step ! contains !*********************************************************************** subroutine time_step(f,df,p) ! ! Runge Kutta advance, accurate to order itorder. ! At the moment, itorder can be 1, 2, or 3. ! ! 2-apr-01/axel: coded ! 14-sep-01/axel: moved itorder to cdata ! use Mpicomm use Cdata use Equ use Particles_main use BorderProfiles, only: border_quenching use Interstellar, only: calc_snr_damp_int use Shear, only: advance_shear use Special, only: special_after_timestep ! real, dimension (mx,my,mz,mfarray) :: f real, dimension (mx,my,mz,mvar) :: df,fold real, dimension (nx) :: diffarr,d2o,d2n,d2s,d2e,d2w real, dimension (nx) :: cdt1,cdt2,fold_tmp type (pencil_case) :: p real :: ds, dt1, dt1_local real, save :: dt1_last=0.0 integer :: j ! ! Set up df and ds for each time sub. ! lfirst=.true. df=0. ds=1. ! ! make sure fold exists at start-up ! if (it==1) fold=f ! ! Change df according to the chosen physics modules. ! call pde(f,df,p) ! ! If we are in the first time substep we need to calculate timestep dt. ! Only do it on the root processor, then broadcast dt to all others. ! if (ldt) then dt1_local=maxval(dt1_max(1:nx)) !Timestep growth limiter if (real(ddt) > 0.) dt1_local=max(dt1_local,dt1_last) call mpiallreduce_max(dt1_local,dt1,comm=MPI_COMM_WORLD) dt=1.0/dt1 !Timestep growth limiter if (ddt/=0.) dt1_last=dt1_local/ddt endif if (ip<=6) print*,'TIMESTEP: iproc,dt=',iproc,dt !(all have same dt?) ! ! Time evolution of grid variables. ! diffarr=1. ! do m=m1,m2 if (coord_system=='cartesian') then d2o=-2.*(dx_1(l1:l2)**2+dy_1(m)**2) d2n=dx_1(l1:l2)**2 d2s=dx_1(l1:l2)**2 d2e=dy_1(m)**2 d2w=dy_1(m)**2 elseif (coord_system=='spherical') then d2o=-2.*dx_1(l1:l2)**2-2.*r2_mn*dy_1(m)**2-r2_mn*sin2th(m) d2n=dx_1(l1:l2)**2+r1_mn*dx_1(l1:l2) d2s=dx_1(l1:l2)**2-r1_mn*dx_1(l1:l2) d2e=dy_1(m)**2+.5*tanth(m)*dy_1(m)*r2_mn d2w=dy_1(m)**2-.5*tanth(m)*dy_1(m)*r2_mn endif ! ! copy current f to fold_tmp, and set it to fold after it has been used ! do j=1,mvar; do n=n1,n2; if (lborder_profiles) call border_quenching(f,df,j,dt_beta_ts(itsub)) cdt1=.5*(1./dt+diffarr*d2o) cdt2=2./(1./dt-diffarr*d2o) fold_tmp=f(l1:l2,m,n,j) f(l1:l2,m,n,j)=(df(l1:l2,m,n,j)+diffarr*( & d2n*f(l1+1:l2+1,m,n,j)+d2s*f(l1-1:l2-1,m,n,j) & +d2e*f(l1:l2,m+1,n,j)+d2w*f(l1:l2,m-1,n,j) & )+cdt1*fold(l1:l2,m,n,j))*cdt2 fold(l1:l2,m,n,j)=fold_tmp enddo; enddo enddo ! if (lspecial) & call special_after_timestep(f,df,dt_beta_ts(itsub)*ds) ! ! Increase time. ! t=t+dt*ds ! endsubroutine time_step !*********************************************************************** endmodule Timestep