subroutine bdf3 ( dydt, tspan, y0, n, m, t, y ) !*****************************************************************************80 ! !! bdf3() uses the BDF3 method + fsolve_bdf3() to solve an ODE. ! ! Licensing: ! ! This code is distributed under the MIT license. ! ! Modified: ! ! 27 May 2025 ! ! Author: ! ! John Burkardt ! ! Input: ! ! external dydt: a subroutine that evaluates the right ! hand side of the ODE, of the form ! subroutine dydt ( t, y, dy ) ! ! real ( kind = rk8 ) tspan(2): the initial and final times. ! ! real ( kind = rk8 ) y0(m): the initial condition. ! ! integer n: the number of steps to take. ! ! integer m: the number of variables. ! ! Output: ! ! real ( kind = rk8 ) t(n+1), y(n+1,m): the times and solution values. ! implicit none integer, parameter :: rk8 = kind ( 1.0D+00 ) integer m integer n real ( kind = rk8 ) dely(m) real ( kind = rk8 ) dt external dydt real ( kind = rk8 ) fn(m) integer i integer info real ( kind = rk8 ) k1(m) real ( kind = rk8 ) k2(m) real ( kind = rk8 ) k3(m) real ( kind = rk8 ) t(n+1) real ( kind = rk8 ) t1 real ( kind = rk8 ) t2 real ( kind = rk8 ) t3 real ( kind = rk8 ) t4 real ( kind = rk8 ) tol real ( kind = rk8 ) tspan(2) real ( kind = rk8 ) y(n+1,m) real ( kind = rk8 ) y0(m) real ( kind = rk8 ) y1(m) real ( kind = rk8 ) y2(m) real ( kind = rk8 ) y3(m) real ( kind = rk8 ) y4(m) dt = ( tspan(2) - tspan(1) ) / n call r8vec_linspace ( n + 1, tspan(1), tspan(2), t ) tol = 1.0D-05 do i = 0, n ! ! Initial condition. ! if ( i == 0 ) then y(i+1,1:m) = y0(1:m) ! ! Explicit Runge-Kutta order 3 ! else if ( i < 3 ) then call dydt ( t(i), y(i,:), dely ) k1 = dt * dely call dydt ( t(i) + dt, y(i,:) + k1, dely ) k2 = dt * dely call dydt ( t(i) + 0.5D+00 * dt, y(i,:) + 0.25D+00 * k1 + 0.25D+00 * k2, dely ) k3 = dt * dely y(i+1,:) = y(i,:) + ( k1 + k2 + 4.0D+00 * k3 ) / 6.0D+00 ! ! BDF 3 ! else t1 = t(i-2) y1 = y(i-2,:) t2 = t(i-1) y2 = y(i-1,:) t3 = t(i) y3 = y(i,:) t4 = t(i+1) call dydt ( t(i), y(i,:), dely ) y4 = y(i,:) + dt * dely(:) call fsolve_bdf3 ( dydt, m, t1, y1, t2, y2, t3, y3, t4, y4, fn, tol, info ) if ( info /= 1 ) then write ( *, '(a)' ) '' write ( *, '(a)' ) 'bdf3(): Fatal error!' write ( *, '(a,i10)' ) ' info = ', info stop 1 end if y(i+1,1:m) = y4(1:m) end if end do return end