This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Note: This page has been translated by MathWorks. Click here to see
To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

Multiple Simulations Workflow Tips

The goal of this demo is to provide helpful tips for running multiple simulations using parallel simulation tools. This example will work even if the Parallel Computing Toolbox™ is not available, but the simulations will run in serial. We will be using the model sldemo_suspn_3dof for this example.

mdl = 'sldemo_suspn_3dof';
isModelOpen = bdIsLoaded(mdl);
open_system(mdl);

Initializing an Array of Simulink.SimulationInput Objects

Typically you will construct an array of Simulink.SimulationInput objects in order to run multiple simulations. There are several ways to initialize the array before populating it with data.

numSims = 5;
Cf_sweep = Cf*linspace(.05,.95, numSims);

Method 1: Initialize the array before the loop

in(numSims) = Simulink.SimulationInput;
for idx = 1:numSims
    % Need to populate the model name since we get any empty array by default
    in(idx).ModelName = 'sldemo_suspn_3dof';
    in(idx) = in(idx).setVariable('Cf', Cf_sweep(idx));
end

Method 2: Initialize the array in the loop

Note that the loop variable idx starts from the largest value so that the entire array is pre-allocated.

for idx = numSims:-1:1
    % Since we are indexing from 5 to 1, the first iteration will
    % initialize the array.
    in(idx) = Simulink.SimulationInput('sldemo_suspn_3dof');
    in(idx) = in(idx).setVariable('Cf', Cf_sweep(idx));
end

Setting Model and Block Parameters

The setModelParameter and setBlockParameter methods use the same parameter-value pair syntax that the set_param API uses. This means that most values you pass in to these methods should be character arrays, not their literal value.

for idx = numSims:-1:1
    in(idx) = Simulink.SimulationInput('sldemo_suspn_3dof');

    % Incorrect
    in(idx) = in(idx).setModelParameter('StartTime', 5);

    % Correct
    in(idx) = in(idx).setModelParameter('StartTime', '3');
end

Setting Variables

The setVariable method expects that you will pass the literal value you want to assign to a variable. The idea is that this closely reflects the assignin syntax.

for idx = numSims:-1:1
    in(idx) = Simulink.SimulationInput('sldemo_suspn_3dof');

    % Incorrect, Cf is expected to be a double, not a character array
    in(idx) = in(idx).setVariable('Cf', '2500');

    % Correct, Cf is a scalar double
    in(idx) = in(idx).setVariable('Cf', 2500);
end

Diagnosing Runtime Errors

Assume that you've accidentally set up an array of Simulink.SimulationInput objects with an incorrect value.

Mb_sweep = linspace(0, 1500, numSims);
for idx = numSims:-1:1
    in(idx) = Simulink.SimulationInput('sldemo_suspn_3dof');

    % Accidentally set the Mass to 0 on the first iteration
    in(idx) = in(idx).setVariable('Mb', Mb_sweep(idx));

    % Shorten the stop time
    in(idx) = in(idx).setModelParameter('StopTime','1');
end

Simulating these will cause a runtime error

out = sim(in);
[28-Jul-2018 13:33:59] Running simulations...
[28-Jul-2018 13:34:01] Completed 1 of 5 simulation runs. Run 1 has errors.
[28-Jul-2018 13:34:02] Completed 2 of 5 simulation runs
[28-Jul-2018 13:34:03] Completed 3 of 5 simulation runs
[28-Jul-2018 13:34:03] Completed 4 of 5 simulation runs
[28-Jul-2018 13:34:04] Completed 5 of 5 simulation runs
Warning: Simulation(s) with indices listed below completed with errors. Please
inspect the corresponding SimulationOutput to get more details about the error:
[1] 

Fortunately, you can inspect the Simulink.SimulationOutput object to see any error messages that come from a simulation.

out(1).ErrorMessage
ans =

    'Derivative of state '1' in block 'sldemo_suspn_3dof/Body Dynamics/Vertical (Z) dynamics/Zdot' at time 0.0 is not finite. The simulation will be stopped. There may be a singularity in the solution.  If not, try reducing the step size (either by reducing the fixed step size or by tightening the error tolerances)'

This works to debug issues on parallel workers too.

for idx = numSims:-1:1
    in(idx) = Simulink.SimulationInput('sldemo_suspn_3dof');

    % Accidentally set the Mass to 0 on the first iteration
    in(idx) = in(idx).setVariable('Mb', Mb_sweep(idx));

    % Shorten the stop time
    in(idx) = in(idx).setModelParameter('StopTime','1');
end

out = parsim(in);
[28-Jul-2018 13:34:04] Checking for availability of parallel pool...
Starting parallel pool (parpool) using the 'local' profile ...
connected to 12 workers.
[28-Jul-2018 13:34:51] Loading Simulink on parallel workers...
[28-Jul-2018 13:35:29] Configuring simulation cache folder on parallel workers...
[28-Jul-2018 13:35:30] Loading model on parallel workers...
[28-Jul-2018 13:35:41] Running simulations...
[28-Jul-2018 13:35:53] Completed 1 of 5 simulation runs. Run 1 has errors.
[28-Jul-2018 13:35:53] Completed 2 of 5 simulation runs
[28-Jul-2018 13:35:53] Completed 3 of 5 simulation runs
[28-Jul-2018 13:35:53] Completed 4 of 5 simulation runs
[28-Jul-2018 13:35:53] Completed 5 of 5 simulation runs
Warning: Simulation(s) with indices listed below completed with errors. Please
inspect the corresponding SimulationOutput to get more details about the error:
[1] 
[28-Jul-2018 13:35:53] Cleaning up parallel workers...

Inspecting the Simulink.SimulationOutput reveals a non-finite derivative error.

out(1).ErrorMessage
ans =

    'Derivative of state '1' in block 'sldemo_suspn_3dof/Body Dynamics/Vertical (Z) dynamics/Zdot' at time 0.0 is not finite. The simulation will be stopped. There may be a singularity in the solution.  If not, try reducing the step size (either by reducing the fixed step size or by tightening the error tolerances)'

The applyToModel method will configure your model with the settings on the SimulationInput so you can debug the problem locally.

in(1).applyToModel;

Notice that the value of the variable Mb in the base workspace changes to 0 to reflect the value that was used in the simulation corresponding to the first SimulationInput object in in.

Close MATLAB Workers

Last, close the parallel pool and the model if they were not previously opened.

if(~isModelOpen)
    close_system(mdl, 0);
end
delete(gcp('nocreate'));
Parallel pool using the 'local' profile is shutting down.