!> 时间积分: 采用蛙跳法 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