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.

The factory pattern in GridPACK bridges the gap between a freshly-partitioned network (whose components hold only raw DataCollection key-value pairs) and a fully-initialized simulation-ready network. gridpack::factory::BaseFactory<_network> provides the generic operations that every application shares; application developers subclass it to add domain-specific initialization logic.

Role of BaseFactory

When a network is first read from an input file and partitioned across MPI ranks, each bus and branch component contains a DataCollection object filled with parsed data. The factory is responsible for:
  1. Wiring the topology — connecting each branch to its endpoint buses and setting Global Array–based matrix-vector indices (setComponents).
  2. Loading component data — invoking load() on each bus and branch so they read their own parameters from the DataCollection (load).
  3. Allocating exchange buffers — enabling ghost-bus updates via initBusUpdate / updateBuses (setExchange).
  4. Switching computation phases — broadcasting an integer mode flag to every component (setMode, setBusMode, setBranchMode).
  5. Distributed validation — checking boolean conditions across all ranks (checkTrue, checkTrueSomewhere).

BaseFactory API

Construction

#include <gridpack/factory/base_factory.hpp>

// _network is your application network type
template <class _network>
class BaseFactory {
public:
  typedef boost::shared_ptr<_network> NetworkPtr;
  BaseFactory(NetworkPtr network);
};
The constructor caches raw pointers to all bus and branch components for fast iteration in setMode and related calls.

setComponents

virtual void setComponents(void);
Must be called after network partitioning and before any other factory method. setComponents performs three tasks:
  • Sets Bus1 / Bus2 pointers on each branch object.
  • Builds the neighbor-bus and neighbor-branch lists on each bus object.
  • Uses Global Arrays to assign globally-unique, contiguous MatVecIndex values to every active bus and branch. These indices are what mappers use to locate rows and columns in distributed matrices.
network->partition();            // partition across MPI ranks
factory.setComponents();         // wire topology and assign indices

load

virtual void load(void);
Iterates over every local bus and branch (including ghost components) and calls component->load(dataCollection). Each application component reads the parameters it needs from its DataCollection. This is where bus voltage ratings, generator MW limits, branch impedances, and similar data move from the parser’s intermediate format into the component’s own member variables.
factory.setComponents();
factory.load();   // buses and branches initialize themselves from DataCollection
Ghost buses and branches receive the same load() call as active ones. Ghosts must hold valid state because neighboring active components on other ranks may read their data during exchange operations.

setExchange

virtual void setExchange(bool flag = true);
Allocates exchange buffers in the network that allow active buses and branches to push state to their ghost copies on neighboring ranks. Must be called before the first network->updateBuses() or network->updateBranches(). The flag parameter controls whether buffers are allocated inside the network object (true, default) or inside the components themselves (false).

setMode

virtual void setMode(int mode);
virtual void setBusMode(int mode);
virtual void setBranchMode(int mode);
Calls setMode(mode) on every bus and branch component (or only buses / only branches for the variant forms). The integer mode is application-defined; by convention, applications declare named constants for each computation phase.
// Application-specific mode constants (defined in the app header)
enum PFMode { YBus = 0, Jacobian = 1, Residual = 2 };

factory.setMode(YBus);       // all buses and branches enter Y-matrix mode
yMapper.mapToMatrix(Y);

factory.setMode(Jacobian);   // switch to Jacobian mode
jMapper.mapToMatrix(J);
setBusMode and setBranchMode allow independent control when buses and branches require different modes simultaneously.

checkTrue / checkTrueSomewhere

bool checkTrue(bool flag);
bool checkTrueSomewhere(bool flag);
checkTrue returns true only if the local flag is true on every MPI rank. checkTrueSomewhere returns true if the flag is true on at least one rank. Internally both perform a Global Arrays GA_Pgroup_igop sum reduction.
bool localConverged = (maxMismatch < tolerance);
bool allConverged   = factory.checkTrue(localConverged);

if (!allConverged) {
  // at least one rank still has large mismatches
  continueIterating();
}
checkTrue and checkTrueSomewhere are collective: every rank in the network’s communicator must call them simultaneously. Calling them conditionally on only a subset of ranks causes a deadlock.

saveData

void saveData(void);
void saveDataAlsotoOrg(void);
Writes current component state back into the DataCollection objects so that results can be passed to output modules or transferred to a second network for chained computations. saveDataAlsotoOrg additionally updates the original voltage magnitudes, angles, and generator output values stored at parse time.

dumpData

void dumpData(void);
Debugging utility that prints the full contents of every bus and branch DataCollection to standard output, one rank at a time. Output ordering is not guaranteed due to I/O buffering.

Extending BaseFactory

Application factories inherit from BaseFactory and add domain-specific initialization phases:
// powerflow_factory.hpp
#include <gridpack/factory/base_factory.hpp>
#include "pf_network.hpp"

class PowerFlowFactory
    : public gridpack::factory::BaseFactory<PFNetwork>
{
public:
  PowerFlowFactory(NetworkPtr net)
    : gridpack::factory::BaseFactory<PFNetwork>(net) {}

  // Override load to add application-specific setup after base load()
  void load(void) override {
    // Call base class first
    gridpack::factory::BaseFactory<PFNetwork>::load();

    // Then perform PF-specific initialization
    for (int i = 0; i < p_numBuses; i++) {
      p_network->getBus(i)->setVoltageLimits();
    }
  }

  // Additional PF-specific factory methods
  void setReferenceVoltage(void);
  bool checkStatus(void);
};

Typical initialization sequence

// 1. Parse input
PTI33Parser<PFNetwork> parser;
parser.parse("case.raw", network);

// 2. Partition across MPI ranks
network->partition();

// 3. Wire topology and assign global indices
PowerFlowFactory factory(network);
factory.setComponents();

// 4. Allocate exchange buffers
factory.setExchange();

// 5. Load component parameters from DataCollection
factory.load();

// 6. Initialize bus update mechanism (for ghost updates)
network->initBusUpdate();

// 7. Validate initial state across all ranks
bool ok = factory.checkTrue(factory.checkStatus());
if (!ok) {
  // handle initialization failure
}

Network-to-matrix mappers

Use setMode before each mapToMatrix or mapToVector call.

Input parsing and output

Parsers that populate the DataCollection objects that factory.load() reads.

Build docs developers (and LLMs) love