%% Simulate a Simscape Model Using the Partitioning Solver
% This example shows how to compare the speed and the accuracy of a 
% simulation that uses the Partitioning solver to baseline results. It 
% also shows how to compare the speeds of the Partitioning solver and 
% the Backward Euler solver.
%% 
% Open the model. At the MATLAB&reg; command prompt, enter the code.

model = 'ssc_dcmotor';
open_system(model)
%% 
% To return all simulation outputs within a single 
% |Simulink.SimulationOutput| object so that you can later compare 
% simulation times, enable the single-output format of the |sim| command.

% Enable single-output format 
set_param(model,'ReturnWorkspaceOutputs', 'on')
%% 
% Enable the signal that goes to the *Motor RPM* scope block for 
% Simulink&reg; data logging and viewing with the Simulink&reg Data Inspector.

% Define the w sensor subsystem and the path
%    to it as variables
rpmSensor = 'Sensing';
rpmSensorPath = [model,'/',rpmSensor];

% Mark the output signal from the w sensor subsystem 
%   for Simulink(R) data logging
phRpmSensor = get_param(rpmSensorPath,'PortHandles');
set_param(phRpmSensor.Outport(1),'DataLogging','on')
%% 
% The logging badge marks the signal in the model.
%
% <<../ssc_dcmotor_sdi_signal_em.jpg>>
%
%% 
% Run timed simulations for each of these solvers:
%% 
% * Variable-step global solver, the original solver for the model
% * Fixed-step local Backward Euler solver
% * Fixed-step local Partitioning solver

% Define the Solver Configuration block and the path
%    to it as variables
solvConfig = 'Solver Configuration';
solvConfigPath = [model,'/',solvConfig];

% Run a timed simulation using the original solver
out = sim(model); 
tBaseline = out.SimulationMetadata.TimingInfo.ExecutionElapsedWallTime; 

% Select option Solver Configuration >  Use local solver
set_param(solvConfigPath, 'UseLocalSolver', 'on')

% Set Solver Configuration >  Solver type > Partitioning
set_param(solvConfigPath, 'LocalSolverChoice',...
    'NE_PARTITIONING_ADVANCER') 

% Run a timed simulation using the Partitioning solver
out = sim(model); 
tPartition = out.SimulationMetadata.TimingInfo.ExecutionElapsedWallTime; 

% Set Solver Configuration >  Solver type > Backward Euler
set_param(solvConfigPath, 'UseLocalSolver', 'on',...
    'LocalSolverChoice','NE_BACKWARD_EULER_ADVANCER')

% Run a timed simulation using the Backward Euler solver
out = sim(model); 
tBackEuler = out.SimulationMetadata.TimingInfo.ExecutionElapsedWallTime;
 
% Compute the percent difference for the simulation times
spdPartitionVsBaseline = 100*(tBaseline - tPartition)/tBaseline;
spdBackEulerVsBaseline = 100*(tBaseline - tBackEuler)/tBaseline;
spdPartitionVsBackEuler = 100*(tBackEuler - tPartition)/tBackEuler;

% Reset the solver to the original setting by deselecting Use local solver
set_param(solvConfigPath, 'UseLocalSolver', 'off')

%%
compTimeDiffTable = table({'Baseline';...
    'Partitioning';...
    'Backward Euler'},...
    {tBaseline;tPartition;tBackEuler},...
'VariableNames', {'Solver','Sim_Duration'});

display(compTimeDiffTable);

%%
compPctDiffTable = table({'Partitioning versus Baseline';...
    'Backward Euler versus Baseline';...
    'Partitioning versus Backward Euler'},...
    {spdPartitionVsBaseline;...
    spdBackEulerVsBaseline;...
    spdPartitionVsBackEuler},...
'VariableNames', {'Comparison','Percent_Difference'});

display(compPctDiffTable);
%% 
% Simulation time on your machine may differ because simulation speed 
% depends on machine processing power and the computational cost of 
% concurrent processes.
% 
% The local fixed-step Partitioning and Backward Euler solvers are faster  
% than the variable-step baseline solver. The Partitioning solver is 
% typically, but not always, faster than the Backward Euler solver.
%% 
% To compare the results, open the Simulink&reg Data Inspector.

% Get Simulink Data Inspector run IDs for 
%    the last three runs
runIDs = Simulink.sdi.getAllRunIDs;
runBaseline = runIDs(end - 2);
runPartition = runIDs(end - 1);
runBackEuler = runIDs(end);

% Open the Simulink Data Inspector
Simulink.sdi.view

compBaselinePartition = Simulink.sdi.compareRuns(runBaseline,...
    runPartition);
%%  
% Copyright 2018 The MathWorks, Inc.
