open-simulation-platform / libcosim

OSP C++ co-simulation library
https://open-simulation-platform.github.io/libcosim
Mozilla Public License 2.0
61 stars 10 forks source link

Simplify API and code by dropping (alleged) support for changing system structure during simulation #771

Open kyllingstad opened 4 months ago

kyllingstad commented 4 months ago

In principle, the current libcosim API permits one to change the system structure after a simulation has started. More to the point, one is allowed to call execution::add_simulator(), execution::connect_variables(), etc. after execution::simulate_until() or execution::step() has been called. This was a deliberate design choice in the early OSP days, because we were told that the ability to dynamically add and remove entities was a desirable feature in certain human-in-the-loop simulation use cases.

Now, several years later, I am fairly certain that no one is using this for anything and it doesn't even work. Firstly, because we don't have tests for it, and secondly, for the following reason: If a subsimulator is added with fixed_step_algorithm::add_simulator() after fixed_step_algorithm::initialize() has been called, then the subsimulator’s initialisation functions (simulator::setup() and simulator::do_iteration()) will never be called. This, again, means that the underlying FMU will never have its fmi2EnterInitializationMode() and fmi2ExitInitializationMode() functions called, and then it’s not allowed to call its fmi2DoStep() function either.

This leaves us with two choices: fix this feature or drop it. I say drop it.

Dropping it would allow us to simplify the API in several places:

Furthermore, it would allow us to simplify the implementation in several places:

Proposed action plan:

davidhjp01 commented 1 month ago

After discussion, we agreed that we will drop a support on adding/removing simulators (models) and simplify libcosim code. But dynamic adding/removing connections dynamically can be useful (future work).

kyllingstad commented 2 weeks ago

Pull request #777 dynamically prevents adding/removing subsimulators after initialisation, so it is a step in the right direction. But I think it would be even better to prevent it statically, i.e., by not having functions like add_simulator(), simulator_added() etc. at all. Instead, a complete list of subsimulators could be passed to the execution, algorithm, observers, etc. at some point, for example during construction.