Simulating ODEs with S-Functions, step by step Abstract This application shows how models based on a system of ODEs (Ordinary Differential Equations) are simulated using S-Functions in SimuLink. Furthermore it is demonstrated how the model can be masked in order to construct a menu for entering the model parameters. 1. Starting 1) Copy and unpack the zip file (remember the directory where you placed the zip file) 2) Run MatLab 3) In MatLab, change directory to the zip file - For Version 6: use the 'Current Directory' window - For Versions below 6: use 'cd' command. 4) Check whether you are in the right directory by typing 'pwd' and 'dir'. You see the unpacked files appear. 5) Run SimuLink 6) Open (in SimuLink) the file 'SimpleConstructionMask.mdl' 7) Press (Simulation / Start) 2. Problem: We want to simulate a system of ODEs in SimuLink and create a menu for entering the model parameters. The system van ODEs is: dT1 Ti − T1 T1 − T2 = (1/C1) ⋅ ( − ) dt R1 R2 dT2 T1 − T2 T2 − Te ) = (1/C2) ⋅ ( − dt R2 R3 The following steps are needed to construct the model 'SimpleConstructionMask.mdl' I) Simulate the system of ODEs in MatLab using ode The file ‘simcondvfun.m’ contains de differential equations for using with ode: %SIMCONDVFUN SIMple CONstruction Differential Equation FUNction % %JvS 12/2003 % % x(1)=T(1) % x(2)=T(2) function xdot=simcondvfun(t,x) xdot=zeros(2,1); %modelparameters R1=0.1; %K/W R2=1; %K/W R3=0.05; %K/W C1=4e4; %J/K C2=4e4; %J/K % input Te=0; Ti=20; %oC %oC xdot(1)=(1/C1)* ( xdot(2)=(1/C2)* ( ( Ti -x(1))/R1 (x(1)-x(2))/R2 - (x(1)-x(2))/R2 (x(2)- Te)/R3 ); ); The file ‘simconstart.m’ simulates the system. %SIMCONSTART SIMple CONstruction START % %JvS 12/2003 clear all t0=0; te=10*3600; T0=[10 10]'; %start time %end time %start values temperature [t,x]=ode23('simcondvfun', [t0 te], T0); plot(t,x) Type ‘simconstart’ at the MatLab prompt. This gives the following result: II) Copy the contents of the ode mfile into a S-Function, adapt the code of the S-Function, simulate the system in SimuLink The file ‘simconsfun1.m’ is the S-Function to simulate the ODEs in SimuLink. The adaptation of a standard S-Function is presented in red: function [sys,x0,str,ts] = simconsfun1(t,x,u,flag) %SIMCONSFUN1 SIMple CONstruction SFunction 1 % %JvS 12/2003 % %input u; output y %u(1)=Te %u(2)=Ti %y(1)=x(1) %y(2)=x(2) switch flag, %%%%%%%%%%%%%%%%%% % Initialization % %%%%%%%%%%%%%%%%%% case 0, [sys,x0,str,ts]=mdlInitializeSizes; %%%%%%%%%%%%%%% % Derivatives % %%%%%%%%%%%%%%% case 1, sys=mdlDerivatives(t,x,u); %%%%%%%%%%% % Outputs % %%%%%%%%%%% case 3, sys=mdlOutputs(t,x,u); %%%%%%%%%%%%%%%%%%% % Unhandled flags % %%%%%%%%%%%%%%%%%%% case { 2, 4, 9 }, sys = []; %%%%%%%%%%%%%%%%%%%% % Unexpected flags % %%%%%%%%%%%%%%%%%%%% otherwise error(['Unhandled flag = ',num2str(flag)]); end % end wpfun1 % %===================================================================== ======== % mdlInitializeSizes % Return the sizes, initial conditions, and sample times for the Sfunction. %===================================================================== ======== % function [sys,x0,str,ts]=mdlInitializeSizes sizes = simsizes; sizes.NumContStates sizes.NumDiscStates sizes.NumOutputs sizes.NumInputs sizes.DirFeedthrough sizes.NumSampleTimes = = = = = = 2; 0; 2; 2; 1; 1; sys x0 str ts = = = = simsizes(sizes); [10; 10]; []; [0 0]; % end mdlInitializeSizes % %===================================================================== ======== % mdlDerivatives % Return the derivatives for the continuous states. %===================================================================== ======== % function sys=mdlDerivatives(t,x,u) %model parameters R1=0.1; %K/W R2=1; %K/W R3=0.05; %K/W C1=4e4; %J/K C2=4e4; %J/K % input Te=u(1); Ti=u(2); %oC %oC xdot(1)=(1/C1)* ( xdot(2)=(1/C2)* ( ( Ti -x(1))/R1 (x(1)-x(2))/R2 - (x(1)-x(2))/R2 (x(2)- Te)/R3 ); ); sys = [xdot(1); xdot(2)]; % end mdlDerivatives % %===================================================================== ======== % mdlOutputs % Return the block outputs. %===================================================================== ======== % function sys=mdlOutputs(t,x,u) sys = x; % end mdlOutputs The system can be simulated by ‘SimpleConstruction.mdl’: The name of the S-Function can be entered by double clicking S-Function block: The results are the same as in section I) III) Masking the model and creating a menu for the model parameters. If we want to change a parameter of the model at section II, (for example a heat resistance value) we have to change the code of the S-Function (simconsfun1) by editing, saving the mfile and simulate again. This can be done in a more user-friendly way by creating a menu for the model parameters. This can be done as follows: A) Adapt de S-Function ‘simconsfun1.m’ as follows (the changes relative to simconsfun1 are shown in red) and save as ‘simconsfun2.m’ function [sys,x0,str,ts] = simconsfun2(t,x,u,flag) %SIMCONSFUN1 SIMple CONstruction SFunction 2 with extended input % %JvS 12/2003 % %input u; output y %u(1)=Te %u(2)=Ti %u(3)=R1 %u(4)=R2 %u(5)=R3 %u(6)=C1 %u(7)=C2 %y(1)=x(1) %y(2)=x(2) switch flag, %%%%%%%%%%%%%%%%%% % Initialization % %%%%%%%%%%%%%%%%%% case 0, [sys,x0,str,ts]=mdlInitializeSizes; %%%%%%%%%%%%%%% % Derivatives % %%%%%%%%%%%%%%% case 1, sys=mdlDerivatives(t,x,u); %%%%%%%%%%% % Outputs % %%%%%%%%%%% case 3, sys=mdlOutputs(t,x,u); %%%%%%%%%%%%%%%%%%% % Unhandled flags % %%%%%%%%%%%%%%%%%%% case { 2, 4, 9 }, sys = []; %%%%%%%%%%%%%%%%%%%% % Unexpected flags % %%%%%%%%%%%%%%%%%%%% otherwise error(['Unhandled flag = ',num2str(flag)]); end % end wpfun1 % %===================================================================== ======== % mdlInitializeSizes % Return the sizes, initial conditions, and sample times for the Sfunction. %===================================================================== ======== % function [sys,x0,str,ts]=mdlInitializeSizes sizes = simsizes; sizes.NumContStates sizes.NumDiscStates sizes.NumOutputs sizes.NumInputs sizes.DirFeedthrough sizes.NumSampleTimes sys x0 str ts = = = = = = = = = = 2; 0; 2; 7; 1; 1; simsizes(sizes); [10; 10]; []; [0 0]; % end mdlInitializeSizes % %===================================================================== ======== % mdlDerivatives % Return the derivatives for the continuous states. %===================================================================== ======== % function sys=mdlDerivatives(t,x,u) %modelparameters zijn nu input R1=u(3); %K/W R2=u(4); %K/W R3=u(5); %K/W C1=u(6); %J/K C2=u(7); %J/K % input Te=u(1); Ti=u(2); %oC %oC xdot(1)=(1/C1)* ( xdot(2)=(1/C2)* ( ( Ti -x(1))/R1 (x(1)-x(2))/R2 - (x(1)-x(2))/R2 (x(2)- Te)/R3 ); ); sys = [xdot(1); xdot(2)]; % end mdlDerivatives % %===================================================================== ======== % mdlOutputs % Return the block outputs. %===================================================================== ======== % function sys=mdlOutputs(t,x,u) sys = x; % end mdlOutputs B) Adapt the SimuLink model as follows: C) Select all blocks and click ‘Create Subsystem’ in the Edit menu. The next result is obtained: D) Select the Subsystem (by clicking one time) and click ‘Edit Mask’ in the Edit menu. Click the ‘Initialization’ button and add 5 variables (R1, R2, R3, C1 en C2as follows: Press OK and save the model as ‘SimpleConstructionTest.mdl’ Enter the values of the model parameters in the menu by double clicking the Subsystem: R1 R2 R3 C1 C2 0.1 1 0.05 4e4 4e4 Simulate ‘SimpleConstructionTest.mdl’. The result should be the same as ‘SimpleConstructionMask.mdl’.