Skip to content

Commit

Permalink
Transfer variables after setup and initialisation
Browse files Browse the repository at this point in the history
`fixed_step_algorithm::initialize()` ends by calling
`simulator::start_simulation()`, which, for an FMI 2.0 FMU ends up
calling `fmi2ExitInitializationMode()`. This function is not prohibited from
modifying variable values, which means that we must assume that it does.
Previously we did not, which led to issue #609, which to me looks like a
pretty severe correctness issue. Here, I've added `get_variables()` and
`set_variables()` calls at additional points in the call sequence of a
`slave_simulator()` where variable values may be needed/changed, and
I've added a variable transfer at the end of
`fixed_step_algorithm::initialize()`.

Closes #609.
  • Loading branch information
kyllingstad committed Jun 24, 2024
1 parent 1b5b849 commit 6ee3911
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 31 deletions.
55 changes: 25 additions & 30 deletions src/cosim/algorithm/fixed_step_algorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,15 +168,7 @@ class fixed_step_algorithm::impl
});
}
pool_.wait_for_tasks_to_finish();

for (const auto& s : simulators_) {
transfer_variables(s.second.outgoingSimConnections);
transfer_variables(s.second.outgoingFunConnections);
}
for (const auto& f : functions_) {
f.second.fun->calculate();
transfer_variables(f.second.outgoingSimConnections);
}
calculate_and_transfer();
}

for (auto& s : simulators_) {
Expand All @@ -185,6 +177,7 @@ class fixed_step_algorithm::impl
});
}
pool_.wait_for_tasks_to_finish();
calculate_and_transfer();
}

std::pair<duration, std::unordered_set<simulator_index>> do_step(time_point currentT)
Expand All @@ -193,8 +186,8 @@ class fixed_step_algorithm::impl
bool failed = false;
std::stringstream errMessages;
std::unordered_set<simulator_index> finished;
// Initiate simulator time steps.

// Initiate simulator time steps.
for (auto& s : simulators_) {
auto& info = s.second;
if (stepCounter_ % info.decimationFactor == 0) {
Expand All @@ -220,37 +213,20 @@ class fixed_step_algorithm::impl
});
}
}

++stepCounter_;

for (auto& [idx, info] : simulators_) {
if (stepCounter_ % info.decimationFactor == 0) {
finished.insert(idx);
}
}

// Wait for all time steps to finish, then calculate functions and
// transfer variables.
pool_.wait_for_tasks_to_finish();

if (failed) {
throw error(make_error_code(errc::simulation_error), errMessages.str());
}

// Transfer the outputs from simulators that have finished their
// individual time steps within this co-simulation time step.
for (auto simIndex : finished) {
auto& simInfo = simulators_.at(simIndex);
transfer_variables(simInfo.outgoingSimConnections);
transfer_variables(simInfo.outgoingFunConnections);
}

// Calculate functions and transfer their outputs to simulators.
for (const auto& f : functions_) {
const auto& info = f.second;
if (stepCounter_ % info.decimationFactor == 0) {
info.fun->calculate();
transfer_variables(info.outgoingSimConnections);
}
}
calculate_and_transfer();

return {baseStepSize_, std::move(finished)};
}
Expand Down Expand Up @@ -330,6 +306,25 @@ class fixed_step_algorithm::impl
});
}

void calculate_and_transfer()
{
// Transfer the outputs from simulators that have finished their
// individual time steps within the current co-simulation time step.
for (const auto& s : simulators_) {
if (stepCounter_ % s.second.decimationFactor == 0) {
transfer_variables(s.second.outgoingSimConnections);
transfer_variables(s.second.outgoingFunConnections);
}
}
// Calculate functions and transfer their outputs to simulators.
for (const auto& f : functions_) {
if (stepCounter_ % f.second.decimationFactor == 0) {
f.second.fun->calculate();
transfer_variables(f.second.outgoingSimConnections);
}
}
}

void transfer_variables(const std::vector<connection_ss>& connections)
{
for (const auto& c : connections) {
Expand Down
4 changes: 3 additions & 1 deletion src/cosim/slave_simulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,8 @@ class slave_simulator::impl
std::optional<time_point> stopTime,
std::optional<double> relativeTolerance)
{
return slave_->setup(startTime, stopTime, relativeTolerance);
slave_->setup(startTime, stopTime, relativeTolerance);
get_variables(duration::zero());
}

void do_iteration()
Expand All @@ -501,6 +502,7 @@ class slave_simulator::impl

void start_simulation()
{
set_variables(duration::zero());
slave_->start_simulation();
get_variables(duration::zero());
}
Expand Down

0 comments on commit 6ee3911

Please sign in to comment.