Accessing variables from a Simulink model initFcn callback with parsim

9 visualizzazioni (ultimi 30 giorni)
I'm running a model in parallel using parsim. I define all the variables used by the model with the setVariable method of a Simulink.SimulationInput object. All works fine until I try to access one of this variables from the initFcn callback.
Aparently, the variables defined in the model workspace, that are accesible from the model itself, are not accessible from the callbacks. Is there any way of defining a variable for the SimulationInput object, that can be accessed from the model callbacks when using parsim?
This is a dummy example of what I'm trying to do:
%% Create an array of input data
n = 10;
Av = (1:n)*50;
Bv = (1:n)*100;
t = 0:1e-3:10;
for i =1:n
simInput.A = Av(i);
simInput.B = Bv(i);
in(i) = Simulink.SimulationInput('parsimTest');
in(i) = in(i).setVariable('simInput',simInput,'Workspace','parsimTest');
in(i) = in(i).setModelParameter('StopTime','7.5');
end
%% Run in paralell
out = parsim(in,'ShowSimulationManager','on');
And this is the model and the initFcn callback:
I already tried to use the option
'TransferBaseWorkspaceVariables','on'
within the parsim function. That would work if the variable I try to access in the initFcn is constant over the parallel simulations, but I need it to change.
Thanks in advance!
Guillermo

Risposta accettata

Paul
Paul il 30 Apr 2025
Hi Guillermo,
In my opinion, the documentation is very poor in explaining the interaction between workspaces, models, and model callback functions (particuarly the InitFcn) particuarly when running with Simulink.SimulationInput objects and parsim. My understanding, based primarily on observation, is as follows:
When running with Simulink.SimulationInput objects, the workspace precedence for model execution (not accounting for masks or perhaps other special cases) is:
Model Workspace -> Global Workspace -> Base Workspace.
Note that Global Workspace is unique to using Simulink.SimulationInput. When we use setVariable, "By default, when you do not specify the Workspace argument, variables on a SimulationInput ... object are scoped to a global workspace specific to each object." However, the model InitFcn runs in the Base Workspace (just like it runs in the Base Workspace when not using Simulink.SimulationInput) as best as I can observe.
One solution that seems to work is to use the PreSimFcn to assign a variable in the Base Workspace of the worker, which will be visible to the InitFcn.
%% Create an array of input data
n = 10;
Av = (1:n)*50;
Bv = (1:n)*100;
t = 0:1e-3:10;
for i =1:n
simInput.A = Av(i);
simInput.B = Bv(i);
in(i) = Simulink.SimulationInput('parsimTest');
in(i) = in(i).setVariable('simInput',simInput,'Workspace','parsimTest');
in(i) = in(i).setModelParameter('StopTime','7.5');
in(i) = in(i).setPreSimFcn(@(s) assignin('base','simInput',simInput));
end
%% Run in paralell
out = parsim(in,'ShowSimulationManager','on');
In this particular case, the same variable is being set in the Base Workspace of the worker and in the Model Workspace. My understanding is that the InitFcn will use the former and block parameters will use the latter (though they both have the same value in this case). Might be interesting to change value of simInput.A after the call to setVariable and before the call to setPreSimFcn to verify it works that way.
  1 Commento
Guillermo Rubio
Guillermo Rubio il 5 Mag 2025
Hi Paul,
I've tried your solution and it works fine. I also tried the modification you said, and it's confirmed it works that way, i.e. the value assigned with setVariable is the one used by the model blocks while the modified one assigned later with setPreSimFcn is only used by the initFcn callback:
%% Create an array of input data
n = 10;
Av = (1:n)*50;
Bv = (1:n)*100;
t = 0:1e-3:10;
for i =1:n
simInput.A = Av(i);
simInput.B = Bv(i);
in(i) = Simulink.SimulationInput('parsimTest');
in(i) = in(i).setVariable('simInput',simInput,'Workspace','parsimTest');
in(i) = in(i).setModelParameter('StopTime','7.5');
simInput.A = Av(i)+Bv(i);
in(i) = in(i).setPreSimFcn(@(s) assignin('base','simInput',simInput));
end
%% Run in paralell
out = parsim(in,'ShowSimulationManager','on','TransferBaseWorkspaceVariables','on');
And the results obtained are:
>> out(1).simOutput1.signals.values
ans =
310
>> out(2).simOutput1.signals.values
ans =
610
>> out(1).simOutput.signals.values
ans =
5000
>> out(2).simOutput.signals.values
ans =
20000
I also check that it only works this way if setVariable is used setting the target Workspace to the model one. If using global or base, the modified value is the one used also on the model blocks.
Thank you very much for your answer and for the information provided.
Best regards,

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Run Individual Simulations in Help Center e File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by