spx_time_integration.f90 Source File


Contents


Source Code

!> 时间积分: 采用蛙跳法
module spx_time_integration

    use spx_kinds, only: rk
    use seakeeping_module, only: leapfrog_init, leapfrog
    use spx_env, only: rgn_obj, stat, dt
    use spx_configuration, only: tic_obj, spc_obj
    use fffc_module, only: terminal_obj, progress_bar, display
    use spx_command_line, only: cli_obj
    use spx_dynamics, only: solver
    use spx_logger, only: lgr_obj
    use spx_pif_h5part, only: pif_obj
    use spx_memory, only: mem_obj
    use spx_nnps_pairs, only: pairs
    use spx_math, only: dim
    implicit none

    private
    public :: tig_obj

    !> 时间积分器
    type time_integrator
        real(rk) :: dt  !! 单步时间步长
        real(rk) :: cur_time  !! 当前时刻
    contains
        procedure :: init, run
    end type time_integrator

    type(time_integrator) :: tig_obj  !! 时间积分器对象

contains

    !> 初始化时间积分器
    subroutine init(self)
        class(time_integrator), intent(inout) :: self

        self%dt = tic_obj%cfl*rgn_obj%hsml/spc_obj%c0
        dt = self%dt
        self%cur_time = 0.0_rk
        if (cli_obj%debug_mode) write (lgr_obj%unit, lgr_obj%fmt) 'dt', self%dt

        call display(pif_obj%numbers(4), 'number of total particles:', inline=.true.)
        call display(rgn_obj%hsml, 'smoothing length (m):', inline=.true.)
        call display(tic_obj%stop_time, 'simulation duration (sec):', inline=.true.)
        call display(self%dt, 'time step (sec):', inline=.true.)

    end subroutine init

    !> 时间积分
    !> @note 例程修改了粒子域的位置、速度和加速度
    subroutine run(self)
        class(time_integrator), intent(inout) :: self
        integer :: nstep, nsize, maxstep

        nstep = max(int(tic_obj%dt/self%dt), 1)  ! 一次积分和输出的步数
        nsize = dim*pif_obj%numbers(1)
        maxstep = int(tic_obj%stop_time/self%dt)  ! 最大步数

        call display(nstep, 'number of steps per output:', inline=.true.)
        if (cli_obj%debug_mode) write (lgr_obj%unit, lgr_obj%fmt) 'nstep', nstep
        call terminal_obj%info('start time integration')

        call leapfrog_init(solver, rgn_obj%loc, rgn_obj%vel, rgn_obj%acc, self%cur_time, self%dt, nsize)

        do while (self%cur_time < tic_obj%stop_time)
            call leapfrog(solver, rgn_obj%loc, rgn_obj%vel, rgn_obj%acc, &
                          self%cur_time, nstep, self%dt, nsize)
            call mem_obj%check(pairs%len, pif_obj%numbers(4))
            call stat%update(rgn_obj%loc)           ! 更新统计信息
            call pif_obj%write(self%cur_time)
            call progress_bar(int(self%cur_time/self%dt), maxstep, advance=.false.)
        end do
        call progress_bar(int(self%cur_time/self%dt), maxstep, advance=.true.)

    end subroutine run

end module spx_time_integration