subroutine b1g3 ( dydt, tspan, y0, n, m, t, y ) !*****************************************************************************80 ! !! b1g3() uses the b1g3 method + fsolve_be() to solve an ODE. ! ! Licensing: ! ! This code is distributed under the MIT license. ! ! Modified: ! ! 27 November 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): contains the initial and final times. ! ! real ( kind = rk8 ) y0(m): a column vector containing 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 ) dt external dydt real ( kind = rk8 ) fm(m) integer i integer info real ( kind = rk8 ) t(n+1) real ( kind = rk8 ) t1 real ( kind = rk8 ) t2 real ( kind = rk8 ) t3 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 ) yp1(m) real ( kind = rk8 ) yp2(m) dt = ( tspan(2) - tspan(1) ) / n call r8vec_linspace ( n + 1, tspan(1), tspan(2), t ) info = 0 tol = 1.0D-05 do i = 0, n ! ! Step 0 uses the initial condition. ! if ( i == 0 ) then y(i+1,1:m) = y0(1:m) ! ! Step 1 uses the midpoint method. ! else if ( i == 1 ) then t1 = t(i) y1 = y(i,1:m) call dydt ( t1, y1, yp1 ) t2 = t1 + 0.5D+00 * dt y2 = y1 + 0.5D+00 * yp1 ! ! Call fsolve_be() to compute ym. ! Better: create fsolve_midpoint, returning 2*y2-y1. ! call fsolve_be ( dydt, m, t1, y1, t2, y2, fm, tol, info ) if ( info /= 1 ) then write ( *, '(a)' ) '' write ( *, '(a)' ) 'b1g3(): Fatal error!' write ( *, '(a,i10)' ) ' info = ', info stop 1 end if y(i+1,1:m) = 2.0D+00 * y2 - y1 ! ! Later steps use B1G3. ! else t1 = t(i-1) y1 = y(i-1,:) t2 = t(i) y2 = y(i,:) call dydt ( t2, y2, yp2 ) t3 = t(i+1) y3 = y2 + dt * yp2 call fsolve_b1g3 ( dydt, m, t1, y1, t2, y2, t3, y3, fm, tol, info ); if ( info /= 1 ) then write ( *, '(a)' ) '' write ( *, '(a)' ) 'b1g3(): Fatal error!' write ( *, '(a,i10)' ) ' info = ', info stop 1 end if y(i+1,:) = y3; end if write ( *, '(3g14.6)' ) t(i+1), y(i+1,:) end do return end