Point to Point Case

Author

Aleksandra Lekić, Haixiao Li

Published

February 23, 2026

Tip

This page presents a simple point-to-point AC/DC case. This example serves as a starting point to learn the workflow of building, solving, and analyzing OPF and HPS problems within HARMONY before moving to more complex multi-terminal or large-scale systems.

Main Procedure

Define Components

We take adding generators and converters, as the example. First, we need to declare the components, includes name, grid areas, and fundamental parameters. See Figure 1.

Figure 1: Decalre a component.

Then, we need to make connection to the bus. Here as we can see, For the generator, it has one terminal, which is connected to AC bus1. For the converter, it has two terminals, which are connected to AC bus2 and DC bus1. See Figure 2.

Figure 2: Make connection to the bus.

Lastly, we need to supplement some information, that are especially for OPF computation. See Figure 3.

Figure 3: Make connection to the bus.

Make a AC/DC Network

We need to make a AC/DC network through connecting each components. See Figure 4, Figure 5, and Figure 6.

Figure 4: Connet components in AC grid area#1.
Figure 5: Connet components in AC grid area#2.
Figure 6: Connet AC grid area#1 and area#2.

Access OPF and HPS results

The results will be printed and you can observe OPF results, and the HPS results with the updated operating points from the OPF. See Figure 7.

Figure 7: Printed OPF and HPS results.

Code Explanation

Code Script

  #include "Examples.h"

  #include "../network.h"
  #include "../Bus.h"
  #include "../Include_components.h"
  #include "../Solver/OPF/powerflow.h"
  #include "../Solver/Stability_Estimate/Stability_estimate.h"


  void example_point2point_case() {

      ///* ---------- 0 Set Network Object ---------- */
      Network net;

      ///* ---------- 1.1 Create AC Buses ---------- */
      Bus* bus1_ac = new Bus("ACBUS01", "AC1", 3);
      Bus* bus2_ac = new Bus("ACBUS02", "AC1", 3);
      Bus* bus3_ac = new Bus("ACBUS03", "AC2", 3);
      Bus* bus4_ac = new Bus("ACBUS04", "AC2", 3); // 

      ///*  ---------- 1.2 Add AC Loads  ---------- */

      // using RLC model
      std::vector<double> load_params2 = { 2.28e3, 1.457, 0 };
      Load* load2 = new Load("LOAD02", "AC2", 3, load_params2);
      // using PQ load model
      // LoadPQ* load2 = new LoadPQ("LOAD02", "AC2", 3, { 50e6, 5e6 });
      net.connectElementToBus(load2, 1, bus4_ac);

      ///*  ---------- 1.3 Add AC Generators  ---------- */

      /// Generator 1
      double Zsrc = 5; 
      AC_source* src1 = new AC_source("SRC01", "AC1", 3, 345e3, Zsrc);
      net.connectElementToBus(src1, 1, bus1_ac);
      map<string, double> src_info1 = {
          {"Pmax", 250.0},   // Maximum active power output (MW)
          {"Pmin", 10.0},    // Minimum active power output (MW)

          {"Qmax", 10.0},    // Maximum reactive power output (MVar)
          {"Qmin", -10.0},   // Minimum reactive power output (MVar)

          {"c2", 0.11},      // Quadratic coefficient of the generation cost function (c2*P^2 + c1*P + c0)
          {"c1", 5.0},       // Linear coefficient of the generation cost function
          {"c0", 150},       // Constant term of the generation cost function (fixed operation cost)

          {"Ref", 1},         // Reference bus flag (1 = set as slack/reference bus)
          {"Vg", 345 * 1.06} // Generator terminal voltage reference
      };
      src1->setOPFInfo(src_info1);

      ///*  ---------- 1.4 Add Branches  ---------- */
      double ACR1 = 5; double ACX1 = 140;
      std::complex<double> ACZ1(ACR1, ACX1);
      Impedance* br1_ac = new Impedance("br1_ac", "AC1", 3, ACZ1);
      net.connectElementToBus(br1_ac, /*terminal=*/1, bus1_ac);
      net.connectElementToBus(br1_ac, /*terminal=*/2, bus2_ac);

      double ACR2 = 5; double ACX2 = 140;
      std::complex<double> ACZ2(ACR2, ACX2);
      Impedance* br2_ac = new Impedance("br2_ac", "AC2", 3, ACZ2);
      net.connectElementToBus(br2_ac, /*terminal=*/1, bus3_ac);
      net.connectElementToBus(br2_ac, /*terminal=*/2, bus4_ac);

      ///*  ---------- 2.1 Create DC Buses  ---------- */
      Bus* bus1_dc = new Bus("DCBUS01", "DC1", 1);
      Bus* bus2_dc = new Bus("DCBUS02", "DC1", 1);

      ///*  ---------- 2.2 Create DC Buses  ---------- */
      double DCR1 = 20;
      Impedance* br1_dc = new Impedance("br1_dc", "DC1", 1, DCR1);
      net.connectElementToBus(br1_dc, /*terminal=*/1, bus1_dc);
      net.connectElementToBus(br1_dc, /*terminal=*/2, bus2_dc);

      ///*  ---------- 2.3 Create Converters ---------- */
      vector<double> converter_params1 = {
          2 * M_PI * 50,  // Omega (Nominal Frequency in rad/s)
          50.0 * 1e6,     // Active Power (P) in W
          0 * 1e6,        // Reactive Power (Q) in VA
          0.0,            // Theta (Voltage Angle in rad)
          345.0 * 1e3,    // AC Voltage (V_m) in V
          50 * 1e6,       // DC power (P_dc) in W
          440.0 * 1e3,    // DC Voltage (V_dc) in kV
          0.05,           // Arm Inductance (L_arm) in H
          1.07,           // Arm Resistance (R_arm) in Ω
          0.01,           // Capacitance per Submodule (C_arm) in F
          400,            // Number of Submodules (N)
          0.0005,         // Reactor Inductance (L_reactor) in H
          0.0001,         // Reactor Resistance (R_reactor) in Ω
          0.0             // Time Delay (t_delay) in seconds
    };
      std::vector<double> controller_params1 = {
          1, 0, 0.001103374, 0.00073, 1, 0, // PLL controller parameters
          0, // DC voltage controller parameters
          1, 0, 6.6667e-07, 3.3333e-04, 1, 50e6, // active power
          0, // AC voltage
          1, 0, 6.6667e-07, 3.3333e-04, 1, 0, // reactive power
          1, 0, 120, 400, 1, 0, // energy controller parameters 
          1, 0, 19.93, 4500, 1, 166.67, // zcc controller parameters 
          1, 0, 117.93, 8.5e4, 2, 666.67, 0, // occ controller parameters
          1, 0, 19.93, 4500, 2, 0, 0, // ccc controller parameters
          0 // droop control
      };
      MMC* mmc1 = new MMC("MMC1", "AC1_DC1", converter_params1, controller_params1);
      net.connectElementToBus(mmc1, 1, bus2_ac);
      net.connectElementToBus(mmc1, 2, bus1_dc);

      vector<double> converter_params2 = {
          2 * M_PI * 50,  // Omega (Nominal Frequency in rad/s)
          -50.0 * 1e6,    // Active Power (P) in W
          -20e6,          // Reactive Power (Q) in VA
          0.0,            // Theta (Voltage Angle in rad)
          345.0 * 1e3,    // AC Voltage (V_m) in V
          -50 * 1e6,       // DC power (P_dc) in W
          440.0 * 1e3,    // DC Voltage (V_dc) in kV
          0.05,           // Arm Inductance (L_arm) in H
          1.07,           // Arm Resistance (R_arm) in Ω
          0.01,           // Capacitance per Submodule (C_arm) in F
          400,            // Number of Submodules (N)
          0.0005,         // Reactor Inductance (L_reactor) in H
          0.0001,         // Reactor Resistance (R_reactor) in Ω
          0.0             // Time Delay (t_delay) in seconds
      };
      std::vector<double> controller_params2 = { 
          1, 0, 0.001103374, 0.00073, 1, 0, // PLL controller parameters
          1, 0, 2, 82, 2, 0, 440e3, // DC voltage controller parameters
          0, // active power
          0, // AC voltage
          1, 0, 6.6667e-07, 3.3333e-04, 1, -20e6, // reactive power
          1, 0, 120, 400, 1, 0, // energy controller parameters 
          1, 0, 19.93, 4500, 1, -41.66, // zcc controller parameters 
          1, 0, 117.93, 8.5e4, 2, -89.71, 0, // occ controller parameters
          1, 0, 19.93, 4500, 2, 0, 0, // ccc controller parameters
          0  // droop control
      };
      MMC* mmc2 = new MMC("MMC2", "AC2_DC1", converter_params2, controller_params2);
      net.connectElementToBus(mmc2, 1, bus3_ac);
      net.connectElementToBus(mmc2, 2, bus2_dc);

      ///*----- 3 OPF Implementatiopn ----- */
      PowerFlow pf;

      //const auto& data = net.getNetData();
      std::map<std::string, double> global_params;
      double omega = 2 * M_PI * 50;
      global_params["omega"] = omega;
      global_params["baseMVA"] = 100;
      global_params["ACbaseKV"] = 345.0; // Base voltage in kV, can be adjusted as needed
      global_params["DCbaseKV"] = 400.0; // Base voltage for DC, can be adjusted as needed
      global_params["Z_base"] = global_params["ACbaseKV"] * global_params["ACbaseKV"] / global_params["baseMVA"]; // Base impedance, can be adjusted as needed

      pf.make_OPF(&net, global_params, false, false, false, true);
  }

Execution Results

  Optimization succeeded. Solution found!

  =================================================================================================
  |   AC  Grid Bus Data                                                                           |
  =================================================================================================
  Area    Bus        Voltage             Generation            Load                 RES
  #       #     Mag [pu]/Ang [deg]  Pg [MW]   Qg [MVAr]  P [MW]   Q [MVAr]  Pres [MW]  Qres[MVAr]
  -----   -----  ------------------  --------  ---------  -------  -------   ---------  -----------
    1       1    1.060  /   0.00*         -          -      0.00     0.00         -          -
    1       2    1.059  /   3.17          -          -      0.00     0.00         -          -
    1       3    1.060  /  -0.11       52.87       4.47     0.00     0.00         -          -
    2       1    1.100  /   0.00          -          -      0.00     0.00         -          -
    2       2    1.086  /   2.81          -          -     50.18    10.07         -          -
  -----   -----  ------------------  --------  ---------  -------  -------   ---------  -----------
  The total generation cost is $721.77/MWh (€668.31/MWh)


  ===========================================================================================
  |     AC Grids Branch Data                                                                |
  ===========================================================================================
  Area   Branch  From   To        From Branch Flow         To Branch Flow        Branch Loss
  #      #       Bus#   Bus#    Pij [MW]   Qij [MVAr]    Pij [MW]   Qij [MVAr]  Pij_loss [MW]
  ----   ------  -----  -----  ---------  ----------   ----------  ----------  -------------
    1      1       2      1      -52.762       2.878       52.867       0.052       0.105
    1      2       1      3      -52.867      -0.052       52.867       4.474       0.000
    2      1       1      2       50.275      12.688      -50.181     -10.074       0.093
  ----   ------  -----  -----  ---------  -----------    --------  ----------  -------------
  The total AC network losses is 0.198 MW.

  ================================================================================
  |   MTDC Bus Data                                                                |
  ==================================================================================
  Bus   Bus    AC   DC Voltage   DC Power   PCC Bus Injection   Converter loss
  DC #  AC #  Area   Vdc [pu]    Pdc [MW]   Ps [MW]  Qs [MVAr]  Conv_Ploss [MW]
  -----  ----  ----  ---------    --------   -------  --------   ------------
    1     1     2     1.272       -51.431   -50.275  -12.688      1.157
    2     2     1     1.275        51.568    52.762   -2.878      1.194
  -----  ----  ----  ---------    --------   -------  --------    --------
  The total converter losses is 2.351 MW

  ===================================================================
  |     MTDC Branch Data                                              |
  =====================================================================
  Branch  From   To     From Branch    To Branch      Branch Loss
  #       Bus#   Bus#   Flow Pij [MW]  Flow Pij [MW]  Pij_loss [MW]
  ------  -----  -----   ---------      ---------      ---------
      1      1      2     -51.431         51.568         0.137
  ------  -----  -----   ---------      ---------      ---------
  The total DC network losses is 0.137 MW.

  Execution time is 0.166 s

  === Updating 2 MMC elements with OPF results ===
  Converged (small step) in 990 iterations.
  [Updated MMC] MMC2 | Vm=379.494 kV, theta=0.000 deg, Pac=-50.275 MW, Qac=-12.688 MVar, Vdc=438.827 kV, Pdc=-51.431 MW
  Equilibrium state:
    -90.379     22.289    -39.067      0.000      0.000   -719.733   1427.202      0.237      1.017    303.461  -1246.133 438824.453
  Converged (small step) in 217753 iterations.
  [Updated MMC] MMC1 | Vm=365.519 kV, theta=3.174 deg, Pac=52.762 MW, Qac=-2.878 MVar, Vdc=439.999 kV, Pdc=51.568 MW
  Equilibrium state:
      96.232      5.249     39.985     -0.000     -0.000   -177.615  -1168.105     -0.337     -0.269     65.655   1273.031 439997.138