Sensitivity Analysis using PyFMI - FMU in for-loop

2 posts / 0 new
Last post
TomSe
Offline
Joined: 2016-07-29
Sensitivity Analysis using PyFMI - FMU in for-loop

Dear JModelica Community

We need your help!

Main goal:

We are trying to realize a sensitivity analysis of a district heating network.

Approach:

- Modelica model of the system (in Dymola) using the AixLib and BuildingSystem libraries

- Export model as FMU co-simulation

- Use SALib (sensitivity analysis python library) to define the samples (parameter sweep)

- Use PyFMI to run the model in a for-loop in Python for all the individual samples (and parallelize the for loop maybe using JobLib to perfome the simulation on multiple processors)

- SALib to perform a variance-based sensitivity analyses (http://salib.readthedocs.io/en/latest/basics.html#an-example)

 

As a first step, we prepared a simple modelica model of the Ishigami function (not time dependent). This function is often used to test sensitivity analysis methods (https://www.sfu.ca/~ssurjano/ishigami.html).

The python code (including loading the FMU with PyFMI and the parameter sweep works fine.

The problem we have right now, is that after a certain amount of simulation we get an error. The error output looks not always the same. Sometimes we get

FMUException: Error loading the binary. Could not load the DLL: Eine DLL-Initialisierungsroutine ist fehlgeschlagen.

Translation:

A DLL-Initilisation routine is failed.

And sometimes we get:

FMUException: Error loading the binary. Could not load the DLL: Für diesen Befehl ist nicht genügend Speicher verfügbar.

Translation:

There is not enough memory available for this command.

 

The error occurs after around 650 simulation runs (and this is not dependent if the simulations are performed in smaller loop-blocks which are re-run one after another or if one single for loop runs through all the simulations)

Working environment: Windows 10, Python 2.7, PyFMI installed using pip (not JModelica), Python coding on Jupyther notebook (on Mozilla Firefox)

We have only basic knowledge of python and PyFMI and are really struggling with this error!

Attached you can find

- FMU

- Modelica code (see below)

- Python code as py file

- Python code as jupyter notebook file -> change txt to ipynb

- Output scatter plot of the python code.

 

Modelica model:

---------------------------------------------------------------------

model IshigamiFunction

  final parameter Real a = 7;

  final parameter Real b = 0.05;

  parameter Real x1 = 1;

  parameter Real x2 = 1;

  parameter Real x3 = 1;

  Real f;

equation

  f = sin(x1) + a * sin(x2)^2 + b * x3^4 * sin(x1);

end IshigamiFunction;

---------------------------------------------------------------------

 

I also made a post on Stackoverflow:

https://stackoverflow.com/questions/47357897/sensitivity-analysis-using-...

 

TomSe
Offline
Joined: 2016-07-29
Some more information

I made some more tests, and this is what I found:

Depending on if the FMU is exported from Dymola or from JModelica the behavior is different:

Using an FMU exported from Dymola:

  • Taking the load_fmu line out of the for-loop seems to work
  • Even with the load_fmu not in the for-loop there are sometimes crashes
  • Adding a new line model.reset() before the model.set(...) command seems to work fine
  • The results are different when simulated with or without model.reset() -> Why??
  • model.instantiate() instead of model.reset() -> doesn't work. The memory usage in the task manager goes up to around 350 MB and then ERROR

Using an FMU exported from JModelica:

  • Works fine even if the load_fmu is within the for-loop (but slower)
  • This does not correspond the example given in the documentation in chapter 5.4.2 (http://www.jmodelica.org/api-docs/usersguide/2.1/ch05s04.html#d0e1854) where the load_fmu command is given within the for-loop
  • The command model.reset() or model.instatiate() is required within the for-loop (contrary to Dymola FMU)

My question:

What is the right why to do a loop, which simulates a model many times with differen parameters?

What is the difference between using model.reset(), model.instatiate() or none of them?

 

Attached you can find an FMU exported from JModelica and a plot showing the difference between a for-loop with model.reset() and without.

 

Python code:

fmu = 'Model\IshigamiFunction\IshigamiFunction_Dymola.fmu'

model = load_fmu(fmu, log_level=0)
n_sim = param_values.shape[0]

y = np.zeros([param_values.shape[0]])
x1 = np.zeros([param_values.shape[0]])
x2 = np.zeros([param_values.shape[0]])
x3 = np.zeros([param_values.shape[0]])

for i, X in enumerate(param_values):
    model.reset()
    model.set(problem['names'], X)
    res = model.simulate(final_time = 1)
    y[i] = res['f'][-1]
    x1[i] = res['x1'][-1]
    x2[i] = res['x2'][-1]
    x3[i] = res['x3'][-1]
    print i+1

 

AttachmentSize
IshigamiFunction_JModelica.fmu 659.54 KB
IshigamiFunction_ScatterPlots_WithWithoutModelReset.png 107.61 KB
Login or register to post comments