%% Use MAT-Files to Feed Data to Inport Blocks for Rapid Simulations
% This example shows how the code generator RSim -i option lets you use a MAT-file as the input data source for Inport blocks for rapid simulations. The data in such a MAT-file can be presented in the following formats:
% One variable that defines a time/input data matrix of double values.
% One variable that defines a structure that uses a combination of Simulink® data types.
% Multiple variables, each defining a structure that uses a combination of Simulink® data types.
% This flexibility lends itself well to applications for which you must run simulations over a range of input data stored in different data files. This example explains how to use this feature.
% To quickly run multiple simulations in the Simulink environment, consider using rapid accelerator instead of RSim. See docid:simulink_ug.brc689t.
%% Prepare Model
% Open the model and save a copy to a writable location. Then, open the  Simulink Coder app. Set model configuration parameter *System target file to rsim.tlc.
% For more information on doing this graphically and setting up other model configuration parameters relate to the RSim system target file,  look here.

mdlName = 'rtwdemo_rsim_i';
open_system(mdlName);
cs = getActiveConfigSet(mdlName);
cs.switchTarget('rsim.tlc',[]);

%
%% Configure Inport Blocks
% To use the RSim -i option, you must configure each Inport block properly. You can double-click an Inport block to view its properties. By default, Inport blocks inherit their properties from downstream blocks. Before you can import data from external MAT-files, you must set the parameters of each Inport block to match the data in the MAT file. In most cases, these parameters of an Inport block must be set:
% Interpolate Data
% Port Dimensions
% Data Type
% Signal Type
% For more information on these parameters, click the Help button. This example model includes three Inport blocks. A requirement for the example is for Inport 1 and Inport 2 to interpolate between data, and for Inport 3 to not interpolate. The dimension of the Inport blocks are 2, 1, and 2, respectively. Signals are real. The settings are as follows:

for i =1:3
    portName      =['/In', num2str(i)];
    Interp        = get_param(strcat(mdlName,portName),'Interpolate');
    PortDimension = get_param(strcat(mdlName,portName),'PortDimensions');
    DataType      = get_param(strcat(mdlName,portName),'OutDataTypeStr');
    SignalType    = get_param(strcat(mdlName,portName),'SignalType');
end

% For inports In1 and In2, interpolation is selected. For inport In3, interpolation is cleared.
% For inports In1 and In3, port dimension is set to 2. For inport In2, port dimension is set to 1.
% For inports In1, In2, and In3, data type is double and signal type is real.
%% Build Model
% Build an executable for the model. During the build process, a structural checksum is calculated and embedded into the generated executable program. This checksum is used to check that a parameter set passed to the executable program is compatible with the program.

evalc('rtwbuild(mdlName)');

%
%% Identify Signals for Data File
% After you configure the Inport block, prepare the data file based on the Inport blocks. This figure shows the input signals to be used.

t=[0:0.01:2*pi]';
s1 = [2*sin(t) 2*cos(t)];
s2 = sin(2*t);
s3 = [0.5*sin(3*t) 0.5*cos(3*t)];
figure;
plot(t, [s1 s2 s3]);

% This figure displays the input signals.
%
%% Prepare MAT-File
% Generally, you can create the MAT-file from a workspace variable. The RSim -i option supports three data file formats:
% One variable in TU matrix format of doubles
% For this format, the first column is the time vector and the remaining columns are input vectors. The number of columns in the TU matrix equals the sum of the dimensions of the root Inport blocks plus 1. This MATLAB® code generates a MAT-file containing one variable var_matrix in TU matrix format. You can use this format only if the input ports in the model have the same data type.

t=[0:0.1:2*pi]';
Ina1 = [2*sin(t) 2*cos(t)];
Ina2 = sin(2*t);
Ina3 = [0.5*sin(3*t) 0.5*cos(3*t)];
var_matrix = [ t Ina1 Ina2 Ina3];
save rsim_i_matrix.mat var_matrix;

% MAT-file rsim_i_matrix.mat contains one variable var_matrix in TU matrix format.
%
% One variable in structure format
% For this format, the variable must contain two fields: time and signals. If you set the block parameter Interpolate data for one of the Inport blocks, the time field of the variable must not be an empty vector and the width of the signals must equal the total width of the Inport blocks. This code generates a MAT-file that contains one variable var_matrix in signal variable structure format. This format is more flexible than the TU matrix format because it can support input ports with different data types.

t= [0:0.1:2*pi]';
var_single_struct.time = t;
var_single_struct.signals(1).values(:,1) = 2*sin(t);
var_single_struct.signals(1).values(:,2) = 2*cos(t);
var_single_struct.signals(2).values = sin(2*t);
var_single_struct.signals(3).values(:,1) = 0.5*sin(3*t) ;
var_single_struct.signals(3).values(:,2) = 0.5*cos(3*t) ;
v=[var_single_struct.signals(1).values var_single_struct.signals(2).values ...
    var_single_struct.signals(3).values ];
save rsim_i_single_struct.mat var_single_struct;

% MAT-file rsim_i_single_struct.mat contains one variable var_single_struct in struct format.
%
% Multiple variables in structure format
% For this format, the number of variables equals the number of Inport blocks. Different variables can have different time vectors. This code generates a MAT-file that contains multiple variables, each in structure format. This is the most flexible format because it allows each Inport block to have its own time vector.

t= [0:0.1:2*pi]';
Inb1.time = t;
Inb1.signals.values(:,1) = 2*sin(t);
Inb1.signals.values(:,2) = 2*cos(t);
t= [0:0.2:2*pi]';
Inb2.time = t;
Inb2.signals.values(:,1) = sin(2*t);
t= [0:0.1:2*pi]';
Inb3.time =  t;
Inb3.signals.values(:,1) = 0.5*sin(3*t);
Inb3.signals.values(:,2) = 0.5*cos(3*t);
save rsim_i_multi_struct.mat Inb1;
save rsim_i_multi_struct.mat Inb2 -append;
save rsim_i_multi_struct.mat Inb3 -append;

% MAT-file rsim_i_multi_struct.mat contains three variables Inb1, Inb2, and Inb3 in struct format. Use the save command with the -append option to preserve the order of variables in the generated MAT-file.
%
%% Run RSim Simulations and Plot Results
% You can use RSim -i options for batch mode simulation. Prepare different MAT-files and run the RSim program executable with them.
% This part of the example shows three plots. Each plot shows simulation results for a MAT-file with a different variable format. The model is compiled once.

figure
fileName = ({'rsim_i_matrix', 'rsim_i_single_struct', 'rsim_i_multi_struct'});
for i=1:3
    % bang out and run a simulation using new parameter data
    name = fileName(i);
    runstr = ['.', filesep, 'rtwdemo_rsim_i -i ',char(name),'.mat', ' -v'];
    evalc('system(runstr)');
    pause(0.5);
    % load simulation data into MATLAB(R) for plotting.
    load rtwdemo_rsim_i.mat;
    subplot(3,1,i);
    axis([0,6, -5, 5]);
    plot(rt_tout, rt_yout);
    hold on
end
close_system(mdlName, 0);

%
% Copyright 2005-2019 The MathWorks, Inc.