How to run a multi-simulation¶
The objective of this tutorial is to explain the definition, the postprocessings and the storage of a multi-simulation in Pyleecan.
The following organization aims to enable:
multi-simulation of a single model or a complete workflow
multi-simulation of multi-simulations
parallelization to speed up calculations
errors management
built-in postprocessings
efficient storage
VarParam class¶
A simulation, as defined by the Simulation object, corresponds to the computation of machine quantities on a single operating point. A multi-simulation is defined as a list of simulations, all based on a reference simulation with variations of its parameters.
To define a multi-simulation in pyleecan, first the reference simulation must be defined as a Simulation object. Then an optional VarParam object (that inherits from an abstract VarSimu class) is set as a property of the reference simulation object. VarParam object defines how to generate the simulation list, how to parallelize (or not) the computation and which data to gather. To do so, VarParam class contains :
Attribute |
Type |
Description |
---|---|---|
paramexplorer_list |
91ParamExplorer93 |
simulation parameters to variate |
datakeeper_list |
91DataKeeper93 |
output data to keep |
nb_proc |
int |
number of processes used |
is_keep_all_output |
bool |
True to keep every output |
stop_if_error |
bool |
error tolerance |
ref_simu_index |
int |
Index of the reference simulation, if None the reference simulation is not in the multi-simulation |
nb_simu |
int |
number of simulations |
On a side note, as all pyleecan object, VarParam also has a parent property that links to the reference simulation.
Input parameters: ParamExplorerSet¶
The parameter to change in the reference simulation and how are defined with ParamExplorer objects. ParamExplorerSet is a ParamExplorer that enables to set the parameters variations from a list of values. The parameters to change are defined with a function (setter) which enables to do complex operation with the value as argument (cf example below). This setter can also be defined as a string to target directly a parameter. When generating the list of simulations to run, the function is executed before running the simulation to set the parameters as expected. The ParamExplorerSet has five attributes:
Attribute |
Type |
Description |
---|---|---|
name |
str |
name of the data |
symbol |
str |
short name to access in XOutput |
unit |
str |
data unit |
setter |
function |
function that takes a Simulation and a value in argument and modifies the simulation |
value |
list |
list that contains the different parameter values to explore |
When a VarParam is defined with several ParamExplorer, it will creates every simulation by making the cartesian product of every ParamExplorerSet values.
In the following example, two ParamExplorer are defined, the first one scales every parameter of the slot according to a single value, the second directly update the current matrix:
def slot_scale(simu, scale_factor):
"""Edit stator slot size according to a percentage
Parameters
----------
simu: Simulation
simulation to modify
scale_factor: float
stator slot scale factor
"""
simu.machine.stator.slot.W0 *= scale_factor
simu.machine.stator.slot.W1 *= scale_factor
simu.machine.stator.slot.W2 *= scale_factor
simu.machine.stator.slot.H0 *= scale_factor
simu.machine.stator.slot.H1 *= scale_factor
paramexplorer_list=[
ParamExplorerSet(
name = "Stator slot scale factor",
symbol = "stat_slot",
unit="",
setter=slot_scale,
value = [0.99, 1.01]
),
ParamExplorerSet(
name = "Current",
symbol = "I",
unit="A",
setter="simu.input.Is.value",
value = [array_current1, array_current2, array_current3]
),
]
A VarParam with both the ParamExplorer above creates the six following simulations:
simulation number |
Stator slot scale factor |
Stator current |
---|---|---|
1 |
0.99 |
array_current1 |
2 |
0.99 |
array_current2 |
3 |
0.99 |
array_current3 |
4 |
1.01 |
array_current1 |
5 |
1.01 |
array_current2 |
6 |
1.01 |
array_current3 |
Variables to keep: DataKeeper¶
VarParam contains a list of DataKeeper to specify which data to keep after each simulation by defining post-processing on Output object. A DataKeeper is a class with six attributes:
Attribute |
Type |
Description |
---|---|---|
name |
str |
name of the data |
symbol |
str |
short name to access in XOutput |
unit |
str |
data unit |
keeper |
function |
function that takes an Output in argument and returns a value |
error_keeper |
function |
function that takes a Simulation in argument and returns a value, this attribute permits to handle errors and attribute permits to handle errors and to put NaN values in the result matrices |
result |
list |
list containing DataKeeper results for each simulation |
This following datakeepers enable to store the average torque and the radial magnetic flux for each of the six simulations:
datakeeper_list = [
DataKeeper(
name = "Average Torque",
unit = "N.m",
symbole = "Tem_av",
keeper = lambda output: output.mag.Tem_av,
error_keeper = lambda simu: np.nan
),
DataKeeper(
name = "Radial Magnetic Flux",
unit = "H",
symbol = "Br",
keeper = lambda output: output.mag.Br,
error_keeper = lambda simu: np.nan * np.zeros(
len(simu.machine.time.value), len(simu.machine.angle.value)
)
)
]
DataKeepers with their results are stored in a dict whose keys are the data symbol. DataKeepers results contain results from DataKeeper.keeper(output) (or DataKeeper.error_keeper(simu) when the simulation raise an error).
Running VarParam¶
When the method Simulation.run
is called, the reference simulation is
executed first. Then, if a VarParam is defined, the corresponding list
of simulations is generated and run. If a VarParam is defined,
Simulation.run
returns an XOutput object else it returns an
Output.
XOutput class¶
XOutput is a daughter of Output that enables to store VarParam results:
Attribute |
Type |
Description |
---|---|---|
simu |
Simulation |
Reference Simulation |
geo |
OutGeo |
Reference Simulation geometry output |
elec |
OutElec |
Reference Simulation electrical module output |
mag |
OutMag |
Reference Simulation magnetic module output |
force |
OutForce |
Reference Simulation force module output |
struct |
OutStruct |
Reference Simulation structural module output |
post |
OutPost |
Reference Simulation post-processing settings |
input_param |
list |
List of ParamExplorerSet containing values for each simulation |
output_list |
list |
List containing each Output |
xoutput_dict |
dict |
Dictionnary containing VarParamDataKeeper |
Reference simulation results are stored in the properties inherited from Output and other simulation results are stored in a list of Output and/or in a dict containing DataKeeper, according to VarParam parameters. Paramater variations are stored in a specific list of ParamExplorerSet created at the beginning of the simulation.
If VarParam.is_keep_all_output
is True, then each output of each
simulation is stored in the output_list. This option is set as False by
default to avoid memory issues.
The class has some getters to gather results: list slices can be
extracted according to some input values e.g. extract average torque for
simulations with a specific value of slot angle or a specific speed. To
ease the access to the results, XOutput behaves like a dictionary to
access directly to XOutput.xout_dict
and like a list to access
directly to XOuput.output_list
. Furthermore, len(XOutput)
returns
the number of simulations, which is 6 in this case. For this example,
the following call returns a list containing the average torque for each
simulation with the stator scale factor set to 0.99.
xouput['Tem_av'].result[0:3]