Skip to content

fluxopt.components

Classes:

Name Description
Port

System boundary importing and exporting carriers.

Converter

Conversion between input and output flows.

Port pydantic-model

Bases: Element

System boundary importing and exporting carriers.

imports bring flow into the system (sources); exports send it out of the system (sinks).

Show JSON schema:
{
  "$defs": {
    "Flow": {
      "description": "A single energy flow on a carrier.\n\n``short_id`` defaults to ``carrier`` (or ``carrier:node`` when ``node``\nis set).  Set explicitly to disambiguate multiple flows on the same\ncarrier::\n\n    Flow(carrier='elec')  # short_id='elec'\n    Flow(carrier='heat', node='A')  # short_id='heat:A'\n    Flow(carrier='elec', short_id='base')  # short_id='base'\n\n``short_id`` must be unique within a component.  The system-global\nqualified id ``component(short_id)`` is derived at build time and\nappears as the ``flow`` coordinate in ``ModelData`` and results; the\nflow itself is never modified. Storage resolves colliding short_ids\nto ``charge`` / ``discharge`` at that point.\n\nSee: docs/math/flows.md",
      "properties": {
        "carrier": {
          "title": "Carrier",
          "type": "string"
        },
        "short_id": {
          "default": "",
          "title": "Short Id",
          "type": "string"
        },
        "node": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Node"
        },
        "size": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/$defs/Sizing"
            },
            {
              "$ref": "#/$defs/Investment"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Size"
        },
        "relative_rate_min": {
          "$ref": "#/$defs/Variate",
          "default": 0.0
        },
        "relative_rate_max": {
          "$ref": "#/$defs/Variate",
          "default": 1.0
        },
        "fixed_relative_profile": {
          "anyOf": [
            {
              "$ref": "#/$defs/Variate"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "effects_per_flow_hour": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Per Flow Hour",
          "type": "object"
        },
        "flow_hours_min": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Flow Hours Min"
        },
        "flow_hours_max": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Flow Hours Max"
        },
        "load_factor_min": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Load Factor Min"
        },
        "load_factor_max": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Load Factor Max"
        },
        "ramp_up_per_hour": {
          "anyOf": [
            {
              "$ref": "#/$defs/Variate"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "ramp_down_per_hour": {
          "anyOf": [
            {
              "$ref": "#/$defs/Variate"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "status": {
          "anyOf": [
            {
              "$ref": "#/$defs/Status"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "prior_rates": {
          "anyOf": [
            {
              "items": {
                "type": "number"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Prior Rates"
        }
      },
      "required": [
        "carrier"
      ],
      "title": "Flow",
      "type": "object"
    },
    "Investment": {
      "description": "Singular discrete build-timing optimization.\n\nThe solver decides WHEN to build (which period) and at what size.\nOnce built, capacity is available for ``lifetime`` periods.\nSize is decided once \u2014 no growth or partial retirement.",
      "properties": {
        "size_min": {
          "minimum": 0,
          "title": "Size Min",
          "type": "number"
        },
        "size_max": {
          "minimum": 0,
          "title": "Size Max",
          "type": "number"
        },
        "mandatory": {
          "default": true,
          "title": "Mandatory",
          "type": "boolean"
        },
        "lifetime": {
          "anyOf": [
            {
              "exclusiveMinimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Lifetime"
        },
        "prior_size": {
          "default": 0.0,
          "minimum": 0,
          "title": "Prior Size",
          "type": "number"
        },
        "effects_per_size_at_build": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Per Size At Build",
          "type": "object"
        },
        "effects_fixed_at_build": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Fixed At Build",
          "type": "object"
        },
        "effects_per_size_recurring": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Per Size Recurring",
          "type": "object"
        },
        "effects_fixed_recurring": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Fixed Recurring",
          "type": "object"
        }
      },
      "required": [
        "size_min",
        "size_max"
      ],
      "title": "Investment",
      "type": "object"
    },
    "ProfileRef": {
      "description": "Reference to a time-series stored outside the model definition.\n\nA serializable stand-in for an inline ``Variate`` array: the profile lives\nin a data file / dataset and is named here, so structural definitions\nround-trip to YAML/JSON without inlining 8760-point series. Resolve it to a\n:class:`xr.DataArray` with :meth:`resolve` before building the model.",
      "properties": {
        "dataset": {
          "title": "Dataset",
          "type": "string"
        },
        "variable": {
          "title": "Variable",
          "type": "string"
        }
      },
      "required": [
        "dataset",
        "variable"
      ],
      "title": "ProfileRef",
      "type": "object"
    },
    "Sizing": {
      "description": "Capacity optimization parameters.\n\nThe solver decides the optimal size within [size_min, size_max].\n\n- ``mandatory=True``: continuous, size in [min, max], no binary.\n- ``mandatory=False``: binary indicator gates size: 0 or [min, max].\n- ``size_min == size_max`` with ``mandatory=False``: binary invest\n  at exact size (yes/no).\n\nSee: docs/math/sizing.md",
      "properties": {
        "size_min": {
          "minimum": 0,
          "title": "Size Min",
          "type": "number"
        },
        "size_max": {
          "minimum": 0,
          "title": "Size Max",
          "type": "number"
        },
        "mandatory": {
          "default": true,
          "title": "Mandatory",
          "type": "boolean"
        },
        "effects_per_size": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Per Size",
          "type": "object"
        },
        "effects_fixed": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Fixed",
          "type": "object"
        }
      },
      "required": [
        "size_min",
        "size_max"
      ],
      "title": "Sizing",
      "type": "object"
    },
    "Status": {
      "description": "Binary on/off behavior parameters.\n\nTogether with relative bounds, gives semi-continuous behavior:\n``{0} U [min, max] * size``.\n\nSee: docs/math/status.md",
      "properties": {
        "uptime_min": {
          "anyOf": [
            {
              "minimum": 0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Uptime Min"
        },
        "uptime_max": {
          "anyOf": [
            {
              "minimum": 0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Uptime Max"
        },
        "downtime_min": {
          "anyOf": [
            {
              "minimum": 0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Downtime Min"
        },
        "downtime_max": {
          "anyOf": [
            {
              "minimum": 0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Downtime Max"
        },
        "effects_per_running_hour": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Per Running Hour",
          "type": "object"
        },
        "effects_per_startup": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Per Startup",
          "type": "object"
        }
      },
      "title": "Status",
      "type": "object"
    },
    "Variate": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "integer"
        },
        {
          "items": {
            "type": "number"
          },
          "type": "array"
        },
        {
          "$ref": "#/$defs/ProfileRef"
        }
      ]
    }
  },
  "description": "System boundary importing and exporting carriers.\n\n``imports`` bring flow into the system (sources); ``exports`` send it out\nof the system (sinks).",
  "properties": {
    "id": {
      "title": "Id",
      "type": "string"
    },
    "imports": {
      "items": {
        "$ref": "#/$defs/Flow"
      },
      "title": "Imports",
      "type": "array"
    },
    "exports": {
      "items": {
        "$ref": "#/$defs/Flow"
      },
      "title": "Exports",
      "type": "array"
    }
  },
  "required": [
    "id"
  ],
  "title": "Port",
  "type": "object"
}

Config:

  • default: _PYDANTIC_CFG

Fields:

id pydantic-field

id: str

Port id (prefixes qualified flow ids).

imports pydantic-field

imports: list[Flow]

Flows bringing the carrier into the system (sources, e.g. grid supply).

exports pydantic-field

exports: list[Flow]

Flows sending the carrier out of the system (sinks, e.g. demand).

model_post_init

model_post_init(__context: Any) -> None

Reject duplicate short_ids across imports and exports.

Source code in src/fluxopt/components.py
@override
def model_post_init(self, __context: Any) -> None:
    """Reject duplicate short_ids across imports and exports."""
    _check_unique_short_ids(f'Port {self.id!r}', [*self.imports, *self.exports])

Converter pydantic-model

Bases: Element

Conversion between input and output flows.

Two mutually exclusive modes:

  • Linear — conversion_factors=[{flow_short_id: a_f}, ...], one dict per equation; constraint sum_f(a_f * P_{f,t}) = 0.
  • Piecewise — conversion=PiecewiseConversion(...); the solver interpolates between breakpoints, optionally with on/off via PiecewiseConversion.status.
Show JSON schema:
{
  "$defs": {
    "Flow": {
      "description": "A single energy flow on a carrier.\n\n``short_id`` defaults to ``carrier`` (or ``carrier:node`` when ``node``\nis set).  Set explicitly to disambiguate multiple flows on the same\ncarrier::\n\n    Flow(carrier='elec')  # short_id='elec'\n    Flow(carrier='heat', node='A')  # short_id='heat:A'\n    Flow(carrier='elec', short_id='base')  # short_id='base'\n\n``short_id`` must be unique within a component.  The system-global\nqualified id ``component(short_id)`` is derived at build time and\nappears as the ``flow`` coordinate in ``ModelData`` and results; the\nflow itself is never modified. Storage resolves colliding short_ids\nto ``charge`` / ``discharge`` at that point.\n\nSee: docs/math/flows.md",
      "properties": {
        "carrier": {
          "title": "Carrier",
          "type": "string"
        },
        "short_id": {
          "default": "",
          "title": "Short Id",
          "type": "string"
        },
        "node": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Node"
        },
        "size": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/$defs/Sizing"
            },
            {
              "$ref": "#/$defs/Investment"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Size"
        },
        "relative_rate_min": {
          "$ref": "#/$defs/Variate",
          "default": 0.0
        },
        "relative_rate_max": {
          "$ref": "#/$defs/Variate",
          "default": 1.0
        },
        "fixed_relative_profile": {
          "anyOf": [
            {
              "$ref": "#/$defs/Variate"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "effects_per_flow_hour": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Per Flow Hour",
          "type": "object"
        },
        "flow_hours_min": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Flow Hours Min"
        },
        "flow_hours_max": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Flow Hours Max"
        },
        "load_factor_min": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Load Factor Min"
        },
        "load_factor_max": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Load Factor Max"
        },
        "ramp_up_per_hour": {
          "anyOf": [
            {
              "$ref": "#/$defs/Variate"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "ramp_down_per_hour": {
          "anyOf": [
            {
              "$ref": "#/$defs/Variate"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "status": {
          "anyOf": [
            {
              "$ref": "#/$defs/Status"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "prior_rates": {
          "anyOf": [
            {
              "items": {
                "type": "number"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Prior Rates"
        }
      },
      "required": [
        "carrier"
      ],
      "title": "Flow",
      "type": "object"
    },
    "Investment": {
      "description": "Singular discrete build-timing optimization.\n\nThe solver decides WHEN to build (which period) and at what size.\nOnce built, capacity is available for ``lifetime`` periods.\nSize is decided once \u2014 no growth or partial retirement.",
      "properties": {
        "size_min": {
          "minimum": 0,
          "title": "Size Min",
          "type": "number"
        },
        "size_max": {
          "minimum": 0,
          "title": "Size Max",
          "type": "number"
        },
        "mandatory": {
          "default": true,
          "title": "Mandatory",
          "type": "boolean"
        },
        "lifetime": {
          "anyOf": [
            {
              "exclusiveMinimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Lifetime"
        },
        "prior_size": {
          "default": 0.0,
          "minimum": 0,
          "title": "Prior Size",
          "type": "number"
        },
        "effects_per_size_at_build": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Per Size At Build",
          "type": "object"
        },
        "effects_fixed_at_build": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Fixed At Build",
          "type": "object"
        },
        "effects_per_size_recurring": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Per Size Recurring",
          "type": "object"
        },
        "effects_fixed_recurring": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Fixed Recurring",
          "type": "object"
        }
      },
      "required": [
        "size_min",
        "size_max"
      ],
      "title": "Investment",
      "type": "object"
    },
    "PiecewiseConversion": {
      "description": "Piecewise-linear conversion linking N flows.\n\nWraps :func:`linopy.piecewise.add_piecewise_formulation`. All flows\nshare interpolation weights \u2014 every operating point lies on the same\npiece of the curve.\n\nTwo input forms:\n\n- **Dict** \u2014 equality-only, terse for the common case::\n\n      PiecewiseConversion(points={'fuel': [0, 50, 100], 'Heat': [0, 45, 70]})\n\n- **List of tuples** \u2014 supports per-flow inequality bounds::\n\n      PiecewiseConversion(\n          points=[\n              ('fuel', [0, 50, 100]),\n              ('Heat', [0, 45, 70], '>='),\n          ]\n      )\n\nSee: docs/math/converters.md",
      "properties": {
        "points": {
          "anyOf": [
            {
              "additionalProperties": {
                "items": {
                  "$ref": "#/$defs/Variate"
                },
                "type": "array"
              },
              "type": "object"
            },
            {
              "items": {
                "anyOf": [
                  {
                    "maxItems": 2,
                    "minItems": 2,
                    "prefixItems": [
                      {
                        "type": "string"
                      },
                      {
                        "items": {
                          "$ref": "#/$defs/Variate"
                        },
                        "type": "array"
                      }
                    ],
                    "type": "array"
                  },
                  {
                    "maxItems": 3,
                    "minItems": 3,
                    "prefixItems": [
                      {
                        "type": "string"
                      },
                      {
                        "items": {
                          "$ref": "#/$defs/Variate"
                        },
                        "type": "array"
                      },
                      {
                        "enum": [
                          "==",
                          "<=",
                          ">="
                        ],
                        "type": "string"
                      }
                    ],
                    "type": "array"
                  }
                ]
              },
              "type": "array"
            }
          ],
          "title": "Points"
        },
        "method": {
          "$ref": "#/$defs/PiecewiseMethod",
          "default": "auto"
        },
        "status": {
          "anyOf": [
            {
              "$ref": "#/$defs/Status"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "availability": {
          "$ref": "#/$defs/Variate",
          "default": 1.0
        }
      },
      "required": [
        "points"
      ],
      "title": "PiecewiseConversion",
      "type": "object"
    },
    "PiecewiseMethod": {
      "enum": [
        "auto",
        "sos2",
        "incremental",
        "lp"
      ],
      "type": "string"
    },
    "ProfileRef": {
      "description": "Reference to a time-series stored outside the model definition.\n\nA serializable stand-in for an inline ``Variate`` array: the profile lives\nin a data file / dataset and is named here, so structural definitions\nround-trip to YAML/JSON without inlining 8760-point series. Resolve it to a\n:class:`xr.DataArray` with :meth:`resolve` before building the model.",
      "properties": {
        "dataset": {
          "title": "Dataset",
          "type": "string"
        },
        "variable": {
          "title": "Variable",
          "type": "string"
        }
      },
      "required": [
        "dataset",
        "variable"
      ],
      "title": "ProfileRef",
      "type": "object"
    },
    "Sizing": {
      "description": "Capacity optimization parameters.\n\nThe solver decides the optimal size within [size_min, size_max].\n\n- ``mandatory=True``: continuous, size in [min, max], no binary.\n- ``mandatory=False``: binary indicator gates size: 0 or [min, max].\n- ``size_min == size_max`` with ``mandatory=False``: binary invest\n  at exact size (yes/no).\n\nSee: docs/math/sizing.md",
      "properties": {
        "size_min": {
          "minimum": 0,
          "title": "Size Min",
          "type": "number"
        },
        "size_max": {
          "minimum": 0,
          "title": "Size Max",
          "type": "number"
        },
        "mandatory": {
          "default": true,
          "title": "Mandatory",
          "type": "boolean"
        },
        "effects_per_size": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Per Size",
          "type": "object"
        },
        "effects_fixed": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Fixed",
          "type": "object"
        }
      },
      "required": [
        "size_min",
        "size_max"
      ],
      "title": "Sizing",
      "type": "object"
    },
    "Status": {
      "description": "Binary on/off behavior parameters.\n\nTogether with relative bounds, gives semi-continuous behavior:\n``{0} U [min, max] * size``.\n\nSee: docs/math/status.md",
      "properties": {
        "uptime_min": {
          "anyOf": [
            {
              "minimum": 0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Uptime Min"
        },
        "uptime_max": {
          "anyOf": [
            {
              "minimum": 0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Uptime Max"
        },
        "downtime_min": {
          "anyOf": [
            {
              "minimum": 0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Downtime Min"
        },
        "downtime_max": {
          "anyOf": [
            {
              "minimum": 0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Downtime Max"
        },
        "effects_per_running_hour": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Per Running Hour",
          "type": "object"
        },
        "effects_per_startup": {
          "additionalProperties": {
            "$ref": "#/$defs/Variate"
          },
          "title": "Effects Per Startup",
          "type": "object"
        }
      },
      "title": "Status",
      "type": "object"
    },
    "Variate": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "integer"
        },
        {
          "items": {
            "type": "number"
          },
          "type": "array"
        },
        {
          "$ref": "#/$defs/ProfileRef"
        }
      ]
    }
  },
  "description": "Conversion between input and output flows.\n\nTwo mutually exclusive modes:\n\n- **Linear** \u2014 ``conversion_factors=[{flow_short_id: a_f}, ...]``,\n  one dict per equation; constraint ``sum_f(a_f * P_{f,t}) = 0``.\n- **Piecewise** \u2014 ``conversion=PiecewiseConversion(...)``; the solver\n  interpolates between breakpoints, optionally with on/off via\n  ``PiecewiseConversion.status``.",
  "properties": {
    "id": {
      "title": "Id",
      "type": "string"
    },
    "inputs": {
      "items": {
        "$ref": "#/$defs/Flow"
      },
      "title": "Inputs",
      "type": "array"
    },
    "outputs": {
      "items": {
        "$ref": "#/$defs/Flow"
      },
      "title": "Outputs",
      "type": "array"
    },
    "conversion_factors": {
      "items": {
        "additionalProperties": {
          "$ref": "#/$defs/Variate"
        },
        "type": "object"
      },
      "title": "Conversion Factors",
      "type": "array"
    },
    "conversion": {
      "anyOf": [
        {
          "$ref": "#/$defs/PiecewiseConversion"
        },
        {
          "type": "null"
        }
      ],
      "default": null
    }
  },
  "required": [
    "id",
    "inputs",
    "outputs"
  ],
  "title": "Converter",
  "type": "object"
}

Fields:

id pydantic-field

id: str

Converter id.

inputs pydantic-field

inputs: list[Flow]

Input flows.

outputs pydantic-field

outputs: list[Flow]

Output flows.

conversion_factors pydantic-field

conversion_factors: list[dict[str, Variate]]

Linear-mode equations. Empty when conversion is set.

conversion pydantic-field

conversion: PiecewiseConversion | None = None

Piecewise-mode curve. None for linear mode.

model_post_init

model_post_init(__context: Any) -> None

Validate short_id uniqueness, mode exclusivity, and factor references.

Source code in src/fluxopt/components.py
@override
def model_post_init(self, __context: Any) -> None:
    """Validate short_id uniqueness, mode exclusivity, and factor references."""
    flows = [*self.inputs, *self.outputs]
    _check_unique_short_ids(f'Converter {self.id!r}', flows)
    known = {f.short_id for f in flows}

    if self.conversion is not None:
        if self.conversion_factors:
            msg = (
                f'Converter {self.id!r}: cannot set both conversion_factors and conversion '
                f'(they are mutually exclusive linear vs piecewise modes)'
            )
            raise ValueError(msg)
        curve_flows = {flow for flow, _, _ in self.conversion._iter_normalized()}
        unknown = curve_flows - known
        if unknown:
            msg = (
                f'Converter {self.id!r}: PiecewiseConversion references unknown flow short_ids '
                f'{sorted(unknown)}; known: {sorted(known)}'
            )
            raise ValueError(msg)
        if self.conversion.status is not None:
            for f in flows:
                if f.status is not None:
                    msg = (
                        f'Converter {self.id!r}: flow {f.short_id!r} cannot have flow-level '
                        f'status when PiecewiseConversion.status is set'
                    )
                    raise ValueError(msg)
    else:
        for eq_i, equation in enumerate(self.conversion_factors):
            unknown = set(equation) - known
            if unknown:
                msg = (
                    f'Converter {self.id!r}: conversion_factors[{eq_i}] references unknown '
                    f'flow short_ids {sorted(unknown)}; known: {sorted(known)}'
                )
                raise ValueError(msg)

boiler classmethod

Create a boiler converter: fuel * eta = thermal.

Parameters:

Name Type Description Default

id

str

Converter id.

required

thermal_efficiency

Variate

Thermal efficiency eta.

required

fuel_flow

Flow

Input fuel flow.

required

thermal_flow

Flow

Output thermal flow.

required
Source code in src/fluxopt/components.py
@classmethod
def boiler(cls, id: str, thermal_efficiency: Variate, fuel_flow: Flow, thermal_flow: Flow) -> Converter:
    """Create a boiler converter: fuel * eta = thermal.

    Args:
        id: Converter id.
        thermal_efficiency: Thermal efficiency eta.
        fuel_flow: Input fuel flow.
        thermal_flow: Output thermal flow.
    """
    return cls._single_io(id, thermal_efficiency, fuel_flow, thermal_flow)

heat_pump classmethod

Create a heat pump converter with source heat.

Two conversion equations

electrical * COP = thermal electrical + source = thermal

Parameters:

Name Type Description Default

id

str

Converter id.

required

cop

Variate

Coefficient of performance.

required

electrical_flow

Flow

Input electrical flow.

required

source_flow

Flow

Input environmental heat flow (air, ground, water).

required

thermal_flow

Flow

Output thermal flow.

required
Source code in src/fluxopt/components.py
@classmethod
def heat_pump(
    cls,
    id: str,
    cop: Variate,
    electrical_flow: Flow,
    source_flow: Flow,
    thermal_flow: Flow,
) -> Converter:
    """Create a heat pump converter with source heat.

    Two conversion equations:
        electrical * COP = thermal
        electrical + source = thermal

    Args:
        id: Converter id.
        cop: Coefficient of performance.
        electrical_flow: Input electrical flow.
        source_flow: Input environmental heat flow (air, ground, water).
        thermal_flow: Output thermal flow.
    """
    return cls(
        id=id,
        inputs=[electrical_flow, source_flow],
        outputs=[thermal_flow],
        conversion_factors=[
            {electrical_flow.short_id: cop, thermal_flow.short_id: -1},
            {electrical_flow.short_id: 1, source_flow.short_id: 1, thermal_flow.short_id: -1},
        ],
    )

power2heat classmethod

Create an electric resistance heater: electrical * eta = thermal.

Parameters:

Name Type Description Default

id

str

Converter id.

required

efficiency

Variate

Electrical-to-thermal efficiency.

required

electrical_flow

Flow

Input electrical flow.

required

thermal_flow

Flow

Output thermal flow.

required
Source code in src/fluxopt/components.py
@classmethod
def power2heat(cls, id: str, efficiency: Variate, electrical_flow: Flow, thermal_flow: Flow) -> Converter:
    """Create an electric resistance heater: electrical * eta = thermal.

    Args:
        id: Converter id.
        efficiency: Electrical-to-thermal efficiency.
        electrical_flow: Input electrical flow.
        thermal_flow: Output thermal flow.
    """
    return cls._single_io(id, efficiency, electrical_flow, thermal_flow)

chp classmethod

Create a CHP converter with separate electrical and thermal outputs.

Parameters:

Name Type Description Default

id

str

Converter id.

required

eta_el

Variate

Electrical efficiency.

required

eta_th

Variate

Thermal efficiency.

required

fuel_flow

Flow

Input fuel flow.

required

electrical_flow

Flow

Output electrical flow.

required

thermal_flow

Flow

Output thermal flow.

required
Source code in src/fluxopt/components.py
@classmethod
def chp(
    cls,
    id: str,
    eta_el: Variate,
    eta_th: Variate,
    fuel_flow: Flow,
    electrical_flow: Flow,
    thermal_flow: Flow,
) -> Converter:
    """Create a CHP converter with separate electrical and thermal outputs.

    Args:
        id: Converter id.
        eta_el: Electrical efficiency.
        eta_th: Thermal efficiency.
        fuel_flow: Input fuel flow.
        electrical_flow: Output electrical flow.
        thermal_flow: Output thermal flow.
    """
    return cls(
        id=id,
        inputs=[fuel_flow],
        outputs=[electrical_flow, thermal_flow],
        conversion_factors=[
            {fuel_flow.short_id: eta_el, electrical_flow.short_id: -1},
            {fuel_flow.short_id: eta_th, thermal_flow.short_id: -1},
        ],
    )