Rerelease of MTK driven PowerDynamics.jl

Today I want to announce a major rerelease of PowerDynamics.jl! For the past 1½ years, we’ve been working on essentially rewriting the entire library, with a main focus on MTK-based modeling and tight integration with the SciML ecosystem.

At its core, PowerDynamics.jl is a modeling framework for simulating dynamic power grid behavior – “dynamic” here meaning that we target RMS and Quasi-EMT simulations of voltage transients ranging from milliseconds to minutes.
It’s a modeling framework in the sense that it helps you create ODEProblems and ODEFunctions to use with DifferentialEquations.jl and other packages in the SciML ecosystem. We focus on modeling to directly enable the use of advanced SciML tools such as SciMLSensitivity.jl.

Check out our documentation to learn more, and feel free to reach out via GitHub, email, or Slack if you have any questions. :blush:

Main Features

  • ModelingToolkit-based frontend: Our component models are built using MTK. You can define machines, controllers, line models, fault models, and more – all equation-based using MTK. We generate julia code for individual components (buses/lines) based on those MTK models for our backend. This gives you maximum flexibility at the component level. See the example in the docs.

  • NetworkDynamics.jl-based backend: We use NetworkDynamics.jl as our backend to “connect” individual component models on a graph into a full network. While this approach is less flexible than modeling the full network in MTK, it allows us to scale to larger networks without excessive symbolic simplification times. It also makes the network structure more explicit, which is useful for initialization (e.g., via power flow).

  • Automatic component initialization: Finding initial states can be challenging. PowerDynamics.jl allows you to attach power flow models to your dynamic models, solve the power flow problem, and determine free states/parameters in each dynamic component model to match the steady state given by the power flow. See the docs.

  • Symbolic indexing and observable support: Symbolic indexing means all your typical SciML workflows like plot(sol; idxs=VIndex(2, :mtk_var)) work seamlessly. Here, we plot the variable named mtk_var of the MTK model placed at vertex 2. Observable support means that :mtk_var can refer to any state, parameter, input, output, or observable of the original MTK model.

  • Callbacks on the component level: You can define events and callbacks per component. For example, you may define a power line that disconnects once it reaches its maximum current. This behavior becomes part of your component model. When used in a power grid, PowerDynamics.jl transforms those individual callbacks to efficient vector callbacks for the full network automatically.

  • SciMLSensitivity compatibility: Not necessarily a feature, but a natural result of our approach – it enables powerful workflows like parameter estimation (see the docs example).

  • Sparsity detection: Network problems are often very sparse. We provide an interface to SparseConnectivityTracer.jl to speed up your simulations with just a few lines of code (see the docs).

Relation to Other Libraries

The main other Julia library in this space is PowerSimulationsDynamics.jl. In contrast, one of our primary goals was tight integration with MTK. We also intentionally avoid “hiding” the SciML interface behind custom solve wrappers to integrate better with outher SciML workflows.

There is also RMSPowerSims.jl, which is more of a learning-oriented library and does not focus on high-performance simulations.

10 Likes