CATIA-Systems / FMPy

Simulate Functional Mockup Units (FMUs) in Python
Other
429 stars 118 forks source link

Issues with non-integer --output-interval in ModelExchange simulation of a Buildings FMU #655

Closed casella closed 3 months ago

casella commented 6 months ago

Hi,

we encountered a weird problem while testing OMC-generated FMUs of the Buildings library with FMPy. Steps to reproduce:

However, if you set --output-interval 7.2 or --output.interval 5.7, the simulation hangs somewhere before stopTime and eventually a partial result file is issued.

This is quite weird, maybe it's a problem with our installation, but if you can reproduce it, it would be nice to have it fixed. Keeping @deepak19015 and @AndreaBartolini in the loop.

Thanks!

casella commented 6 months ago

For your convenience, this is the FMU (renamed to .zip) exported on Windows 10: ThreeRoomsContamDiscretizedDoor.zip

casella commented 4 months ago

@t-sommer could you please give us some feedback about this issue? Thanks!

t-sommer commented 4 months ago

As a quick fix you can change simulation.py line 1040 to

                if t_next <= time + eps:
casella commented 4 months ago

Thanks @t-sommer! This is not urgent, but I guess it needs to be fixed, eventually.

BTW, I hope you are getting much less headaches and complaints caused by OMC-generated FMUs these days, compared to when we met in Aachen last year. If you still do, please let me know, we are eager to improve and we now have the resources to do that.

t-sommer commented 4 months ago

We should use isclose() instead of a fixed epsilon when comparing floats to account for numerical tolerances (see also https://stackoverflow.com/questions/5595425/what-is-the-best-way-to-compare-floats-for-almost-equality-in-python).

casella commented 4 months ago

This is always tricky. Of course comparing 1.23456789 with 1.23456788 requires a different epsilon than comparing 1.23456789e12 with 1.23456788e12, and I guess isclose() just does it with relative tolerances. The question is, what happens if you are comparing 1.23e-14 with 3.12e-14, and both are the results of some computations whose exact solution is 0.0? In that case, you also need some a-priori information about the range of those numbers to judge about numerical rounding errors. In Modelica, you can use the nominal attribute for that, also see the paper we wrote some time ago on the topic.

In the specific case of this ticket, I guess one should somehow take into account either stopTime - startTime or stepSize, otherwise you could get into trouble. For example, when I am simulating step responses of systems for control design purposes, I often start the simulation at a slightly negative time value, to make sure that the system output is at equilibrium before applying the step change. E.g., startTime = -1, stopTime = 10, stepSize = 0.01. Now, while not-too-large integer numbers have exact floating point representation, decimal numbers such as 0.01 don't. So, if you start from -1 and sum 0.01 to it 100 times you won't get exactly to zero. I just tried it in Matlab and I got 7.5287e-16. Using relative tolerances for such small number doesn't make sense, one should probably use and absolute tolerance linked to either 0.01 or 11.

@t-sommer what do you think?

casella commented 3 months ago

Thanks @t-sommer! Do you have plans for the next release of FMPy?

t-sommer commented 3 months ago

v0.3.21 is out.