How to use ode45 within Appdesigner?
3 views (last 30 days)
Show older comments
Hello everyone, I'm looking for some help about using ode45 within an app of Appdesigner. The aim of the app is to gather a lot of inputs from the user and to use them to solve a system of differential equations with ode45 (I achieved to solve the system with ode45 in editor but I have not been able to transpose it into AppDesigner).
Most of the variables are declared as private properties to be used in different functions and components of the app.
The problem is that I don't really know how to write the ode45 function when it used in appdesigner.
As you will see in tho code below, I'm trying to solve a ode system with a Mass matrix and a 'Force' Matrix but I don't know how to call them because I can't write something like :
opt=odeset('Mass',@Masse(app));
[teta,y]=ode45(@Force(app),[0:pi/180:4*pi],y0,opt);
The functions are included in the "private methods" but I don't understand everything about it.
The example I tried below doesn't include the input gathering as I would like to be able to perform correctly one ode resolution before going further. I don't know I if asked correctly my question but I hope you will be able to help me a little. Thank you in advance, Valentin
classdef TestODE < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
Button matlab.ui.control.Button
UIAxes matlab.ui.control.UIAxes
end
properties (Access = private)
R;
L=144e-3;
B=69e-3;
S=76.8e-3;
E=10;
teta=0:pi/180:4*pi;
h0;
P0=1e5;
T0=298;
m0;
end
methods (Access = private)
function M=Masse(app,teta,y)
[V,dV]=Volume(app,teta);
[cp,h,mp,~,~]=janaf(y(2),'gf',1); % janaf is a function I wrote
u=h-app.h0-((y(1).*volume)./y(3));
r=8.314/mp;
cv=cp-r;
M=[V -y(3)*r -r*y(2) ;
0 y(3)*cv u ;
0 0 1 ];
end
function [V dV] = Volume(app,teta)
app.R=app.S/2;
C=app.S*pi*app.B^2/4;
x=app.R.*cos(teta)+sqrt(app.L.^2-app.R.^2.*(sin(teta)).^2);
Sp=pi/4.*app.B.^2;
Vmin=C./(app.E-1);
V=Vmin+Sp.*(app.L+app.R-x);
dV=Sp.*app.R.*sin(teta).*(1+app.R.*cos(teta)./(app.L.^2-app.R.^2*...
(sin(teta)).^2).^0.5);
end
function F = Force(app,teta,y)
[V,dV]=Volume(app,teta);
F=[-y(1)*dV ; -y(1)*dV ; 0];
end
function main(app)
Cu=app.S*pi*app.B^2/4;
Vmin=Cu./(app.E-1);
app.m0=Vmin*1.2;
y0=[app.P0 ; app.T0 ; app.m0];
app.R=app.S/2;
[~,app.h0,~,~,~]=janaf(298,'gf',1);
opt=odeset('Mass',@Masse);
[teta,y]=ode45(@Force,[0:pi/180:4*pi],y0,opt);
end
end
methods (Access = private)
% Button pushed function: Button
function ButtonPushed(app, event)
main(app)
end
end
[...]
end
0 Comments
Answers (1)
Cris LaPierre
on 7 Nov 2018
Edited: Cris LaPierre
on 7 Nov 2018
The first approach is to express your differential equations in an anonymous function.
cbxFxn = @(t,h) [h(2); 0];
[tx, x] = ode45(cbxFxn,tspan,x0);
However, that is not always possible.
If you need to express your differential equations in a function, then that function must be declared in a methods (Static) section of app designer. Static methods do not require an object of that class as input. This is important since all non-static functions in an app have app as the first input, while ode functions must have t as the first input.
A static methods section must be manually added to your code. None of the options will create it for you automatically. Here is how you could set it up.
properties (Access = private)
...
end
methods (Access = private)
function ...
...
end
end
methods (Static)
function dydt = odefcn(t,y)
A = 1;
B = 2;
dydt = zeros(2,1);
dydt(1) = y(2);
dydt(2) = (A/B)*t.*y(1);
end
end
Then elsewhere in your callbacks/other functions, you would call ode45 as you normally would:
[t,y] = ode45(@app.odefcn, tspan, y0);
0 Comments
See Also
Categories
Find more on Ordinary Differential Equations in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!