Archived OpenModelica forums. Posting is disabled.

Alternative forums include GitHub discussions or StackOverflow (make sure to read the Stack Overflow rules; you need to have well-formed questions)


Forgot password? | Forgot username? | Register
  • Index
  • » Users
  • » glang
  • » Profile

Posts

Posts

following bsfc map (toGperkWh) should be quite close to the map used in the example from the manual;
except I've dismissed gain1, and factored it into the map
Interpolation = ContinuousDerivative

load     bsfc
0.00    750
0.04    500
0.20    350
0.40    290
0.60    230
0.77    210
0.80    212
0.90    223
1.00    300

[0, 750; 0.04, 500; 0.2, 350; 0.4, 290; 0.6, 230; 0.77, 210; 0.8, 212; 0.9, 223; 1, 300]

bsfc-map.mo

somehow I got it working, but results look different; nevertheless, hopefully a first and helpful step...

think the key is to add
__OpenModelica_simulationFlags(s="optimization", optimizerNP="1"),
__OpenModelica_commandLineOptions="+g=Optimica");
to the model annotation.
(see: https://www.openmodelica.org/doc/OpenMo … imization)

fuel consumption map will need some finetuning.

Example-14-1-6-2.mo

simulation settings: start time: 0
                                stop time: 20
                                number of steps: 100
                                integration method: optimization

you're welcome.
not sure if the fmu is 100% okay, just recognized that with a certain tool tuning (changing) the parameter during runtime worked (after manually editing the xml)
so yes, after exporting the fmu k1 was 'fixed', and I changed it to 'tunable'
then zipped the directory to an fmu, which I've tested
quite sure that there has something to be improved on the OM side.
Best
GL

Hello w1ldw0lf,
just wanted to mention, that with the modified fmu
  <ScalarVariable
    name="k1"
    valueReference="6"
    description="gain 1"
    variability="tunable"
    causality="parameter"
    >

it is possible, to change k1 whilst the simulation is running, and the output is as expected (see attached csv files from an actual simulation, using a slider to control k1)
(I'm working with AVL Model.CONNECT, not sure about other tools...)

I've added another output 'k1_check' which just outputs the value of k1 during runtime


1648649650_tunableParameter.fmu

FMU-1-in.csv

FMU-1-res.csv

sorry if I'm bothering you, but as I'm also very much interested in using OM fmu's (and was struggling a bit too) I'm quite interested in this topic being resolved
cheers, GL


after checking the FMI standard:

causality = parameter:
A data value that is provided by the importer or user to change the behavior of the FMU.
It is constant during the simulation (except for tunable parameters)

so sorry if I didn't get your initial question right...my proposed solution doesn't provide a tunable parameter, just one you can set at the beginning of the simulation.

maybe just use a normal input instead of a tunable parameter.

PS: after manually editing the ModelDescription.xml:
  <ScalarVariable
    name="k1"
    valueReference="4"
    description="gain 1"
    variability="fixed"
    causality="parameter"
    >
to:
  <ScalarVariable
    name="k1"
    valueReference="4"
    description="gain 1"
    variability="tunable"
    causality="parameter"
    >
and zipping to tunableParameter.fmu the fmu it seems to work.
just a work around, think there is something missing in OM to define tunable parameters; but just my guess; maybe there is a better way to define tunable parameters inside the model?

Hello,
my xml looks similar,
but when I run the fmu (in the co-simulation tool of my choice) I can change the values of k and k1, and the results of y and y1 are correct.

I think you are right - variability of k and k1 should be set to "tunable";
maybe someone with better knowledge of the FMI standard can comment on this please?
strange that it works with variability = "fixed"

Have you tested your fmu?

attached my fmu (co-simulation and model exchange), which you can also run in OM (don't forget to change the name from 'tunableParameter_me_FMU' to e.g. 'tunableParameter_me_FMU_1' when inserting into a model, otherwise you'll get an error)

tunableParameter.fmu

tunableParameter.mo

using OM 1.18.1
tunable parameter works
see example, one parameter is the value k of the gain-block, another defined as 'parameter Real k1 = 1'

I remember there were issues with older versions, there you had to disable the translation flag 'Evaluate all parameters' (think since 1.18 disabled by default)

not sure about 'parameter input Real xyz' - never used that

hope this helps

Jan-11-22 08:34:18
Looking for a way to optimize a parameter of a Modelica model (OMOptim, OMPython,...)

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()

  • Index
  • » Users
  • » glang
  • » Profile
You are here: