| rkA(x,t,tau,err,derivsRK,param)
|
function [x, t, tau] = rkA(x,t,tau,err,derivsRK,param)
% Adaptive Runge-Kutta routine
% Input arguments -
% x = current value of dependent variable
% t = independent variable (usually time)
% tau = step size (usually timestep) to be attempted
% err = desired fractional local truncation error
% derivsRK = right hand side of the ODE; derivsRK is the
% name of the function with returns dx/dt
% Calling format derivsRK(t,x,param).
% param = extra parameters passed to derivsRK
% Output arguments -
% x = new value of the dependent variable
% t = new value of the independent variable
% tau = suggested step size to be used on next call to rkA
tsave = t; xsave = x;
Safe1 = .9; Safe2 = 4.; % Safety factors
maxtry = 100; % Maximum number of attempts
for itry=1:maxtry,
%% Do the two small steps %%
half_tau = 0.5 * tau;
xtemp = rk4(xsave,tsave,half_tau,derivsRK,param);
t = tsave + half_tau;
x = rk4(xtemp,t,half_tau,derivsRK,param);
%% Do the single large step %%
t = tsave + tau;
xtemp = rk4(xsave,tsave,tau,derivsRK,param);
%% Compute the error %%
scale = .5*(abs(x) + abs(xtemp))*err;
xdiff = x - xtemp;
errmax = max(abs(xdiff)./(scale + eps));
%% Estimate new tau value if errmax unacceptable %%
tau_old = tau;
tau = Safe1*tau_old*errmax^(-0.20);
%% Never decrease tau by more than a factor of Safe2 %%
tau = max(tau,tau_old/Safe2);
if errmax < 1, % If error is acceptable, break out of loop
break;
end
end
%% Never increase tau by more than a factor of Safe2 %%
tau = min(tau,Safe2*tau_old);
|
|