Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/GridOPTICS/GridPACK/llms.txt

Use this file to discover all available pages before exploring further.

Every GridPACK application is controlled by a single XML configuration file. The gridpack::utility::Configuration class reads that file on process 0, broadcasts the parsed tree to all MPI ranks, and provides a hierarchical key-value API for accessing parameters. Components across the framework — parsers, linear solvers, Newton-Raphson loops, dynamic simulation time-steppers — all read from the same shared configuration instance.

Configuration class

gridpack::utility::Configuration lives in the gridpack::utility namespace. A singleton accessor (Configuration::configuration()) provides the shared instance used throughout an application. Alternatively, a local instance can be created and passed explicitly.
#include <gridpack/configuration/configuration.hpp>

// Option 1: shared singleton (most common)
gridpack::utility::Configuration *config =
    gridpack::utility::Configuration::configuration();

// Option 2: local instance
gridpack::utility::Configuration config;

Opening a configuration file

The file is opened collectively: all MPI ranks in the communicator receive the parsed XML tree.
gridpack::parallel::Communicator comm;
bool ok = config->open("input.xml", comm);
if (!ok) {
  // XML parse error or file not found
}
open() reads the file only on the rank that calls it (rank 0 by convention), then broadcasts the content via MPI. Subsequent get() calls are purely local reads from the in-memory tree.

Reading values

get() is overloaded for bool, int, double, std::string, and std::vector<double>. Every overload has two forms: one returns the value directly with a default, and one writes to a pointer and returns bool indicating whether the key was present.
// With default — always succeeds
double tol     = config->get("Configuration.PowerFlow.tolerance", 1.0e-6);
int    maxIter = config->get("Configuration.PowerFlow.maxIterations", 50);
std::string raw = config->get("Configuration.PowerFlow.networkConfiguration",
                               std::string("case.raw"));

// Pointer form — returns false if key absent
double damp;
bool found = config->get("Configuration.PowerFlow.dampingFactor", &damp);
if (!found) damp = 1.0;
Keys use the . separator to navigate the XML hierarchy. The string "Configuration.PowerFlow.tolerance" maps to:
<Configuration>
  <PowerFlow>
    <tolerance>1.0e-6</tolerance>
  </PowerFlow>
</Configuration>

Cursors

A cursor represents a position in the XML tree. Rather than repeating the full path for every get() call inside a component, obtain a cursor to the relevant subtree and use relative keys:
// Get a cursor to the PowerFlow block
gridpack::utility::Configuration::CursorPtr pf =
    config->getCursor("Configuration.PowerFlow");

// Relative keys — no need to repeat the prefix
double tol  = pf->get("tolerance", 1.0e-6);
int maxIter = pf->get("maxIterations", 50);

// Pass cursor to a solver for self-configuration
gridpack::math::LinearSolver solver(A);
solver.configure(pf);   // solver reads its own keys under pf
getCursor returns nullptr if the path does not exist in the XML. Always check before dereferencing if the block is optional.

Iterating over child elements

When the XML has repeated elements with the same tag (e.g., a list of faults or contingencies), use children() to iterate:
gridpack::utility::Configuration::CursorPtr faults =
    config->getCursor("Configuration.DynamicSimulation.Faults");

gridpack::utility::Configuration::ChildCursors children;
faults->children(children);

for (auto &c : children) {
  std::string branch = c->get("Branch", "none");
  double      time   = c->get("StartTime", 0.0);
  // process fault...
}

Complete example XML file

The following file covers the sections used by the most common GridPACK applications — power flow, dynamic simulation, and linear-solver tuning:
<?xml version="1.0" encoding="utf-8"?>
<Configuration>

  <!-- Power flow application -->
  <PowerFlow>
    <networkConfiguration>network.raw</networkConfiguration>
    <maxIteration>50</maxIteration>
    <tolerance>1.0e-6</tolerance>
    <dampingFactor>1.0</dampingFactor>

    <LinearSolver>
      <PETScOptions>
        -ksp_type bcgs
        -pc_type bjacobi
        -sub_pc_type ilu
        -ksp_max_it 500
        -ksp_rtol 1.0e-8
      </PETScOptions>
    </LinearSolver>
  </PowerFlow>

  <!-- Dynamic simulation application -->
  <DynamicSimulation>
    <networkConfiguration>network.raw</networkConfiguration>
    <simulationTime>1.0</simulationTime>
    <timeStep>0.005</timeStep>
    <generatorParameters>gen_models.dyr</generatorParameters>
    <equilibriumInit>false</equilibriumInit>

    <Faults>
      <Fault>
        <Branch>1 2</Branch>
        <StartTime>0.1</StartTime>
        <EndTime>0.2</EndTime>
      </Fault>
    </Faults>

    <LinearSolver>
      <PETScOptions>
        -ksp_type gmres
        -ksp_gmres_restart 50
        -pc_type asm
        -sub_pc_type lu
        -ksp_rtol 1.0e-6
      </PETScOptions>
    </LinearSolver>
  </DynamicSimulation>

  <!-- State estimation application -->
  <StateEstimation>
    <networkConfiguration>network.raw</networkConfiguration>
    <measurementList>measurements.xml</measurementList>
    <tolerance>1.0e-5</tolerance>
    <maxIteration>30</maxIteration>
    <dampingFactor>1.0</dampingFactor>
    <diagnosticOutputLevel>standard</diagnosticOutputLevel>
  </StateEstimation>

</Configuration>

Newton-Raphson parameters

The following parameters are recognized by the built-in Newton-Raphson solvers in power flow and state estimation. They live inside the application-specific XML block (e.g., <PowerFlow>):
XML elementC++ defaultDescription
<tolerance>1.0e-6Residual infinity-norm below which NR declares convergence
<maxIteration>50Maximum number of Newton-Raphson iterations
<dampingFactor>1.0Step-size multiplier (0 < d ≤ 1) applied to the Newton correction
// Reading NR parameters in application code
gridpack::utility::Configuration::CursorPtr pf =
    config->getCursor("Configuration.PowerFlow");

double tol   = pf->get("tolerance",     1.0e-6);
int    maxIt = pf->get("maxIteration",  50);
double damp  = pf->get("dampingFactor", 1.0);
Reduce dampingFactor to values between 0.5 and 0.8 when the Newton iteration diverges or oscillates on stressed cases. A smaller damping factor sacrifices convergence speed for robustness.

Enabling diagnostic logging

// Log all configuration reads to std::cout
config->enableLogging(&std::cout);

// Or to a file stream
std::ofstream log("config_trace.log");
config->enableLogging(&log);
Logging records every key access with its resolved value, which is useful for diagnosing missing or misnamed XML elements.

How solvers self-configure

Solver classes in the math module inherit from utility::WrappedConfigurable. When solver.configure(cursor) is called, the solver’s p_configure implementation reads its own keys from the cursor. For example, LinearSolverImplementation reads <PETScOptions> and passes the string directly to PetscOptionsInsertString.
// In application driver
gridpack::utility::Configuration::CursorPtr cursor =
    config->getCursor("Configuration.PowerFlow");

gridpack::math::LinearSolver solver(A);
solver.configure(cursor);  // reads <LinearSolver><PETScOptions>...</PETScOptions></LinearSolver>
The solver looks for its configuration block as a child of the cursor you pass — not at the root of the XML tree. Pass the cursor to the application-level block (e.g., PowerFlow), not the root Configuration cursor.

Math module: solvers

LinearSolver, NonlinearSolver, and DAESolver — all configured via the XML system.

Input parsing and output

PSS/E RAW parsers that read the networkConfiguration path from this XML file.

Build docs developers (and LLMs) love