Constraint Macros

MacroEnergy.@add_balanceMacro
@add_balance(component, balance_id, equation)

A macro to add a balance definition to a Node, Transformation, or Storage.

@add_balance is the primary balance-definition interface for asset modelers. It supports equality and inequality balances with flow(...) terms and scalar or time-varying coefficients.

@add_balance lets a modeler write a named flow relationship in ordinary algebraic form and attach it to a vertex. Macro stores that relationship as normalized balance data, which BalanceConstraint later enforces at each time step.

Arguments

  • component: The component object to add balance data to
  • balance_id: Symbol key for the balance equation (e.g., :energy, :mass)
  • equation: Balance equation with operators: ==, =, <=, <, >=, >

Supported terms

  • flow(edge)

Coefficients

Coefficients may be:

  • a scalar number
  • a length-1 vector
  • a vector with one coefficient per time step of the host vertex

Coefficients should be written before flow(edge), for example heat_rate * flow(edge).

@add_balance expects linear terms. Expressions such as c / flow(edge) are nonlinear because they divide by a decision variable. Write every flow term as a coefficient multiplied by a flow, such as (1 / efficiency) * flow(edge).

Examples

@add_balance(transform, :energy, flow(elec_edge) == 0.5 * flow(h2_edge))
@add_balance(transform, :energy_lb, flow(elec_edge) >= eff * flow(h2_edge))

Method

@add_balance parses the equation, moves all terms onto the left-hand side, records the constraint sense (:eq, :le, or :ge), and converts each flow(...) term into a BalanceTerm. For flow terms, the stored coefficient is pre-adjusted using the edge incidence at the host vertex so that the compiled balance reproduces the algebraic equation the user wrote.

source
MacroEnergy.@add_stoichiometric_balanceMacro
@add_stoichiometric_balance(component, balance_id, equation, base_term)

Expand a stoichiometric-style balance written with the --> operator into multiple pairwise balances anchored on base_term.

This macro is a convenience wrapper for recipe-style or chemical-style relationships. For general balances, @add_balance is the preferred interface.

@add_stoichiometric_balance lets a modeler describe a recipe using incoming_terms --> outgoing_terms, then expands that shorthand into one or more ordinary balances that Macro can store and enforce.

Example

@add_stoichiometric_balance(
    electrolyzer,
    :energy,
    flow(elec_edge) --> efficiency * flow(h2_edge),
    flow(h2_edge),
)

Method

The macro parses the left and right sides of --> into weighted flow(...) terms, validates that left-hand terms are incoming and right-hand terms are outgoing relative to the host component, identifies the coefficient on base_term, and generates one pairwise @add_balance call for each remaining term using the proportional rule base_coeff * flow(term) - term_coeff * flow(base_term) == 0. This keeps the recipe syntax compact while delegating final balance construction to @add_balance.

source
MacroEnergy.@add_to_balanceMacro
@add_to_balance(component, balance_id, expression)

Add one or more terms to an existing named balance without writing an explicit constraint sense. This stores the provided expression as a raw additive contribution to balance_id.

Modelers should usually write positive coefficients for both incoming and outgoing flow(...) terms. MacroEnergy applies edge-direction handling later when compiling the balance, so outgoing flows contribute with a negative sign in the common case.

Example

@add_to_balance(transform, :energy, flow(fuel_edge))
@add_to_balance(transform, :energy, 0.5 * flow(elec_edge))
source
MacroEnergy.@add_to_storage_balanceMacro
@add_to_storage_balance(storage, expression)
@add_to_storage_balance(storage, :storage, expression)

Add terms to the reserved :storage balance on a storage component. This macro is a convenience wrapper around @add_to_balance that defaults the balance ID to :storage.

Modelers should usually write positive coefficients for both inflow and outflow terms. MacroEnergy applies edge-direction handling later when compiling the final storage balance, so outgoing storage flows reduce storage in the common case.

Example

@add_to_storage_balance(storage, charge_efficiency * flow(charge_edge))
@add_to_storage_balance(storage, 1 / discharge_efficiency * flow(discharge_edge))
source
MacroEnergy.@inspect_stoichiometric_balanceMacro
@inspect_stoichiometric_balance(component, balance_id, equation, base_term)
@inspect_stoichiometric_balance(component, balance_id, equation, base_term, verify_edge_directions = true)

Return the pairwise algebraic balance equations that @add_stoichiometric_balance would generate.

This is a debugging helper for understanding the recipe expansion without reading the lower-level BalanceTerm machinery. The macro returns a vector of Pair{Symbol, Expr} values mapping each generated balance ID to the plain algebraic equation that would be passed to @add_balance.

By default the macro skips orientation validation so the algebraic expansion can be inspected without requiring live component and edge objects. Pass verify_edge_directions = true to reuse the same orientation validation as @add_stoichiometric_balance.

source