Skip to content

Add simple one-sided co-sim example taking constant current over zmq - #537

Open
PhilipFackler wants to merge 1 commit into
developfrom
PhilipFackler/simple-zmq-cosim
Open

Add simple one-sided co-sim example taking constant current over zmq#537
PhilipFackler wants to merge 1 commit into
developfrom
PhilipFackler/simple-zmq-cosim

Conversation

@PhilipFackler

Copy link
Copy Markdown
Collaborator

Description

See #469

Introduce a minimal example using zmq for communication between GridKit processes.

Proposed changes

This example duplicates the behavior of the ThreeBusConstantSource example, but with the ConstantSignalSource component removed and its behavior reproduced in the app (external to the system model) with currents being received over zmq from another app.

Checklist

  • All tests pass.
  • Code compiles cleanly with flags -Wall -Wpedantic -Wconversion -Wextra.
  • The new code follows GridKit™ style guidelines.
  • There are unit tests for the new code.
  • The new code is documented.
  • The feature branch is rebased with respect to the target branch.
  • I have updated CHANGELOG.md to reflect the changes in this PR. If this is a minor PR that is part of a larger fix already included in the file, state so.

Further comments

A lot of comments here. 😄 I have numbered them for reference in discussion.

  1. I verified locally that the solution output is equal to that of the ConstantSignalSource example.
  2. This example code is temporary; longer-term, this will be generalized and moved to the applications directory.
  3. This example uses the "step_callback" in Ida::runSimulation rather than managing the stepping itself; this is questionable :), since we are intending to remove that.
  4. The app implementation is a bit crude because this proof-of-concept (first attempt) was meant to be non-invasive (no modification to the phasor dynamics libraries). In order to move forward with a more general implementation, we will need some other tools.
    1. The immediate next step would be to add a "branch-terminal-adapter" (not sure what to name it) so that bus voltage (coming in over zmq) could be read from outside the system. This would enable a true co-simulation example with two systems solving in step with one another.
    2. Beyond that, the path diverges depending on how often we want to synchronize: just at every time step OR at every call to evaluateResidual
      1. Every residual: Use the "IOPorts" PR replacement of ComponentSignals. Extend it to make ports configurable...enabling the zmq exchange to be triggered when signals are read from ports.
      2. Every step
        1. Add a modified version of ConstantSignalSource that would use zmq to update its "constant" values.
        2. Use "IOPorts" as-is/was to enable this more naturally from outside the system (no new component needed). This would make the most sense from the application perspective because the application input file could simply specify which signals to assign to the network.

I'll add that in either of the "IOPorts" scenarios the co-simulation "manager" could be set up to exchange all necessary variables in one send/recv.

@PhilipFackler
PhilipFackler requested a review from pelesh August 13, 2026 17:34
@PhilipFackler
PhilipFackler force-pushed the PhilipFackler/simple-zmq-cosim branch from c94431f to 5eef957 Compare August 13, 2026 17:38
@nkoukpaizan nkoukpaizan added the enhancement New feature or request label Aug 13, 2026
@pelesh
pelesh requested a review from hambrickjc August 13, 2026 19:19

@pelesh pelesh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to document code and add a README file with description of the cosimulation app and the example.

Comment on lines -36 to -47
SystemModelData<double, size_t> parseSystemModelData(const std::string& fileName)
{
auto stream = std::ifstream(fileName);
if (!stream)
{
std::stringstream ss;
ss << "Could not open file: " << fileName;
Log::error() << ss.str() << std::endl;
throw std::runtime_error(ss.str());
}
return parseSystemModelData(stream);
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this function removed?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It caused a compiler error for my app because it's redundant/ambiguous.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants