ode - MATLAB: Saving parameters inside ode45 using 'assignin' -
i'm running set of odes ode45 in matlab , need save 1 of variables (that's not derivative) later use. i'm using function 'assignin' assign temporary variable in base workspace , updating @ each step. seems work, however, size of array not match size of solution vector acquired ode45. example, have following nested function:
function [z,y] = droplet_momentum(theta,k,g,p,zspan,y0) options = odeset('reltol',1e-7,'abstol',1e-7); [z,y] = ode45(@momentum,zspan,y0,options); function dy = momentum(z,y) dy = zeros(4,1); %entrained total velocity ve = sin(theta)*(y(4)); %total relative velocity urs = sqrt((y(1) - y(4))^2 + (y(2) - ve*cos(theta))^2 + (y(3))^2); %coefficients psi = k*urs/y(1); phi = p*urs/y(1); %liquid axial velocity dy(1) = psi*sign(y(1) - y(4))*(1 + (1/6)*(abs(y(1) - y(4))*g)^(2/3)); %liquid radial velocity dy(2) = psi*sign(y(2) - ve*cos(theta))*(1 + (1/6)*(abs(y(2) - ... ve*cos(theta))*g)^(2/3)); %liquid tangential velocity dy(3) = psi*sign(y(3))*(1 + (1/6)*(abs(y(3))*g)^(2/3)); %gaseous axial velocity dy(4) = (1/z/y(4))*((phi/z)*sign(y(1) - y(4))*(1 + ... (1/6)*(abs(y(1) - y(4))*g)^(2/3)) + ve*ve - y(4)*y(4)); assignin('base','ve_step',ve); evalin('base','ve_out(end+1) = ve_step'); end end in above code, theta (radians), k (negative value), p, & g constants , sake of example can taken value. zspan integration time step ode solver , y0 initial conditions vector (4x1). again, sake of example these can take reasonable value. in main file, function called following:
ve_out = 0; [z,y] = droplet_momentum(theta,k,g,p,zspan,y0); ve_out = ve_out(2:end); this method works without complaint matlab, problem size of ve_out not same size of z or y. reason because matlab calls ode function multiple times algorithm, solution going smaller ve_out. am304 suggested, calculated dy giving ode function z , y vector such dy = momentum(z,y), however, need working 'assignin' (or similar method) because version of problem has implicit dependence between dy , ve , computationally expensive calculate dy @ every iteration (i running problem many iterations).
ok, let's start off quick example of sscce:
function [z,y] = khan options = odeset('reltol',1e-7,'abstol',1e-7); [z,y] = ode45(@momentum,[0 12],[0 0],options); end function dy = momentum(z,y) dy = [0 0]'; dy(1) = 3*y(1) + 2* y(2) - 2; dy(2) = y(1) - y(2); ve = dy(1)+ y(2); assignin('base','ve_step',ve); evalin('base','ve_out(end+1) = ve_step;'); assignin('base','t_step',z); evalin('base','t_out(end+1) = t_step;'); end by running [z,y] = khan command line, complete functional code demonstrates problem, without headaches associated. patience has been exhausted: live , learn.
this seems work, however, size of array not match size of solution vector acquired ode45
note added 2 lines code extracts time variable. command prompt, 1 has run following understand what's going on:
ve_out = []; t_out = []; [z,y] = khan; size (z) size (t_out) size (ve_out) plot (diff(t_out)) ans = 109 1 ans = 1 163 ans = 1 163 
basically ode45 iterative algorithm, means regularly course correct (that's why regularly see diff(t) = 0). can't force algorithm want, have live it.
so options are
1. use fixed step algorithm
2. have function call reproduces want after ode45 algorithm has done dirty work. (am304's solution)
3. collects data time function, have algorithm parse through removes data.
Comments
Post a Comment