# include # include # include # include "bdf2.h" # include "fsolve.h" /******************************************************************************/ void bdf2 ( void dydt ( double x, double y[], double yp[] ), double tspan[2], double y0[], int n, int m, double t[], double y[] ) /******************************************************************************/ /* Purpose: bdf2() approximates the solution to an ODE using the BDF2 method. Licensing: This code is distributed under the MIT license. Modified: 01 December 2023 Author: John Burkardt Input: dydt: a function that evaluates the right hand side of the ODE. double tspan[2]: contains the initial and final times. double y0[m]: a column vector containing the initial condition. int n: the number of steps to take. int m: the number of variables. Output: double t[n+1], y[m*(n+1)]: the times and solution values. */ { double *dely; double dt; double *fn; int i; int info; int j; double t1; double t2; double t3; double tol; double *y1; double *y2; double *y3; dely = ( double * ) malloc ( m * sizeof ( double ) ); fn = ( double * ) malloc ( m * sizeof ( double ) ); y1 = ( double * ) malloc ( m * sizeof ( double ) ); y2 = ( double * ) malloc ( m * sizeof ( double ) ); y3 = ( double * ) malloc ( m * sizeof ( double ) ); dt = ( tspan[1] - tspan[0] ) / ( double ) ( n ); tol = 1.0E-05; for ( i = 0; i <= n; i++ ) { if ( i == 0 ) { t[i] = tspan[0]; for ( j = 0; j < m; j++ ) { y[i*m+j] = y0[j]; } } else if ( i == 1 ) { t1 = t[i-1]; for ( j = 0; j < m; j++ ) { y1[j] = y[(i-1)*m+j]; } t2 = t1 + dt; dydt ( t1, y1, dely ); for ( j = 0; j < m; j++ ) { y2[j] = y1[j] + dt * dely[j]; } info = fsolve_be ( dydt, m, t1, y1, t2, y2, fn, tol ); if ( info != 1 ) { printf ( "\n" ); printf ( "bdf2(): Fatal error!\n" ); printf ( " info = %d\n", info ); exit ( 1 ); } t[i] = t2; for ( j = 0; j < m; j++ ) { y[i*m+j] = y2[j]; } } else { t1 = t[i-2]; for ( j = 0; j < m; j++ ) { y1[j] = y[(i-2)*m+j]; } t2 = t1 + dt; for ( j = 0; j < m; j++ ) { y2[j] = y[(i-1)*m+j]; } t3 = t2 + dt; dydt ( t2, y2, dely ); for ( j = 0; j < m; j++ ) { y3[j] = y2[j] + dt * dely[j]; } info = fsolve_bdf2 ( dydt, m, t1, y1, t2, y2, t3, y3, fn, tol ); if ( info != 1 ) { printf ( "\n" ); printf ( "bdf2(): Fatal error!\n" ); printf ( " info = %d\n", info ); exit ( 1 ); } t[i] = t3; for ( j = 0; j < m; j++ ) { y[i*m+j] = y3[j]; } } } free ( dely ); free ( fn ); free ( y1 ); free ( y2 ); free ( y3 ); return; }