2010-10-13 03:32:10 -03:00
|
|
|
!!******************************************************************************
|
2008-12-07 18:57:08 -06:00
|
|
|
!!
|
2012-07-22 12:30:20 -03:00
|
|
|
!! This file is part of the AMUN source code, a program to perform
|
|
|
|
!! Newtonian or relativistic magnetohydrodynamical simulations on uniform or
|
|
|
|
!! adaptive mesh.
|
2008-12-07 18:57:08 -06:00
|
|
|
!!
|
2014-01-02 11:52:59 -02:00
|
|
|
!! Copyright (C) 2008-2014 Grzegorz Kowal <grzegorz@amuncode.org>
|
2008-12-07 18:57:08 -06:00
|
|
|
!!
|
2012-07-22 12:30:20 -03:00
|
|
|
!! This program is free software: you can redistribute it and/or modify
|
|
|
|
!! 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.
|
2008-12-07 18:57:08 -06:00
|
|
|
!!
|
2011-04-29 11:21:30 -03:00
|
|
|
!! This program 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
|
2012-07-22 12:30:20 -03:00
|
|
|
!! along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2008-12-07 18:57:08 -06:00
|
|
|
!!
|
2010-10-13 03:32:10 -03:00
|
|
|
!!******************************************************************************
|
2008-12-07 18:57:08 -06:00
|
|
|
!!
|
2012-07-28 11:47:14 -03:00
|
|
|
!! module: EVOLUTION
|
|
|
|
!!
|
2013-12-11 10:59:25 -02:00
|
|
|
!! This module provides an interface for temporal integration with
|
|
|
|
!! the stability handling. New integration methods can be added by
|
|
|
|
!! implementing more evolve_* subroutines.
|
2012-07-22 12:30:20 -03:00
|
|
|
!!
|
|
|
|
!!******************************************************************************
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
|
|
|
module evolution
|
|
|
|
|
2012-07-28 11:47:14 -03:00
|
|
|
! module variables are not implicit by default
|
|
|
|
!
|
2008-12-07 18:57:08 -06:00
|
|
|
implicit none
|
|
|
|
|
2013-12-11 10:59:25 -02:00
|
|
|
! pointer to the temporal integration subroutine
|
|
|
|
!
|
|
|
|
procedure(evolve_euler), pointer, save :: evolve => null()
|
|
|
|
|
2012-07-28 11:47:14 -03:00
|
|
|
! evolution parameters
|
|
|
|
!
|
2013-12-11 22:48:48 -02:00
|
|
|
real , save :: cfl = 0.5d+00
|
2012-07-28 11:47:14 -03:00
|
|
|
|
2013-12-12 15:36:55 -02:00
|
|
|
! coefficient controlling the decay of scalar potential ѱ
|
|
|
|
!
|
|
|
|
real , save :: alpha = 2.0d+00
|
|
|
|
real , save :: decay = 1.0d+00
|
|
|
|
|
2012-08-01 12:56:52 -03:00
|
|
|
! time variables
|
2012-07-28 11:47:14 -03:00
|
|
|
!
|
2014-01-08 17:34:15 -02:00
|
|
|
integer, save :: step = 0
|
|
|
|
real , save :: time = 0.0d+00
|
2013-12-11 22:48:48 -02:00
|
|
|
real , save :: dt = 1.0d+00
|
|
|
|
real , save :: dtn = 1.0d+00
|
2008-12-07 18:57:08 -06:00
|
|
|
|
2012-07-28 11:47:14 -03:00
|
|
|
! by default everything is private
|
|
|
|
!
|
|
|
|
private
|
|
|
|
|
|
|
|
! declare public subroutines
|
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
public :: initialize_evolution, finalize_evolution
|
2013-12-11 22:48:48 -02:00
|
|
|
public :: advance, new_time_step
|
2012-07-28 11:47:14 -03:00
|
|
|
|
|
|
|
! declare public variables
|
|
|
|
!
|
2014-01-08 17:34:15 -02:00
|
|
|
public :: cfl, step, time, dt, dtn
|
2012-07-28 11:47:14 -03:00
|
|
|
|
|
|
|
!- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
!
|
2008-12-07 18:57:08 -06:00
|
|
|
contains
|
|
|
|
!
|
2008-12-08 21:07:10 -06:00
|
|
|
!===============================================================================
|
2012-07-28 11:47:14 -03:00
|
|
|
!!
|
|
|
|
!!*** PUBLIC SUBROUTINES *****************************************************
|
|
|
|
!!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
!===============================================================================
|
|
|
|
!
|
2012-07-28 11:47:14 -03:00
|
|
|
! subroutine INITIALIZE_EVOLUTION:
|
|
|
|
! -------------------------------
|
|
|
|
!
|
2012-08-01 12:56:52 -03:00
|
|
|
! Subroutine initializes module EVOLUTION by setting its parameters.
|
2012-07-28 11:47:14 -03:00
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
! Arguments:
|
|
|
|
!
|
|
|
|
! verbose - a logical flag turning the information printing;
|
|
|
|
! iret - an integer flag for error return value;
|
2012-07-28 11:47:14 -03:00
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
subroutine initialize_evolution(verbose, iret)
|
2012-07-28 11:47:14 -03:00
|
|
|
|
2012-08-01 12:56:52 -03:00
|
|
|
! include external procedures
|
2012-07-28 11:47:14 -03:00
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
use parameters, only : get_parameter_string, get_parameter_real
|
2012-07-28 11:47:14 -03:00
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
!
|
|
|
|
implicit none
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
! subroutine arguments
|
|
|
|
!
|
|
|
|
logical, intent(in) :: verbose
|
|
|
|
integer, intent(inout) :: iret
|
|
|
|
|
|
|
|
! local variables
|
|
|
|
!
|
|
|
|
character(len=255) :: integration = "rk2"
|
|
|
|
character(len=255) :: name_int = ""
|
2012-07-28 11:47:14 -03:00
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
! get the integration method and the value of the CFL coefficient
|
2012-07-28 11:47:14 -03:00
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
call get_parameter_string("time_advance", integration)
|
|
|
|
call get_parameter_real ("cfl" , cfl )
|
2013-12-12 15:36:55 -02:00
|
|
|
call get_parameter_real ("alpha" , alpha )
|
2012-07-28 11:47:14 -03:00
|
|
|
|
2013-12-11 10:59:25 -02:00
|
|
|
! select the integration method, check the correctness of the integration
|
|
|
|
! parameters and adjust the CFL coefficient if necessary
|
2012-07-31 15:13:51 -03:00
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
select case(trim(integration))
|
|
|
|
|
|
|
|
case ("euler", "EULER")
|
|
|
|
|
|
|
|
name_int = "1st order Euler method"
|
|
|
|
evolve => evolve_euler
|
|
|
|
|
|
|
|
case ("rk2", "RK2")
|
|
|
|
|
|
|
|
name_int = "2nd order Runge-Kutta method"
|
|
|
|
evolve => evolve_rk2
|
|
|
|
|
|
|
|
case default
|
|
|
|
|
|
|
|
if (verbose) then
|
|
|
|
write (*,"(1x,a)") "The selected time advance method is not " // &
|
|
|
|
"implemented: " // trim(integration)
|
|
|
|
name_int = "2nd order Runge-Kutta method"
|
|
|
|
evolve => evolve_rk2
|
|
|
|
end if
|
|
|
|
|
|
|
|
end select
|
|
|
|
|
2013-12-12 15:36:55 -02:00
|
|
|
! calculate the decay factor for magnetic field divergence scalar source term
|
|
|
|
!
|
|
|
|
decay = exp(- alpha * cfl)
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
! print information about the Riemann solver
|
|
|
|
!
|
|
|
|
if (verbose) then
|
|
|
|
|
|
|
|
write (*,"(4x,a,1x,a)" ) "time advance =", trim(name_int)
|
|
|
|
|
|
|
|
end if
|
2012-07-31 15:13:51 -03:00
|
|
|
|
2012-07-28 11:47:14 -03:00
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
end subroutine initialize_evolution
|
|
|
|
!
|
|
|
|
!===============================================================================
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
! subroutine FINALIZE_EVOLUTION:
|
|
|
|
! -----------------------------
|
|
|
|
!
|
|
|
|
! Subroutine releases memory used by the module.
|
|
|
|
!
|
|
|
|
! Arguments:
|
|
|
|
!
|
|
|
|
! iret - an integer flag for error return value;
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
subroutine finalize_evolution(iret)
|
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
!
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
! subroutine arguments
|
|
|
|
!
|
|
|
|
integer, intent(inout) :: iret
|
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
2014-01-02 12:18:04 -02:00
|
|
|
nullify(evolve)
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
end subroutine finalize_evolution
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
2012-07-31 15:04:40 -03:00
|
|
|
! subroutine ADVANCE:
|
|
|
|
! ------------------
|
|
|
|
!
|
2012-08-01 12:56:52 -03:00
|
|
|
! Subroutine advances the solution by one time step using the selected time
|
|
|
|
! integration method.
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
2014-01-08 18:07:54 -02:00
|
|
|
! Arguments:
|
|
|
|
!
|
|
|
|
! dtnext - next time step;
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
2014-01-08 18:07:54 -02:00
|
|
|
subroutine advance(dtnext)
|
2012-07-31 15:04:40 -03:00
|
|
|
|
2012-08-01 12:56:52 -03:00
|
|
|
! include external procedures
|
|
|
|
!
|
2014-01-23 10:58:15 -02:00
|
|
|
use blocks , only : set_blocks_update
|
2012-08-01 12:56:52 -03:00
|
|
|
use boundaries , only : boundary_variables
|
|
|
|
use mesh , only : update_mesh
|
|
|
|
|
|
|
|
! include external variables
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
2012-08-01 12:56:52 -03:00
|
|
|
use coordinates , only : toplev
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
!
|
|
|
|
implicit none
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
|
|
! input variables
|
|
|
|
!
|
|
|
|
real, intent(in) :: dtnext
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
! find new time step
|
|
|
|
!
|
2014-01-08 18:07:54 -02:00
|
|
|
call new_time_step(dtnext)
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
! advance the solution using the selected method
|
|
|
|
!
|
|
|
|
call evolve()
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
|
|
! chec if we need to perform the refinement step
|
|
|
|
!
|
|
|
|
if (toplev > 1) then
|
|
|
|
|
2014-01-23 10:58:15 -02:00
|
|
|
! set all meta blocks to not be updated
|
|
|
|
!
|
|
|
|
call set_blocks_update(.false.)
|
|
|
|
|
2012-07-31 15:04:40 -03:00
|
|
|
! check refinement and refine
|
|
|
|
!
|
|
|
|
call update_mesh()
|
|
|
|
|
2012-07-31 16:38:16 -03:00
|
|
|
! update primitive variables
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
2014-01-23 10:58:15 -02:00
|
|
|
call update_variables()
|
|
|
|
|
2014-04-09 08:51:04 -03:00
|
|
|
! update boundaries
|
|
|
|
!
|
|
|
|
call boundary_variables()
|
|
|
|
|
2014-01-23 10:58:15 -02:00
|
|
|
! set all meta blocks to be updated
|
|
|
|
!
|
|
|
|
call set_blocks_update(.true.)
|
|
|
|
|
|
|
|
end if ! toplev > 1
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
end subroutine advance
|
|
|
|
!
|
|
|
|
!===============================================================================
|
2014-01-08 18:07:54 -02:00
|
|
|
!
|
|
|
|
! subroutine NEW_TIME_STEP:
|
|
|
|
! ------------------------
|
|
|
|
!
|
|
|
|
! Subroutine estimates the new time step from the maximum speed in the system
|
|
|
|
! and source term constraints.
|
|
|
|
!
|
|
|
|
! Arguments:
|
|
|
|
!
|
|
|
|
! dtnext - next time step;
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
subroutine new_time_step(dtnext)
|
|
|
|
|
|
|
|
! include external procedures
|
|
|
|
!
|
|
|
|
use equations , only : maxspeed, cmax, cmax2
|
|
|
|
#ifdef MPI
|
|
|
|
use mpitools , only : reduce_maximum_real, reduce_maximum_integer
|
|
|
|
#endif /* MPI */
|
|
|
|
|
|
|
|
! include external variables
|
|
|
|
!
|
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
use coordinates , only : adx, ady, adz
|
|
|
|
use coordinates , only : toplev
|
2014-05-29 12:04:55 -03:00
|
|
|
use sources , only : viscosity, resistivity
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
!
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
! input variables
|
|
|
|
!
|
|
|
|
real, intent(in) :: dtnext
|
|
|
|
|
|
|
|
! local pointers
|
|
|
|
!
|
|
|
|
type(block_data), pointer :: pblock
|
|
|
|
|
|
|
|
! local variables
|
|
|
|
!
|
|
|
|
integer :: iret
|
|
|
|
integer(kind=4) :: lev
|
|
|
|
real :: cm, dx_min
|
|
|
|
|
|
|
|
! local parameters
|
|
|
|
!
|
|
|
|
real, parameter :: eps = tiny(cmax)
|
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! reset the maximum speed, and the highest level
|
|
|
|
!
|
|
|
|
cmax = eps
|
|
|
|
lev = 1
|
|
|
|
|
|
|
|
! iterate over all data blocks in order to find the maximum speed among them
|
|
|
|
! and the highest level which is required to obtain the spatial step
|
|
|
|
!
|
|
|
|
pblock => list_data
|
|
|
|
do while (associated(pblock))
|
|
|
|
|
|
|
|
! find the maximum level occupied by blocks (can be smaller than toplev)
|
|
|
|
!
|
|
|
|
lev = max(lev, pblock%meta%level)
|
|
|
|
|
|
|
|
! obtain the maximum speed for the current block
|
|
|
|
!
|
|
|
|
cm = maxspeed(pblock%q(:,:,:,:))
|
|
|
|
|
|
|
|
! compare global and local maximum speeds
|
|
|
|
!
|
|
|
|
cmax = max(cmax, cm)
|
|
|
|
|
|
|
|
! assiociate the pointer with the next block
|
|
|
|
!
|
|
|
|
pblock => pblock%next
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
#ifdef MPI
|
|
|
|
! find maximum speed in the system from all processors
|
|
|
|
!
|
|
|
|
call reduce_maximum_real (cmax, iret)
|
|
|
|
call reduce_maximum_integer(lev , iret)
|
|
|
|
#endif /* MPI */
|
|
|
|
|
|
|
|
! calculate squared cmax
|
|
|
|
!
|
|
|
|
cmax2 = cmax * cmax
|
|
|
|
|
|
|
|
! find the smallest spatial step
|
|
|
|
!
|
|
|
|
#if NDIMS == 2
|
|
|
|
dx_min = min(adx(lev), ady(lev))
|
|
|
|
#endif /* NDIMS == 2 */
|
|
|
|
#if NDIMS == 3
|
|
|
|
dx_min = min(adx(lev), ady(lev), adz(lev))
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
|
|
|
! calcilate the new time step
|
|
|
|
!
|
2014-06-02 11:47:37 -03:00
|
|
|
dtn = dx_min / max(cmax &
|
|
|
|
+ 2.0d+00 * max(viscosity, resistivity) / dx_min, eps)
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
|
|
! calculate the new time step
|
|
|
|
!
|
|
|
|
dt = cfl * dtn
|
|
|
|
|
|
|
|
! round the time
|
|
|
|
!
|
|
|
|
if (dtnext > 0.0d+00) dt = min(dt, dtnext)
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
end subroutine new_time_step
|
|
|
|
!
|
|
|
|
!===============================================================================
|
2012-07-28 11:47:14 -03:00
|
|
|
!!
|
|
|
|
!!*** PRIVATE SUBROUTINES ****************************************************
|
|
|
|
!!
|
|
|
|
!===============================================================================
|
2010-12-01 10:39:18 -02:00
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
! subroutine EVOLVE_EULER:
|
|
|
|
! -----------------------
|
|
|
|
!
|
|
|
|
! Subroutine advances the solution by one time step using the 1st order
|
|
|
|
! Euler integration method.
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
subroutine evolve_euler()
|
|
|
|
|
|
|
|
! include external procedures
|
|
|
|
!
|
|
|
|
use boundaries , only : boundary_variables
|
2014-04-29 18:35:58 -03:00
|
|
|
use sources , only : update_sources
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
! include external variables
|
|
|
|
!
|
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
use coordinates , only : im, jm, km
|
2013-12-12 16:09:47 -02:00
|
|
|
use equations , only : nv, ibp
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
!
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
! local pointers
|
|
|
|
!
|
|
|
|
type(block_data), pointer :: pblock
|
|
|
|
|
|
|
|
! local arrays
|
|
|
|
!
|
|
|
|
real, dimension(nv,im,jm,km) :: du
|
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! update fluxes for the first step of the RK2 integration
|
|
|
|
!
|
|
|
|
call update_fluxes()
|
|
|
|
|
|
|
|
! update the solution using numerical fluxes stored in the data blocks
|
|
|
|
!
|
|
|
|
pblock => list_data
|
|
|
|
do while (associated(pblock))
|
|
|
|
|
|
|
|
! calculate variable increment for the current block
|
|
|
|
!
|
2014-05-27 16:29:53 -03:00
|
|
|
call update_increment(pblock, du(:,:,:,:))
|
2013-12-11 10:59:25 -02:00
|
|
|
|
2014-04-29 18:35:58 -03:00
|
|
|
! add source terms
|
|
|
|
!
|
|
|
|
call update_sources(pblock, du(:,:,:,:))
|
|
|
|
|
2013-12-11 10:59:25 -02:00
|
|
|
! update the solution for the fluid variables
|
|
|
|
!
|
2014-05-27 16:29:53 -03:00
|
|
|
pblock%u0(1:nv,:,:,:) = pblock%u0(1:nv,:,:,:) + dt * du(1:nv,:,:,:)
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
! update the conservative variable pointer
|
|
|
|
!
|
2013-12-12 15:36:55 -02:00
|
|
|
pblock%u => pblock%u0
|
|
|
|
|
|
|
|
! update ψ by its source term
|
|
|
|
!
|
|
|
|
if (ibp > 0) pblock%u(ibp,:,:,:) = decay * pblock%u(ibp,:,:,:)
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
! assign pointer to the next block
|
|
|
|
!
|
|
|
|
pblock => pblock%next
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
! update primitive variables
|
|
|
|
!
|
|
|
|
call update_variables()
|
|
|
|
|
2014-04-09 08:51:04 -03:00
|
|
|
! update boundaries
|
|
|
|
!
|
|
|
|
call boundary_variables()
|
|
|
|
|
2013-12-11 10:59:25 -02:00
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
end subroutine evolve_euler
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
! subroutine EVOLVE_RK2:
|
|
|
|
! ---------------------
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
|
|
|
! Subroutine advances the solution by one time step using the 2nd order
|
|
|
|
! Runge-Kutta time integration method.
|
|
|
|
!
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
subroutine evolve_rk2()
|
2012-07-31 15:04:40 -03:00
|
|
|
|
2012-08-01 12:56:52 -03:00
|
|
|
! include external procedures
|
|
|
|
!
|
|
|
|
use boundaries , only : boundary_variables
|
2014-04-29 18:35:58 -03:00
|
|
|
use sources , only : update_sources
|
2012-08-01 12:56:52 -03:00
|
|
|
|
|
|
|
! include external variables
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
2012-08-01 12:56:52 -03:00
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
use coordinates , only : im, jm, km
|
2013-12-12 15:36:55 -02:00
|
|
|
use equations , only : nv, ibp
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
!
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
! local pointers
|
|
|
|
!
|
|
|
|
type(block_data), pointer :: pblock
|
|
|
|
|
|
|
|
! local arrays
|
|
|
|
!
|
2013-12-10 21:36:35 -02:00
|
|
|
real, dimension(nv,im,jm,km) :: du
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
2012-07-31 16:02:59 -03:00
|
|
|
! update fluxes for the first step of the RK2 integration
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
2012-07-31 16:02:59 -03:00
|
|
|
call update_fluxes()
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
|
|
! update the solution using numerical fluxes stored in the data blocks
|
|
|
|
!
|
|
|
|
pblock => list_data
|
|
|
|
do while (associated(pblock))
|
|
|
|
|
2012-07-31 16:23:20 -03:00
|
|
|
! calculate variable increment for the current block
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
2014-05-27 16:29:53 -03:00
|
|
|
call update_increment(pblock, du(:,:,:,:))
|
2012-07-31 15:04:40 -03:00
|
|
|
|
2014-04-29 18:35:58 -03:00
|
|
|
! add source terms
|
|
|
|
!
|
|
|
|
call update_sources(pblock, du(:,:,:,:))
|
|
|
|
|
2012-07-31 15:04:40 -03:00
|
|
|
! update the solution for the fluid variables
|
|
|
|
!
|
2014-05-27 16:29:53 -03:00
|
|
|
pblock%u1(1:nv,:,:,:) = pblock%u0(1:nv,:,:,:) + dt * du(1:nv,:,:,:)
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
|
|
! update the conservative variable pointer
|
|
|
|
!
|
|
|
|
pblock%u => pblock%u1
|
|
|
|
|
|
|
|
! assign pointer to the next block
|
|
|
|
!
|
|
|
|
pblock => pblock%next
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
2012-07-31 16:38:16 -03:00
|
|
|
! update primitive variables
|
|
|
|
!
|
|
|
|
call update_variables()
|
|
|
|
|
2014-04-09 08:51:04 -03:00
|
|
|
! update boundaries
|
|
|
|
!
|
|
|
|
call boundary_variables()
|
|
|
|
|
2012-07-31 16:02:59 -03:00
|
|
|
! update fluxes for the second step of the RK2 integration
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
2012-07-31 16:02:59 -03:00
|
|
|
call update_fluxes()
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
|
|
! update the solution using numerical fluxes stored in the data blocks
|
|
|
|
!
|
|
|
|
pblock => list_data
|
|
|
|
do while (associated(pblock))
|
|
|
|
|
2012-07-31 16:23:20 -03:00
|
|
|
! calculate variable increment for the current block
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
2014-05-27 16:29:53 -03:00
|
|
|
call update_increment(pblock, du(:,:,:,:))
|
2012-07-31 15:04:40 -03:00
|
|
|
|
2014-04-29 18:35:58 -03:00
|
|
|
! add source terms
|
|
|
|
!
|
|
|
|
call update_sources(pblock, du(:,:,:,:))
|
|
|
|
|
2012-07-31 15:04:40 -03:00
|
|
|
! update the solution for the fluid variables
|
|
|
|
!
|
2014-05-27 16:29:53 -03:00
|
|
|
pblock%u0(1:nv,:,:,:) = 0.5d+00 * (pblock%u0(1:nv,:,:,:) &
|
|
|
|
+ pblock%u1(1:nv,:,:,:) + dt * du(1:nv,:,:,:))
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
|
|
! update the conservative variable pointer
|
|
|
|
!
|
|
|
|
pblock%u => pblock%u0
|
|
|
|
|
2013-12-12 15:36:55 -02:00
|
|
|
! update ψ by its source term
|
|
|
|
!
|
|
|
|
if (ibp > 0) pblock%u(ibp,:,:,:) = decay * pblock%u(ibp,:,:,:)
|
|
|
|
|
2012-07-31 15:04:40 -03:00
|
|
|
! assign pointer to the next block
|
|
|
|
!
|
|
|
|
pblock => pblock%next
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
2013-12-11 10:59:25 -02:00
|
|
|
! update primitive variables
|
|
|
|
!
|
|
|
|
call update_variables()
|
|
|
|
|
2014-04-09 08:51:04 -03:00
|
|
|
! update boundaries
|
|
|
|
!
|
|
|
|
call boundary_variables()
|
|
|
|
|
2012-07-31 15:04:40 -03:00
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
end subroutine evolve_rk2
|
2012-07-31 15:04:40 -03:00
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
2012-07-31 16:02:59 -03:00
|
|
|
! subroutine UPDATE_FLUXES:
|
|
|
|
! ------------------------
|
|
|
|
!
|
|
|
|
! Subroutine iterates over all data blocks and calculates the numerical
|
|
|
|
! fluxes for each block. After the fluxes are updated, they are corrected
|
|
|
|
! for blocks which have neighbours at higher refinement level.
|
|
|
|
!
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
subroutine update_fluxes()
|
|
|
|
|
2012-08-01 12:56:52 -03:00
|
|
|
! include external procedures
|
2012-07-31 16:02:59 -03:00
|
|
|
!
|
2012-08-01 17:41:56 -03:00
|
|
|
use boundaries , only : boundary_fluxes
|
2012-08-01 16:38:10 -03:00
|
|
|
use schemes , only : update_flux
|
2012-08-01 12:56:52 -03:00
|
|
|
|
|
|
|
! include external variables
|
|
|
|
!
|
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
use coordinates , only : adx, ady, adz
|
2012-07-31 16:02:59 -03:00
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
!
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
! local pointers
|
|
|
|
!
|
2012-07-31 16:23:20 -03:00
|
|
|
type(block_data), pointer :: pblock
|
2012-07-31 16:02:59 -03:00
|
|
|
|
|
|
|
! local vectors
|
|
|
|
!
|
2012-07-31 16:23:20 -03:00
|
|
|
real, dimension(3) :: dx
|
|
|
|
|
|
|
|
! local variables
|
|
|
|
!
|
|
|
|
integer :: n
|
2012-07-31 16:02:59 -03:00
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! iterate over all data blocks
|
|
|
|
!
|
|
|
|
pblock => list_data
|
|
|
|
do while (associated(pblock))
|
|
|
|
|
|
|
|
! obtain dx, dy, and dz for the current block
|
|
|
|
!
|
|
|
|
dx(1) = adx(pblock%meta%level)
|
|
|
|
dx(2) = ady(pblock%meta%level)
|
|
|
|
dx(3) = adz(pblock%meta%level)
|
|
|
|
|
|
|
|
! update the flux for the current block
|
|
|
|
!
|
|
|
|
do n = 1, NDIMS
|
2012-07-31 16:49:14 -03:00
|
|
|
call update_flux(n, dx(n), pblock%q(:,:,:,:), pblock%f(n,:,:,:,:))
|
2012-07-31 16:02:59 -03:00
|
|
|
end do
|
|
|
|
|
|
|
|
! assign pointer to the next block
|
|
|
|
!
|
|
|
|
pblock => pblock%next
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
! correct the numerical fluxes of the blocks which have neighbours at higher
|
|
|
|
! level
|
|
|
|
!
|
2012-08-01 17:41:56 -03:00
|
|
|
call boundary_fluxes()
|
2012-07-31 16:02:59 -03:00
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
end subroutine update_fluxes
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
2014-05-27 16:29:53 -03:00
|
|
|
! subroutine UPDATE_INCREMENT:
|
|
|
|
! ---------------------------
|
|
|
|
!
|
|
|
|
! Subroutine calculate the conservative variable increment from the fluxes.
|
|
|
|
!
|
|
|
|
! Arguments:
|
|
|
|
!
|
|
|
|
! dh - the ratio of the time step to the spatial step;
|
|
|
|
! f - the array of numerical fluxes;
|
|
|
|
! du - the array of variable increment;
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
subroutine update_increment(pdata, du)
|
|
|
|
|
|
|
|
! include external variables
|
|
|
|
!
|
|
|
|
use blocks , only : block_data
|
|
|
|
use coordinates , only : im, jm, km, ibl, jbl, kbl, ieu, jeu, keu
|
|
|
|
use coordinates , only : adxi, adyi, adzi
|
|
|
|
use equations , only : nv
|
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
!
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
! subroutine arguments
|
|
|
|
!
|
|
|
|
type(block_data), pointer , intent(inout) :: pdata
|
|
|
|
real(kind=8), dimension(nv,im,jm,km), intent(inout) :: du
|
|
|
|
|
|
|
|
! local variables
|
|
|
|
!
|
|
|
|
integer :: i , j , k
|
|
|
|
real(kind=8) :: dxi, dyi, dzi
|
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! reset the increment array du
|
|
|
|
!
|
|
|
|
du(:,:,:,:) = 0.0d+00
|
|
|
|
|
|
|
|
! prepare coordinate intervals
|
|
|
|
!
|
|
|
|
dxi = adxi(pdata%meta%level)
|
|
|
|
dyi = adyi(pdata%meta%level)
|
|
|
|
#if NDIMS == 3
|
|
|
|
dzi = adzi(pdata%meta%level)
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
|
|
|
! perform update along the X direction
|
|
|
|
!
|
|
|
|
do i = ibl, ieu
|
|
|
|
du(:,i,:,:) = du(:,i,:,:) &
|
|
|
|
- dxi * (pdata%f(1,:,i,:,:) - pdata%f(1,:,i-1,:,:))
|
|
|
|
end do
|
|
|
|
|
|
|
|
! perform update along the Y direction
|
|
|
|
!
|
|
|
|
do j = jbl, jeu
|
|
|
|
du(:,:,j,:) = du(:,:,j,:) &
|
|
|
|
- dyi * (pdata%f(2,:,:,j,:) - pdata%f(2,:,:,j-1,:))
|
|
|
|
end do
|
|
|
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
! perform update along the Z direction
|
|
|
|
!
|
|
|
|
do k = kbl, keu
|
|
|
|
du(:,:,:,k) = du(:,:,:,k) &
|
|
|
|
- dzi * (pdata%f(3,:,:,:,k) - pdata%f(3,:,:,:,k-1))
|
|
|
|
end do
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
end subroutine update_increment
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
2012-07-31 16:38:16 -03:00
|
|
|
! subroutine UPDATE_VARIABLES:
|
|
|
|
! ---------------------------
|
|
|
|
!
|
|
|
|
! Subroutine iterates over all data blocks and converts the conservative
|
|
|
|
! variables to their primitive representation.
|
|
|
|
!
|
|
|
|
!
|
|
|
|
!===============================================================================
|
|
|
|
!
|
|
|
|
subroutine update_variables()
|
|
|
|
|
2012-08-01 12:56:52 -03:00
|
|
|
! include external procedures
|
|
|
|
!
|
|
|
|
use equations , only : update_primitive_variables
|
2014-02-07 12:12:27 -02:00
|
|
|
use shapes , only : update_shapes
|
2012-08-01 12:56:52 -03:00
|
|
|
|
|
|
|
! include external variables
|
2012-07-31 16:38:16 -03:00
|
|
|
!
|
2014-01-23 10:56:29 -02:00
|
|
|
use blocks , only : block_meta, list_meta
|
2012-08-01 12:56:52 -03:00
|
|
|
use blocks , only : block_data, list_data
|
2012-07-31 16:38:16 -03:00
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
!
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
! local pointers
|
|
|
|
!
|
2014-01-23 10:56:29 -02:00
|
|
|
type(block_meta), pointer :: pmeta
|
|
|
|
type(block_data), pointer :: pdata
|
2012-07-31 16:38:16 -03:00
|
|
|
!
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
2014-01-23 10:56:29 -02:00
|
|
|
! associate the pointer with the first block on the data block list
|
|
|
|
!
|
|
|
|
pdata => list_data
|
|
|
|
|
2012-07-31 16:38:16 -03:00
|
|
|
! iterate over all data blocks
|
|
|
|
!
|
2014-01-23 10:56:29 -02:00
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
! associate pmeta with the corresponding meta block
|
|
|
|
!
|
|
|
|
pmeta => pdata%meta
|
2012-07-31 16:38:16 -03:00
|
|
|
|
2014-02-07 12:12:27 -02:00
|
|
|
! convert conserved variables to primitive ones for the current block and
|
|
|
|
! update shapes if necessary
|
2012-07-31 16:38:16 -03:00
|
|
|
!
|
2014-02-07 12:12:27 -02:00
|
|
|
if (pmeta%update) then
|
|
|
|
call update_primitive_variables(pdata%u, pdata%q)
|
|
|
|
call update_shapes(pdata)
|
|
|
|
end if
|
2012-07-31 16:38:16 -03:00
|
|
|
|
|
|
|
! assign pointer to the next block
|
|
|
|
!
|
2014-01-23 10:56:29 -02:00
|
|
|
pdata => pdata%next
|
2012-07-31 16:38:16 -03:00
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
end subroutine update_variables
|
2011-05-19 18:35:36 -03:00
|
|
|
|
2008-12-08 21:07:10 -06:00
|
|
|
!===============================================================================
|
2008-12-07 18:57:08 -06:00
|
|
|
!
|
2012-08-01 16:38:10 -03:00
|
|
|
end module evolution
|