Multiple Simulations Workflow Tips - MATLAB & Simulink (original) (raw)

Main Content

The goal of this example 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.

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.

[05-Aug-2024 17:02:10] Running simulations... [05-Aug-2024 17:02:13] Completed 1 of 5 simulation runs. Run 1 has errors. [05-Aug-2024 17:02:15] Completed 2 of 5 simulation runs [05-Aug-2024 17:02:16] Completed 3 of 5 simulation runs [05-Aug-2024 17:02:19] Completed 4 of 5 simulation runs [05-Aug-2024 17:02:20] Completed 5 of 5 simulation runs Warning: One or more simulations completed with errors. For more information, inspect the SimulationOutput objects at these indices: [1]

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

ans =

'Derivative of state '1' in block '<a href="matlab:open_and_hilite_hyperlink ('sldemo_suspn_3dof/Body Dynamics/Vertical (Z) dynamics/Zdot','error')">sldemo_suspn_3dof/Body Dynamics/Vertical (Z) dynamics/Zdot</a>' 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);

[05-Aug-2024 17:02:21] Checking for availability of parallel pool... Starting parallel pool (parpool) using the 'Processes' profile ... 05-Aug-2024 17:03:27: Job Queued. Waiting for parallel pool job with ID 5 to start ... Connected to parallel pool with 6 workers. [05-Aug-2024 17:03:51] Starting Simulink on parallel workers... [05-Aug-2024 17:04:57] Configuring simulation cache folder on parallel workers... [05-Aug-2024 17:04:57] Loading model on parallel workers... [05-Aug-2024 17:05:15] Running simulations... [05-Aug-2024 17:05:36] Completed 1 of 5 simulation runs. Run 1 has errors. [05-Aug-2024 17:05:36] Received simulation output (size: 11.27 KB) for run 1 from parallel worker. [05-Aug-2024 17:05:36] Completed 2 of 5 simulation runs [05-Aug-2024 17:05:36] Received simulation output (size: 38.73 KB) for run 2 from parallel worker. [05-Aug-2024 17:05:36] Completed 3 of 5 simulation runs [05-Aug-2024 17:05:36] Received simulation output (size: 38.73 KB) for run 3 from parallel worker. [05-Aug-2024 17:05:36] Completed 4 of 5 simulation runs [05-Aug-2024 17:05:36] Received simulation output (size: 38.73 KB) for run 4 from parallel worker. [05-Aug-2024 17:05:36] Completed 5 of 5 simulation runs Warning: One or more simulations completed with errors. For more information, inspect the SimulationOutput objects at these indices: [1] [05-Aug-2024 17:05:36] Received simulation output (size: 38.76 KB) for run 5 from parallel worker. [05-Aug-2024 17:05:36] Cleaning up parallel workers...

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

ans =

'Derivative of state '1' in block '<a href="matlab:open_and_hilite_hyperlink ('sldemo_suspn_3dof/Body Dynamics/Vertical (Z) dynamics/Zdot','error')">sldemo_suspn_3dof/Body Dynamics/Vertical (Z) dynamics/Zdot</a>' 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.

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 'Processes' profile is shutting down.

See Also

parsim | Simulink.SimulationInput

Topics