- Index
- » Usage and Applications
- » OpenModelica Usage and Applications
- » Parameter Sweep Optimization with...
Parameter Sweep Optimization with OpenModelica
Parameter Sweep Optimization with OpenModelica
Hi folks,
I am currently looking for a possibility to perform a static parameter sweep optimization on a Modelica model. I've started with the onboard OMOptim tool. Unfortunatly, it seems like the tool itself as well as the documentation are no longer maintained. For OM v1.17, I couldn't manage to get it started at all, while for OM v1.16, the tool does work for me, but I can't define a optimization problem, since no parameters appear in the list of variables after loading the model according to the documentation.
My questions:
1) Does OMOptim generally not work in the new versions or is the error on my side? I've inculded the very basic model which
I've used for testing OMOptim. It inculdes a single parameter (Param) and a single objective to be minimized (Error.y)
OptimTest.mo
2) If OMOptim is not longer maintained/used by the community, what is the current "state of the art" for solving such a optimization problem with OpenModelica? Do you use the Python or the Matlab interface?
Thank you very very much for your help!!
Cheers
Re: Parameter Sweep Optimization with OpenModelica
a possible solution is to export the modelica model as an fmu and do the parameter sweep / optimization using any tool that can load fmus and do optimization (check out fmi-standard.org)
here a solution using python (based on the great example provided by t-sommer on https://github.com/CATIA-Systems/FMPy/b … _input.py)
remark1: I've created another modelica example, as the purpose of the original example with the tables wasn't clear to me...
remark2: the method presented here only works for quasi-steady state models, but modification for transient modes should be easy
remark3: fmu export is done by right-clicking on the model in the navigator, and choosing export/FMU;
use FMI setting 'Version 2.0' and 'Co-Simulation' in Tools/Options/FMI !
in the Messages-pane you'll see the path where the fmu is stored (usually C:\Users\USERNAME\AppData\Local\Temp\OpenModelica\OMEdit\)
test-parVar.mo
somehow uploading the python script doesn't work, thus I include the plain text
""" This example demonstrates how to use the FMU.get*() and FMU.set*() functions
to set custom input and get the output after each simulation step """
# based on:
# source: https://github.com/CATIA-Systems/FMPy/b … m_input.py
from fmpy import read_model_description, extract
from fmpy.fmi2 import FMU2Slave
import matplotlib.pyplot as plt
import shutil
import numpy as np
FMU_FILENAME = 'test_parVar.fmu'
INPUT_NAME = 'param'
OUTPUT_NAME = 'error'
def simulate(lower_bound, upper_bound):
# define the model name and simulation parameters
start_time = 0.0
stop_time = 2.0
step_size = 1e-2
# read the model description
model_description = read_model_description(FMU_FILENAME)
# collect the value references
vrs = {}
for variable in model_description.modelVariables:
vrs[variable.name] = variable.valueReference
# get the value references for the variables we want to get/set
vr_input = vrs[INPUT_NAME] # real input block name
vr_output = vrs[OUTPUT_NAME] # real output block name
# extract the FMU
unzipdir = extract(FMU_FILENAME)
fmu = FMU2Slave(guid=model_description.guid,
unzipDirectory=unzipdir,
modelIdentifier=model_description.coSimulation.modelIdentifier,
instanceName='instance1')
# initialize
fmu.instantiate()
fmu.setupExperiment(startTime=start_time)
fmu.enterInitializationMode()
fmu.exitInitializationMode()
time = start_time
results = [] # list to record the results
# simulation loop
while time <= stop_time:
# NOTE: the FMU.get*() and FMU.set*() functions take lists of
# value references as arguments and return lists of values
# calculate the input
x = lower_bound + (upper_bound-lower_bound)/(stop_time-start_time)*(time-start_time)
# set the input
fmu.setReal([vr_input], [x])
# perform one step
fmu.doStep(currentCommunicationPoint=time, communicationStepSize=step_size)
# advance the time
time += step_size
# get the value for 'error'
output = fmu.getReal([vr_output])[0] # return value of getReal is a list, we need just the value
# append the results
results.append([time, x, output])
fmu.terminate()
fmu.freeInstance()
# clean up
shutil.rmtree(unzipdir, ignore_errors=True)
return results
if __name__ == '__main__':
results = simulate(-5, 5) # range for parameter sweep
results_np = np.array(results)
plt.plot(results_np[:,1], results_np[:,2])
plt.show()
- glang
- 9 Posts
- Index
- » Usage and Applications
- » OpenModelica Usage and Applications
- » Parameter Sweep Optimization with...