- #1
Dr.D
- 2,412
- 722
- TL;DR Summary
- Is there a way to do preliminary calculations required only one time and then pass the results (via the parameter list?) to the derivative function?
The problem of interest at the moment is the solution of a simple damped oscillator problem,
xddot+2*zeta*wn*xdot+wn^2*x = 0
Everything seems to work fine provided I include the values of zeta and wn inside the function that defines the derivative values.
But zeta and wn are actually calculated from the mass, damping, and stiffness values, M, B, and K, as
wn=sqrt(K/M)
zeta=B/(2*wn*M)
What I'm seeing in Octave is that these calculations must be included inside the derivative evaluation function and executed repeatedly with every function call. Is that true?
For this simple problem this is a trivial waste, but in a more complex problem, with many parameters, it would be desirable to calculate items like wn and zeta before the first call to the function and then pass the computed values to the function as arguments. Is this possible? It does not seem to work, and every example I've found so far, does all the parameter evaluation within the derivative function.
Here is an example (that does not quite work!) of the question above:
In the context of the question above, is it not possible to move lines 4-8 outside the function definition?
As an additional question, does anyone see why this code will not run? If I remove the semi-colon at the end of the call to lsode, I get a two column output that appears to be soln(100,2), but this matrix never shows up in the Workspace list. I'm baffled!
PS: OK, I got the code to function correctly. The 'clear' after the lsode call was wiping out the solution. But the central question of avoiding inclusion of the parameter calcs remains.
xddot+2*zeta*wn*xdot+wn^2*x = 0
Everything seems to work fine provided I include the values of zeta and wn inside the function that defines the derivative values.
But zeta and wn are actually calculated from the mass, damping, and stiffness values, M, B, and K, as
wn=sqrt(K/M)
zeta=B/(2*wn*M)
What I'm seeing in Octave is that these calculations must be included inside the derivative evaluation function and executed repeatedly with every function call. Is that true?
For this simple problem this is a trivial waste, but in a more complex problem, with many parameters, it would be desirable to calculate items like wn and zeta before the first call to the function and then pass the computed values to the function as arguments. Is this possible? It does not seem to work, and every example I've found so far, does all the parameter evaluation within the derivative function.
Here is an example (that does not quite work!) of the question above:
Matlab:
% Test7.m
1; % a do-nothing line to avoid file being a function definition
function zdot=g(z,t)
M=3; % mass
K=9; % stiffness
B=.6; % damping coeff
wn=sqrt(K/M); % undamped nat'l freq
zeta=B/(2*M*wn); % damping factor
zdot(1)=z(2); % x-dot
zdot(2)=-2*zeta*wn*z(2)-wn^2*z(1); % x-ddot
endfunction
tf=2; % final time
soln=lsode("g",[1, 0],t=linspace(0,tf,100));
clear; clf; hold on;
x=soln(:,1)
xd=soln(:,2);
plot(t,x,'k',t,xd,'b'); % plot x(t) and xdot(t)
plot([0 tf],[0 0],'k') % draw time axis
As an additional question, does anyone see why this code will not run? If I remove the semi-colon at the end of the call to lsode, I get a two column output that appears to be soln(100,2), but this matrix never shows up in the Workspace list. I'm baffled!
PS: OK, I got the code to function correctly. The 'clear' after the lsode call was wiping out the solution. But the central question of avoiding inclusion of the parameter calcs remains.
Last edited by a moderator: