I am having trouble figuring out how to fix my script, specifically using the ODE45 command.
This is what I have so far:
clc; clear all;
global I11 I22 I33 Mx My Mz w10 w20 w30 eps10 eps20 eps30 eps40 IC
I11 = 160;
I22 = 400;
I33 = 400;
Mx = 0;
My = 0;
Mz = 45;
w10 = 2;
w20 = -1;
w30 = 1;
eps10 = 0;
eps20 = 0;
eps30 = 0;
eps40 = 1;
IC = [w10 w20 w30 eps10 eps20 eps30 eps40];
function soln = DynEqn1(t,y,I11,I22,I33,Mx,My,Mz)
global I11 I22 I33 Mx My Mz w10 w20 w30 eps10 eps20 eps30 eps40
w1 = y(1);
w2 = y(2);
w3 = y(3);
eps1 = y(4);
eps2 = y(5);
eps3 = y(6);
eps4 = y(7);
w1_dot = Mx - w2*w3*(I33-I22)/I11;
w2_dot = My - w1*w3*(I11-I33)/I22;
w3_dot = Mz - w1*w2*(I22-I11)/I33;
eps1_dot = .5*(w1*eps4-w2*eps3+w3*eps2);
eps2_dot = .5*(w1*eps3+w2*eps4-w3*eps1);
eps3_dot = .5*(-w1*eps2+w2*eps1+w3*eps4);
eps4_dot = -.5*(w1*eps1+w2*eps2+w3*eps3);
soln = [w1_dot; w2_dot; w3_dot; eps1_dot; eps2_dot; eps3_dot; eps4_dot];
end
I recently though the issues was with my variables, which is why I defined them all as global.
When I try to run the following in the command window:
[t, y] = ode45(#(t,y) DynEqn1(t,y,I11,I22,I33,Mx,My,Mz), [0 30], IC);
I get these errors:
>> [t, y] = ode45(#(t,y) DynEqn1(t,y,I11,I22,I33,Mx,My,Mz), [0 30], IC);
Undefined function or variable 'DynEqn1'.
Error in #(t,y)DynEqn1(t,y,I11,I22,I33,Mx,My,Mz)
Error in odearguments (line 90)
f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ode45 (line 115)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);
I've tried researching it on Mathworks and other websites, but couldn't figure out what is the issue.
I'm not too familiar using the 'ODE45' function as well.
Any help is appreciated. Thank you.
Are you defining a local function inside a script file? If so, bear in mind that "Local functions are only visible within the file where they are defined. They are not visible to functions in other files, and cannot be called from the Command Window." (Ref.)
You need to either call ode45(...DynEqn1...) from the script file, rather than the command line, or create a separate file to make the function visible to the outside world.
Related
I'm struggling to use piecewise function in this pdpk model in MATLAB I keep getting the error of
"Error using odearguments (line 113)
Inputs must be floats, namely single or double.
Error in ode45 (line 106)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);"
Please help!
listed code below***
vnf = 1; qnf = 1; vf = 1; qf = 1;
vb = 1; pf = 20; vl = 1; ql = 1;
vmax = 1; Km = 1; pl = 2; pb = 18;
Ci = 0.32; % benzene conc in inhaled air
Qp = 5.74; % alveolar ventilation rate
conds = [0 0 0 0]; %--- initial conditions order: [NF F B L]
pul = piecewise(t > 6, 0, t <= 6, 1);
f = #(t,x) [qnf*(x(3)/vb - x(1)/vnf);...
qf*(x(3)/vb - x(2)/vf/pf);...
-qnf*(x(3)/vb - x(1)/vnf) - qf*(x(3)/vb - x(2)/vf/pf) - ql*(x(3)/vb - x(4)/vl/pl) + pul*Qp*(Ci - (x(3)/vb - pb));...
ql*(x(3)/vb - x(4)/vl/pl) - vmax*x(4)/vl/(Km + x(4)/vl)];
[t,x] = ode45(f, [0 10], conds);
Basically I would like to use the fsolve command in order to find the roots of an equation.
I think I should create a function handle that evaluates this equation in the form "right hand side - left hand side =0", but I've been struggling to make this work. Does anyone know how to do this?
The equation itself is 1/sqrt(f) = -1.74log((1.254/((1.27310^8)sqrt(f)))+((110^-3)/3.708)). So I would like to find the point of intersection of the left and right side by solving for 1/sqrt(f)+(1.74log((1.254/((1.27310^8)sqrt(f)))+((110^-3)/3.708))) = 0 using fsolve.
Thanks a lot!
The code so far (not working at all)
f = #(x) friction(x,rho,mu,e,D,Q, tol, maxIter) ;
xguess = [0, 1];
sol = fsolve(x, xguess ) ;
function y = friction(x,rho,mu,e,D,Q, tol, maxIter)
D = 0.1;
L = 100
rho = 1000;
mu = 0.001;
e = 0.0001;
Q = 0.01;
U = (4*Q)/(pi*D^2);
Re = (rho*U*D)/mu ;
y = (1/sqrt(x))-(-1.74*log((1.254/(Re*sqrt(x)))+((e/D)/3.708)))
end
Error message:
Error using lsqfcnchk (line 80)
FUN must be a function, a valid character vector expression, or an inline function object.
Error in fsolve (line 238)
funfcn = lsqfcnchk(FUN,'fsolve',length(varargin),funValCheck,gradflag);
Error in Untitled (line 6)
sol = fsolve(x, xguess ) ;
opt = optimset('Display', 'Iter');
sol = fsolve(#(x) friction(x), 1, opt);
function y = friction(x)
D = 0.1;
L = 100; % note -- unused
rho = 1000;
mu = 0.001;
e = 0.0001;
Q = 0.01;
U = (4*Q)/(pi*D^2);
Re = (rho*U*D)/mu ;
y = (1/sqrt(x))-(-1.74*log((1.254/(Re*sqrt(x)))+((e/D)/3.708)));
end
sol = 0.0054
the first argument of fsolve should be the function not variable. Replace:
sol = fsolve(x, xguess );
with
sol = fsolve(f, xguess );
And define Rho, mu, e etc before you define f (not inside the friction function).
I have a problem using the MATLAB DAE-solvers.
I'm trying to simulate the behaviour of a mechanical system using lagrangien mechanics. To do so, I followed the following tutorial to use MATLAB'sDAE-solvers.
But when I ran my code, I got the following error message:
Warning: Failure at t=5.076437e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed
(1.803513e-15) at time t.
In ode15i (line 406)
Trying to find my mistake, I literally copied the code from the tutorial and ran it. The code is as follows:
syms l g m real
syms x(t) y(t) T(t)
eqns = [(m*diff(x(t),2) - T(t)/l*x(t)),
(m*diff(y(t),2) - T(t)/l*y(t) + m*g),
(x(t)^2 + y(t)^2 - l^2) ];
vars = [x(t); y(t); T(t)];
[eqns, vars] = reduceDifferentialOrder(eqns, vars);
if(~isLowIndexDAE(eqns, vars))
[DAEs, DAEvars] = reduceDAEIndex(eqns, vars);
[DAEs, DAEvars] = reduceRedundancies(DAEs, DAEvars);
end
%change to function, set parameters
f = daeFunction(DAEs, DAEvars, m, l, g);
m = 1.0;
r = 1.0;
g = 9.81;
F = #(t, Y, YP) f(t, Y, YP, m, r, g);
%get initial conditions
y0est = [0.5*r; -0.8*r; 0; 0; 0; 0; 0];
yp0est = zeros(7,1);
opt = odeset('RelTol', 10.0^(-7), 'AbsTol' , 10.0^(-7));
[y0, yp0] = decic(F, 0, y0est, [], yp0est, [], opt);
%simulate
[t,y] = ode15i(F, [0, 5], y0, yp0, opt);
I need help plotting a differential equation ... it keeps coming out all funky and the graph is not what it's supposed to look like.
function [dydt] = diff(y,t)
dydt = (-3*y)+(t*(exp(-3*t)));
end
tI = 0;
yI = -0.1;
tEnd = 5;
dt = 0.5;
t = tI:dt:tEnd;
y = zeros(size(t));
y(1) = yI;
for k = 2:numel(y)
yPrime = diff(t(k-1),y(k-1));
y(k) = y(k-1) + dt*yPrime;
end
plot(t,y)
grid on
title('Engr')
xlabel('Time')
ylabel('y(t)')
legend(['dt = ' num2str(dt)])
That's my code, but the graph is not anything like what it's supposed to look like. Am I missing something like an index for the for statement?
Edit
I am getting an error:
Error using diff
Difference order N must be a positive integer scalar.
Error in diff3 (line 12)
yPrime = diff(t(k-1),y(k-1));
After fixing the errors pointed out by Danil Asotsky and horchler in the comments:
avoiding name conflict with built-in function 'diff'
changing the order of arguments to t,y.
decreasing the time-step dt to 0.1
converting ODE right-hand side to an anonymous function
(and removing unnecessary parentheses in the function definition), your code could look like this:
F = #(t,y) -3*y+t*exp(-3*t);
tI = 0;
yI = -0.1;
tEnd = 5;
dt = 0.1;
t = tI:dt:tEnd;
y = zeros(size(t));
y(1) = yI;
for k = 2:numel(y)
yPrime = F(t(k-1),y(k-1));
y(k) = y(k-1) + dt*yPrime;
end
plot(t,y)
grid on
title('Engr')
xlabel('Time')
ylabel('y(t)')
legend(['dt = ' num2str(dt)])
which performs as expected:
We are trying to model a DC/DC buck converter using matlab's ode23 solver. When we try to run our code the following errors come up:
??? Error using ==> odearguments at 91
The last entry in tspan must be different
from the first entry.
Error in ==> ode23 at 171
[neq, tspan, ntspan, next, t0, tfinal,
tdir, y0, f0, odeArgs, odeFcn, ...
Error in ==> buck2 at 13
[t,x] = ode23(#event1,[t0 tf],x0);
When we take out the code that modifies the initial condition array the code runs without errors but does not produce the expected result.
This is our code:
function buck2
close all
clear all
clc
t0 = 0;
tf = 1;
x0 = [0 0]; % Initial conditions
for i = 1:10
if (1 <= i <= 4),
[t,x] = ode23(#event1,[t0 tf],x0);
nt = length(t);
else
[t,x] = ode23(#event2,[t0 tf],x0);
nt = length(t);
end
t0 = t(nt);
x0 = x(nt);
end
plot(t,x)
function xdot = event1(t,x)
L = (12.12e-6);
C = (19.5e-6);
RC = (2.5*19.5e-6);
xdot = [(24/L) - (x(2)/L); (x(1)/C) - (x(2)/RC)];
function xdot = event2(t,x)
L = (12.12e-6);
C = (19.5e-6);
RC = (2.5*19.5e-6);
xdot = [-(x(2)/L); (x(1)/C) - (x(2)/RC)];
here's the problem:
in the loop, the first iteration:
you call the following
[t,x] = ode23(#event1,[t0 tf],x0);
t0 = 0; and tf = 1;
then further down the loop:
t0 = t(nt); %so t0 = 1;
next for loop iteration:
[t,x] = ode23(#event1,[t0 tf],x0);
in other words:
[t,x] = ode23(#event1,[1 1],x0);
solution:
either modify t0 = t(nt); or update tf with tf = t0 +1;
update:
also, you should correct the following x0 = x(nt,:);