Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/GMLC-TDC/HELICS/llms.txt

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

Value federates are the most common type of federate in HELICS co-simulations. They model the physics of a system—batteries, generators, thermal loads, fluid networks—and exchange physical quantities with other federates through a publish/subscribe interface. Where value signals differ fundamentally from messages is in their semantics: a published value is persistent, meaning it remains available to all subscribers with its latest value until the publisher updates it. This reflects physical reality, where a voltage or temperature at a boundary is a continuous quantity that other simulators can read at any time, not a one-shot packet that disappears after receipt.

Interface types for value federates

HELICS provides four interface types for value exchange. The choice between them determines whether the federate or the federation configuration specifies the connection mapping.
InterfaceDirectionConnection specified by
PublicationSendingRecipient is optional (targets)
SubscriptionReceivingSender is specified via key
Named InputReceivingNamed; targets are optional
Directed OutputSendingRecipient is required
Publications and subscriptions are the most commonly used pair. A publication declares a value the federate will produce; a subscription declares a named publication the federate wants to receive. The publisher does not need to know its subscribers, and a subscription does not need to know it is a subscription—it simply names the publication it wants. Named inputs are a more flexible alternative to subscriptions. Like subscriptions, they receive values, but they are themselves named within the federation and can receive from multiple sources simultaneously. This is useful for aggregation scenarios.
Publications and subscriptions are the recommended starting point for most co-simulations. Named inputs are more appropriate when a single receiving interface must aggregate values from several publishers, or when the mapping of connections is managed centrally in a broker configuration file rather than within each federate.

Supported data types

HELICS supports a wide range of data types for value signals. The type is specified when registering the interface and determines how HELICS serializes and deserializes the value. HELICS will perform type conversion where possible if the publisher and subscriber specify different types.
Type stringDescription
double64-bit floating-point scalar
int64-bit signed integer
stringUTF-8 string
complexComplex number (real + imaginary as doubles)
vectorArray of doubles
complex_vectorArray of complex numbers
named_pointNamed double value (string + double pair)
booleanTrue/false
timeHELICS time value

JSON configuration

Federate publications, subscriptions, and inputs are most commonly configured via a JSON file. The same file also contains timing settings and federate-level properties.
{
  "name": "BatteryFederate",
  "loglevel": "warning",
  "coreType": "zmq",
  "period": 1.0,
  "uninterruptible": false,
  "terminate_on_error": true,
  "publications": [
    {
      "key": "BatteryFederate/EV1_current",
      "type": "double",
      "unit": "A",
      "global": false,
      "only_transmit_on_change": true,
      "tolerance": 0.001
    }
  ],
  "subscriptions": [
    {
      "key": "ChargerFederate/EV1_voltage",
      "type": "double",
      "unit": "V",
      "default": 0.0
    }
  ]
}

Key publication options

  • key — The unique identifier for this publication within the federate. If global is false (the default), the full federation-wide key becomes <federate_name>/<key>. If global is true, the key value is used as-is across the entire federation and must be unique.
  • type — The data type of the published value (see supported types above).
  • unit — Physical unit string. HELICS can perform unit conversion for double types (e.g., V to mV). A warning is generated if units are specified but incompatible.
  • global — When true, the key is the global name. Use for small federations with few publications to keep key strings short.
  • only_transmit_on_change and tolerance — HELICS will suppress publishing a new value unless it differs from the previous value by more than tolerance. Reduces unnecessary network traffic.

Key subscription options

  • key — The name of the publication to subscribe to. If the publication was registered with global: false, use the full <federate_name>/<publication_key> form.
  • default — The value returned before any publication has been received. Prevents undefined reads at simulation start.
  • only_update_on_change and tolerance — Symmetric to the publication option; the subscription considers a value “updated” only if it differs by more than tolerance.

C API

The HELICS C API is the basis for all language bindings. The following examples show the core calls for working with value federates.

Registering interfaces

#include <helics/helics.h>

HelicsError err = helicsErrorInitialize();

// Register a local publication (key is prepended with federate name)
HelicsPublication pub = helicsFederateRegisterPublication(
    fed,
    "EV1_current",           // key
    HELICS_DATA_TYPE_DOUBLE, // type
    "A",                     // units
    &err
);

// Register a global publication (key used as-is federation-wide)
HelicsPublication global_pub = helicsFederateRegisterGlobalPublication(
    fed,
    "BatteryFederate/EV1_voltage",
    HELICS_DATA_TYPE_DOUBLE,
    "V",
    &err
);

// Register a subscription (unnamed input targeting a specific publication)
HelicsInput sub = helicsFederateRegisterSubscription(
    fed,
    "ChargerFederate/EV1_voltage", // key of the publication to subscribe to
    "V",                           // expected units
    &err
);

Publishing values

// Publish a double
helicsPublicationPublishDouble(pub, 4.2, &err);

// Publish an integer
helicsPublicationPublishInteger(pub_int, 42, &err);

// Publish a string
helicsPublicationPublishString(pub_str, "nominal", &err);

// Publish a vector of doubles
double values[3] = {1.0, 2.0, 3.0};
helicsPublicationPublishVector(pub_vec, values, 3, &err);

// Publish a complex number
helicsPublicationPublishComplex(pub_cplx, 3.0, 4.0, &err);

Reading subscriptions and inputs

// Read a double
double current = helicsInputGetDouble(sub, &err);

// Read an integer
int64_t count = helicsInputGetInteger(sub_int, &err);

// Read a string
char buf[256];
helicsInputGetString(sub_str, buf, 256, NULL, &err);

// Check whether the input has been updated since last read
HelicsBool updated = helicsInputIsUpdated(sub);
if (updated == HELICS_TRUE) {
    double new_val = helicsInputGetDouble(sub, &err);
}

Global vs. local publications

The global flag on a publication controls the scope of its name within the federation. Local publications ("global": false) have their key automatically prefixed with the federate name. A publication with key "EV1_current" in a federate named "BatteryFederate" becomes "BatteryFederate/EV1_current" federation-wide. Subscribers must use this full name. Local publications are recommended for large federations where unique global names would be difficult to guarantee. Global publications ("global": true) use the key value as-is across the entire federation. The user is responsible for ensuring uniqueness. Global keys are convenient in small federations where short, descriptive names improve readability.
If two federates register global publications with the same key, HELICS will generate an error during initialization. Prefer local (non-global) publications for any federation with more than a few federates.

Inputs vs. subscriptions

Subscriptions are unnamed receiving interfaces—they are identified only by the publication key they target. Inputs are named receiving interfaces; they are known to the federation by their own key and can be connected to one or more publications via the targets field.
{
  "inputs": [
    {
      "key": "aggregate_power_input",
      "global": true,
      "targets": ["FederateA/power_output", "FederateB/power_output"],
      "type": "double",
      "default": 0.0
    }
  ]
}
When an input has multiple targets, the value returned by helicsInputGetDouble() is the most recently received value from any of those targets. For aggregation of multiple values you would need to query each target publication individually.
Use subscriptions when your federate needs a simple one-to-one connection to another federate’s publication. Use named inputs when you need the receiving interface itself to be identifiable by other tools or when connecting multiple sources to a single receiving point.

Build docs developers (and LLMs) love