2010-10-13 03:32:10 -03:00
|
|
|
!!******************************************************************************
|
2008-12-07 18:57:08 -06:00
|
|
|
!!
|
|
|
|
!! module: evolution - handling the time evolution of the block structure
|
|
|
|
!!
|
2011-02-27 22:45:54 -03:00
|
|
|
!! Copyright (C) 2008-2011 Grzegorz Kowal <grzegorz@gkowal.info>
|
2008-12-07 18:57:08 -06:00
|
|
|
!!
|
2010-10-13 03:32:10 -03:00
|
|
|
!!******************************************************************************
|
2008-12-07 18:57:08 -06:00
|
|
|
!!
|
2011-04-25 13:44:34 -03:00
|
|
|
!! This file is part of AMUN.
|
2008-12-07 18:57:08 -06:00
|
|
|
!!
|
2011-04-25 13:44:34 -03:00
|
|
|
!! AMUN is free software; you can redistribute it and/or modify
|
2008-12-07 18:57:08 -06:00
|
|
|
!! it under the terms of the GNU General Public License as published by
|
|
|
|
!! the Free Software Foundation; either version 3 of the License, or
|
|
|
|
!! (at your option) any later version.
|
|
|
|
!!
|
2011-04-25 13:44:34 -03:00
|
|
|
!! AMUN is distributed in the hope that it will be useful,
|
2008-12-07 18:57:08 -06:00
|
|
|
!! but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
!! GNU General Public License for more details.
|
|
|
|
!!
|
|
|
|
!! You should have received a copy of the GNU General Public License
|
|
|
|
!! along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
!!
|
2010-10-13 03:32:10 -03:00
|
|
|
!!******************************************************************************
|
2008-12-07 18:57:08 -06:00
|
|
|
!!
|
|
|
|
!
|
|
|
|
module evolution
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
integer, save :: n
|
2010-12-01 13:13:27 -02:00
|
|
|
real , save :: t, dt, dtn
|
2008-12-07 18:57:08 -06:00
|
|
|
|
|
|
|
contains
|
|
|
|
!
|
2008-12-08 21:07:10 -06:00
|
|
|
!===============================================================================
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2008-12-08 21:07:10 -06:00
|
|
|
! evolve: subroutine sweeps over all leaf blocks and performs one step time
|
|
|
|
! evolution for each according to the selected integration scheme
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2008-12-08 21:07:10 -06:00
|
|
|
!===============================================================================
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2010-12-01 15:14:07 -02:00
|
|
|
subroutine evolve()
|
2008-12-07 18:57:08 -06:00
|
|
|
|
2010-12-08 18:19:16 -02:00
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
use boundaries, only : boundary_variables
|
2011-04-26 12:37:25 -03:00
|
|
|
#ifdef REFINE
|
|
|
|
use config , only : maxlev
|
|
|
|
#endif /* REFINE */
|
2011-03-18 15:33:24 -03:00
|
|
|
#ifdef VISCOSITY
|
|
|
|
use config , only : visc
|
|
|
|
#endif /* VISCOSITY */
|
2011-03-22 17:24:28 -03:00
|
|
|
#if defined MHD && defined RESISTIVITY
|
2010-12-14 17:29:38 -02:00
|
|
|
use config , only : ueta
|
2011-03-22 17:24:28 -03:00
|
|
|
#endif /* MHD & RESISTIVITY */
|
2010-12-08 18:19:16 -02:00
|
|
|
#ifdef FORCE
|
2011-03-07 00:08:31 -03:00
|
|
|
use forcing , only : fourier_transform, evolve_forcing
|
2010-12-08 18:19:16 -02:00
|
|
|
#endif /* FORCE */
|
|
|
|
use mesh , only : update_mesh
|
|
|
|
use mesh , only : dx_min
|
|
|
|
use scheme , only : cmax
|
|
|
|
use timer , only : start_timer, stop_timer
|
2011-03-07 00:08:31 -03:00
|
|
|
use variables , only : idn, imz
|
2008-12-07 18:57:08 -06:00
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
! local variables
|
|
|
|
!
|
2009-09-14 18:28:17 -03:00
|
|
|
type(block_data), pointer :: pblock
|
2010-12-01 10:39:18 -02:00
|
|
|
real :: cm
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2008-12-08 21:07:10 -06:00
|
|
|
!-------------------------------------------------------------------------------
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2010-12-08 18:19:16 -02:00
|
|
|
#ifdef FORCE
|
2011-03-07 00:08:31 -03:00
|
|
|
! perform the Fourier transform of the velocity field
|
|
|
|
!
|
|
|
|
pblock => list_data
|
|
|
|
do while (associated(pblock))
|
|
|
|
|
|
|
|
if (pblock%meta%leaf) &
|
|
|
|
call fourier_transform(pblock%meta%level &
|
|
|
|
, pblock%meta%xmin, pblock%meta%ymin, pblock%meta%zmin &
|
|
|
|
, pblock%u(idn:imz,:,:,:))
|
|
|
|
|
|
|
|
pblock => pblock%next ! assign pointer to the next block
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
2010-12-08 18:19:16 -02:00
|
|
|
! evolve the forcing source terms by the time interval dt
|
|
|
|
!
|
|
|
|
call evolve_forcing(dt)
|
|
|
|
#endif /* FORCE */
|
|
|
|
|
2009-09-14 18:28:17 -03:00
|
|
|
! iterate over all data blocks and perform one step of time evolution
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2009-09-14 18:28:17 -03:00
|
|
|
pblock => list_data
|
2008-12-09 14:51:33 -06:00
|
|
|
do while (associated(pblock))
|
2008-12-07 18:57:08 -06:00
|
|
|
|
|
|
|
! check if this block is a leaf
|
|
|
|
!
|
2009-09-14 18:28:17 -03:00
|
|
|
if (pblock%meta%leaf) &
|
2008-12-09 21:06:21 -06:00
|
|
|
#ifdef EULER
|
|
|
|
call evolve_euler(pblock)
|
|
|
|
#endif /* EULER */
|
2008-12-08 16:21:59 -06:00
|
|
|
#ifdef RK2
|
2008-12-09 14:51:33 -06:00
|
|
|
call evolve_rk2(pblock)
|
2008-12-08 16:21:59 -06:00
|
|
|
#endif /* RK2 */
|
2010-12-03 15:38:48 -02:00
|
|
|
#ifdef RK3
|
|
|
|
call evolve_rk3(pblock)
|
|
|
|
#endif /* RK3 */
|
2008-12-07 18:57:08 -06:00
|
|
|
|
|
|
|
! assign pointer to the next block
|
|
|
|
!
|
2008-12-09 14:51:33 -06:00
|
|
|
pblock => pblock%next
|
2008-12-07 18:57:08 -06:00
|
|
|
|
2008-12-09 14:51:33 -06:00
|
|
|
end do
|
2008-12-07 18:57:08 -06:00
|
|
|
|
2008-12-09 20:37:31 -06:00
|
|
|
! update boundaries
|
2008-12-08 12:14:13 -06:00
|
|
|
!
|
2008-12-13 22:41:37 -06:00
|
|
|
call start_timer(4)
|
2010-12-01 15:14:07 -02:00
|
|
|
call boundary_variables()
|
2008-12-13 22:41:37 -06:00
|
|
|
call stop_timer(4)
|
2008-12-08 12:14:13 -06:00
|
|
|
|
2011-03-10 01:08:00 -03:00
|
|
|
#ifdef REFINE
|
2011-04-26 12:37:25 -03:00
|
|
|
! chec if we need to perform the refinement step
|
|
|
|
!
|
|
|
|
if (maxlev .gt. 1) then
|
|
|
|
|
2010-03-14 15:40:24 -03:00
|
|
|
! check refinement and refine
|
|
|
|
!
|
2011-04-26 12:37:25 -03:00
|
|
|
call start_timer(5)
|
|
|
|
call update_mesh()
|
|
|
|
call stop_timer(5)
|
2010-03-14 15:40:24 -03:00
|
|
|
|
|
|
|
! update boundaries
|
|
|
|
!
|
2011-04-26 12:37:25 -03:00
|
|
|
call start_timer(4)
|
|
|
|
call boundary_variables()
|
|
|
|
call stop_timer(4)
|
|
|
|
|
|
|
|
end if ! maxlev > 1
|
2010-03-14 15:40:24 -03:00
|
|
|
|
2011-03-10 01:08:00 -03:00
|
|
|
#endif /* REFINE */
|
2010-12-01 10:39:18 -02:00
|
|
|
! update the maximum speed
|
2008-12-09 14:51:33 -06:00
|
|
|
!
|
2010-12-01 10:39:18 -02:00
|
|
|
call update_maximum_speed()
|
|
|
|
|
|
|
|
! get maximum time step
|
|
|
|
!
|
|
|
|
dtn = dx_min / max(cmax, 1.0d-16)
|
2011-03-18 15:33:24 -03:00
|
|
|
#ifdef VISCOSITY
|
|
|
|
dtn = min(dtn, 0.5d0 * dx_min * dx_min / max(1.0d-16, visc))
|
|
|
|
#endif /* VISCOSITY */
|
2011-03-22 17:24:28 -03:00
|
|
|
#if defined MHD && defined RESISTIVITY
|
2010-12-14 17:29:38 -02:00
|
|
|
dtn = min(dtn, 0.5d0 * dx_min * dx_min / max(1.0d-16, ueta))
|
2011-03-22 17:24:28 -03:00
|
|
|
#endif /* MHD & RESISTIVITY */
|
2010-12-01 10:39:18 -02:00
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
end subroutine evolve
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
! update_maximum_speed: subroutine updates module variable cmax with the value
|
|
|
|
! corresponding to the maximum speed in the system
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
subroutine update_maximum_speed()
|
|
|
|
|
2010-12-03 18:02:07 -02:00
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
#ifdef MPI
|
|
|
|
use mpitools, only : mallreducemaxr
|
|
|
|
#endif /* MPI */
|
|
|
|
use scheme , only : maxspeed, cmax
|
2010-12-01 10:39:18 -02:00
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
! local variables
|
|
|
|
!
|
|
|
|
type(block_data), pointer :: pblock
|
|
|
|
real :: cm
|
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! reset the maximum speed
|
|
|
|
!
|
|
|
|
cmax = 1.0d-16
|
2008-12-09 14:51:33 -06:00
|
|
|
|
|
|
|
! iterate over all blocks in order to find the maximum speed
|
|
|
|
!
|
2009-09-14 18:28:17 -03:00
|
|
|
pblock => list_data
|
2008-12-09 14:51:33 -06:00
|
|
|
do while (associated(pblock))
|
|
|
|
|
|
|
|
! check if this block is a leaf
|
|
|
|
!
|
2009-09-14 18:28:17 -03:00
|
|
|
if (pblock%meta%leaf) &
|
2008-12-09 14:51:33 -06:00
|
|
|
cm = maxspeed(pblock%u)
|
|
|
|
|
|
|
|
! compare global and local maximum speeds
|
|
|
|
!
|
|
|
|
cmax = max(cmax, cm)
|
|
|
|
|
|
|
|
! assign pointer to the next block
|
|
|
|
!
|
|
|
|
pblock => pblock%next
|
|
|
|
|
|
|
|
end do
|
2010-12-03 18:02:07 -02:00
|
|
|
|
|
|
|
#ifdef MPI
|
|
|
|
! reduce the maximum speed over all processes
|
|
|
|
!
|
|
|
|
call mallreducemaxr(cmax)
|
|
|
|
#endif /* MPI */
|
2010-02-28 18:35:57 -03:00
|
|
|
!
|
2008-12-08 21:07:10 -06:00
|
|
|
!-------------------------------------------------------------------------------
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2010-12-01 10:39:18 -02:00
|
|
|
end subroutine update_maximum_speed
|
2008-12-09 21:06:21 -06:00
|
|
|
#ifdef EULER
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
! evolve_euler: subroutine evolves the current block using Euler integration
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
subroutine evolve_euler(pblock)
|
|
|
|
|
2010-12-01 09:25:30 -02:00
|
|
|
use blocks , only : block_data
|
|
|
|
use config , only : im, jm, km
|
2010-12-08 21:48:43 -02:00
|
|
|
#ifdef FORCE
|
|
|
|
use forcing , only : real_forcing
|
|
|
|
#endif /* FORCE */
|
2010-12-06 16:20:49 -02:00
|
|
|
use mesh , only : adxi, adyi, adzi
|
2008-12-18 12:18:36 -06:00
|
|
|
#ifdef SHAPE
|
2010-12-01 09:25:30 -02:00
|
|
|
use problem , only : update_shapes
|
2008-12-18 12:18:36 -06:00
|
|
|
#endif /* SHAPE */
|
2010-12-01 13:13:27 -02:00
|
|
|
use scheme , only : update, cmax
|
2010-12-01 09:25:30 -02:00
|
|
|
use variables, only : nqt, nfl
|
2010-12-01 10:53:21 -02:00
|
|
|
#ifdef MHD
|
|
|
|
use variables, only : ibx, ibz
|
|
|
|
#ifdef GLM
|
2010-12-01 11:20:25 -02:00
|
|
|
use config , only : alpha_p
|
|
|
|
use mesh , only : dx_min
|
2010-12-01 10:53:21 -02:00
|
|
|
use variables, only : iph
|
|
|
|
#endif /* GLM */
|
|
|
|
#endif /* MHD */
|
2010-12-08 21:48:43 -02:00
|
|
|
#ifdef FORCE
|
|
|
|
use variables, only : idn, imx, imy, imz
|
|
|
|
#endif /* FORCE */
|
2008-12-09 21:06:21 -06:00
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
! input arguments
|
|
|
|
!
|
2009-10-28 00:12:18 -02:00
|
|
|
type(block_data), intent(inout) :: pblock
|
2008-12-09 21:06:21 -06:00
|
|
|
|
|
|
|
! local variables
|
|
|
|
!
|
2010-12-06 16:20:49 -02:00
|
|
|
real :: dxi, dyi, dzi, ch2
|
2010-12-01 11:20:25 -02:00
|
|
|
#if defined MHD && defined GLM
|
2010-12-06 16:20:49 -02:00
|
|
|
real :: decay
|
2010-12-01 11:20:25 -02:00
|
|
|
#endif /* MHD & GLM */
|
2008-12-09 21:06:21 -06:00
|
|
|
|
|
|
|
! local arrays
|
|
|
|
!
|
2010-09-19 00:08:20 +02:00
|
|
|
real, dimension(nqt,im,jm,km) :: du
|
2010-12-08 21:48:43 -02:00
|
|
|
#ifdef FORCE
|
|
|
|
real, dimension( 3,im,jm,km) :: f
|
|
|
|
#endif /* FORCE */
|
2008-12-09 21:06:21 -06:00
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
2010-12-06 16:20:49 -02:00
|
|
|
! prepare dxi, dyi, and dzi
|
|
|
|
!
|
|
|
|
dxi = adxi(pblock%meta%level)
|
|
|
|
dyi = adyi(pblock%meta%level)
|
|
|
|
dzi = adzi(pblock%meta%level)
|
|
|
|
|
2011-03-06 23:37:51 -03:00
|
|
|
! 1st step of integration
|
|
|
|
!
|
|
|
|
call update(pblock%u(:,:,:,:), du(:,:,:,:), dxi, dyi, dzi)
|
2008-12-18 12:18:36 -06:00
|
|
|
|
|
|
|
#ifdef SHAPE
|
|
|
|
! restrict update in a defined shape
|
|
|
|
!
|
2010-12-06 16:20:49 -02:00
|
|
|
call update_shapes(pblock, du)
|
2008-12-18 12:18:36 -06:00
|
|
|
#endif /* SHAPE */
|
2008-12-09 21:06:21 -06:00
|
|
|
|
2010-12-01 10:53:21 -02:00
|
|
|
! update the solution for the fluid variables
|
2008-12-09 21:06:21 -06:00
|
|
|
!
|
2010-12-01 10:53:21 -02:00
|
|
|
pblock%u(1:nfl,:,:,:) = pblock%u(1:nfl,:,:,:) + dt * du(1:nfl,:,:,:)
|
|
|
|
|
|
|
|
#ifdef MHD
|
|
|
|
! update the solution for the magnetic variables
|
|
|
|
!
|
|
|
|
pblock%u(ibx:ibz,:,:,:) = pblock%u(ibx:ibz,:,:,:) + dt * du(ibx:ibz,:,:,:)
|
|
|
|
|
|
|
|
#ifdef GLM
|
2010-12-01 10:57:40 -02:00
|
|
|
! calculate c_h^2
|
|
|
|
!
|
|
|
|
ch2 = cmax * cmax
|
|
|
|
|
2010-12-01 10:53:21 -02:00
|
|
|
! update the solution for the scalar potential Psi
|
|
|
|
!
|
2010-12-01 10:57:40 -02:00
|
|
|
pblock%u(iph,:,:,:) = pblock%u(iph,:,:,:) + ch2 * dt * du(iph,:,:,:)
|
2010-12-01 11:20:25 -02:00
|
|
|
|
|
|
|
! evolve Psi due to the source term
|
|
|
|
!
|
|
|
|
decay = exp(- alpha_p * cmax * dt / dx_min)
|
|
|
|
pblock%u(iph,:,:,:) = decay * pblock%u(iph,:,:,:)
|
2010-12-01 10:53:21 -02:00
|
|
|
#endif /* GLM */
|
|
|
|
#endif /* MHD */
|
2011-04-26 10:36:16 -03:00
|
|
|
#ifdef FORCE
|
|
|
|
! obtain the forcing terms in real space
|
|
|
|
!
|
|
|
|
call real_forcing(pblock%meta%level, pblock%meta%xmin, pblock%meta%ymin &
|
|
|
|
, pblock%meta%zmin, f(:,:,:,:))
|
|
|
|
|
|
|
|
! update momenta due to the forcing terms
|
|
|
|
!
|
|
|
|
pblock%u(imx,:,:,:) = pblock%u(imx,:,:,:) + pblock%u(idn,:,:,:) * f(1,:,:,:)
|
|
|
|
pblock%u(imy,:,:,:) = pblock%u(imy,:,:,:) + pblock%u(idn,:,:,:) * f(2,:,:,:)
|
|
|
|
pblock%u(imz,:,:,:) = pblock%u(imz,:,:,:) + pblock%u(idn,:,:,:) * f(3,:,:,:)
|
|
|
|
|
|
|
|
#endif /* FORCE */
|
2009-10-28 00:12:18 -02:00
|
|
|
!
|
2008-12-09 21:06:21 -06:00
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
end subroutine evolve_euler
|
|
|
|
#endif /* EULER */
|
2008-12-08 16:21:59 -06:00
|
|
|
#ifdef RK2
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2008-12-08 21:07:10 -06:00
|
|
|
!===============================================================================
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2010-12-03 15:38:48 -02:00
|
|
|
! evolve_rk2: subroutine evolves the current block using the 2nd order
|
|
|
|
! Runge-Kutta method
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2008-12-08 21:07:10 -06:00
|
|
|
!===============================================================================
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
|
|
|
subroutine evolve_rk2(pblock)
|
|
|
|
|
2010-12-01 09:25:30 -02:00
|
|
|
use blocks , only : block_data
|
|
|
|
use config , only : im, jm, km
|
2010-12-08 21:55:45 -02:00
|
|
|
#ifdef FORCE
|
|
|
|
use forcing , only : real_forcing
|
|
|
|
#endif /* FORCE */
|
2010-12-06 16:20:49 -02:00
|
|
|
use mesh , only : adxi, adyi, adzi
|
2008-12-18 12:18:36 -06:00
|
|
|
#ifdef SHAPE
|
2010-12-01 09:25:30 -02:00
|
|
|
use problem , only : update_shapes
|
2008-12-18 12:18:36 -06:00
|
|
|
#endif /* SHAPE */
|
2010-12-01 13:13:27 -02:00
|
|
|
use scheme , only : update, cmax
|
2010-12-01 09:25:30 -02:00
|
|
|
use variables, only : nqt, nfl
|
2010-12-01 10:53:21 -02:00
|
|
|
#ifdef MHD
|
|
|
|
use variables, only : ibx, ibz
|
|
|
|
#ifdef GLM
|
2010-12-01 11:20:25 -02:00
|
|
|
use config , only : alpha_p
|
|
|
|
use mesh , only : dx_min
|
2010-12-01 10:53:21 -02:00
|
|
|
use variables, only : iph
|
|
|
|
#endif /* GLM */
|
|
|
|
#endif /* MHD */
|
2010-12-08 21:55:45 -02:00
|
|
|
#ifdef FORCE
|
|
|
|
use variables, only : idn, imx, imy, imz
|
|
|
|
#endif /* FORCE */
|
2008-12-07 18:57:08 -06:00
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
! input arguments
|
|
|
|
!
|
2009-10-28 00:12:18 -02:00
|
|
|
type(block_data), intent(inout) :: pblock
|
2008-12-07 18:57:08 -06:00
|
|
|
|
|
|
|
! local variables
|
|
|
|
!
|
2010-12-06 16:20:49 -02:00
|
|
|
real :: dxi, dyi, dzi, ch2
|
2010-12-01 11:20:25 -02:00
|
|
|
#if defined MHD && defined GLM
|
2010-12-06 16:20:49 -02:00
|
|
|
real :: decay
|
2010-12-01 11:20:25 -02:00
|
|
|
#endif /* MHD & GLM */
|
2008-12-08 16:21:59 -06:00
|
|
|
|
|
|
|
! local arrays
|
|
|
|
!
|
2010-09-19 00:08:20 +02:00
|
|
|
real, dimension(nqt,im,jm,km) :: u1, du
|
2010-12-08 21:55:45 -02:00
|
|
|
#ifdef FORCE
|
|
|
|
real, dimension( 3,im,jm,km) :: f
|
|
|
|
#endif /* FORCE */
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2008-12-08 21:07:10 -06:00
|
|
|
!-------------------------------------------------------------------------------
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2010-12-06 16:20:49 -02:00
|
|
|
! prepare dxi, dyi, and dzi
|
|
|
|
!
|
|
|
|
dxi = adxi(pblock%meta%level)
|
|
|
|
dyi = adyi(pblock%meta%level)
|
|
|
|
dzi = adzi(pblock%meta%level)
|
|
|
|
|
2010-12-03 15:38:48 -02:00
|
|
|
!! 1st step of integration
|
|
|
|
!!
|
2010-12-06 16:20:49 -02:00
|
|
|
call update(pblock%u(:,:,:,:), du(:,:,:,:), dxi, dyi, dzi)
|
2008-12-18 12:18:36 -06:00
|
|
|
|
|
|
|
#ifdef SHAPE
|
|
|
|
! restrict update in a defined shape
|
|
|
|
!
|
2010-12-03 15:38:48 -02:00
|
|
|
call update_shapes(pblock, du(:,:,:,:))
|
2008-12-08 16:21:59 -06:00
|
|
|
|
2011-04-26 11:50:57 -03:00
|
|
|
#endif /* SHAPE */
|
2010-12-01 10:53:21 -02:00
|
|
|
! update the solution for the fluid variables
|
|
|
|
!
|
|
|
|
u1(1:nfl,:,:,:) = pblock%u(1:nfl,:,:,:) + dt * du(1:nfl,:,:,:)
|
|
|
|
|
|
|
|
#ifdef MHD
|
|
|
|
! update the solution for the magnetic variables
|
2008-12-08 16:21:59 -06:00
|
|
|
!
|
2010-12-01 10:53:21 -02:00
|
|
|
u1(ibx:ibz,:,:,:) = pblock%u(ibx:ibz,:,:,:) + dt * du(ibx:ibz,:,:,:)
|
|
|
|
|
|
|
|
#ifdef GLM
|
2011-03-06 23:37:51 -03:00
|
|
|
! calculate c_h^2
|
|
|
|
!
|
|
|
|
ch2 = cmax * cmax
|
|
|
|
|
2010-12-01 10:53:21 -02:00
|
|
|
! update the solution for the scalar potential Psi
|
|
|
|
!
|
2010-12-01 10:57:40 -02:00
|
|
|
u1(iph,:,:,:) = pblock%u(iph,:,:,:) + ch2 * dt * du(iph,:,:,:)
|
2011-04-26 11:50:57 -03:00
|
|
|
|
2010-12-01 10:53:21 -02:00
|
|
|
#endif /* GLM */
|
|
|
|
#endif /* MHD */
|
2008-12-08 16:21:59 -06:00
|
|
|
! 2nd step of integration
|
|
|
|
!
|
2010-12-06 16:20:49 -02:00
|
|
|
call update(u1(:,:,:,:), du(:,:,:,:), dxi, dyi, dzi)
|
2008-12-08 16:21:59 -06:00
|
|
|
|
2008-12-18 12:18:36 -06:00
|
|
|
#ifdef SHAPE
|
|
|
|
! restrict update in a defined shape
|
|
|
|
!
|
2010-12-03 15:38:48 -02:00
|
|
|
call update_shapes(pblock, du(:,:,:,:))
|
2008-12-18 12:18:36 -06:00
|
|
|
|
2011-04-26 11:50:57 -03:00
|
|
|
#endif /* SHAPE */
|
2010-12-01 10:53:21 -02:00
|
|
|
! update the solution for the fluid variables
|
|
|
|
!
|
|
|
|
pblock%u(1:nfl,:,:,:) = 0.5d0 * (pblock%u(1:nfl,:,:,:) &
|
2010-12-03 15:38:48 -02:00
|
|
|
+ u1(1:nfl,:,:,:) + dt * du(1:nfl,:,:,:))
|
2010-12-01 10:53:21 -02:00
|
|
|
|
|
|
|
#ifdef MHD
|
|
|
|
! update the solution for the magnetic variables
|
|
|
|
!
|
|
|
|
pblock%u(ibx:ibz,:,:,:) = 0.5d0 * (pblock%u(ibx:ibz,:,:,:) &
|
2010-12-03 15:38:48 -02:00
|
|
|
+ u1(ibx:ibz,:,:,:) + dt * du(ibx:ibz,:,:,:))
|
2010-12-01 10:53:21 -02:00
|
|
|
|
|
|
|
#ifdef GLM
|
|
|
|
! update the solution for the scalar potential Psi
|
2008-12-08 16:21:59 -06:00
|
|
|
!
|
2010-12-01 10:53:21 -02:00
|
|
|
pblock%u(iph,:,:,:) = 0.5d0 * (pblock%u(iph,:,:,:) &
|
2010-12-03 15:38:48 -02:00
|
|
|
+ u1(iph,:,:,:) + ch2 * dt * du(iph,:,:,:))
|
2010-12-01 11:20:25 -02:00
|
|
|
|
|
|
|
! evolve Psi due to the source term
|
|
|
|
!
|
|
|
|
decay = exp(- alpha_p * cmax * dt / dx_min)
|
|
|
|
pblock%u(iph,:,:,:) = decay * pblock%u(iph,:,:,:)
|
2011-04-26 11:50:57 -03:00
|
|
|
|
2010-12-01 10:53:21 -02:00
|
|
|
#endif /* GLM */
|
|
|
|
#endif /* MHD */
|
2011-04-26 10:36:16 -03:00
|
|
|
#ifdef FORCE
|
|
|
|
! obtain the forcing terms in real space
|
|
|
|
!
|
|
|
|
call real_forcing(pblock%meta%level, pblock%meta%xmin, pblock%meta%ymin &
|
|
|
|
, pblock%meta%zmin, f(:,:,:,:))
|
|
|
|
|
|
|
|
! update momenta due to the forcing terms
|
|
|
|
!
|
|
|
|
pblock%u(imx,:,:,:) = pblock%u(imx,:,:,:) + pblock%u(idn,:,:,:) * f(1,:,:,:)
|
|
|
|
pblock%u(imy,:,:,:) = pblock%u(imy,:,:,:) + pblock%u(idn,:,:,:) * f(2,:,:,:)
|
|
|
|
pblock%u(imz,:,:,:) = pblock%u(imz,:,:,:) + pblock%u(idn,:,:,:) * f(3,:,:,:)
|
|
|
|
|
|
|
|
#endif /* FORCE */
|
2009-10-28 00:12:18 -02:00
|
|
|
!
|
2008-12-08 21:07:10 -06:00
|
|
|
!-------------------------------------------------------------------------------
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
|
|
|
end subroutine evolve_rk2
|
2008-12-08 16:21:59 -06:00
|
|
|
#endif /* RK2 */
|
2010-12-03 15:38:48 -02:00
|
|
|
#ifdef RK3
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
! evolve_rk3: subroutine evolves the current block using the 3rd order
|
|
|
|
! Runge-Kutta method
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
subroutine evolve_rk3(pblock)
|
|
|
|
|
|
|
|
use blocks , only : block_data
|
|
|
|
use config , only : im, jm, km
|
2010-12-09 17:54:59 -02:00
|
|
|
#ifdef FORCE
|
|
|
|
use forcing , only : real_forcing
|
|
|
|
#endif /* FORCE */
|
2010-12-06 16:20:49 -02:00
|
|
|
use mesh , only : adxi, adyi, adzi
|
2010-12-03 15:38:48 -02:00
|
|
|
#ifdef SHAPE
|
|
|
|
use problem , only : update_shapes
|
|
|
|
#endif /* SHAPE */
|
|
|
|
use scheme , only : update, cmax
|
|
|
|
use variables, only : nqt, nfl
|
|
|
|
#ifdef MHD
|
|
|
|
use variables, only : ibx, ibz
|
|
|
|
#ifdef GLM
|
|
|
|
use config , only : alpha_p
|
|
|
|
use mesh , only : dx_min
|
|
|
|
use variables, only : iph
|
|
|
|
#endif /* GLM */
|
|
|
|
#endif /* MHD */
|
2010-12-09 17:54:59 -02:00
|
|
|
#ifdef FORCE
|
|
|
|
use variables, only : idn, imx, imy, imz
|
|
|
|
#endif /* FORCE */
|
2010-12-03 15:38:48 -02:00
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
! input arguments
|
|
|
|
!
|
|
|
|
type(block_data), intent(inout) :: pblock
|
|
|
|
|
|
|
|
! local variables
|
|
|
|
!
|
2010-12-06 16:20:49 -02:00
|
|
|
real :: dxi, dyi, dzi, ch2
|
2010-12-03 15:38:48 -02:00
|
|
|
#if defined MHD && defined GLM
|
2010-12-06 16:20:49 -02:00
|
|
|
real :: decay
|
2010-12-03 15:38:48 -02:00
|
|
|
#endif /* MHD & GLM */
|
|
|
|
|
|
|
|
! local arrays
|
|
|
|
!
|
|
|
|
real, dimension(nqt,im,jm,km) :: u1, du
|
2010-12-09 17:54:59 -02:00
|
|
|
#ifdef FORCE
|
|
|
|
real, dimension( 3,im,jm,km) :: f
|
|
|
|
#endif /* FORCE */
|
2010-12-03 15:38:48 -02:00
|
|
|
|
|
|
|
! parameters
|
|
|
|
!
|
|
|
|
real, parameter :: f4 = 1.0d0 / 4.0d0, f3 = 1.0d0 / 3.0d0
|
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
2010-12-06 16:20:49 -02:00
|
|
|
! prepare dxi, dyi, and dzi
|
|
|
|
!
|
|
|
|
dxi = adxi(pblock%meta%level)
|
|
|
|
dyi = adyi(pblock%meta%level)
|
|
|
|
dzi = adzi(pblock%meta%level)
|
|
|
|
|
2010-12-03 15:38:48 -02:00
|
|
|
!! 1st step of integration
|
|
|
|
!!
|
2010-12-06 16:20:49 -02:00
|
|
|
call update(pblock%u(:,:,:,:), du(:,:,:,:), dxi, dyi, dzi)
|
2010-12-03 15:38:48 -02:00
|
|
|
|
|
|
|
#ifdef SHAPE
|
|
|
|
! restrict update in a defined shape
|
|
|
|
!
|
|
|
|
call update_shapes(pblock, du(:,:,:,:))
|
|
|
|
#endif /* SHAPE */
|
|
|
|
|
|
|
|
! update the solution for the fluid variables
|
|
|
|
!
|
|
|
|
u1(1:nfl,:,:,:) = pblock%u(1:nfl,:,:,:) + dt * du(1:nfl,:,:,:)
|
|
|
|
|
|
|
|
#ifdef MHD
|
|
|
|
! update the solution for the magnetic variables
|
|
|
|
!
|
|
|
|
u1(ibx:ibz,:,:,:) = pblock%u(ibx:ibz,:,:,:) + dt * du(ibx:ibz,:,:,:)
|
|
|
|
|
|
|
|
#ifdef GLM
|
2011-03-06 23:37:51 -03:00
|
|
|
! calculate c_h^2
|
|
|
|
!
|
|
|
|
ch2 = cmax * cmax
|
|
|
|
|
2010-12-03 15:38:48 -02:00
|
|
|
! update the solution for the scalar potential Psi
|
|
|
|
!
|
|
|
|
u1(iph,:,:,:) = pblock%u(iph,:,:,:) + ch2 * dt * du(iph,:,:,:)
|
|
|
|
#endif /* GLM */
|
|
|
|
#endif /* MHD */
|
|
|
|
|
|
|
|
!! 2nd step of integration
|
|
|
|
!!
|
2010-12-06 16:20:49 -02:00
|
|
|
call update(u1(:,:,:,:), du(:,:,:,:), dxi, dyi, dzi)
|
2010-12-03 15:38:48 -02:00
|
|
|
|
|
|
|
#ifdef SHAPE
|
|
|
|
! restrict update in a defined shape
|
|
|
|
!
|
|
|
|
call update_shapes(pblock, du(:,:,:,:))
|
|
|
|
#endif /* SHAPE */
|
|
|
|
|
|
|
|
! update the solution for the fluid variables
|
|
|
|
!
|
|
|
|
u1(1:nfl,:,:,:) = f4 * (3.0d0 * pblock%u(1:nfl,:,:,:) &
|
|
|
|
+ u1(1:nfl,:,:,:) + dt * du(1:nfl,:,:,:))
|
|
|
|
|
|
|
|
#ifdef MHD
|
|
|
|
! update the solution for the magnetic variables
|
|
|
|
!
|
|
|
|
u1(ibx:ibz,:,:,:) = f4 * (3.0d0 * pblock%u(ibx:ibz,:,:,:) &
|
|
|
|
+ u1(ibx:ibz,:,:,:) + dt * du(ibx:ibz,:,:,:))
|
|
|
|
|
|
|
|
#ifdef GLM
|
|
|
|
! update the solution for the scalar potential Psi
|
|
|
|
!
|
|
|
|
u1(iph,:,:,:) = f4 * (3.0d0 * pblock%u(iph,:,:,:) &
|
|
|
|
+ u1(iph,:,:,:) + ch2 * dt * du(iph,:,:,:))
|
|
|
|
#endif /* GLM */
|
|
|
|
#endif /* MHD */
|
|
|
|
|
|
|
|
!! 3rd step of integration
|
|
|
|
!!
|
2010-12-06 16:20:49 -02:00
|
|
|
call update(u1(:,:,:,:), du(:,:,:,:), dxi, dyi, dzi)
|
2010-12-03 15:38:48 -02:00
|
|
|
|
|
|
|
#ifdef SHAPE
|
|
|
|
! restrict update in a defined shape
|
|
|
|
!
|
|
|
|
call update_shapes(pblock, du(:,:,:,:))
|
|
|
|
#endif /* SHAPE */
|
|
|
|
|
|
|
|
! update the solution for the fluid variables
|
|
|
|
!
|
|
|
|
pblock%u(1:nfl,:,:,:) = f3 * (pblock%u(1:nfl,:,:,:) &
|
|
|
|
+ 2.0d0 * (u1(1:nfl,:,:,:) + dt * du(1:nfl,:,:,:)))
|
|
|
|
|
|
|
|
#ifdef MHD
|
|
|
|
! update the solution for the magnetic variables
|
|
|
|
!
|
|
|
|
pblock%u(ibx:ibz,:,:,:) = f3 * (pblock%u(ibx:ibz,:,:,:) &
|
|
|
|
+ 2.0d0 * (u1(ibx:ibz,:,:,:) + dt * du(ibx:ibz,:,:,:)))
|
|
|
|
|
|
|
|
#ifdef GLM
|
|
|
|
! update the solution for the scalar potential Psi
|
|
|
|
!
|
|
|
|
pblock%u(iph,:,:,:) = f3 * (pblock%u(iph,:,:,:) &
|
|
|
|
+ 2.0d0 * (u1(iph,:,:,:) + ch2 * dt * du(iph,:,:,:)))
|
|
|
|
|
|
|
|
! evolve analytically Psi due to the source term
|
|
|
|
!
|
|
|
|
decay = exp(- alpha_p * cmax * dt / dx_min)
|
|
|
|
pblock%u(iph,:,:,:) = decay * pblock%u(iph,:,:,:)
|
|
|
|
#endif /* GLM */
|
|
|
|
#endif /* MHD */
|
2011-04-26 10:36:16 -03:00
|
|
|
#ifdef FORCE
|
|
|
|
! obtain the forcing terms in real space
|
|
|
|
!
|
|
|
|
call real_forcing(pblock%meta%level, pblock%meta%xmin, pblock%meta%ymin &
|
|
|
|
, pblock%meta%zmin, f(:,:,:,:))
|
|
|
|
|
|
|
|
! update momenta due to the forcing terms
|
|
|
|
!
|
|
|
|
pblock%u(imx,:,:,:) = pblock%u(imx,:,:,:) + pblock%u(idn,:,:,:) * f(1,:,:,:)
|
|
|
|
pblock%u(imy,:,:,:) = pblock%u(imy,:,:,:) + pblock%u(idn,:,:,:) * f(2,:,:,:)
|
|
|
|
pblock%u(imz,:,:,:) = pblock%u(imz,:,:,:) + pblock%u(idn,:,:,:) * f(3,:,:,:)
|
|
|
|
|
|
|
|
#endif /* FORCE */
|
2010-12-03 15:38:48 -02:00
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
end subroutine evolve_rk3
|
|
|
|
#endif /* RK3 */
|
2010-02-28 18:35:57 -03:00
|
|
|
!
|
2008-12-08 21:07:10 -06:00
|
|
|
!===============================================================================
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
|
|
|
end module
|