Integrate field with explicit embedded Runge-Kutta scheme, fast mode.
The time steps is adaptively resized using the local truncation error estimation by means of the embedded pairs of RK schemes.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(integrator_runge_kutta_emd), | intent(inout) | :: | self | Integrator. |
||
class(integrand_object), | intent(inout) | :: | U | Field to be integrated. |
||
real(kind=R_P), | intent(in) | :: | Dt | Time step. |
||
real(kind=R_P), | intent(in) | :: | t | Time. |
||
real(kind=R_P), | intent(out), | optional | :: | new_Dt | New adapted time step. |
subroutine integrate_fast(self, U, Dt, t, new_Dt)
!< Integrate field with explicit embedded Runge-Kutta scheme, fast mode.
!<
!< The time steps is adaptively resized using the local truncation error estimation by means of the embedded pairs of RK schemes.
class(integrator_runge_kutta_emd), intent(inout) :: self !< Integrator.
class(integrand_object), intent(inout) :: U !< Field to be integrated.
real(R_P), intent(in) :: Dt !< Time step.
real(R_P), intent(in) :: t !< Time.
real(R_P), intent(out), optional :: new_Dt !< New adapted time step.
real(R_P) :: Dt_ !< Time step, local variable.
real(R_P) :: error !< Local truncation error estimation.
integer(I_P) :: s !< First stages counter.
integer(I_P) :: ss !< Second stages counter.
Dt_ = Dt
do
! compute stages
do s=1, self%stages
self%stage(s) = U
do ss=1, s - 1
call self%buffer%multiply_fast(lhs=self%stage(ss), rhs=Dt_ * self%alph(s, ss))
call self%stage(s)%add_fast(lhs=self%stage(s), rhs=self%buffer)
enddo
call self%stage(s)%t_fast(t=t + self%gamm(s) * Dt_)
enddo
! compute new time step
self%U1 = U
self%U2 = U
do s=1, self%stages
call self%buffer%multiply_fast(lhs=self%stage(s), rhs=Dt_ * self%beta(s, 1))
call self%U1%add_fast(lhs=self%U1, rhs=self%buffer)
call self%buffer%multiply_fast(lhs=self%stage(s), rhs=Dt_ * self%beta(s, 2))
call self%U2%add_fast(lhs=self%U2, rhs=self%buffer)
enddo
error = self%U2.lterror.self%U1
if (error <= self%tolerance) exit
call self%new_Dt(error=error, Dt=Dt_)
enddo
U = self%U1
if (present(new_Dt)) new_Dt = Dt_
endsubroutine integrate_fast