temporal.f90 Source File


This file depends on

sourcefile~~temporal.f90~~EfferentGraph sourcefile~temporal.f90 temporal.f90 sourcefile~mpimod.f90 mpimod.F90 sourcefile~temporal.f90->sourcefile~mpimod.f90 sourcefile~phys_consts.f90 phys_consts.F90 sourcefile~temporal.f90->sourcefile~phys_consts.f90 sourcefile~mesh.f90 mesh.f90 sourcefile~temporal.f90->sourcefile~mesh.f90 sourcefile~mpimod.f90->sourcefile~phys_consts.f90 sourcefile~mesh.f90->sourcefile~phys_consts.f90

Files dependent on this one

sourcefile~~temporal.f90~~AfferentGraph sourcefile~temporal.f90 temporal.f90 sourcefile~gemini.f90 gemini.f90 sourcefile~gemini.f90->sourcefile~temporal.f90

Contents

Source Code


Source Code

module temporal

!DO NOT FIX THESE WARNINGS - THEY ARE FOR UNUSED VARIABLES THAT MAY BE LEVERAGED
!IN LATER RELEASES
!/home/zettergm/zettergmdata/GEMINI/temporal/temporal.f90:65:0: warning: unused
!parameter ‘ns’ [-Wunused-parameter]
!   pure subroutine
!dt_calc(tcfl,ns,Ts,vs1,vs2,vs3,B1,B2,B3,dx1i,dx2i,dx3i,potsolve,cour1,cour2,cour3,dt) ^
!/home/zettergm/zettergmdata/GEMINI/temporal/temporal.f90:65:0: warning: unused parameter ‘b1’ [-Wunused-parameter]
!/home/zettergm/zettergmdata/GEMINI/temporal/temporal.f90:65:0: warning: unused parameter ‘b2’ [-Wunused-parameter]
!/home/zettergm/zettergmdata/GEMINI/temporal/temporal.f90:65:0: warning: unused parameter ‘b3’ [-Wunused-parameter]
!/home/zettergm/zettergmdata/GEMINI/temporal/temporal.f90:65:0: warning: unused parameter ‘potsolve’ [-Wunused-parameter]

use phys_consts, only:  kB,mu0,ms,lsp,pi, wp, debug
use mpimod, only: mpi_realprec, tagdt, lid, myid, MPI_COMM_WORLD,MPI_STATUS_IGNORE
use mesh, only:  curvmesh

implicit none

private
public :: dt_comm

contains


subroutine dt_comm(t,tout,tglowout,flagglow,tcfl,ns,Ts,vs1,vs2,vs3,B1,B2,B3,x,potsolve,dt)

real(wp), intent(in) :: t,tout,tglowout,tcfl
real(wp), dimension(-1:,-1:,-1:,:), intent(in) :: ns,Ts,vs1,vs2,vs3
real(wp),  dimension(-1:,-1:,-1:), intent(in) :: B1,B2,B3
type(curvmesh), intent(in) :: x
integer, intent(in) :: flagglow,potsolve
real(wp), intent(out) :: dt

real(wp), dimension(lsp) :: cour1,cour2,cour3
integer :: iid,isp, ierr
real(wp) :: dttmp


call dt_calc(tcfl,ns,Ts,vs1,vs2,vs3,B1,B2,B3,x%dl1i,x%dl2i,x%dl3i,potsolve,cour1,cour2,cour3,dt)

if (myid/=0) then
  call mpi_send(dt,1,mpi_realprec,0,tagdt,MPI_COMM_WORLD,ierr)   !send what I think dt should be
  call mpi_recv(dt,1,mpi_realprec,0,tagdt,MPI_COMM_WORLD,MPI_STATUS_IGNORE,ierr)   !receive roots decision
else
  !FIGURE OUT GLOBAL DT REQUIRED FOR STABILITY
  do iid=1,lid-1
    call mpi_recv(dttmp,1,mpi_realprec,iid,tagdt,MPI_COMM_WORLD,MPI_STATUS_IGNORE,ierr)

    if (dttmp < dt) dt=dttmp
  end do

  !CHECK WHETHER WE'D OVERSTEP OUR TARGET OUTPUT TIME
  !GLOW OUTPUT HAS PRIORITY SINCE IT WILL OUTPUT MORE OFTEN
  if ((flagglow/=0).and.(t+dt>tglowout)) then
    dt=tglowout-t
    print *, 'GLOW is throttling dt...'
  end if

  if (t+dt>tout) then
    dt=tout-t
    if (debug) print *, 'Slowing down for an output...'
  end if

  !DON'T ALLOW ZERO DT
  dt = max(dt, 1e-6_wp)

  !SEND GLOBAL DT TO ALL WORKERS
  do iid=1,lid-1
    call mpi_send(dt,1,mpi_realprec,iid,tagdt,MPI_COMM_WORLD,ierr)
  end do

  if (debug) then
    print *, 'dt figured to be:  ',dt
    print *, 'x1,x2,x3 courant numbers (root process only!):  '
    do isp=1,lsp
      print '(a,f4.2,a,f4.2,a,f4.2)', '    ',cour1(isp),', ',cour2(isp),', ',cour3(isp)
      !! these are roots courant numbers
    end do
    print *, 'Min and max density:  ',minval(pack(ns(:,:,:,7),.true.)),maxval(pack(ns(:,:,:,7),.true.))
  endif
end if

end subroutine dt_comm


pure subroutine dt_calc(tcfl,ns,Ts,vs1,vs2,vs3,B1,B2,B3,dx1i,dx2i,dx3i,potsolve,cour1,cour2,cour3,dt)

!------------------------------------------------------------
!-------COMPUTE TIME STEP SUCH THAT STABILITY CONDITION IS
!-------SATISFIED.  NOTE THAT THE DIFFERENTIALS ARE ASSUMED
!-------TO HAVE UNITS OF DISTANCE, SO THEY MUST IMPLICITLY
!-------INCLUDE THE METRIC FACTORS.
!------------------------------------------------------------


real(wp), intent(in) :: tcfl
real(wp), dimension(-1:,-1:,-1:,:), intent(in) :: ns,Ts,vs1,vs2,vs3
real(wp),  dimension(-1:,-1:,-1:), intent(in) :: B1,B2,B3
real(wp), dimension(:,:,:), intent(in) :: dx1i
real(wp), dimension(:,:,:), intent(in) :: dx2i
real(wp), dimension(:,:,:), intent(in) :: dx3i
integer, intent(in) :: potsolve
real(wp), dimension(lsp), intent(out) :: cour1,cour2,cour3
real(wp), intent(out) :: dt

real(wp), dimension(lsp) :: gridrate1,gridrate2,gridrate3
real(wp) :: vsnd
real(wp) :: rhom,Bmag,vA
integer :: lx1,lx2,lx3,ix1,ix2,ix3,isp

lx1=size(Ts,1)-4
lx2=size(Ts,2)-4
lx3=size(Ts,3)-4

gridrate1=0._wp
gridrate2=0._wp
gridrate3=0._wp


!EVALUATE TIME STEP AGAINST LOCAL SOUND SPEED AND ADVECTION
do isp=1,lsp
  do ix3=1,lx3
    do ix2=1,lx2
      do ix1=1,lx1
        if (isp<lsp) then
          vsnd=sqrt(kB*Ts(ix1,ix2,ix3,isp)/ms(isp)+5._wp/3._wp*kB*Ts(ix1,ix2,ix3,lsp)/ms(isp))
        else
          vsnd=0._wp
        end if

        gridrate1(isp)=max((vsnd+abs(vs1(ix1,ix2,ix3,isp)))/dx1i(ix1,ix2,ix3),gridrate1(isp))
        gridrate2(isp)=max(abs(vs2(ix1,ix2,ix3,isp))/dx2i(ix1,ix2,ix3),gridrate2(isp))
        gridrate3(isp)=max(abs(vs3(ix1,ix2,ix3,isp))/dx3i(ix1,ix2,ix3),gridrate3(isp))
      end do
    end do
  end do
end do


!    !CHECK GRIDRATE MAX AGAINST LOCAL ALFVEN SPEED (IF THIS SIMULATION IS INDUCTIVE)
!    !NOTE THAT THIS SHOULD REALLY INCLUDE MAGNETOSONIC (FAST) MODES IN GRIDRATE DETERMINATION
!    !AS OF 2/10/2016 THIS CODE IS NOT USED AT ALL, BUT IS KEPT FOR FUTURE DEVELOPMENT
!    if (potsolve == 2) then
!      do ix3=1,lx3
!        do ix2=1,lx2
!          do ix1=1,lx1
!            rhom=0._wp
!            do isp=1,lsp
!              rhom=rhom+ms(isp)*ns(ix1,ix2,ix3,isp)
!            end do
!            Bmag=sqrt(B1(ix1,ix2,ix3)**2+B2(ix1,ix2,ix3)**2+B3(ix1,ix2,ix3)**2)
!
!            vA=Bmag/sqrt(rhom*mu0)
!
!            do isp=1,lsp
!              gridrate1(isp)=max(vA/dx1i(ix1),gridrate1(isp))
!              gridrate2(isp)=max(vA/dx2i(ix2),gridrate2(isp))
!              gridrate3(isp)=max(vA/dx3i(ix3),gridrate3(isp))
!            end do
!          end do
!        end do
!      end do
!    end if


!ENFORCE A MINIMUM VALUE FOR THE GRIDRATE (WHICH IS CFL/DT, GRID POINTS PER SECOND)
gridrate1=max(gridrate1, 1e-10_wp)
gridrate2=max(gridrate2, 1e-10_wp)
gridrate3=max(gridrate3, 1e-10_wp)

dt=tcfl*min(minval(1._wp/gridrate1),minval(1._wp/gridrate2),minval(1._wp/gridrate3))
cour1=dt*gridrate1
cour2=dt*gridrate2
cour3=dt*gridrate3
end subroutine dt_calc

end module temporal