Development Guide

This describes the steps to implement new model that can be solved by the algorithms provided in this package.

Algorithm overview

Two-level ADMM algorithm can be implemented by defining the functions called in the while loop of admm_two_level() function in algorithms/admm_two_level.jl file. These functions take two arguments of type AdmmEnv and AbstractOPFModel. You need to define your model structure that inherits AbstractOPFModel so that those functions can be called using multiple dispatching.

Mathematical description

It is important to understand the algorithm implemented in this package before implementing one for your own model.

The algorithm aims at solving the following optimization problem

\[\begin{align*} \min_{x_i \in X_i,\bar{x} \in \bar{X},z} \quad & \sum_{i=1}^N f_i(x_i) \\ \text{subject to} \quad & x - \bar{x} + z = 0 & (\lambda) \\ & z = 0 & (\lambda_z) \\ & x:=(x_1,\dots,x_N) \end{align*}\]

by using the form of augmented Lagrangian method as follows:

  1. Initialize $\lambda_z$ and $\beta$.
  2. Solve the following problem for given $(\lambda_z,\beta)$:

\[\begin{align*} \min_{x_i \in X_i,\bar{x} \in \bar{X},z} \quad & \sum_{i=1}^N f_i(x_i) + \lambda_z^T z + \frac{\beta}{2} \|z\|_2^2 \tag{AugLag} \\ \text{subject to} \quad & x - \bar{x} + z = 0 & (\lambda) \end{align*}\]

  1. Update $\lambda_z$
  2. Repeat steps 2-3 until $z \approx 0$.

Implementation steps

We encourage to follow our naming convention for the files created for your own model. In this description, we assume that we are creating our own model called myopf. The steps required to implement the two-level ADMM algorithm for the model myopf are as follows:

  1. Create a directory models/myopf for your own model.

  2. Create a file models/myopf/myopf_model.jl to define the model structure from AbstractOPFModel.

    mutable struct ModelMyopf{T,TD,TI,TM} <: AbstractOPFModel{T,TD,TI,TM}
        # ...
    end

    Examples are available in models/acopf/acopf_model.jl and models/mpacopf_model.jl.

  3. Implement all necessary functions: A list of functions required to implement

Note

ExaAdmm.jl provides a default implementation for each function, dispatching on AbstractOPFModel. This default implementation matches the behavior of ModelAcopf, and allow the user to avoid overloading if the behavior of the new model ModelMyopf matches those of ModelAcopf for a particular function.

A list of functions required to implement

Define the following functions that will take your new model structure:

Functions in myopf_admm_increment_outer.jl

Functions in myopf_admm_prepoststep_{cpu,gpu}.jl

Functions in myopf_admm_update_x_{cpu,gpu}.jl

ExaAdmm.admm_update_xMethod

Update variable x, representing the variables for generators and lines in the component-based decomposition of ACOPF.

source

Functions in myopf_admm_update_xbar_{cpu,gpu}.jl

Functions in myopf_admm_update_z_{cpu,gpu}.jl

ExaAdmm.admm_update_zMethod

Update variable z, representing the artificial variables that are driven to zero in the two-level ADMM.

source

Functions in myopf_admm_update_l_{cpu,gpu}.jl

Functions in myopf_admm_update_lz_{cpu,gpu}.jl

Functions in myopf_admm_update_residual_{cpu,gpu}.jl

ExaAdmm.admm_update_residualMethod

Compute and update the primal and dual residuals at current iteration.

Arguments

  • env::AdmmEnv – struct that defines the environment of ADMM
  • mod::ModelAcopf – struct that defines model

Notes

The primal and dual residuals are stored in mod.solution.rp and mod.solution.rd, respectively.

source
Note

Internally, these x and xbar correspond to u and v variables in the code, respectively. Variables u and v have the same structure. For example in ACOPF, the variable stores modeling variable values in the following order:

\[({\color{blue} (p_{g,i}, q_{g,i})_{i=1,\dots,|G|}}, {\color{red} (p_{ij,\ell}, q_{ij,\ell}, p_{ji,\ell}, q_{ji,\ell}, w_{i,\ell}, w_{j,\ell}, t_{i,\ell}, t_{j,\ell})_{\ell=1,\dots,|L|}})\]

Notes for GPU

To make your model run on Nvidia GPUs, the AdmmEnv and you also need to implement these functions that take arrays of type CuArray. You can find examples in interface/solve_acopf.jl and interface/solve_mpacopf.jl.