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
|
|
|
|
!!
|
2021-02-04 17:35:04 -03:00
|
|
|
|
!! Copyright (C) 2008-2021 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
|
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
! import external subroutines
|
|
|
|
|
!
|
|
|
|
|
use timers, only : set_timer, start_timer, stop_timer
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
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
|
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
! timer indices
|
|
|
|
|
!
|
2015-01-09 13:38:18 -02:00
|
|
|
|
integer , save :: imi, ima, imt, imu, imf, iui, imv
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2018-08-29 23:25:11 -03:00
|
|
|
|
! interfaces for procedure pointers
|
|
|
|
|
!
|
|
|
|
|
abstract interface
|
|
|
|
|
subroutine evolve_iface()
|
|
|
|
|
end subroutine
|
2021-10-15 13:51:25 -03:00
|
|
|
|
subroutine update_errors_iface(n, m)
|
|
|
|
|
integer, intent(in) :: n, m
|
|
|
|
|
end subroutine
|
2018-08-29 23:25:11 -03:00
|
|
|
|
end interface
|
|
|
|
|
|
2013-12-11 10:59:25 -02:00
|
|
|
|
! pointer to the temporal integration subroutine
|
|
|
|
|
!
|
2018-08-29 23:25:11 -03:00
|
|
|
|
procedure(evolve_iface), pointer, save :: evolve => null()
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
2021-10-15 13:51:25 -03:00
|
|
|
|
! pointer to the error update subroutine
|
|
|
|
|
!
|
|
|
|
|
procedure(update_errors_iface), pointer, save :: update_errors => null()
|
|
|
|
|
|
2012-07-28 11:47:14 -03:00
|
|
|
|
! evolution parameters
|
|
|
|
|
!
|
2021-07-19 12:58:57 -03:00
|
|
|
|
logical , save :: error_control = .false.
|
2021-07-10 12:24:20 -03:00
|
|
|
|
character(len=255), save :: name_int = ""
|
2021-10-15 13:51:25 -03:00
|
|
|
|
character(len=255), save :: name_norm = ""
|
2021-07-10 12:24:20 -03:00
|
|
|
|
integer , save :: stages = 2
|
|
|
|
|
integer , save :: registers = 1
|
|
|
|
|
real(kind=8) , save :: cfl = 5.0d-01
|
2012-07-28 11:47:14 -03:00
|
|
|
|
|
2020-08-19 18:38:25 -03:00
|
|
|
|
! coefficients controlling the decay of scalar potential ѱ
|
2013-12-12 15:36:55 -02:00
|
|
|
|
!
|
2020-08-19 21:34:40 -03:00
|
|
|
|
real(kind=8) , save :: glm_alpha = 5.0d-01
|
2013-12-12 15:36:55 -02:00
|
|
|
|
|
2012-08-01 12:56:52 -03:00
|
|
|
|
! time variables
|
2012-07-28 11:47:14 -03:00
|
|
|
|
!
|
2019-01-30 14:45:07 -02:00
|
|
|
|
integer , save :: step = 0
|
|
|
|
|
real(kind=8) , save :: time = 0.0d+00
|
|
|
|
|
real(kind=8) , save :: dt = 1.0d+00
|
|
|
|
|
real(kind=8) , save :: dtn = 1.0d+00
|
2021-08-17 11:23:36 -03:00
|
|
|
|
real(kind=8) , save :: dth = 1.0d+00
|
2020-08-28 21:41:04 -03:00
|
|
|
|
real(kind=8) , save :: dte = 0.0d+00
|
2008-12-07 18:57:08 -06:00
|
|
|
|
|
2020-09-16 06:40:50 -03:00
|
|
|
|
! the absolute and relative tolerances, limiting factors, the maximum error,
|
|
|
|
|
! the maximum number of passes for the adaptive step,
|
|
|
|
|
! the total number of integration iterations, the number of rejected iterations
|
2020-08-31 22:29:40 -03:00
|
|
|
|
!
|
2020-09-01 16:38:11 -03:00
|
|
|
|
real(kind=8) , save :: atol = 1.0d-04
|
|
|
|
|
real(kind=8) , save :: rtol = 1.0d-04
|
2020-09-15 22:59:20 -03:00
|
|
|
|
real(kind=8) , save :: fac = 9.0d-01
|
|
|
|
|
real(kind=8) , save :: facmin = 1.0d-01
|
|
|
|
|
real(kind=8) , save :: facmax = 5.0d+00
|
2021-10-15 15:29:42 -03:00
|
|
|
|
real(kind=8) , save :: errtol = 1.0d+00
|
2021-10-15 12:15:14 -03:00
|
|
|
|
real(kind=8) , save :: chi = 1.0d+00
|
2020-09-01 16:38:11 -03:00
|
|
|
|
integer , save :: mrej = 5
|
|
|
|
|
integer , save :: niterations = 0
|
|
|
|
|
integer , save :: nrejections = 0
|
|
|
|
|
|
|
|
|
|
! errors in three recent steps
|
|
|
|
|
!
|
2021-10-15 12:15:14 -03:00
|
|
|
|
real(kind=8), dimension(3), save :: betas, errs
|
2020-08-31 22:29:40 -03:00
|
|
|
|
|
2021-09-20 08:44:38 -03:00
|
|
|
|
! GLM variables
|
|
|
|
|
!
|
|
|
|
|
real(kind=8), dimension(:), allocatable, save :: adecay, aglm
|
|
|
|
|
|
2012-07-28 11:47:14 -03:00
|
|
|
|
! by default everything is private
|
|
|
|
|
!
|
|
|
|
|
private
|
|
|
|
|
|
|
|
|
|
! declare public subroutines
|
|
|
|
|
!
|
2019-01-30 14:45:07 -02:00
|
|
|
|
public :: initialize_evolution, finalize_evolution, print_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
|
|
|
|
|
!
|
2021-08-17 11:23:36 -03:00
|
|
|
|
public :: step, time, dt, dtn, dth, dte, cfl, glm_alpha, registers
|
2021-10-15 15:29:42 -03:00
|
|
|
|
public :: atol, rtol, mrej, niterations, nrejections, errs, errtol
|
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;
|
2019-02-08 09:28:44 -02:00
|
|
|
|
! status - an integer flag for error return value;
|
2012-07-28 11:47:14 -03:00
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2019-02-08 09:28:44 -02:00
|
|
|
|
subroutine initialize_evolution(verbose, status)
|
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
|
|
|
|
!
|
2021-09-20 08:44:38 -03:00
|
|
|
|
use coordinates, only : toplev, adx, ady, adz
|
|
|
|
|
use parameters , only : get_parameter
|
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
|
|
|
|
|
!
|
2019-02-08 09:28:44 -02:00
|
|
|
|
logical, intent(in) :: verbose
|
|
|
|
|
integer, intent(out) :: status
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
|
|
! local variables
|
|
|
|
|
!
|
2021-10-15 13:51:25 -03:00
|
|
|
|
character(len=255) :: integration = "rk2", error_norm = "l2"
|
2019-02-08 12:03:10 -02:00
|
|
|
|
integer :: n
|
2019-02-08 09:28:44 -02:00
|
|
|
|
|
|
|
|
|
! local parameters
|
|
|
|
|
!
|
|
|
|
|
character(len=*), parameter :: loc = 'EVOLUTION::initialize_evolution()'
|
2012-07-28 11:47:14 -03:00
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
! set timer descriptions
|
|
|
|
|
!
|
|
|
|
|
call set_timer('evolution:: initialization' , imi)
|
|
|
|
|
call set_timer('evolution:: solution advance', ima)
|
|
|
|
|
call set_timer('evolution:: new time step' , imt)
|
|
|
|
|
call set_timer('evolution:: solution update' , imu)
|
|
|
|
|
call set_timer('evolution:: flux update' , imf)
|
2015-01-09 13:38:18 -02:00
|
|
|
|
call set_timer('evolution:: increment update', iui)
|
2014-09-14 20:38:53 -03:00
|
|
|
|
call set_timer('evolution:: variable update' , imv)
|
|
|
|
|
|
|
|
|
|
! start accounting time for module initialization/finalization
|
|
|
|
|
!
|
|
|
|
|
call start_timer(imi)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
! reset the status flag
|
|
|
|
|
!
|
|
|
|
|
status = 0
|
|
|
|
|
|
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
|
|
|
|
!
|
2019-01-28 21:24:53 -02:00
|
|
|
|
call get_parameter("time_advance", integration)
|
|
|
|
|
call get_parameter("stages" , stages )
|
|
|
|
|
call get_parameter("cfl" , cfl )
|
2020-08-19 18:38:25 -03:00
|
|
|
|
call get_parameter("glm_alpha" , glm_alpha )
|
2012-07-28 11:47:14 -03:00
|
|
|
|
|
2020-09-01 16:38:11 -03:00
|
|
|
|
! get the absolute and relative tolerances, the maximum number of passes for
|
2020-09-15 22:59:20 -03:00
|
|
|
|
! the adaptive step, and limiting factors
|
2020-08-31 22:29:40 -03:00
|
|
|
|
!
|
2020-09-01 16:38:11 -03:00
|
|
|
|
call get_parameter("absolute_tolerance", atol)
|
|
|
|
|
call get_parameter("relative_tolerance", rtol)
|
|
|
|
|
call get_parameter("maximum_rejections", mrej)
|
2021-10-15 12:15:14 -03:00
|
|
|
|
call get_parameter("chi" , chi)
|
2020-09-15 22:59:20 -03:00
|
|
|
|
call get_parameter("factor" , fac )
|
|
|
|
|
call get_parameter("minimum_factor" , facmin)
|
|
|
|
|
call get_parameter("maximum_factor" , facmax)
|
2020-08-31 22:29:40 -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))
|
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
case ("euler", "EULER", "rk1", "RK1")
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
2021-07-10 12:24:20 -03:00
|
|
|
|
evolve => evolve_euler
|
|
|
|
|
registers = 1
|
|
|
|
|
name_int = "1st order Euler"
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
|
|
case ("rk2", "RK2")
|
|
|
|
|
|
2021-07-10 12:24:20 -03:00
|
|
|
|
evolve => evolve_rk2
|
|
|
|
|
registers = 2
|
|
|
|
|
name_int = "2nd order Runge-Kutta"
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
2014-08-26 13:25:31 -03:00
|
|
|
|
case ("ssprk(m,2)", "SSPRK(m,2)")
|
|
|
|
|
|
2021-07-19 12:58:57 -03:00
|
|
|
|
error_control = .true.
|
2021-07-10 12:24:20 -03:00
|
|
|
|
evolve => evolve_ssprk2_m
|
|
|
|
|
registers = 3
|
|
|
|
|
stages = max(2, min(9, stages))
|
|
|
|
|
cfl = (stages - 1) * cfl
|
2021-07-19 13:03:40 -03:00
|
|
|
|
write(name_int, "('Optimal 2nd order SSPRK(',i0,',2) with error control')") stages
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2014-08-19 20:50:49 -03:00
|
|
|
|
case ("rk3", "RK3")
|
|
|
|
|
|
2021-07-10 12:24:20 -03:00
|
|
|
|
evolve => evolve_rk3
|
|
|
|
|
registers = 2
|
|
|
|
|
name_int = "3rd order Runge-Kutta"
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
case ("rk3.4", "RK3.4", "ssprk(4,3)", "SSPRK(4,3)")
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2021-07-10 12:24:20 -03:00
|
|
|
|
evolve => evolve_ssprk34
|
|
|
|
|
registers = 2
|
|
|
|
|
cfl = 2.0d+00 * cfl
|
|
|
|
|
name_int = "3rd order SSPRK(4,3)"
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
case ("rk3.5", "RK3.5", "ssprk(5,3)", "SSPRK(5,3)")
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2021-07-10 12:24:20 -03:00
|
|
|
|
evolve => evolve_ssprk35
|
|
|
|
|
registers = 2
|
|
|
|
|
cfl = 2.65062919143939d+00 * cfl
|
|
|
|
|
name_int = "3rd order SSPRK(5,3)"
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2021-10-15 12:15:14 -03:00
|
|
|
|
case ("SSPRK3(2)4", "SSP3(2)4", "ssprk3(2)4", "ssp3(2)4")
|
|
|
|
|
|
|
|
|
|
error_control = .true.
|
|
|
|
|
evolve => evolve_ssp324
|
|
|
|
|
registers = 3
|
|
|
|
|
stages = 4
|
|
|
|
|
cfl = 2.0d+00 * cfl
|
|
|
|
|
name_int = "3ʳᵈ-order 4-step embedded SSP3(2)4 method"
|
|
|
|
|
|
|
|
|
|
betas(:) = [ 5.5d-01, -2.7d-01, 5.0d-02 ]
|
|
|
|
|
|
|
|
|
|
call get_parameter("beta(1)", betas(1))
|
|
|
|
|
call get_parameter("beta(2)", betas(2))
|
|
|
|
|
call get_parameter("beta(3)", betas(3))
|
|
|
|
|
|
|
|
|
|
betas(:) = - betas(:) / 3.0d+00
|
|
|
|
|
|
2019-02-08 12:03:10 -02:00
|
|
|
|
case ("rk3.m", "ssprk(m,3)", "SSPRK(m,3)")
|
|
|
|
|
|
2021-07-19 12:58:57 -03:00
|
|
|
|
error_control = .true.
|
2021-07-10 12:24:20 -03:00
|
|
|
|
evolve => evolve_ssprk3_m
|
|
|
|
|
registers = 3
|
2019-02-08 12:03:10 -02:00
|
|
|
|
n = 2
|
|
|
|
|
do while(n**2 <= stages)
|
|
|
|
|
n = n + 1
|
|
|
|
|
end do
|
|
|
|
|
n = n - 1
|
2021-07-10 12:24:20 -03:00
|
|
|
|
stages = max(4, n**2)
|
|
|
|
|
cfl = (n - 1) * n * cfl
|
2021-07-19 13:03:40 -03:00
|
|
|
|
write(name_int, "('Optimal 3rd order SSPRK(',i0,',3) with error control')") stages
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2019-02-08 08:48:32 -02:00
|
|
|
|
case ("rk4.10", "RK4.10", "ssprk(10,4)", "SSPRK(10,4)")
|
|
|
|
|
|
2021-07-10 12:24:20 -03:00
|
|
|
|
evolve => evolve_ssprk4_10
|
|
|
|
|
registers = 2
|
|
|
|
|
cfl = 6.0d+00 * cfl
|
|
|
|
|
name_int = "Optimal 4th order SSPRK(10,4)"
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
2013-12-11 10:59:25 -02:00
|
|
|
|
case default
|
|
|
|
|
|
|
|
|
|
if (verbose) then
|
2019-02-08 09:28:44 -02:00
|
|
|
|
write(*,*)
|
|
|
|
|
write(*,"(1x,a)") "ERROR!"
|
|
|
|
|
write(*,"(1x,a)") "The selected time advance method is not " // &
|
|
|
|
|
"implemented: " // trim(integration)
|
|
|
|
|
write(*,"(1x,a)") "Available methods: 'euler' 'rk2', 'rk3'," // &
|
|
|
|
|
" 'ssprk(m,2)', 'ssprk(4,3)', 'ssprk(5,3)'," // &
|
2019-02-08 12:03:10 -02:00
|
|
|
|
" 'ssprk(m,3)', 'ssprk(10,4)'."
|
2013-12-11 10:59:25 -02:00
|
|
|
|
end if
|
2019-02-08 09:28:44 -02:00
|
|
|
|
status = 1
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
|
|
end select
|
|
|
|
|
|
2021-10-15 13:51:25 -03:00
|
|
|
|
! select error norm
|
|
|
|
|
!
|
|
|
|
|
call get_parameter("error_norm", error_norm)
|
|
|
|
|
|
|
|
|
|
select case(trim(error_norm))
|
|
|
|
|
case("max", "maximum", "infinity")
|
|
|
|
|
update_errors => update_errors_max
|
|
|
|
|
name_norm = "maximum norm"
|
|
|
|
|
case default
|
|
|
|
|
update_errors => update_errors_l2
|
|
|
|
|
name_norm = "L2-norm"
|
|
|
|
|
end select
|
|
|
|
|
|
2020-09-01 16:38:11 -03:00
|
|
|
|
! reset recent error history
|
|
|
|
|
!
|
|
|
|
|
errs = 1.0d+00
|
|
|
|
|
|
2021-09-20 08:44:38 -03:00
|
|
|
|
! GLM coefficients for all refinement levels
|
|
|
|
|
!
|
|
|
|
|
allocate(adecay(toplev), aglm(toplev))
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
|
aglm(:) = - glm_alpha / min(adx(:), ady(:), adz(:))
|
|
|
|
|
#else /* NDIMS == 3 */
|
|
|
|
|
aglm(:) = - glm_alpha / min(adx(:), ady(:))
|
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
! stop accounting time for module initialization/finalization
|
|
|
|
|
!
|
|
|
|
|
call stop_timer(imi)
|
|
|
|
|
#endif /* PROFILE */
|
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:
|
|
|
|
|
!
|
2019-02-08 09:28:44 -02:00
|
|
|
|
! status - an integer flag for error return value;
|
2013-12-11 10:59:25 -02:00
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2020-09-01 16:38:11 -03:00
|
|
|
|
subroutine finalize_evolution(verbose, status)
|
2019-02-08 09:28:44 -02:00
|
|
|
|
|
|
|
|
|
! include external procedures
|
|
|
|
|
!
|
2020-09-01 16:38:11 -03:00
|
|
|
|
use helpers , only : print_section, print_parameter
|
2019-02-08 09:28:44 -02:00
|
|
|
|
use iso_fortran_env, only : error_unit
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
|
!
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
! subroutine arguments
|
|
|
|
|
!
|
2020-09-01 16:38:11 -03:00
|
|
|
|
logical, intent(in) :: verbose
|
2019-02-08 09:28:44 -02:00
|
|
|
|
integer, intent(out) :: status
|
|
|
|
|
|
|
|
|
|
! local parameters
|
|
|
|
|
!
|
|
|
|
|
character(len=*), parameter :: loc = 'EVOLUTION::finalize_evolution()'
|
2013-12-11 10:59:25 -02:00
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
2014-09-14 20:38:53 -03:00
|
|
|
|
!
|
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
! start accounting time for module initialization/finalization
|
|
|
|
|
!
|
|
|
|
|
call start_timer(imi)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2021-09-20 08:44:38 -03:00
|
|
|
|
if (allocated(adecay)) deallocate(adecay)
|
|
|
|
|
if (allocated(aglm)) deallocate(aglm)
|
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
! reset the status flag
|
|
|
|
|
!
|
|
|
|
|
status = 0
|
|
|
|
|
|
2021-10-15 13:51:25 -03:00
|
|
|
|
! nullify pointers
|
2013-12-11 10:59:25 -02:00
|
|
|
|
!
|
2014-01-02 12:18:04 -02:00
|
|
|
|
nullify(evolve)
|
2021-10-15 13:51:25 -03:00
|
|
|
|
nullify(update_errors)
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
2020-09-01 16:38:11 -03:00
|
|
|
|
! print integration summary
|
|
|
|
|
!
|
|
|
|
|
if (niterations > 0) then
|
|
|
|
|
call print_section(verbose, "Integration summary")
|
|
|
|
|
call print_parameter(verbose, "Number of iterations", niterations)
|
|
|
|
|
call print_parameter(verbose, "Number of rejections", nrejections)
|
|
|
|
|
end if
|
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
! stop accounting time for module initialization/finalization
|
|
|
|
|
!
|
|
|
|
|
call stop_timer(imi)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2013-12-11 10:59:25 -02:00
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
end subroutine finalize_evolution
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2019-01-30 14:45:07 -02:00
|
|
|
|
! subroutine PRINT_EVOLUTION:
|
|
|
|
|
! --------------------------
|
|
|
|
|
!
|
|
|
|
|
! Subroutine prints module parameters.
|
|
|
|
|
!
|
|
|
|
|
! Arguments:
|
|
|
|
|
!
|
|
|
|
|
! verbose - a logical flag turning the information printing;
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
|
|
|
|
subroutine print_evolution(verbose)
|
|
|
|
|
|
|
|
|
|
! import external procedures and variables
|
|
|
|
|
!
|
|
|
|
|
use equations, only : magnetized
|
2019-01-30 22:30:30 -02:00
|
|
|
|
use helpers , only : print_section, print_parameter
|
2019-01-30 14:45:07 -02:00
|
|
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
|
!
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
! subroutine arguments
|
|
|
|
|
!
|
|
|
|
|
logical, intent(in) :: verbose
|
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
if (verbose) then
|
|
|
|
|
|
2019-01-30 22:30:30 -02:00
|
|
|
|
call print_section(verbose, "Evolution")
|
2020-09-01 16:38:11 -03:00
|
|
|
|
call print_parameter(verbose, "time advance", name_int)
|
2021-07-10 12:24:20 -03:00
|
|
|
|
call print_parameter(verbose, "no. of registers", registers)
|
2020-09-01 16:38:11 -03:00
|
|
|
|
call print_parameter(verbose, "CFL coefficient", cfl)
|
2019-01-30 14:45:07 -02:00
|
|
|
|
if (magnetized) then
|
2020-08-19 18:38:25 -03:00
|
|
|
|
call print_parameter(verbose, "GLM alpha coefficient", glm_alpha)
|
2019-01-30 14:45:07 -02:00
|
|
|
|
end if
|
2021-07-19 12:58:57 -03:00
|
|
|
|
if (error_control) then
|
|
|
|
|
call print_parameter(verbose, "absolute tolerance", atol)
|
|
|
|
|
call print_parameter(verbose, "relative tolerance", rtol)
|
2021-10-15 13:51:25 -03:00
|
|
|
|
call print_parameter(verbose, "error norm" , name_norm)
|
2021-07-19 12:58:57 -03:00
|
|
|
|
call print_parameter(verbose, "maximum rejections", mrej)
|
2021-10-15 12:15:14 -03:00
|
|
|
|
call print_parameter(verbose, "chi" , chi)
|
2021-07-19 12:58:57 -03:00
|
|
|
|
call print_parameter(verbose, "factor" , fac)
|
|
|
|
|
call print_parameter(verbose, "minimum factor" , facmin)
|
|
|
|
|
call print_parameter(verbose, "maximum factor" , facmax)
|
|
|
|
|
end if
|
2019-01-30 14:45:07 -02:00
|
|
|
|
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
end subroutine print_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:
|
|
|
|
|
!
|
2019-02-12 10:34:38 -02:00
|
|
|
|
! dtnext - the next time step;
|
|
|
|
|
! status - the subroutine call status: 0 for success, otherwise failure;
|
2012-07-31 15:04:40 -03:00
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2019-02-12 10:34:38 -02:00
|
|
|
|
subroutine advance(dtnext, status)
|
2012-08-01 12:56:52 -03:00
|
|
|
|
|
2019-02-12 10:34:38 -02:00
|
|
|
|
! references
|
2012-07-31 15:04:40 -03:00
|
|
|
|
!
|
2019-02-12 10:34:38 -02:00
|
|
|
|
use blocks , only : set_blocks_update
|
|
|
|
|
use coordinates, only : toplev
|
2020-05-01 21:16:46 -03:00
|
|
|
|
use forcing , only : update_forcing, forcing_enabled
|
2019-02-12 10:34:38 -02:00
|
|
|
|
use mesh , only : update_mesh
|
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
|
|
|
|
|
!
|
2019-02-12 10:34:38 -02:00
|
|
|
|
real(kind=8), intent(in) :: dtnext
|
|
|
|
|
integer , intent(out) :: status
|
2012-07-31 15:04:40 -03:00
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
! start accounting time for solution advance
|
|
|
|
|
!
|
|
|
|
|
call start_timer(ima)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
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
|
|
|
|
|
2017-07-12 12:07:16 -03:00
|
|
|
|
! add forcing contribution
|
|
|
|
|
!
|
2020-08-06 10:40:17 -03:00
|
|
|
|
if (forcing_enabled) call update_forcing(dt)
|
2017-07-12 12:07:16 -03:00
|
|
|
|
|
2020-04-20 13:09:50 -03:00
|
|
|
|
! check if we need to perform the refinement step
|
2012-07-31 15:04:40 -03:00
|
|
|
|
!
|
|
|
|
|
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
|
|
|
|
|
!
|
2019-02-12 10:31:30 -02:00
|
|
|
|
call update_mesh(status)
|
2019-02-12 10:34:38 -02:00
|
|
|
|
if (status /= 0) go to 100
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
2012-07-31 16:38:16 -03:00
|
|
|
|
! update primitive variables
|
2012-07-31 15:04:40 -03:00
|
|
|
|
!
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(time + dt, 0.0d+00)
|
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
|
|
|
|
|
2018-02-09 07:24:47 -02:00
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
! check variables for NaNs
|
|
|
|
|
!
|
|
|
|
|
call check_variables()
|
|
|
|
|
#endif /* DEBUG */
|
|
|
|
|
|
2019-02-12 10:34:38 -02:00
|
|
|
|
! error entry point
|
|
|
|
|
!
|
|
|
|
|
100 continue
|
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
! stop accounting time for solution advance
|
|
|
|
|
!
|
|
|
|
|
call stop_timer(ima)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
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
|
2020-08-14 19:40:10 -03:00
|
|
|
|
use mpitools , only : reduce_maximum
|
2014-01-08 18:07:54 -02:00
|
|
|
|
#endif /* MPI */
|
|
|
|
|
|
|
|
|
|
! include external variables
|
|
|
|
|
!
|
|
|
|
|
use blocks , only : block_data, list_data
|
2020-08-06 10:44:36 -03:00
|
|
|
|
use coordinates , only : adx, ady
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
|
use coordinates , only : adz
|
|
|
|
|
#endif /* NDIMS == 3 */
|
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
|
|
|
|
|
|
2014-09-13 09:47:07 -03:00
|
|
|
|
! subroutine arguments
|
2014-01-08 18:07:54 -02:00
|
|
|
|
!
|
2014-09-13 09:47:07 -03:00
|
|
|
|
real(kind=8), intent(in) :: dtnext
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
|
|
|
|
! local pointers
|
|
|
|
|
!
|
2014-09-13 09:47:07 -03:00
|
|
|
|
type(block_data), pointer :: pdata
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
|
|
|
|
! local variables
|
|
|
|
|
!
|
2020-08-14 19:40:10 -03:00
|
|
|
|
integer :: mlev
|
2014-08-04 09:12:05 -03:00
|
|
|
|
real(kind=8) :: cm, dx_min
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
|
|
|
|
! local parameters
|
|
|
|
|
!
|
2014-08-04 09:12:05 -03:00
|
|
|
|
real(kind=8), parameter :: eps = tiny(cmax)
|
2014-01-08 18:07:54 -02:00
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
! start accounting time for new time step estimation
|
|
|
|
|
!
|
|
|
|
|
call start_timer(imt)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2014-01-08 18:07:54 -02:00
|
|
|
|
! reset the maximum speed, and the highest level
|
|
|
|
|
!
|
|
|
|
|
cmax = eps
|
2014-09-13 09:47:07 -03:00
|
|
|
|
mlev = 1
|
|
|
|
|
|
|
|
|
|
! assign pdata with the first block on the data block list
|
|
|
|
|
!
|
|
|
|
|
pdata => list_data
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
|
|
|
|
! iterate over all data blocks in order to find the maximum speed among them
|
2014-09-13 09:47:07 -03:00
|
|
|
|
! and the highest level which is required to obtain the minimum spacial step
|
2014-01-08 18:07:54 -02:00
|
|
|
|
!
|
2014-09-13 09:47:07 -03:00
|
|
|
|
do while (associated(pdata))
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
2014-09-13 09:47:07 -03:00
|
|
|
|
! update the maximum level
|
2014-01-08 18:07:54 -02:00
|
|
|
|
!
|
2014-09-13 09:47:07 -03:00
|
|
|
|
mlev = max(mlev, pdata%meta%level)
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
2014-09-13 09:47:07 -03:00
|
|
|
|
! get the maximum speed for the current block
|
2014-01-08 18:07:54 -02:00
|
|
|
|
!
|
2014-09-13 09:47:07 -03:00
|
|
|
|
cm = maxspeed(pdata%q(:,:,:,:))
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
2014-09-13 09:47:07 -03:00
|
|
|
|
! update the maximum speed
|
2014-01-08 18:07:54 -02:00
|
|
|
|
!
|
|
|
|
|
cmax = max(cmax, cm)
|
|
|
|
|
|
2014-09-13 09:47:07 -03:00
|
|
|
|
! assign pdata to the next block
|
2014-01-08 18:07:54 -02:00
|
|
|
|
!
|
2014-09-13 09:47:07 -03:00
|
|
|
|
pdata => pdata%next
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
2014-09-13 09:47:07 -03:00
|
|
|
|
end do ! over data blocks
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
|
|
|
|
#ifdef MPI
|
2014-09-13 09:47:07 -03:00
|
|
|
|
! reduce maximum speed and level over all processors
|
2014-01-08 18:07:54 -02:00
|
|
|
|
!
|
2020-08-14 19:40:10 -03:00
|
|
|
|
call reduce_maximum(cmax)
|
|
|
|
|
call reduce_maximum(mlev)
|
2014-01-08 18:07:54 -02:00
|
|
|
|
#endif /* MPI */
|
|
|
|
|
|
2014-09-13 09:47:07 -03:00
|
|
|
|
! calculate the squared cmax
|
2014-01-08 18:07:54 -02:00
|
|
|
|
!
|
|
|
|
|
cmax2 = cmax * cmax
|
|
|
|
|
|
2014-09-13 09:47:07 -03:00
|
|
|
|
! find the smallest spacial step
|
2014-01-08 18:07:54 -02:00
|
|
|
|
!
|
|
|
|
|
#if NDIMS == 2
|
2014-09-13 09:47:07 -03:00
|
|
|
|
dx_min = min(adx(mlev), ady(mlev))
|
2014-01-08 18:07:54 -02:00
|
|
|
|
#endif /* NDIMS == 2 */
|
|
|
|
|
#if NDIMS == 3
|
2014-09-13 09:47:07 -03:00
|
|
|
|
dx_min = min(adx(mlev), ady(mlev), adz(mlev))
|
2014-01-08 18:07:54 -02:00
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
|
2014-08-20 18:10:30 -03:00
|
|
|
|
! calculate the new time step
|
2014-01-08 18:07:54 -02:00
|
|
|
|
!
|
2021-08-17 11:23:36 -03:00
|
|
|
|
dth = cfl * dx_min / max(cmax &
|
2014-06-02 11:47:37 -03:00
|
|
|
|
+ 2.0d+00 * max(viscosity, resistivity) / dx_min, eps)
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
|
|
|
|
! round the time
|
|
|
|
|
!
|
2021-08-17 11:23:36 -03:00
|
|
|
|
dtn = dth
|
2021-07-19 15:12:08 -03:00
|
|
|
|
if (error_control .and. dte > 0.0d+00) dtn = min(dtn, dte)
|
2021-07-19 13:16:31 -03:00
|
|
|
|
if (dtnext > 0.0d+00) dtn = min(dtn, dtnext)
|
2021-07-19 15:12:08 -03:00
|
|
|
|
dt = dtn
|
2014-01-08 18:07:54 -02:00
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
! stop accounting time for new time step estimation
|
|
|
|
|
!
|
|
|
|
|
call stop_timer(imt)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2014-01-08 18:07:54 -02:00
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
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.
|
|
|
|
|
!
|
2014-09-13 09:53:40 -03:00
|
|
|
|
! References:
|
|
|
|
|
!
|
|
|
|
|
! [1] Press, W. H, Teukolsky, S. A., Vetterling, W. T., Flannery, B. P.,
|
|
|
|
|
! "Numerical Recipes in Fortran",
|
|
|
|
|
! Cambridge University Press, Cambridge, 1992
|
|
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
|
|
|
|
subroutine evolve_euler()
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
|
use boundaries, only : boundary_fluxes
|
2021-09-20 08:44:38 -03:00
|
|
|
|
use equations , only : ibp, cmax
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use sources , only : update_sources
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
type(block_data), pointer :: pdata
|
|
|
|
|
|
|
|
|
|
real(kind=8) :: tm, dtm
|
2013-12-11 10:59:25 -02:00
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call start_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2017-03-07 15:36:51 -03:00
|
|
|
|
tm = time + dt
|
|
|
|
|
dtm = dt
|
|
|
|
|
|
2014-09-13 09:53:40 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-04-29 18:35:58 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,1) = pdata%uu(:,:,:,:,1) + dt * pdata%du(:,:,:,:)
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,1)
|
2013-12-12 15:36:55 -02:00
|
|
|
|
|
2014-09-13 09:53:40 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
if (ibp > 0) then
|
2021-09-20 08:44:38 -03:00
|
|
|
|
adecay(:) = exp(aglm(:) * cmax * dt)
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-09-20 08:44:38 -03:00
|
|
|
|
pdata%u(ibp,:,:,:) = adecay(pdata%meta%level) * pdata%u(ibp,:,:,:)
|
2021-07-10 18:52:55 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
end if
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call stop_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
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.
|
|
|
|
|
!
|
2014-08-19 20:50:49 -03:00
|
|
|
|
! References:
|
|
|
|
|
!
|
|
|
|
|
! [1] Press, W. H, Teukolsky, S. A., Vetterling, W. T., Flannery, B. P.,
|
|
|
|
|
! "Numerical Recipes in Fortran",
|
|
|
|
|
! Cambridge University Press, Cambridge, 1992
|
2012-07-31 15:04:40 -03:00
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2013-12-11 10:59:25 -02:00
|
|
|
|
subroutine evolve_rk2()
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
|
use boundaries, only : boundary_fluxes
|
2021-09-20 08:44:38 -03:00
|
|
|
|
use equations , only : ibp, cmax
|
|
|
|
|
use sources , only : update_sources
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
type(block_data), pointer :: pdata
|
|
|
|
|
|
|
|
|
|
real(kind=8) :: tm, dtm
|
2012-07-31 15:04:40 -03:00
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call start_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
!= 1st step: U(1) = U(n) + dt * F[U(n)]
|
2017-03-07 15:36:51 -03:00
|
|
|
|
!
|
|
|
|
|
tm = time + dt
|
|
|
|
|
dtm = dt
|
|
|
|
|
|
2014-09-13 10:00:16 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-04-29 18:35:58 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,1) + dt * pdata%du(:,:,:,:)
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,2)
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
2014-09-13 10:00:16 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2012-07-31 16:38:16 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
!= 2nd step: U(n+1) = 1/2 U(n) + 1/2 U(1) + 1/2 dt * F[U(1)]
|
2017-03-07 15:36:51 -03:00
|
|
|
|
!
|
|
|
|
|
tm = time + dt
|
|
|
|
|
dtm = 0.5d+00 * dt
|
|
|
|
|
|
2014-09-13 10:00:16 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-09-13 10:00:16 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,1) = 0.5d+00 * (pdata%uu(:,:,:,:,1) &
|
2021-07-10 17:51:28 -03:00
|
|
|
|
+ pdata%uu(:,:,:,:,2) &
|
|
|
|
|
+ dt * pdata%du(:,:,:,:))
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,1)
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
2014-09-13 10:00:16 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
if (ibp > 0) then
|
2021-09-20 08:44:38 -03:00
|
|
|
|
adecay(:) = exp(aglm(:) * cmax * dt)
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-09-20 08:44:38 -03:00
|
|
|
|
pdata%u(ibp,:,:,:) = adecay(pdata%meta%level) * pdata%u(ibp,:,:,:)
|
2021-07-10 18:52:55 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
end if
|
2012-07-31 15:04:40 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2013-12-11 10:59:25 -02:00
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call stop_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
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
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2020-08-28 23:36:52 -03:00
|
|
|
|
! subroutine EVOLVE_SSPRK2_M:
|
|
|
|
|
! --------------------------
|
2014-08-26 13:25:31 -03:00
|
|
|
|
!
|
|
|
|
|
! Subroutine advances the solution by one time step using the 2nd order
|
|
|
|
|
! m-stage Strong Stability Preserving Runge-Kutta time integration method.
|
|
|
|
|
! Up to 9 stages are allowed, due to stability problems with more stages.
|
|
|
|
|
!
|
|
|
|
|
! References:
|
|
|
|
|
!
|
|
|
|
|
! [1] Gottlieb, S. and Gottlieb, L.-A., J.
|
|
|
|
|
! "Strong Stability Preserving Properties of Runge-Kutta Time
|
|
|
|
|
! Discretization Methods for Linear Constant Coefficient Operators",
|
|
|
|
|
! Journal of Scientific Computing,
|
|
|
|
|
! 2003, vol. 18, no. 1, pp. 83-109
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2020-08-28 23:36:52 -03:00
|
|
|
|
subroutine evolve_ssprk2_m()
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2020-08-28 23:36:52 -03:00
|
|
|
|
use blocks , only : block_data, list_data, get_dblocks
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use boundaries , only : boundary_fluxes
|
2020-08-28 23:36:52 -03:00
|
|
|
|
use coordinates, only : nc => ncells, nb, ne
|
2021-09-20 08:44:38 -03:00
|
|
|
|
use equations , only : errors, nf, ibp, cmax
|
2020-08-28 23:36:52 -03:00
|
|
|
|
#ifdef MPI
|
|
|
|
|
use mpitools , only : reduce_maximum
|
|
|
|
|
#endif /* MPI */
|
|
|
|
|
use sources , only : update_sources
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
type(block_data), pointer :: pdata
|
|
|
|
|
|
2020-09-01 16:57:36 -03:00
|
|
|
|
logical :: test
|
|
|
|
|
integer :: n, l, nrej
|
2021-10-15 15:29:42 -03:00
|
|
|
|
real(kind=8) :: tm, dtm, ds, umax, emax
|
2020-09-15 22:59:20 -03:00
|
|
|
|
real(kind=8) :: fc, fcmn, fcmx
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
|
|
|
|
logical , save :: first = .true.
|
2020-08-28 23:36:52 -03:00
|
|
|
|
real(kind=8), save :: ft, fl, fr, gt, gl
|
|
|
|
|
|
|
|
|
|
real(kind=8), dimension(:,:,:,:,:), allocatable :: lerr
|
2020-09-15 22:59:20 -03:00
|
|
|
|
|
|
|
|
|
real(kind=8), parameter :: k1 = -2.9d-01, k2 = 1.05d-01, k3 = -5.0d-02
|
2014-08-26 13:25:31 -03:00
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call start_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2014-08-26 13:25:31 -03:00
|
|
|
|
if (first) then
|
|
|
|
|
|
|
|
|
|
ft = 1.0d+00 / (stages - 1)
|
|
|
|
|
fl = 1.0d+00 / stages
|
|
|
|
|
fr = 1.0d+00 - fl
|
|
|
|
|
|
2020-08-28 23:36:52 -03:00
|
|
|
|
gt = fl - ft
|
|
|
|
|
gl = fl
|
|
|
|
|
|
2014-08-26 13:25:31 -03:00
|
|
|
|
first = .false.
|
|
|
|
|
|
|
|
|
|
end if
|
|
|
|
|
|
2020-09-15 22:59:20 -03:00
|
|
|
|
fc = fac
|
|
|
|
|
fcmn = facmin
|
|
|
|
|
fcmx = facmax
|
|
|
|
|
|
2020-08-28 23:36:52 -03:00
|
|
|
|
l = get_dblocks()
|
|
|
|
|
#if NDIMS == 3
|
2020-08-31 11:52:19 -03:00
|
|
|
|
allocate(lerr(l,nf,nc,nc,nc))
|
2020-08-28 23:36:52 -03:00
|
|
|
|
#else /* NDIMS == 3 */
|
|
|
|
|
allocate(lerr(l,nf,nc,nc, 1))
|
|
|
|
|
#endif /* NDIMS == 3 */
|
2020-09-01 16:57:36 -03:00
|
|
|
|
|
|
|
|
|
test = .true.
|
|
|
|
|
nrej = 0
|
|
|
|
|
|
|
|
|
|
do while(test)
|
|
|
|
|
|
|
|
|
|
lerr(:,:,:,:,:) = 0.0d+00
|
|
|
|
|
|
|
|
|
|
ds = ft * dt
|
2020-08-28 23:36:52 -03:00
|
|
|
|
|
2020-08-31 20:10:48 -03:00
|
|
|
|
!= 1st step: U(1) = U(n), U(2) = U(n)
|
2014-08-26 13:25:31 -03:00
|
|
|
|
!
|
2020-09-01 16:57:36 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,1)
|
|
|
|
|
pdata%uu(:,:,:,:,3) = pdata%uu(:,:,:,:,1)
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,2)
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2020-09-01 16:57:36 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2020-08-31 20:10:48 -03:00
|
|
|
|
!= 2nd step: U(1) = U(1) + dt/(m-1) F[U(1)], for i = 1, ..., m-1
|
2014-08-26 13:25:31 -03:00
|
|
|
|
!
|
2020-09-01 16:57:36 -03:00
|
|
|
|
do n = 1, stages - 1
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2020-09-01 16:57:36 -03:00
|
|
|
|
tm = time + n * ds
|
|
|
|
|
dtm = ds
|
2017-03-07 15:36:51 -03:00
|
|
|
|
|
2020-09-01 16:57:36 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2020-09-01 16:57:36 -03:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
l = 1
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,2) + ds * pdata%du(:,:,:,:)
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2020-08-28 23:36:52 -03:00
|
|
|
|
#if NDIMS == 3
|
2021-07-10 17:51:28 -03:00
|
|
|
|
lerr(l,:,:,:,:) = lerr(l,:,:,:,:) + gt * pdata%du(:,nb:ne,nb:ne,nb:ne)
|
2020-08-28 23:36:52 -03:00
|
|
|
|
#else /* NDIMS == 3 */
|
2021-07-10 17:51:28 -03:00
|
|
|
|
lerr(l,:,:,:,:) = lerr(l,:,:,:,:) + gt * pdata%du(:,nb:ne,nb:ne, : )
|
2020-08-28 23:36:52 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2020-09-01 16:57:36 -03:00
|
|
|
|
l = l + 1
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2020-09-01 16:57:36 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2020-09-01 16:57:36 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2020-09-01 16:57:36 -03:00
|
|
|
|
end do ! n = 1, stages - 1
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2020-08-31 20:10:48 -03:00
|
|
|
|
!= the final step: U(1) = (m-1)/m U(1) + 1/m U(2) + dt/m F[U(1)]
|
2017-03-07 15:36:51 -03:00
|
|
|
|
!
|
2020-09-01 16:57:36 -03:00
|
|
|
|
tm = time + dt
|
|
|
|
|
dtm = fl * dt
|
2017-03-07 15:36:51 -03:00
|
|
|
|
|
2020-09-01 16:57:36 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2020-09-01 16:57:36 -03:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
l = 1
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = fr * pdata%uu(:,:,:,:,2) &
|
2021-07-10 17:51:28 -03:00
|
|
|
|
+ fl * (pdata%uu(:,:,:,:,3) &
|
|
|
|
|
+ dt * pdata%du(:,:,:,:))
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2020-08-28 23:36:52 -03:00
|
|
|
|
#if NDIMS == 3
|
2021-07-10 17:51:28 -03:00
|
|
|
|
lerr(l,:,:,:,:) = lerr(l,:,:,:,:) + gl * pdata%du(:,nb:ne,nb:ne,nb:ne)
|
2020-08-28 23:36:52 -03:00
|
|
|
|
#else /* NDIMS == 3 */
|
2021-07-10 17:51:28 -03:00
|
|
|
|
lerr(l,:,:,:,:) = lerr(l,:,:,:,:) + gl * pdata%du(:,nb:ne,nb:ne, : )
|
2020-08-28 23:36:52 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2020-09-01 16:57:36 -03:00
|
|
|
|
l = l + 1
|
2020-08-28 23:36:52 -03:00
|
|
|
|
|
2020-09-01 16:57:36 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-26 13:25:31 -03:00
|
|
|
|
|
2021-02-05 16:16:26 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
|
|
|
|
|
2020-08-31 22:38:46 -03:00
|
|
|
|
! find umax
|
|
|
|
|
!
|
2020-09-01 16:57:36 -03:00
|
|
|
|
umax = 0.0d+00
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2020-09-15 20:05:05 -03:00
|
|
|
|
#if NDIMS == 3
|
2021-07-10 14:05:00 -03:00
|
|
|
|
umax = max(umax, maxval(abs(pdata%uu(:,nb:ne,nb:ne,nb:ne,1))), &
|
|
|
|
|
maxval(abs(pdata%uu(:,nb:ne,nb:ne,nb:ne,2))))
|
2020-09-15 20:05:05 -03:00
|
|
|
|
#else /* NDIMS == 3 */
|
2021-07-10 14:05:00 -03:00
|
|
|
|
umax = max(umax, maxval(abs(pdata%uu(:,nb:ne,nb:ne, : ,1))), &
|
|
|
|
|
maxval(abs(pdata%uu(:,nb:ne,nb:ne, : ,2))))
|
2020-09-15 20:05:05 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2020-09-01 16:57:36 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2020-08-31 22:38:46 -03:00
|
|
|
|
|
2020-08-28 23:36:52 -03:00
|
|
|
|
! get the maximum error of each variable
|
|
|
|
|
!
|
2020-09-01 16:57:36 -03:00
|
|
|
|
do l = 1, nf
|
|
|
|
|
errors(l) = dt * maxval(abs(lerr(:,l,:,:,:)))
|
|
|
|
|
end do
|
2020-08-28 23:36:52 -03:00
|
|
|
|
|
|
|
|
|
#ifdef MPI
|
2020-09-01 16:57:36 -03:00
|
|
|
|
call reduce_maximum(umax)
|
|
|
|
|
call reduce_maximum(errors)
|
2020-08-28 23:36:52 -03:00
|
|
|
|
#endif /* MPI */
|
|
|
|
|
|
2020-08-31 22:38:46 -03:00
|
|
|
|
! calculate tolerance and time step
|
|
|
|
|
!
|
2021-10-15 15:29:42 -03:00
|
|
|
|
emax = maxval(errors) / (atol + rtol * umax)
|
2020-09-01 16:57:36 -03:00
|
|
|
|
|
|
|
|
|
if (emax <= 1.0d+00 .or. nrej >= mrej) then
|
|
|
|
|
test = .false.
|
|
|
|
|
|
|
|
|
|
errs(3) = errs(2)
|
|
|
|
|
errs(2) = errs(1)
|
|
|
|
|
errs(1) = emax
|
|
|
|
|
|
2021-10-15 15:29:42 -03:00
|
|
|
|
errtol = emax
|
2020-09-16 06:40:50 -03:00
|
|
|
|
|
2020-09-15 22:59:20 -03:00
|
|
|
|
dte = dt * min(fcmx, max(fcmn, &
|
|
|
|
|
fc * errs(1)**k1 * errs(2)**k2 * errs(3)**k3))
|
|
|
|
|
|
|
|
|
|
fcmx = facmax
|
2020-09-01 16:57:36 -03:00
|
|
|
|
else
|
|
|
|
|
errs(1) = emax
|
|
|
|
|
|
2020-09-15 22:59:20 -03:00
|
|
|
|
dte = dt * min(fcmx, max(fcmn, &
|
|
|
|
|
fc * errs(1)**k1 * errs(2)**k2 * errs(3)**k3))
|
2020-09-01 16:57:36 -03:00
|
|
|
|
dt = dte
|
|
|
|
|
|
2020-09-15 22:59:20 -03:00
|
|
|
|
fcmx = fac
|
|
|
|
|
|
2020-09-01 16:57:36 -03:00
|
|
|
|
nrej = nrej + 1 ! rejection count in the current step
|
|
|
|
|
nrejections = nrejections + 1
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
niterations = niterations + 1
|
|
|
|
|
|
|
|
|
|
end do
|
2020-08-31 22:38:46 -03:00
|
|
|
|
|
2020-08-28 23:36:52 -03:00
|
|
|
|
if (allocated(lerr)) deallocate(lerr)
|
|
|
|
|
|
2020-08-31 22:38:46 -03:00
|
|
|
|
!= final step: U(n+1) = U(1)
|
|
|
|
|
!
|
|
|
|
|
tm = time + dt
|
2020-09-01 18:12:37 -03:00
|
|
|
|
dtm = ft * dt
|
2020-08-31 22:38:46 -03:00
|
|
|
|
|
2020-08-31 20:10:48 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,1) = pdata%uu(:,:,:,:,2)
|
2020-08-31 20:10:48 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,1)
|
2020-08-31 20:10:48 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2020-08-31 20:10:48 -03:00
|
|
|
|
|
2021-09-20 08:44:38 -03:00
|
|
|
|
if (ibp > 0) then
|
|
|
|
|
adecay(:) = exp(aglm(:) * cmax * dt)
|
|
|
|
|
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
pdata%u(ibp,:,:,:) = adecay(pdata%meta%level) * pdata%u(ibp,:,:,:)
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
end if
|
|
|
|
|
|
2020-08-31 20:10:48 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call stop_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2014-08-26 13:25:31 -03:00
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2020-08-28 23:36:52 -03:00
|
|
|
|
end subroutine evolve_ssprk2_m
|
2014-08-26 13:25:31 -03:00
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2014-08-19 20:50:49 -03:00
|
|
|
|
! subroutine EVOLVE_RK3:
|
|
|
|
|
! ---------------------
|
|
|
|
|
!
|
|
|
|
|
! Subroutine advances the solution by one time step using the 3rd order
|
|
|
|
|
! Runge-Kutta time integration method.
|
|
|
|
|
!
|
|
|
|
|
! References:
|
|
|
|
|
!
|
|
|
|
|
! [1] Press, W. H, Teukolsky, S. A., Vetterling, W. T., Flannery, B. P.,
|
|
|
|
|
! "Numerical Recipes in Fortran",
|
|
|
|
|
! Cambridge University Press, Cambridge, 1992
|
|
|
|
|
!
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
|
|
|
|
subroutine evolve_rk3()
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
|
use boundaries, only : boundary_fluxes
|
2021-09-20 08:44:38 -03:00
|
|
|
|
use equations , only : ibp, cmax
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use sources , only : update_sources
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
type(block_data), pointer :: pdata
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
real(kind=8) :: ds
|
|
|
|
|
real(kind=8) :: tm, dtm
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
|
|
|
|
real(kind=8), parameter :: f21 = 3.0d+00 / 4.0d+00, f22 = 1.0d+00 / 4.0d+00
|
|
|
|
|
real(kind=8), parameter :: f31 = 1.0d+00 / 3.0d+00, f32 = 2.0d+00 / 3.0d+00
|
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call start_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
!= 1st substep: U(1) = U(n) + dt F[U(n)]
|
|
|
|
|
!
|
2021-07-10 18:52:55 -03:00
|
|
|
|
ds = dt
|
2017-03-07 15:36:51 -03:00
|
|
|
|
tm = time + ds
|
|
|
|
|
dtm = ds
|
|
|
|
|
|
2014-09-13 10:10:54 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,1) + ds * pdata%du(:,:,:,:)
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,2)
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2014-09-13 10:10:54 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
!= 2nd step: U(2) = 3/4 U(n) + 1/4 U(1) + 1/4 dt F[U(1)]
|
|
|
|
|
!
|
2021-07-10 18:52:55 -03:00
|
|
|
|
ds = f22 * dt
|
2017-03-07 15:36:51 -03:00
|
|
|
|
tm = time + 0.5d+00 * dt
|
|
|
|
|
dtm = ds
|
|
|
|
|
|
2014-09-13 10:10:54 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = f21 * pdata%uu(:,:,:,:,1) &
|
2021-07-10 17:51:28 -03:00
|
|
|
|
+ f22 * pdata%uu(:,:,:,:,2) + ds * pdata%du(:,:,:,:)
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2014-09-13 10:10:54 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
!= 3rd step: U(n+1) = 1/3 U(n) + 2/3 U(2) + 2/3 dt F[U(2)]
|
|
|
|
|
!
|
2021-07-10 18:52:55 -03:00
|
|
|
|
ds = f32 * dt
|
2017-03-07 15:36:51 -03:00
|
|
|
|
tm = time + dt
|
|
|
|
|
dtm = ds
|
|
|
|
|
|
2014-09-13 10:10:54 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,1) = f31 * pdata%uu(:,:,:,:,1) &
|
2021-07-10 17:51:28 -03:00
|
|
|
|
+ f32 * pdata%uu(:,:,:,:,2) + ds * pdata%du(:,:,:,:)
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,1)
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2014-09-13 10:10:54 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
if (ibp > 0) then
|
2021-09-20 08:44:38 -03:00
|
|
|
|
adecay(:) = exp(aglm(:) * cmax * dt)
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-09-20 08:44:38 -03:00
|
|
|
|
pdata%u(ibp,:,:,:) = adecay(pdata%meta%level) * pdata%u(ibp,:,:,:)
|
2021-07-10 18:52:55 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
end if
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-19 20:50:49 -03:00
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call stop_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2014-08-19 20:50:49 -03:00
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
end subroutine evolve_rk3
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2014-08-26 14:47:16 -03:00
|
|
|
|
! subroutine EVOLVE_SSPRK34:
|
|
|
|
|
! -------------------------
|
2014-08-19 21:12:20 -03:00
|
|
|
|
!
|
|
|
|
|
! Subroutine advances the solution by one time step using the 3rd order
|
2014-08-26 14:47:16 -03:00
|
|
|
|
! 4-stage Strong Stability Preserving Runge-Kutta time integration method.
|
2014-08-19 21:12:20 -03:00
|
|
|
|
!
|
|
|
|
|
! References:
|
|
|
|
|
!
|
|
|
|
|
! [1] Ruuth, S. J.,
|
|
|
|
|
! "Global Optimization of Explicit Strong-Stability-Preserving
|
|
|
|
|
! Runge-Kutta methods",
|
|
|
|
|
! Mathematics of Computation,
|
2014-08-26 14:47:16 -03:00
|
|
|
|
! 2006, vol. 75, no. 253, pp. 183-207
|
2014-08-19 21:12:20 -03:00
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2014-08-26 14:47:16 -03:00
|
|
|
|
subroutine evolve_ssprk34()
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
|
use boundaries, only : boundary_fluxes
|
2021-09-20 08:44:38 -03:00
|
|
|
|
use equations , only : ibp, cmax
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use sources , only : update_sources
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
type(block_data), pointer :: pdata
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
real(kind=8) :: ds
|
|
|
|
|
real(kind=8) :: tm, dtm
|
2014-08-19 21:12:20 -03:00
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call start_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
!= 1st step: U(1) = U(n) + 1/2 dt F[U(n)]
|
2014-08-19 21:12:20 -03:00
|
|
|
|
!
|
2021-07-10 18:52:55 -03:00
|
|
|
|
ds = dt / 2.0d+00
|
2017-03-07 15:36:51 -03:00
|
|
|
|
tm = time + ds
|
|
|
|
|
dtm = ds
|
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 18:52:55 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2014-08-26 14:47:16 -03:00
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,1) + dtm * pdata%du(:,:,:,:)
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,2)
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2019-02-13 15:11:47 -02:00
|
|
|
|
!= 2nd step: U(2) = U(2) + 1/2 dt F[U(1)]
|
2014-08-19 21:12:20 -03:00
|
|
|
|
!
|
2019-02-13 15:11:47 -02:00
|
|
|
|
tm = time + dt
|
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,2) + dtm * pdata%du(:,:,:,:)
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-26 14:47:16 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2019-02-13 15:11:47 -02:00
|
|
|
|
!= 3rd step: U(3) = 2/3 U(n) + 1/3 (U(2) + 1/2 dt F[U(2)])
|
2017-03-07 15:36:51 -03:00
|
|
|
|
!
|
2019-02-13 15:11:47 -02:00
|
|
|
|
tm = time + ds
|
2017-03-07 15:36:51 -03:00
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = (2.0d+00 * pdata%uu(:,:,:,:,1) &
|
|
|
|
|
+ pdata%uu(:,:,:,:,2) &
|
2021-07-10 17:51:28 -03:00
|
|
|
|
+ dtm * pdata%du(:,:,:,:)) / 3.0d+00
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-26 14:47:16 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
!= the final step: U(n+1) = U(3) + 1/2 dt F[U(3)]
|
2017-03-07 15:36:51 -03:00
|
|
|
|
!
|
|
|
|
|
tm = time + dt
|
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-26 14:47:16 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,1) = pdata%uu(:,:,:,:,2) + ds * pdata%du(:,:,:,:)
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,1)
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2014-08-26 14:47:16 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
if (ibp > 0) then
|
2021-09-20 08:44:38 -03:00
|
|
|
|
adecay(:) = exp(aglm(:) * cmax * dt)
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-09-20 08:44:38 -03:00
|
|
|
|
pdata%u(ibp,:,:,:) = adecay(pdata%meta%level) * pdata%u(ibp,:,:,:)
|
2021-07-10 18:52:55 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
end if
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-19 21:12:20 -03:00
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call stop_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2014-08-19 21:12:20 -03:00
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2014-08-26 14:47:16 -03:00
|
|
|
|
end subroutine evolve_ssprk34
|
2014-08-19 21:12:20 -03:00
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2021-10-15 12:15:14 -03:00
|
|
|
|
! subroutine EVOLVE_SSP324:
|
|
|
|
|
! --------------------------
|
|
|
|
|
!
|
|
|
|
|
! Subroutine advances the solution by one time step using the 3ʳᵈ-order
|
|
|
|
|
! 4-stage embedded Strong Stability Preserving Runge-Kutta time integration
|
|
|
|
|
! method SSP3(2)4 with the error control.
|
|
|
|
|
!
|
|
|
|
|
! References:
|
|
|
|
|
!
|
|
|
|
|
! [1] Ranocha, H., Dalcin, L., Parsani, M., Ketcheson, D. I.,
|
|
|
|
|
! "Optimized Runge-Kutta Methods with Automatic Step Size Control
|
|
|
|
|
! for Compressible Computational Fluid Dynamics",
|
|
|
|
|
! 2021, arXiv:2104.06836v2
|
|
|
|
|
! [2] Conde, S., Fekete, I., Shadid, J. N.,
|
|
|
|
|
! "Embedded error estimation and adaptive step-size control for
|
|
|
|
|
! optimal explicit strong stability preserving Runge–Kutta methods"
|
|
|
|
|
! 2018, arXiv:1806.08693v1
|
|
|
|
|
! [3] Gottlieb, S., Ketcheson, D., Shu, C.-W.,
|
|
|
|
|
! "Strong stability preserving Runge-Kutta and multistep time
|
|
|
|
|
! discretizations",
|
|
|
|
|
! 2011, World Scientific Publishing
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
|
|
|
|
subroutine evolve_ssp324()
|
|
|
|
|
|
2021-10-15 13:51:25 -03:00
|
|
|
|
use blocks , only : block_data, list_data
|
2021-10-15 12:15:14 -03:00
|
|
|
|
use boundaries , only : boundary_fluxes
|
2021-10-15 13:51:25 -03:00
|
|
|
|
use coordinates, only : nb, ne
|
|
|
|
|
use equations , only : errors, ibp, cmax
|
2021-10-15 12:15:14 -03:00
|
|
|
|
use sources , only : update_sources
|
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
type(block_data), pointer :: pdata
|
|
|
|
|
|
|
|
|
|
logical :: test
|
2021-10-15 13:51:25 -03:00
|
|
|
|
integer :: nrej, i
|
|
|
|
|
real(kind=8) :: tm, dtm, dh, fc
|
2021-10-15 12:15:14 -03:00
|
|
|
|
|
|
|
|
|
real(kind=8), parameter :: onethird = 1.0d+00 / 3.0d+00, &
|
|
|
|
|
twothird = 2.0d+00 / 3.0d+00
|
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call start_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
|
|
|
|
test = .true.
|
|
|
|
|
nrej = 0
|
|
|
|
|
|
|
|
|
|
! at the entry point we assume the previous solution of conserved variables U(n)
|
|
|
|
|
! is stored in pdata%u(:,:,:,:,1) and the primitive variables are already
|
|
|
|
|
! updated from this array;
|
|
|
|
|
!
|
|
|
|
|
! pdata%uu(:,:,:,:,1) - the previous solution, U(n)
|
|
|
|
|
! pdata%uu(:,:,:,:,2) - the new 3rd order solution, U(1)
|
|
|
|
|
! pdata%uu(:,:,:,:,3) - the new 2nd order solution, U(2)
|
|
|
|
|
!
|
|
|
|
|
do while(test)
|
|
|
|
|
|
|
|
|
|
! initiate the fractional time step
|
|
|
|
|
!
|
|
|
|
|
dh = 5.0d-01 * dt
|
|
|
|
|
|
|
|
|
|
!= preparation step: U(1) = U(n)
|
|
|
|
|
!
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,1)
|
|
|
|
|
|
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,2)
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
!= 1st to 3rd steps: U(1) = U(1) + ½ dt F[U(1)], for i = 1...3
|
|
|
|
|
!
|
|
|
|
|
do i = 1, 3
|
|
|
|
|
|
|
|
|
|
tm = time + (i - 1) * dh
|
|
|
|
|
dtm = dh
|
|
|
|
|
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
call update_increment(pdata)
|
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,2) + dh * pdata%du(:,:,:,:)
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
call update_variables(tm, dtm)
|
|
|
|
|
|
|
|
|
|
end do ! i = 1, 3
|
|
|
|
|
|
|
|
|
|
!= 4th step: U(1) = ⅔ U(n) + ⅓ U(1), U(2) = ⅓ U(n) + ⅔ U(1)
|
|
|
|
|
!
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
pdata%uu(:,:,:,:,3) = onethird * pdata%uu(:,:,:,:,1) &
|
|
|
|
|
+ twothird * pdata%uu(:,:,:,:,2)
|
|
|
|
|
pdata%uu(:,:,:,:,2) = twothird * pdata%uu(:,:,:,:,1) &
|
|
|
|
|
+ onethird * pdata%uu(:,:,:,:,2)
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
call update_variables(tm, dtm)
|
|
|
|
|
|
|
|
|
|
!= 5th step: U(1) = U(1) + ½ dt F[U(1)] <- 3ʳᵈ-order candidate
|
|
|
|
|
!
|
|
|
|
|
tm = time + dh
|
|
|
|
|
dtm = dh
|
|
|
|
|
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
call update_increment(pdata)
|
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,2) + dh * pdata%du(:,:,:,:)
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
call update_variables(tm, dtm)
|
|
|
|
|
|
|
|
|
|
!= 6th step: U(2) = ½ (U(1) + U(2)) <- 2ⁿᵈ-order approximation
|
|
|
|
|
!
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
pdata%uu(:,:,:,:,3) = 5.0d-01 * (pdata%uu(:,:,:,:,3) &
|
|
|
|
|
+ pdata%uu(:,:,:,:,2))
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
!= 7th step: decay the magnetic divergence potential of both solutions
|
|
|
|
|
!
|
|
|
|
|
if (ibp > 0) then
|
|
|
|
|
adecay(:) = exp(aglm(:) * cmax * dt)
|
|
|
|
|
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
pdata%uu(ibp,:,:,:,2) = adecay(pdata%meta%level) &
|
|
|
|
|
* pdata%uu(ibp,:,:,:,2)
|
|
|
|
|
pdata%uu(ibp,:,:,:,3) = adecay(pdata%meta%level) &
|
|
|
|
|
* pdata%uu(ibp,:,:,:,3)
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
end if
|
|
|
|
|
|
2021-10-15 13:51:25 -03:00
|
|
|
|
! update the vector of errors
|
2021-10-15 12:15:14 -03:00
|
|
|
|
!
|
2021-10-15 13:51:25 -03:00
|
|
|
|
call update_errors(2, 3)
|
2021-10-15 12:15:14 -03:00
|
|
|
|
|
|
|
|
|
! calculate the tolerance and estimate the next time step due to the error
|
|
|
|
|
!
|
2021-10-15 15:29:42 -03:00
|
|
|
|
errtol = maxval(errors)
|
|
|
|
|
errs(1) = errtol
|
2021-10-15 12:15:14 -03:00
|
|
|
|
fc = product(errs(:)**betas(:))
|
|
|
|
|
fc = 1.0d+00 + chi * atan((fc - 1.0d+00) / chi)
|
|
|
|
|
dte = dt * fc
|
|
|
|
|
|
|
|
|
|
if (fc > fac .or. nrej >= mrej) then
|
|
|
|
|
test = .false.
|
|
|
|
|
|
|
|
|
|
errs(3) = errs(2)
|
|
|
|
|
errs(2) = errs(1)
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
dt = dte
|
|
|
|
|
|
|
|
|
|
nrej = nrej + 1 ! rejection count in the current step
|
|
|
|
|
nrejections = nrejections + 1
|
|
|
|
|
|
|
|
|
|
! since the solution was rejected, we have to revert the primitive variables
|
|
|
|
|
! to the previous state
|
|
|
|
|
!
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,1)
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
call update_variables(tm, dtm)
|
|
|
|
|
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
niterations = niterations + 1
|
|
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
!= final step: U(n+1) = U(1) - update the accepted solution
|
|
|
|
|
!
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
pdata%uu(:,:,:,:,1) = pdata%uu(:,:,:,:,2)
|
|
|
|
|
|
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,1)
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call stop_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
end subroutine evolve_ssp324
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2014-08-26 13:51:11 -03:00
|
|
|
|
! subroutine EVOLVE_SSPRK35:
|
|
|
|
|
! -------------------------
|
|
|
|
|
!
|
|
|
|
|
! Subroutine advances the solution by one time step using the 3rd order
|
|
|
|
|
! 5-stage Strong Stability Preserving Runge-Kutta time integration method.
|
|
|
|
|
!
|
|
|
|
|
! References:
|
|
|
|
|
!
|
|
|
|
|
! [1] Ruuth, S. J.,
|
|
|
|
|
! "Global Optimization of Explicit Strong-Stability-Preserving
|
|
|
|
|
! Runge-Kutta methods",
|
|
|
|
|
! Mathematics of Computation,
|
|
|
|
|
! 2006, vol. 75, no. 253, pp. 183-207
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
|
|
|
|
subroutine evolve_ssprk35()
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
|
use boundaries, only : boundary_fluxes
|
2021-09-20 08:44:38 -03:00
|
|
|
|
use equations , only : ibp, cmax
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use sources , only : update_sources
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
type(block_data), pointer :: pdata
|
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
real(kind=8) :: ds
|
|
|
|
|
real(kind=8) :: tm, dtm
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
|
|
|
|
real(kind=8), parameter :: b1 = 3.77268915331368d-01
|
|
|
|
|
real(kind=8), parameter :: b3 = 2.42995220537396d-01
|
|
|
|
|
real(kind=8), parameter :: b4 = 2.38458932846290d-01
|
|
|
|
|
real(kind=8), parameter :: b5 = 2.87632146308408d-01
|
|
|
|
|
real(kind=8), parameter :: a31 = 3.55909775063327d-01
|
2015-05-16 15:58:01 -03:00
|
|
|
|
real(kind=8), parameter :: a33 = 6.44090224936673d-01
|
2014-08-26 13:51:11 -03:00
|
|
|
|
real(kind=8), parameter :: a41 = 3.67933791638137d-01
|
|
|
|
|
real(kind=8), parameter :: a44 = 6.32066208361863d-01
|
|
|
|
|
real(kind=8), parameter :: a53 = 2.37593836598569d-01
|
|
|
|
|
real(kind=8), parameter :: a55 = 7.62406163401431d-01
|
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call start_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2014-08-26 14:51:14 -03:00
|
|
|
|
!= 1st step: U(1) = U(n) + b1 dt F[U(n)]
|
2014-08-26 13:51:11 -03:00
|
|
|
|
!
|
2021-07-10 18:52:55 -03:00
|
|
|
|
ds = b1 * dt
|
2017-03-07 15:36:51 -03:00
|
|
|
|
tm = time + ds
|
|
|
|
|
dtm = ds
|
|
|
|
|
|
2014-08-26 13:51:11 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,1) + ds * pdata%du(:,:,:,:)
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,2)
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2014-08-26 14:51:14 -03:00
|
|
|
|
!= 2nd step: U(2) = U(1) + b1 dt F[U(1)]
|
2017-03-07 15:36:51 -03:00
|
|
|
|
!
|
|
|
|
|
tm = time + 2.0d+00 * ds
|
|
|
|
|
dtm = ds
|
|
|
|
|
|
2014-08-26 13:51:11 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,2) + ds * pdata%du(:,:,:,:)
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2014-08-26 14:51:14 -03:00
|
|
|
|
!= 3rd step: U(3) = a31 U(n) + a33 U(2) + b3 dt F[U(2)]
|
2014-08-26 13:51:11 -03:00
|
|
|
|
!
|
2021-07-10 18:52:55 -03:00
|
|
|
|
ds = b3 * dt
|
2017-03-07 15:36:51 -03:00
|
|
|
|
tm = time + (2.0d+00 * a33 * b1 + b3) * dt
|
|
|
|
|
dtm = ds
|
|
|
|
|
|
2014-08-26 13:51:11 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = a31 * pdata%uu(:,:,:,:,1) &
|
2021-07-10 17:51:28 -03:00
|
|
|
|
+ a33 * pdata%uu(:,:,:,:,2) + ds * pdata%du(:,:,:,:)
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2014-08-26 14:51:14 -03:00
|
|
|
|
!= 4th step: U(4) = a41 U(n) + a44 U(3) + b4 dt F[U(3)]
|
2014-08-26 13:51:11 -03:00
|
|
|
|
!
|
2021-07-10 18:52:55 -03:00
|
|
|
|
ds = b4 * dt
|
2017-03-07 15:36:51 -03:00
|
|
|
|
tm = time + ((2.0d+00 * b1 * a33 + b3) * a44 + b4) * dt
|
|
|
|
|
dtm = ds
|
|
|
|
|
|
2014-08-26 13:51:11 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,1) = a41 * pdata%uu(:,:,:,:,1) &
|
2021-07-10 17:51:28 -03:00
|
|
|
|
+ a44 * pdata%uu(:,:,:,:,2) + ds * pdata%du(:,:,:,:)
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,1)
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2014-08-26 14:51:14 -03:00
|
|
|
|
!= the final step: U(n+1) = a53 U(2) + a55 U(4) + b5 dt F[U(4)]
|
2014-08-26 13:51:11 -03:00
|
|
|
|
!
|
2021-07-10 18:52:55 -03:00
|
|
|
|
ds = b5 * dt
|
2017-03-07 15:36:51 -03:00
|
|
|
|
tm = time + dt
|
|
|
|
|
dtm = ds
|
|
|
|
|
|
2014-08-26 13:51:11 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,1) = a53 * pdata%uu(:,:,:,:,2) &
|
2021-07-10 17:51:28 -03:00
|
|
|
|
+ a55 * pdata%uu(:,:,:,:,1) + ds * pdata%du(:,:,:,:)
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
if (ibp > 0) then
|
2021-09-20 08:44:38 -03:00
|
|
|
|
adecay(:) = exp(aglm(:) * cmax * dt)
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-09-20 08:44:38 -03:00
|
|
|
|
pdata%u(ibp,:,:,:) = adecay(pdata%meta%level) * pdata%u(ibp,:,:,:)
|
2021-07-10 18:52:55 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
end if
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2014-08-26 13:51:11 -03:00
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call stop_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2014-08-26 13:51:11 -03:00
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
end subroutine evolve_ssprk35
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2019-02-08 12:03:10 -02:00
|
|
|
|
! subroutine EVOLVE_SSPRK3_M:
|
|
|
|
|
! --------------------------
|
2012-07-31 16:02:59 -03:00
|
|
|
|
!
|
2019-02-08 12:03:10 -02:00
|
|
|
|
! Subroutine advances the solution by one time step using the 3rd order
|
|
|
|
|
! m-stage Strong Stability Preserving Runge-Kutta time integration method.
|
2012-07-31 16:02:59 -03:00
|
|
|
|
!
|
2019-02-08 12:03:10 -02:00
|
|
|
|
! References:
|
2012-07-31 16:02:59 -03:00
|
|
|
|
!
|
2019-02-08 12:03:10 -02:00
|
|
|
|
! [1] Gottlieb, S., Ketcheson, D., Shu C. - W.,
|
|
|
|
|
! "Strong stability preserving Runge-Kutta and multistep
|
|
|
|
|
! time discretizations",
|
|
|
|
|
! World Scientific Publishing, 2011
|
2012-07-31 16:02:59 -03:00
|
|
|
|
!
|
2019-02-08 12:03:10 -02:00
|
|
|
|
!===============================================================================
|
2012-07-31 16:02:59 -03:00
|
|
|
|
!
|
2019-02-08 12:03:10 -02:00
|
|
|
|
subroutine evolve_ssprk3_m()
|
2012-08-01 12:56:52 -03:00
|
|
|
|
|
2020-08-28 22:42:26 -03:00
|
|
|
|
use blocks , only : block_data, list_data, get_dblocks
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use boundaries , only : boundary_fluxes
|
2020-08-28 22:42:26 -03:00
|
|
|
|
use coordinates, only : nc => ncells, nb, ne
|
2021-09-20 08:44:38 -03:00
|
|
|
|
use equations , only : errors, nf, ibp, cmax
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#ifdef MPI
|
|
|
|
|
use mpitools , only : reduce_maximum
|
|
|
|
|
#endif /* MPI */
|
|
|
|
|
use sources , only : update_sources
|
2012-07-31 16:02:59 -03:00
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
2019-02-08 12:03:10 -02:00
|
|
|
|
type(block_data), pointer :: pdata
|
2012-07-31 16:02:59 -03:00
|
|
|
|
|
2019-02-08 12:03:10 -02:00
|
|
|
|
logical , save :: first = .true.
|
|
|
|
|
integer , save :: n, n1, n2, n3, n4
|
2020-08-28 22:42:26 -03:00
|
|
|
|
real(kind=8), save :: r, f1, f2, g1, g2
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
logical :: test
|
|
|
|
|
integer :: i, l, nrej
|
2021-10-15 15:29:42 -03:00
|
|
|
|
real(kind=8) :: tm, dtm, ds, umax, emax
|
2020-09-15 22:59:20 -03:00
|
|
|
|
real(kind=8) :: fc, fcmn, fcmx
|
2020-08-28 22:42:26 -03:00
|
|
|
|
|
|
|
|
|
real(kind=8), dimension(:,:,:,:,:), allocatable :: lerr
|
2020-09-15 22:59:20 -03:00
|
|
|
|
|
|
|
|
|
real(kind=8), parameter :: k1 = -5.8d-01 / 3.0d+00, k2 = 7.0d-02, &
|
|
|
|
|
k3 = -1.0d-01 / 3.0d+00
|
2012-07-31 16:02:59 -03:00
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
2019-02-08 12:03:10 -02:00
|
|
|
|
call start_timer(imu)
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2019-02-08 12:03:10 -02:00
|
|
|
|
if (first) then
|
2014-09-13 10:15:34 -03:00
|
|
|
|
|
2019-02-08 12:03:10 -02:00
|
|
|
|
n = int(sqrt(1.0d+00 * stages))
|
|
|
|
|
n1 = (n - 1) * (n - 2) / 2
|
|
|
|
|
n2 = n1 + 1
|
|
|
|
|
n3 = n * (n + 1) / 2 - 1
|
|
|
|
|
n4 = n * (n + 1) / 2 + 1
|
2012-07-31 16:02:59 -03:00
|
|
|
|
|
2019-02-08 12:03:10 -02:00
|
|
|
|
r = (1.0d+00 * (2 * n - 1))
|
|
|
|
|
f1 = (1.0d+00 * n ) / r
|
|
|
|
|
f2 = (1.0d+00 * (n - 1)) / r
|
|
|
|
|
r = 1.0d+00 * (stages - n)
|
|
|
|
|
|
2020-08-28 22:42:26 -03:00
|
|
|
|
g1 = 1.0d+00 / ( stages - n) - 1.0d+00 / stages
|
|
|
|
|
g2 = 1.0d+00 / (2 * stages - n) - 1.0d+00 / stages
|
|
|
|
|
|
2019-02-08 12:03:10 -02:00
|
|
|
|
first = .false.
|
2012-07-31 16:02:59 -03:00
|
|
|
|
|
2019-02-08 12:03:10 -02:00
|
|
|
|
end if
|
|
|
|
|
|
2020-09-15 22:59:20 -03:00
|
|
|
|
fc = fac
|
|
|
|
|
fcmn = facmin
|
|
|
|
|
fcmx = facmax
|
|
|
|
|
|
2020-08-28 23:38:12 -03:00
|
|
|
|
l = get_dblocks()
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#if NDIMS == 3
|
2020-08-31 11:52:19 -03:00
|
|
|
|
allocate(lerr(l,nf,nc,nc,nc))
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#else /* NDIMS == 3 */
|
2020-08-28 23:38:12 -03:00
|
|
|
|
allocate(lerr(l,nf,nc,nc, 1))
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2020-09-01 16:48:28 -03:00
|
|
|
|
|
|
|
|
|
test = .true.
|
|
|
|
|
nrej = 0
|
|
|
|
|
|
|
|
|
|
do while(test)
|
|
|
|
|
|
|
|
|
|
lerr(:,:,:,:,:) = 0.0d+00
|
|
|
|
|
|
|
|
|
|
ds = dt / r
|
2020-08-28 22:42:26 -03:00
|
|
|
|
|
2020-08-31 22:27:38 -03:00
|
|
|
|
!= 1st step: U(1) = U(n)
|
|
|
|
|
!
|
2020-09-01 16:48:28 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2020-08-31 22:27:38 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,1)
|
2020-08-31 22:27:38 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,2)
|
2020-08-31 22:27:38 -03:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2020-08-31 22:27:38 -03:00
|
|
|
|
|
|
|
|
|
!= 2ns step: U(1) = U(1) + dt/r F[U(1)], for i = 1, ..., (n-1)*(n-2)/2
|
2012-07-31 16:02:59 -03:00
|
|
|
|
!
|
2020-09-01 16:48:28 -03:00
|
|
|
|
do i = 1, n1
|
2012-07-31 16:02:59 -03:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
tm = time + i * ds
|
|
|
|
|
dtm = ds
|
2012-07-31 16:02:59 -03:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
l = 1
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,2) + ds * pdata%du(:,:,:,:)
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#if NDIMS == 3
|
2021-07-10 17:51:28 -03:00
|
|
|
|
lerr(l,:,:,:,:) = lerr(l,:,:,:,:) + g1 * pdata%du(:,nb:ne,nb:ne,nb:ne)
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#else /* NDIMS == 3 */
|
2021-07-10 17:51:28 -03:00
|
|
|
|
lerr(l,:,:,:,:) = lerr(l,:,:,:,:) + g1 * pdata%du(:,nb:ne,nb:ne, : )
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2020-09-01 16:48:28 -03:00
|
|
|
|
l = l + 1
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
end do ! n = 1, n1
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-08-31 22:27:38 -03:00
|
|
|
|
!= 3rd step: U(2) = U(1)
|
2014-05-27 16:29:53 -03:00
|
|
|
|
!
|
2019-02-08 12:03:10 -02:00
|
|
|
|
! iterate over all data blocks
|
2014-05-27 16:29:53 -03:00
|
|
|
|
!
|
2020-09-01 16:48:28 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2014-05-27 16:29:53 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,3) = pdata%uu(:,:,:,:,2)
|
2014-05-27 16:29:53 -03:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
pdata => pdata%next
|
2014-05-27 16:29:53 -03:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-08-31 22:27:38 -03:00
|
|
|
|
!= 4th step: U(1) = U(1) + dt/r F[U(1)], for i = (n-1)*(n-2)/2+1, ..., n*(n+1)/2-1
|
2014-05-27 16:29:53 -03:00
|
|
|
|
!
|
2021-07-10 18:52:55 -03:00
|
|
|
|
do i = n2, n3
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
tm = time + i * ds
|
|
|
|
|
dtm = ds
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
call update_increment(pdata)
|
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
l = 1
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,2) + ds * pdata%du(:,:,:,:)
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#if NDIMS == 3
|
2021-07-10 17:51:28 -03:00
|
|
|
|
lerr(l,:,:,:,:) = lerr(l,:,:,:,:) + g2 * pdata%du(:,nb:ne,nb:ne,nb:ne)
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#else /* NDIMS == 3 */
|
2021-07-10 17:51:28 -03:00
|
|
|
|
lerr(l,:,:,:,:) = lerr(l,:,:,:,:) + g2 * pdata%du(:,nb:ne,nb:ne, : )
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2020-09-01 16:48:28 -03:00
|
|
|
|
l = l + 1
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
end do ! i = n2, n3
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-08-31 22:27:38 -03:00
|
|
|
|
!= 5th step: U(1) = n * U(2) + (n - 1) * ( U(1) + dt/r F[U(1)] ) / (2 * n - 1)
|
2019-02-08 12:03:10 -02:00
|
|
|
|
!
|
2020-09-01 16:48:28 -03:00
|
|
|
|
tm = time + dt
|
|
|
|
|
dtm = ds
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
l = 1
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = f1 * pdata%uu(:,:,:,:,3) &
|
2021-07-10 17:51:28 -03:00
|
|
|
|
+ f2 * (pdata%uu(:,:,:,:,2) &
|
|
|
|
|
+ ds * pdata%du(:,:,:,:))
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#if NDIMS == 3
|
2021-07-10 17:51:28 -03:00
|
|
|
|
lerr(l,:,:,:,:) = lerr(l,:,:,:,:) + g2 * pdata%du(:,nb:ne,nb:ne,nb:ne)
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#else /* NDIMS == 3 */
|
2021-07-10 17:51:28 -03:00
|
|
|
|
lerr(l,:,:,:,:) = lerr(l,:,:,:,:) + g2 * pdata%du(:,nb:ne,nb:ne, : )
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2020-09-01 16:48:28 -03:00
|
|
|
|
l = l + 1
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-08-31 22:27:38 -03:00
|
|
|
|
!= 6th step: U(1) = U(1) + dt/r F[U(1)], for i = n*(n+1)/2, ..., m
|
2019-02-08 12:03:10 -02:00
|
|
|
|
!
|
2020-09-01 16:48:28 -03:00
|
|
|
|
do i = n4, stages
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
tm = time + (i - n) * ds
|
|
|
|
|
dtm = ds
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
l = 1
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,2) + ds * pdata%du(:,:,:,:)
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#if NDIMS == 3
|
2021-07-10 17:51:28 -03:00
|
|
|
|
lerr(l,:,:,:,:) = lerr(l,:,:,:,:) + g1 * pdata%du(:,nb:ne,nb:ne,nb:ne)
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#else /* NDIMS == 3 */
|
2021-07-10 17:51:28 -03:00
|
|
|
|
lerr(l,:,:,:,:) = lerr(l,:,:,:,:) + g1 * pdata%du(:,nb:ne,nb:ne, : )
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2020-09-01 16:48:28 -03:00
|
|
|
|
l = l + 1
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2021-02-05 16:15:43 -03:00
|
|
|
|
call update_variables(tm, dtm)
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
end do ! i = n4, stages
|
2019-02-08 12:03:10 -02:00
|
|
|
|
|
2020-08-31 22:38:46 -03:00
|
|
|
|
! find umax
|
|
|
|
|
!
|
2020-09-01 16:48:28 -03:00
|
|
|
|
umax = 0.0d+00
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2020-09-15 20:05:05 -03:00
|
|
|
|
#if NDIMS == 3
|
2021-07-10 14:05:00 -03:00
|
|
|
|
umax = max(umax, maxval(abs(pdata%uu(:,nb:ne,nb:ne,nb:ne,1))), &
|
|
|
|
|
maxval(abs(pdata%uu(:,nb:ne,nb:ne,nb:ne,2))))
|
2020-09-15 20:05:05 -03:00
|
|
|
|
#else /* NDIMS == 3 */
|
2021-07-10 14:05:00 -03:00
|
|
|
|
umax = max(umax, maxval(abs(pdata%uu(:,nb:ne,nb:ne, : ,1))), &
|
|
|
|
|
maxval(abs(pdata%uu(:,nb:ne,nb:ne, : ,2))))
|
2020-09-15 20:05:05 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2020-09-01 16:48:28 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2020-08-31 22:38:46 -03:00
|
|
|
|
|
2020-08-28 22:42:26 -03:00
|
|
|
|
! get the maximum error of each variable
|
|
|
|
|
!
|
2020-09-01 16:48:28 -03:00
|
|
|
|
do l = 1, nf
|
|
|
|
|
errors(l) = dt * maxval(abs(lerr(:,l,:,:,:)))
|
|
|
|
|
end do
|
2020-08-28 22:42:26 -03:00
|
|
|
|
|
|
|
|
|
#ifdef MPI
|
2020-09-01 16:48:28 -03:00
|
|
|
|
call reduce_maximum(umax)
|
|
|
|
|
call reduce_maximum(errors)
|
2020-08-28 22:42:26 -03:00
|
|
|
|
#endif /* MPI */
|
|
|
|
|
|
2020-08-31 22:38:46 -03:00
|
|
|
|
! calculate tolerance and time step
|
|
|
|
|
!
|
2021-10-15 15:29:42 -03:00
|
|
|
|
emax = maxval(errors) / (atol + rtol * umax)
|
2020-09-01 16:48:28 -03:00
|
|
|
|
|
|
|
|
|
if (emax <= 1.0d+00 .or. nrej >= mrej) then
|
|
|
|
|
test = .false.
|
|
|
|
|
|
|
|
|
|
errs(3) = errs(2)
|
|
|
|
|
errs(2) = errs(1)
|
|
|
|
|
errs(1) = emax
|
|
|
|
|
|
2021-10-15 15:29:42 -03:00
|
|
|
|
errtol = emax
|
2020-09-16 06:40:50 -03:00
|
|
|
|
|
2020-09-15 22:59:20 -03:00
|
|
|
|
dte = dt * min(fcmx, max(fcmn, &
|
|
|
|
|
fc * errs(1)**k1 * errs(2)**k2 * errs(3)**k3))
|
|
|
|
|
|
|
|
|
|
fcmx = facmax
|
2020-09-01 16:48:28 -03:00
|
|
|
|
else
|
|
|
|
|
errs(1) = emax
|
|
|
|
|
|
2020-09-15 22:59:20 -03:00
|
|
|
|
dte = dt * min(fcmx, max(fcmn, &
|
|
|
|
|
fc * errs(1)**k1 * errs(2)**k2 * errs(3)**k3))
|
2020-09-01 16:48:28 -03:00
|
|
|
|
dt = dte
|
|
|
|
|
|
2020-09-15 22:59:20 -03:00
|
|
|
|
fcmx = fac
|
|
|
|
|
|
2020-09-01 16:48:28 -03:00
|
|
|
|
nrej = nrej + 1 ! rejection count in the current step
|
|
|
|
|
nrejections = nrejections + 1
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
niterations = niterations + 1
|
|
|
|
|
|
|
|
|
|
end do
|
2020-08-31 22:38:46 -03:00
|
|
|
|
|
2020-08-28 22:42:26 -03:00
|
|
|
|
if (allocated(lerr)) deallocate(lerr)
|
|
|
|
|
|
2020-08-31 22:27:38 -03:00
|
|
|
|
!= final step: U(n+1) = U(1)
|
|
|
|
|
!
|
|
|
|
|
tm = time + dt
|
2020-09-01 18:12:37 -03:00
|
|
|
|
dtm = dt / r
|
2020-08-31 22:27:38 -03:00
|
|
|
|
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,1) = pdata%uu(:,:,:,:,2)
|
2020-08-31 22:27:38 -03:00
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%u => pdata%uu(:,:,:,:,1)
|
2020-08-31 22:27:38 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2020-08-31 22:27:38 -03:00
|
|
|
|
|
|
|
|
|
call update_variables(tm, dtm)
|
|
|
|
|
|
2020-09-01 18:12:37 -03:00
|
|
|
|
if (ibp > 0) then
|
2021-09-20 08:44:38 -03:00
|
|
|
|
adecay(:) = exp(aglm(:) * cmax * dt)
|
|
|
|
|
|
2020-08-31 22:27:38 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
2021-07-10 18:52:55 -03:00
|
|
|
|
|
2021-09-20 08:44:38 -03:00
|
|
|
|
pdata%u(ibp,:,:,:) = adecay(pdata%meta%level) * pdata%u(ibp,:,:,:)
|
2021-07-10 18:52:55 -03:00
|
|
|
|
|
2020-08-31 22:27:38 -03:00
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2020-08-31 22:27:38 -03:00
|
|
|
|
end if
|
|
|
|
|
|
2019-02-08 12:03:10 -02:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call stop_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
end subroutine evolve_ssprk3_m
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2019-02-08 08:48:32 -02:00
|
|
|
|
! subroutine EVOLVE_SSPRK4_10:
|
|
|
|
|
! ---------------------------
|
|
|
|
|
!
|
|
|
|
|
! Subroutine advances the solution by one time step using the 4rd order
|
|
|
|
|
! 10-stage Strong Stability Preserving Runge-Kutta time integration method.
|
|
|
|
|
!
|
|
|
|
|
! References:
|
|
|
|
|
!
|
|
|
|
|
! [1] Gottlieb, S., Ketcheson, D., Shu C. - W.,
|
|
|
|
|
! "Strong stability preserving Runge-Kutta and multistep
|
|
|
|
|
! time discretizations",
|
|
|
|
|
! World Scientific Publishing, 2011
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
|
|
|
|
subroutine evolve_ssprk4_10()
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
|
use boundaries, only : boundary_fluxes
|
2021-09-20 08:44:38 -03:00
|
|
|
|
use equations , only : ibp, cmax
|
2021-07-11 01:26:15 -03:00
|
|
|
|
use sources , only : update_sources
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
type(block_data), pointer :: pdata
|
|
|
|
|
|
|
|
|
|
integer :: n
|
|
|
|
|
real(kind=8) :: tm, dtm
|
2019-02-12 17:36:27 -02:00
|
|
|
|
|
|
|
|
|
real(kind=8), dimension(9) :: ds
|
|
|
|
|
|
|
|
|
|
real(kind=8), dimension(9), parameter :: c = &
|
|
|
|
|
(/ 1.0d+00, 2.0d+00, 3.0d+00, 4.0d+00, 2.0d+00, &
|
|
|
|
|
3.0d+00, 4.0d+00, 5.0d+00, 6.0d+00 /) / 6.0d+00
|
2019-02-08 08:48:32 -02:00
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call start_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2019-02-12 17:36:27 -02:00
|
|
|
|
ds(:) = c(:) * dt
|
|
|
|
|
|
2019-02-08 08:48:32 -02:00
|
|
|
|
!= 1st step: U(2) = U(1)
|
|
|
|
|
!
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = pdata%uu(:,:,:,:,1)
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
2019-02-12 17:36:27 -02:00
|
|
|
|
!= 2nd step: U(1) = [1 + dt/6 L] U(1), for i = 1, ..., 5
|
2019-02-08 08:48:32 -02:00
|
|
|
|
!
|
2019-02-12 17:36:27 -02:00
|
|
|
|
do n = 1, 5
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
2019-02-12 17:36:27 -02:00
|
|
|
|
tm = time + ds(n)
|
|
|
|
|
dtm = ds(1)
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,1) = pdata%uu(:,:,:,:,1) + dtm * pdata%du(:,:,:,:)
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
|
|
|
|
call update_variables(tm, dtm)
|
|
|
|
|
|
2019-02-12 17:36:27 -02:00
|
|
|
|
end do ! n = 1, 5
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
2019-02-08 12:52:30 -02:00
|
|
|
|
!= 3rd step: U(2) = U(2)/25 + 9/25 U(1), U(1) = 15 U(2) - 5 U(1)
|
2019-02-08 08:48:32 -02:00
|
|
|
|
!
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,2) = (pdata%uu(:,:,:,:,2) &
|
|
|
|
|
+ 9.0d+00 * pdata%uu(:,:,:,:,1)) / 2.5d+01
|
|
|
|
|
pdata%uu(:,:,:,:,1) = 1.5d+01 * pdata%uu(:,:,:,:,2) &
|
|
|
|
|
- 5.0d+00 * pdata%uu(:,:,:,:,1)
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
2019-02-12 17:36:27 -02:00
|
|
|
|
!= 4th step: U(1) = [1 + dt/6 L] U(1), for i = 6, ..., 9
|
2019-02-08 08:48:32 -02:00
|
|
|
|
!
|
|
|
|
|
! integrate the intermediate steps
|
|
|
|
|
!
|
2019-02-08 12:52:30 -02:00
|
|
|
|
do n = 6, 9
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
2019-02-12 17:36:27 -02:00
|
|
|
|
tm = time + ds(n)
|
|
|
|
|
dtm = ds(1)
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%uu(:,:,:,:,1) = pdata%uu(:,:,:,:,1) + dtm * pdata%du(:,:,:,:)
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
|
|
|
|
call update_variables(tm, dtm)
|
|
|
|
|
|
|
|
|
|
end do ! n = 6, 9
|
|
|
|
|
|
|
|
|
|
!= the final step: U(n+1) = U(2) + 3/5 U(1) + 1/10 dt F[U(1)]
|
|
|
|
|
!
|
|
|
|
|
tm = time + dt
|
2019-02-12 17:36:27 -02:00
|
|
|
|
dtm = dt / 1.0d+01
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2019-02-08 09:28:44 -02:00
|
|
|
|
call update_increment(pdata)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
call update_sources(pdata, tm, dtm, pdata%du(:,:,:,:))
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2021-07-11 01:26:15 -03:00
|
|
|
|
call boundary_fluxes()
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-07-10 14:05:00 -03:00
|
|
|
|
pdata%uu(:,:,:,:,1) = pdata%uu(:,:,:,:,2) &
|
2021-07-10 17:51:28 -03:00
|
|
|
|
+ 6.0d-01 * pdata%uu(:,:,:,:,1) &
|
|
|
|
|
+ dtm * pdata%du(:,:,:,:)
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
2021-07-10 18:52:55 -03:00
|
|
|
|
end do
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
if (ibp > 0) then
|
2021-09-20 08:44:38 -03:00
|
|
|
|
adecay(:) = exp(aglm(:) * cmax * dt)
|
|
|
|
|
|
2021-07-10 18:52:55 -03:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
2021-09-20 08:44:38 -03:00
|
|
|
|
pdata%u(ibp,:,:,:) = adecay(pdata%meta%level) * pdata%u(ibp,:,:,:)
|
2021-07-10 18:52:55 -03:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
end if
|
2019-02-08 08:48:32 -02:00
|
|
|
|
|
|
|
|
|
call update_variables(tm, dtm)
|
|
|
|
|
|
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
call stop_timer(imu)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
end subroutine evolve_ssprk4_10
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2014-05-27 16:29:53 -03:00
|
|
|
|
! subroutine UPDATE_INCREMENT:
|
|
|
|
|
! ---------------------------
|
|
|
|
|
!
|
2015-01-09 13:38:18 -02:00
|
|
|
|
! Subroutine calculates the conservative variable increment from
|
|
|
|
|
! directional fluxes.
|
2014-05-27 16:29:53 -03:00
|
|
|
|
!
|
|
|
|
|
! Arguments:
|
|
|
|
|
!
|
2015-01-09 13:38:18 -02:00
|
|
|
|
! pdata - the point to data block storing the directional fluxes;
|
2014-05-27 16:29:53 -03:00
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2019-02-08 09:28:44 -02:00
|
|
|
|
subroutine update_increment(pdata)
|
2014-05-27 16:29:53 -03:00
|
|
|
|
|
|
|
|
|
! include external variables
|
|
|
|
|
!
|
2019-02-08 09:28:44 -02:00
|
|
|
|
use blocks , only : block_data
|
2021-07-10 19:25:44 -03:00
|
|
|
|
use coordinates, only : nbl, ne, neu, nn => bcells
|
2021-07-10 18:26:52 -03:00
|
|
|
|
use coordinates, only : adx, ady, adxi, adyi
|
2020-08-06 10:44:36 -03:00
|
|
|
|
#if NDIMS == 3
|
2021-07-10 18:26:52 -03:00
|
|
|
|
use coordinates, only : adz, adzi
|
2020-08-06 10:44:36 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2019-10-02 21:16:29 -03:00
|
|
|
|
use equations , only : nf, ns
|
|
|
|
|
use equations , only : idn, isl, isu
|
2021-07-10 18:26:52 -03:00
|
|
|
|
use schemes , only : update_flux
|
2014-05-27 16:29:53 -03:00
|
|
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
|
!
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
! subroutine arguments
|
|
|
|
|
!
|
2019-02-08 09:28:44 -02:00
|
|
|
|
type(block_data), pointer, intent(inout) :: pdata
|
2014-05-27 16:29:53 -03:00
|
|
|
|
|
|
|
|
|
! local variables
|
|
|
|
|
!
|
2019-10-02 21:16:29 -03:00
|
|
|
|
integer :: i , j , k = 1, p
|
2020-08-06 10:44:36 -03:00
|
|
|
|
integer :: im1, ip1
|
|
|
|
|
integer :: jm1, jp1
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
|
integer :: km1, kp1
|
|
|
|
|
#endif /* NDIMS == 3 */
|
2019-10-02 21:16:29 -03:00
|
|
|
|
real(kind=8) :: df
|
2021-07-10 18:26:52 -03:00
|
|
|
|
|
|
|
|
|
real(kind=8), dimension(NDIMS) :: dh, dhi
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
|
real(kind=8), dimension(nf,nn,nn,nn,3) :: f
|
|
|
|
|
#else /* NDIMS == 3 */
|
|
|
|
|
real(kind=8), dimension(nf,nn,nn, 1,2) :: f
|
|
|
|
|
#endif /* NDIMS == 3 */
|
2014-05-27 16:29:53 -03:00
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
2015-01-09 13:38:18 -02:00
|
|
|
|
! start accounting time for the increment update
|
2014-09-14 20:38:53 -03:00
|
|
|
|
!
|
2015-01-09 13:38:18 -02:00
|
|
|
|
call start_timer(iui)
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2015-01-09 13:38:18 -02:00
|
|
|
|
! prepare the coordinate intervals
|
2014-05-27 16:29:53 -03:00
|
|
|
|
!
|
2021-07-10 18:26:52 -03:00
|
|
|
|
dh(1) = adx(pdata%meta%level)
|
|
|
|
|
dh(2) = ady(pdata%meta%level)
|
2014-05-27 16:29:53 -03:00
|
|
|
|
#if NDIMS == 3
|
2021-07-10 18:26:52 -03:00
|
|
|
|
dh(3) = adz(pdata%meta%level)
|
2014-05-27 16:29:53 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2021-07-10 18:26:52 -03:00
|
|
|
|
dhi(1) = adxi(pdata%meta%level)
|
|
|
|
|
dhi(2) = adyi(pdata%meta%level)
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
|
dhi(3) = adzi(pdata%meta%level)
|
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
|
|
|
|
|
! calculate the interface fluxes
|
|
|
|
|
!
|
|
|
|
|
call update_flux(dh(1:NDIMS), pdata%q(:,:,:,:), f(:,:,:,:,1:NDIMS))
|
2014-05-27 16:29:53 -03:00
|
|
|
|
|
2021-07-10 19:25:44 -03:00
|
|
|
|
! store block interface fluxes
|
|
|
|
|
!
|
|
|
|
|
pdata%fx(:,1,:,:) = f(:,nbl,:,:,1)
|
|
|
|
|
pdata%fx(:,2,:,:) = f(:,ne ,:,:,1)
|
|
|
|
|
pdata%fy(:,:,1,:) = f(:,:,nbl,:,2)
|
|
|
|
|
pdata%fy(:,:,2,:) = f(:,:,ne ,:,2)
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
|
pdata%fz(:,:,:,1) = f(:,:,:,nbl,3)
|
|
|
|
|
pdata%fz(:,:,:,2) = f(:,:,:,ne ,3)
|
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
|
2015-01-09 13:38:18 -02:00
|
|
|
|
! calculate the variable update from the directional fluxes
|
2014-05-27 16:29:53 -03:00
|
|
|
|
!
|
2015-01-09 13:38:18 -02:00
|
|
|
|
#if NDIMS == 3
|
2019-02-05 13:06:24 -02:00
|
|
|
|
do k = nbl, neu
|
2015-01-09 13:38:18 -02:00
|
|
|
|
km1 = k - 1
|
|
|
|
|
#endif /* NDIMS == 3 */
|
2019-02-05 13:06:24 -02:00
|
|
|
|
do j = nbl, neu
|
2015-01-09 13:38:18 -02:00
|
|
|
|
jm1 = j - 1
|
2019-02-05 13:06:24 -02:00
|
|
|
|
do i = nbl, neu
|
2015-01-09 13:38:18 -02:00
|
|
|
|
im1 = i - 1
|
2014-05-27 16:29:53 -03:00
|
|
|
|
|
|
|
|
|
#if NDIMS == 3
|
2021-07-10 18:26:52 -03:00
|
|
|
|
pdata%du(1:nf,i,j,k) = - dhi(1) * (f(:,i,j,k,1) - f(:,im1,j,k,1)) &
|
|
|
|
|
- dhi(2) * (f(:,i,j,k,2) - f(:,i,jm1,k,2)) &
|
|
|
|
|
- dhi(3) * (f(:,i,j,k,3) - f(:,i,j,km1,3))
|
2015-01-09 13:38:18 -02:00
|
|
|
|
#else /* NDIMS == 3 */
|
2021-07-10 18:26:52 -03:00
|
|
|
|
pdata%du(1:nf,i,j,k) = - dhi(1) * (f(:,i,j,k,1) - f(:,im1,j,k,1)) &
|
|
|
|
|
- dhi(2) * (f(:,i,j,k,2) - f(:,i,jm1,k,2))
|
2014-05-27 16:29:53 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2019-02-05 13:06:24 -02:00
|
|
|
|
end do ! i = nbl, neu
|
|
|
|
|
end do ! j = nbl, neu
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
|
end do ! k = nbl, neu
|
2014-05-27 16:29:53 -03:00
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
|
2019-10-02 21:16:29 -03:00
|
|
|
|
! update passive scalars
|
|
|
|
|
!
|
|
|
|
|
if (ns > 0) then
|
|
|
|
|
|
|
|
|
|
! reset passive scalar increments
|
|
|
|
|
!
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%du(isl:isu,:,:,:) = 0.0d+00
|
2019-10-02 21:16:29 -03:00
|
|
|
|
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
|
do k = nbl - 1, neu
|
|
|
|
|
kp1 = k + 1
|
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
do j = nbl - 1, neu
|
|
|
|
|
jp1 = j + 1
|
|
|
|
|
do i = nbl - 1, neu
|
|
|
|
|
ip1 = i + 1
|
|
|
|
|
|
|
|
|
|
! X-face
|
|
|
|
|
!
|
2021-07-10 18:26:52 -03:00
|
|
|
|
if (f(idn,i,j,k,1) >= 0.0d+00) then
|
2019-10-02 21:16:29 -03:00
|
|
|
|
do p = isl, isu
|
2021-07-10 18:26:52 -03:00
|
|
|
|
df = dhi(1) * f(idn,i,j,k,1) * pdata%q(p,i ,j,k)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%du(p,i ,j,k) = pdata%du(p,i ,j,k) - df
|
|
|
|
|
pdata%du(p,ip1,j,k) = pdata%du(p,ip1,j,k) + df
|
2019-10-02 21:16:29 -03:00
|
|
|
|
end do
|
|
|
|
|
else
|
|
|
|
|
do p = isl, isu
|
2021-07-10 18:26:52 -03:00
|
|
|
|
df = dhi(1) * f(idn,i,j,k,1) * pdata%q(p,ip1,j,k)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%du(p,i ,j,k) = pdata%du(p,i ,j,k) - df
|
|
|
|
|
pdata%du(p,ip1,j,k) = pdata%du(p,ip1,j,k) + df
|
2019-10-02 21:16:29 -03:00
|
|
|
|
end do
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
! Y-face
|
|
|
|
|
!
|
2021-07-10 18:26:52 -03:00
|
|
|
|
if (f(idn,i,j,k,2) >= 0.0d+00) then
|
2019-10-02 21:16:29 -03:00
|
|
|
|
do p = isl, isu
|
2021-07-10 18:26:52 -03:00
|
|
|
|
df = dhi(2) * f(idn,i,j,k,2) * pdata%q(p,i,j ,k)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%du(p,i,j ,k) = pdata%du(p,i,j ,k) - df
|
|
|
|
|
pdata%du(p,i,jp1,k) = pdata%du(p,i,jp1,k) + df
|
2019-10-02 21:16:29 -03:00
|
|
|
|
end do
|
|
|
|
|
else
|
|
|
|
|
do p = isl, isu
|
2021-07-10 18:26:52 -03:00
|
|
|
|
df = dhi(2) * f(idn,i,j,k,2) * pdata%q(p,i,jp1,k)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%du(p,i,j ,k) = pdata%du(p,i,j ,k) - df
|
|
|
|
|
pdata%du(p,i,jp1,k) = pdata%du(p,i,jp1,k) + df
|
2019-10-02 21:16:29 -03:00
|
|
|
|
end do
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
|
! Z-face
|
|
|
|
|
!
|
2021-07-10 18:26:52 -03:00
|
|
|
|
if (f(idn,i,j,k,3) >= 0.0d+00) then
|
2019-10-02 21:16:29 -03:00
|
|
|
|
do p = isl, isu
|
2021-07-10 18:26:52 -03:00
|
|
|
|
df = dhi(3) * f(idn,i,j,k,3) * pdata%q(p,i,j,k )
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%du(p,i,j,k ) = pdata%du(p,i,j,k ) - df
|
|
|
|
|
pdata%du(p,i,j,kp1) = pdata%du(p,i,j,kp1) + df
|
2019-10-02 21:16:29 -03:00
|
|
|
|
end do
|
|
|
|
|
else
|
|
|
|
|
do p = isl, isu
|
2021-07-10 18:26:52 -03:00
|
|
|
|
df = dhi(3) * f(idn,i,j,k,3) * pdata%q(p,i,j,kp1)
|
2021-07-10 17:51:28 -03:00
|
|
|
|
pdata%du(p,i,j,k ) = pdata%du(p,i,j,k ) - df
|
|
|
|
|
pdata%du(p,i,j,kp1) = pdata%du(p,i,j,kp1) + df
|
2019-10-02 21:16:29 -03:00
|
|
|
|
end do
|
|
|
|
|
end if
|
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
|
|
|
|
|
end do ! i = nbl, neu
|
|
|
|
|
end do ! j = nbl, neu
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
|
end do ! k = nbl, neu
|
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
end if
|
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
2015-01-09 13:38:18 -02:00
|
|
|
|
! stop accounting time for the increment update
|
2014-09-14 20:38:53 -03:00
|
|
|
|
!
|
2015-01-09 13:38:18 -02:00
|
|
|
|
call stop_timer(iui)
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2014-05-27 16:29:53 -03:00
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
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.
|
|
|
|
|
!
|
2015-05-16 15:58:01 -03:00
|
|
|
|
! Arguments:
|
|
|
|
|
!
|
|
|
|
|
! tm - time at the moment of update;
|
|
|
|
|
! dtm - time step since the last update;
|
2012-07-31 16:38:16 -03:00
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
2015-05-16 15:58:01 -03:00
|
|
|
|
subroutine update_variables(tm, dtm)
|
2012-07-31 16:38:16 -03:00
|
|
|
|
|
2012-08-01 12:56:52 -03:00
|
|
|
|
! include external procedures
|
|
|
|
|
!
|
2018-08-07 14:13:34 -03:00
|
|
|
|
use blocks , only : set_neighbors_update
|
2015-05-11 07:33:29 -03:00
|
|
|
|
use boundaries , only : boundary_variables
|
2012-08-01 12:56:52 -03:00
|
|
|
|
use equations , only : update_primitive_variables
|
2018-01-16 09:57:23 -02:00
|
|
|
|
use equations , only : fix_unphysical_cells, correct_unphysical_states
|
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
|
|
|
|
|
|
2015-05-16 15:58:01 -03:00
|
|
|
|
! subroutine arguments
|
|
|
|
|
!
|
|
|
|
|
real(kind=8), intent(in) :: tm, dtm
|
|
|
|
|
|
2012-07-31 16:38:16 -03:00
|
|
|
|
! 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-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
! start accounting time for variable update
|
|
|
|
|
!
|
|
|
|
|
call start_timer(imv)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2015-05-16 10:31:16 -03:00
|
|
|
|
! update primitive variables in the changed blocks
|
2014-01-23 10:56:29 -02:00
|
|
|
|
!
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
pmeta => pdata%meta
|
2012-07-31 16:38:16 -03:00
|
|
|
|
|
2015-05-16 10:31:16 -03:00
|
|
|
|
if (pmeta%update) call update_primitive_variables(pdata%u, pdata%q)
|
2012-07-31 16:38:16 -03:00
|
|
|
|
|
2014-01-23 10:56:29 -02:00
|
|
|
|
pdata => pdata%next
|
2012-07-31 16:38:16 -03:00
|
|
|
|
end do
|
|
|
|
|
|
2015-05-11 07:33:29 -03:00
|
|
|
|
! update boundaries
|
|
|
|
|
!
|
2017-03-07 16:02:01 -03:00
|
|
|
|
call boundary_variables(tm, dtm)
|
2015-05-11 07:33:29 -03:00
|
|
|
|
|
2020-11-26 10:50:49 -03:00
|
|
|
|
! apply shapes in blocks which need it
|
|
|
|
|
!
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
pmeta => pdata%meta
|
|
|
|
|
|
|
|
|
|
if (pmeta%update) call update_shapes(pdata, tm, dtm)
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
2018-01-16 09:57:23 -02:00
|
|
|
|
! correct unphysical states if detected
|
|
|
|
|
!
|
|
|
|
|
if (fix_unphysical_cells) then
|
2018-08-07 14:13:34 -03:00
|
|
|
|
|
|
|
|
|
! if an unphysical cell appeared in a block while updating its primitive
|
|
|
|
|
! variables it could be propagated to its neighbors through boundary update;
|
|
|
|
|
! mark all neighbors of such a block to be verified and corrected for
|
|
|
|
|
! unphysical cells too
|
|
|
|
|
!
|
|
|
|
|
pmeta => list_meta
|
|
|
|
|
do while (associated(pmeta))
|
|
|
|
|
|
|
|
|
|
if (pmeta%update) call set_neighbors_update(pmeta)
|
|
|
|
|
|
|
|
|
|
pmeta => pmeta%next
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
! verify and correct, if necessary, unphysical cells in recently updated blocks
|
|
|
|
|
!
|
2018-01-16 09:57:23 -02:00
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
pmeta => pdata%meta
|
|
|
|
|
|
2018-08-07 14:13:34 -03:00
|
|
|
|
if (pmeta%update) &
|
2018-08-23 18:05:00 -03:00
|
|
|
|
call correct_unphysical_states(step, pmeta%id, pdata%q, pdata%u)
|
2018-01-16 09:57:23 -02:00
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
end if
|
|
|
|
|
|
2014-09-14 20:38:53 -03:00
|
|
|
|
#ifdef PROFILE
|
|
|
|
|
! stop accounting time for variable update
|
|
|
|
|
!
|
|
|
|
|
call stop_timer(imv)
|
|
|
|
|
#endif /* PROFILE */
|
|
|
|
|
|
2012-07-31 16:38:16 -03:00
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
end subroutine update_variables
|
2021-10-15 13:51:25 -03:00
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
|
|
|
|
! subroutine UPDATE_ERRORS_L2:
|
|
|
|
|
! ---------------------------
|
|
|
|
|
!
|
|
|
|
|
! Subroutine updates the errors with respect to the absolute and relative
|
|
|
|
|
! tolerances using the L2 norm. The errors are calculated per variable.
|
|
|
|
|
!
|
|
|
|
|
! Arguments:
|
|
|
|
|
!
|
|
|
|
|
! n - the index of the higher order solution
|
|
|
|
|
! m - the index of the lower order solution
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
|
|
|
|
subroutine update_errors_l2(n, m)
|
|
|
|
|
|
|
|
|
|
use blocks , only : block_data, list_data, get_nleafs
|
|
|
|
|
use coordinates, only : ncells, nb, ne
|
|
|
|
|
use equations , only : nf, errors
|
|
|
|
|
#ifdef MPI
|
|
|
|
|
use mpitools , only : reduce_sum
|
|
|
|
|
#endif /* MPI */
|
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
integer, intent(in) :: n, m
|
|
|
|
|
|
|
|
|
|
integer :: l
|
|
|
|
|
real(kind=8) :: fnorm
|
|
|
|
|
|
|
|
|
|
type(block_data), pointer :: pdata
|
|
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
errors(:) = 0.0d+00
|
|
|
|
|
fnorm = 1.0d+00 / (get_nleafs() * ncells**NDIMS)
|
|
|
|
|
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
do l = 1, nf
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
|
errors(l) = errors(l) + &
|
|
|
|
|
sum((abs(pdata%uu(l,nb:ne,nb:ne,nb:ne,n) &
|
|
|
|
|
- pdata%uu(l,nb:ne,nb:ne,nb:ne,m)) / &
|
|
|
|
|
(atol + rtol * &
|
|
|
|
|
max(abs(pdata%uu(l,nb:ne,nb:ne,nb:ne,n)), &
|
|
|
|
|
abs(pdata%uu(l,nb:ne,nb:ne,nb:ne,m)))))**2)
|
|
|
|
|
#else /* NDIMS == 3 */
|
|
|
|
|
errors(l) = errors(l) + &
|
|
|
|
|
sum((abs(pdata%uu(l,nb:ne,nb:ne, : ,n) &
|
|
|
|
|
- pdata%uu(l,nb:ne,nb:ne, : ,m)) / &
|
|
|
|
|
(atol + rtol * &
|
|
|
|
|
max(abs(pdata%uu(l,nb:ne,nb:ne, : ,n)), &
|
|
|
|
|
abs(pdata%uu(l,nb:ne,nb:ne, : ,m)))))**2)
|
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
#ifdef MPI
|
|
|
|
|
call reduce_sum(errors)
|
|
|
|
|
#endif /* MPI */
|
|
|
|
|
|
|
|
|
|
errors(:) = sqrt(fnorm * errors(:))
|
|
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
end subroutine update_errors_l2
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
|
|
|
|
! subroutine UPDATE_ERRORS_MAX:
|
|
|
|
|
! ----------------------------
|
|
|
|
|
!
|
|
|
|
|
! Subroutine updates the errors with respect to the absolute and relative
|
|
|
|
|
! tolerances using the maximum norm. The errors are calculated per variable.
|
|
|
|
|
!
|
|
|
|
|
! Arguments:
|
|
|
|
|
!
|
|
|
|
|
! n - the index of the higher order solution
|
|
|
|
|
! m - the index of the lower order solution
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
|
|
|
|
subroutine update_errors_max(n, m)
|
|
|
|
|
|
|
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
|
use coordinates, only : nb, ne
|
|
|
|
|
use equations , only : nf, errors
|
|
|
|
|
#ifdef MPI
|
|
|
|
|
use mpitools , only : reduce_maximum
|
|
|
|
|
#endif /* MPI */
|
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
integer, intent(in) :: n, m
|
|
|
|
|
|
|
|
|
|
integer :: l
|
|
|
|
|
|
|
|
|
|
type(block_data), pointer :: pdata
|
|
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
errors(:) = 0.0d+00
|
|
|
|
|
|
|
|
|
|
pdata => list_data
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
do l = 1, nf
|
|
|
|
|
#if NDIMS == 3
|
|
|
|
|
errors(l) = max(errors(l), &
|
|
|
|
|
maxval(abs(pdata%uu(l,nb:ne,nb:ne,nb:ne,n) &
|
|
|
|
|
- pdata%uu(l,nb:ne,nb:ne,nb:ne,m)) / &
|
|
|
|
|
(atol + rtol * &
|
|
|
|
|
max(abs(pdata%uu(l,nb:ne,nb:ne,nb:ne,n)), &
|
|
|
|
|
abs(pdata%uu(l,nb:ne,nb:ne,nb:ne,m))))))
|
|
|
|
|
#else /* NDIMS == 3 */
|
|
|
|
|
errors(l) = max(errors(l), &
|
|
|
|
|
maxval(abs(pdata%uu(l,nb:ne,nb:ne, : ,n) &
|
|
|
|
|
- pdata%uu(l,nb:ne,nb:ne, : ,m)) / &
|
|
|
|
|
(atol + rtol * &
|
|
|
|
|
max(abs(pdata%uu(l,nb:ne,nb:ne, : ,n)), &
|
|
|
|
|
abs(pdata%uu(l,nb:ne,nb:ne, : ,m))))))
|
|
|
|
|
#endif /* NDIMS == 3 */
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
#ifdef MPI
|
|
|
|
|
call reduce_maximum(errors)
|
|
|
|
|
#endif /* MPI */
|
|
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
end subroutine update_errors_max
|
2014-07-14 13:25:30 -03:00
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
|
|
|
|
! subroutine CHECK_VARIABLES:
|
|
|
|
|
! --------------------------
|
|
|
|
|
!
|
|
|
|
|
! Subroutine iterates over all data blocks and converts the conservative
|
|
|
|
|
! variables to their primitive representation.
|
|
|
|
|
!
|
|
|
|
|
!
|
|
|
|
|
!===============================================================================
|
|
|
|
|
!
|
|
|
|
|
subroutine check_variables()
|
|
|
|
|
|
|
|
|
|
! include external procedures
|
|
|
|
|
!
|
2019-02-05 13:06:24 -02:00
|
|
|
|
use coordinates , only : nn => bcells
|
2018-08-28 22:49:51 -03:00
|
|
|
|
use equations , only : nv, pvars, cvars
|
|
|
|
|
use ieee_arithmetic, only : ieee_is_nan
|
2014-07-14 13:25:30 -03:00
|
|
|
|
|
|
|
|
|
! include external variables
|
|
|
|
|
!
|
|
|
|
|
use blocks , only : block_meta, list_meta
|
|
|
|
|
use blocks , only : block_data, list_data
|
|
|
|
|
|
|
|
|
|
! local variables are not implicit by default
|
|
|
|
|
!
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
! local variables
|
|
|
|
|
!
|
2019-02-05 10:01:37 -02:00
|
|
|
|
integer :: i, j, k = 1, p
|
2014-07-14 13:25:30 -03:00
|
|
|
|
|
|
|
|
|
! local pointers
|
|
|
|
|
!
|
|
|
|
|
type(block_meta), pointer :: pmeta
|
|
|
|
|
type(block_data), pointer :: pdata
|
|
|
|
|
!
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
! associate the pointer with the first block on the data block list
|
|
|
|
|
!
|
|
|
|
|
pdata => list_data
|
|
|
|
|
|
|
|
|
|
! iterate over all data blocks
|
|
|
|
|
!
|
|
|
|
|
do while (associated(pdata))
|
|
|
|
|
|
|
|
|
|
! associate pmeta with the corresponding meta block
|
|
|
|
|
!
|
|
|
|
|
pmeta => pdata%meta
|
|
|
|
|
|
|
|
|
|
! check if there are NaNs in primitive variables
|
|
|
|
|
!
|
2019-02-05 10:01:37 -02:00
|
|
|
|
#if NDIMS == 3
|
2019-02-05 13:06:24 -02:00
|
|
|
|
do k = 1, nn
|
2019-02-05 10:01:37 -02:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2019-02-05 13:06:24 -02:00
|
|
|
|
do j = 1, nn
|
|
|
|
|
do i = 1, nn
|
2014-07-14 13:25:30 -03:00
|
|
|
|
do p = 1, nv
|
2014-08-13 07:31:05 -03:00
|
|
|
|
if (ieee_is_nan(pdata%u(p,i,j,k))) then
|
|
|
|
|
print *, 'U NaN:', cvars(p), pdata%meta%id, i, j, k
|
|
|
|
|
end if
|
2014-08-13 07:43:14 -03:00
|
|
|
|
if (ieee_is_nan(pdata%q(p,i,j,k))) then
|
2014-08-13 07:31:05 -03:00
|
|
|
|
print *, 'Q NaN:', pvars(p), pdata%meta%id, i, j, k
|
|
|
|
|
end if
|
2014-07-14 13:25:30 -03:00
|
|
|
|
end do ! p = 1, nv
|
2019-02-05 13:06:24 -02:00
|
|
|
|
end do ! i = 1, nn
|
|
|
|
|
end do ! j = 1, nn
|
2019-02-05 10:01:37 -02:00
|
|
|
|
#if NDIMS == 3
|
2019-02-05 13:06:24 -02:00
|
|
|
|
end do ! k = 1, nn
|
2019-02-05 10:01:37 -02:00
|
|
|
|
#endif /* NDIMS == 3 */
|
2014-07-14 13:25:30 -03:00
|
|
|
|
|
|
|
|
|
! assign pointer to the next block
|
|
|
|
|
!
|
|
|
|
|
pdata => pdata%next
|
|
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
|
!
|
|
|
|
|
end subroutine check_variables
|
|
|
|
|
#endif /* DEBUG */
|
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
|