OpenModelica / OMSimulator

The OpenModelica FMI & SSP-based co-simulation environment.
Other
73 stars 50 forks source link

Insufficient event location detection #1039

Closed AnHeuermann closed 1 week ago

AnHeuermann commented 3 years ago

Description

Looking at some FMUs from the FMI Cross Check there are a lot of examples where events are not hit sufficiently precise. If I remember it correctly OMSimulator does an event iteration directly after a step triggered an state event indicator (zero crossing) to change. Time events should be fine.

For state events the event handling must be improved. In OpenModelica there is a bisection method implemented to find the time point. This would be an option if we only have some discrete values (e.g. -1 and +1 like in OpenModelcia FMUs) for the zero crossing function available.

If the FMUs has continuous values for the zero crossing functions we can do something that will converge faster to the root, e.g. regula falsi or some Newton method. At least if the FMU supports canGetAndSetFMUstate this should be possible.

Steps to reproduce the behavior

Run e.g. the FMI Cross Check in fmus/2.0/me/win64/Dymola/2019FD01/ControlledTemperature/ControlledTemperature.fmu.

To simulate FMU ControlledTemperature.fmu with OMSimulator run

$ D:\workspace\OMSimulatorStandalone\install\mingw\bin\OMSimulator.exe --stripRoot=true --skipCSVHeader=true --addParametersToCSV=true --intervals=500 --suppressPath=true --timeout=60 ControlledTemperature.lua

Lua file:

-- Lua file for ControlledTemperature.fmu
oms_setTempDirectory("temp")
oms_newModel("model")
oms_addSystem("model.root", oms_system_sc)

-- instantiate FMU
oms_addSubModel("model.root.fmu", "..\\..\\..\\..\\..\\..\\..\\..\\..\\fmus\\2.0\\me\\win64\\Dymola\\2019FD01\\ControlledTemperature\\ControlledTemperature.fmu")

-- Simulation settings
oms_setResultFile("model", "ControlledTemperature_out.csv")
oms_setStartTime("model", 0.0)
oms_setStopTime("model", 10.0)
oms_setTolerance("model", 0.0001)
initialStepSize, minimumStepSize, maximumStepSize, status = oms_getVariableStepSize("model")
oms_setVariableStepSize("model", 0.02, minimumStepSize, 0.02)
oms_setFixedStepSize("model", 0.02)

-- Instantiate, initialize and simulate
oms_instantiate("model")
oms_initialize("model")
oms_simulate("model")
oms_terminate("model")
oms_delete("model")

Expected behavior

Find state events with a given precision by some root finding algorithm.

Screenshots

image In blue: Reference result In red: Result by OMSimulator

Version and OS

AnHeuermann commented 3 years ago

After discussing with @lochel we want to have some sort of flag that can flip between the old and some new approach on event detection. It could be that some use-cases for FMU simulation want's to do the event iteration only after the given step and not at the event location.

I would suggest to use a bisection method for root finding: It is easy to implement, very reliable and has a descent convergence rate (but isn't spectacular fast).

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 2 years ago

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.