Fuel Cell

Contents

Overview | Asset Structure | Flow Equations | Input File (Standard Format) | Types - Asset Structure | Constructors | Examples | Best Practices | Input File (Advanced Format)

Overview

Fuel cell assets in Macro represent electricity generation technologies that convert hydrogen into electricity through electrochemical processes. These assets are defined using either JSON or CSV input files placed in the assets directory, typically named with descriptive identifiers like fuelcell.json or fuelcell.csv.

Asset Structure

A fuel cell asset consists of three main components:

  1. Transformation Component: Balances the hydrogen and electricity flows
  2. Hydrogen Edge: Represents the hydrogen consumption from the supply
  3. Electricity Edge: Represents the electricity production flow

Here is a graphical representation of the fuel cell asset:

%%{init: {'theme': 'base', 'themeVariables': { 'background': '#D1EBDE' }}}%% flowchart LR subgraph FuelCell direction LR A((Hydrogen)) e1@--> B{{..}} B e2@--> C((Electricity)) e1@{ animate: true } e2@{ animate: true } end style A r:48px,fill:lightblue,stroke:black,color:black,stroke-dasharray: 3,5; style B fill:black,stroke:black,color:black; style C r:48px,fill:#FFD700,stroke:black,color:black,stroke-dasharray: 3,5; linkStyle 0 stroke:lightblue, stroke-width: 2px, stroke-dasharray: 5 5; linkStyle 1 stroke:#FFD700, stroke-width: 2px, stroke-dasharray: 5 5;

Flow Equations

The fuelcell asset follows these stoichiometric relationships:

\[\begin{aligned} \phi_{elec} &= \phi_{h2} \cdot \epsilon_{efficiency\_rate} \\ \end{aligned}\]

Where:

  • $\phi$ represents the flow of each commodity
  • $\epsilon$ represents the efficiency rate defined in the table below (see Conversion Process Parameters)

Input File (Standard Format)

The easiest way to include a fuel cell asset in a model is to create a new file (either JSON or CSV) and place it in the assets directory together with the other assets.

your_case/
├── assets/
│   ├── fuelcell.json    # or fuelcell.csv
│   ├── other_assets.json
│   └── ...
├── system/
├── settings/
└── ...

This file can either be created manually, or using the template_asset function, as shown in the Adding an Asset to a System section of the User Guide. The file will be automatically loaded when you run your Macro model.

The following is an example of a fuel cell asset input file:

{
    "fuelcell": [
        {
            "type": "FuelCell",
            "instance_data": [
                {
                    "id": "fuelcell_SE",
                    "location": "SE",
                    "efficiency_rate": 0.875,
                    "investment_cost": 41112,
                    "fixed_om_cost": 1052,
                    "variable_om_cost": 0.0
                }
            ]
        }
    ]
}
Global Data vs Instance Data

When working with JSON input files, the global_data field can be used to group data that is common to all instances of the same asset type. This is useful for setting constraints that are common to all instances of the same asset type and avoid repeating the same data for each instance. See the Examples section below for an example.

The following tables outline the attributes that can be set for a fuel cell asset.

Essential Attributes

FieldTypeDescription
TypeStringAsset type identifier: "FuelCell"
idStringUnique identifier for the fuel cell instance
locationStringGeographic location/node identifier

Conversion Process Parameters

The following set of parameters control the conversion process and stoichiometry of the fuelcell asset (see Flow Equations for more details).

FieldTypeDescriptionUnitsDefault
efficiency_rateFloat64Fuel cell efficiency$MWh_{elec}/MWh_{h2}$1.0

Constraints configuration

Fuel cell assets can have different constraints applied to them, and the user can configure them using the following fields:

FieldTypeDescription
transform_constraintsDict{String,Bool}List of constraints applied to the transformation component.
elec_constraintsDict{String,Bool}List of constraints applied to the electricity edge.
h2_constraintsDict{String,Bool}List of constraints applied to the hydrogen edge.

Users can refer to the Adding Asset Constraints to a System section of the User Guide for a list of all the constraints that can be applied to a fuel cell asset.

Default constraints

To simplify the input file and the asset configuration, the following constraints are applied to the fuel cell asset by default:

Investment Parameters

FieldTypeDescriptionUnitsDefault
can_retireBooleanWhether fuel cell capacity can be retired-true
can_expandBooleanWhether fuel cell capacity can be expanded-true
existing_capacityFloat64Initial installed fuel cell capacityMW0.0
capacity_sizeFloat64Unit size for capacity decisions-1.0

Additional Investment Parameters

Maximum and minimum capacity constraints

If MaxCapacityConstraint or MinCapacityConstraint are added to the constraints dictionary for the electricity edge, the following parameters are used by Macro:

FieldTypeDescriptionUnitsDefault
max_capacityFloat64Maximum allowed fuel cell capacityMWInf
min_capacityFloat64Minimum allowed fuel cell capacityMW0.0

Economic Parameters

FieldTypeDescriptionUnitsDefault
investment_costFloat64CAPEX per unit fuel cell capacity$/MW0.0
annualized_investment_costUnion{Nothing,Float64}Annualized CAPEX$/MW/yrcalculated
fixed_om_costFloat64Fixed O&M costs$/MW/yr0.0
variable_om_costFloat64Variable O&M costs$/MWh0.0
waccFloat64Weighted average cost of capitalfraction0.0
lifetimeIntAsset lifetime in yearsyears1
capital_recovery_periodIntInvestment recovery periodyears1
retirement_periodIntRetirement periodyears0

Operational Parameters

FieldTypeDescriptionUnitsDefault
availabilityDictAvailability file path and header-Empty

Additional Operational Parameters

Minimum flow constraint

If MinFlowConstraint is added to the constraints dictionary for the electricity edge, the following parameter is used:

FieldTypeDescriptionUnitsDefault
min_flow_fractionFloat64Minimum flow as fraction of capacityfraction0.0

Ramping limit constraint

If RampingLimitConstraint is added to the constraints dictionary for the electricity edge, the following parameters are used:

FieldTypeDescriptionUnitsDefault
ramp_up_fractionFloat64Maximum increase in flow between timestepsfraction1.0
ramp_down_fractionFloat64Maximum decrease in flow between timestepsfraction1.0

Types - Asset Structure

The FuelCell asset is defined as follows:

struct FuelCell <: AbstractAsset
    id::AssetId
    fuelcell_transform::Transformation
    h2_edge::Edge{<:Hydrogen}
    elec_edge::Edge{<:Electricity}
end

Constructors

Default constructor

FuelCell(id::AssetId, fuelcell_transform::Transformation, h2_edge::Edge{<:Hydrogen}, elec_edge::Edge{<:Electricity})

Factory constructor

make(asset_type::Type{FuelCell}, data::AbstractDict{Symbol,Any}, system::System)
FieldTypeDescription
asset_typeType{FuelCell}Macro type of the asset
dataAbstractDict{Symbol,Any}Dictionary containing the input data for the asset
systemSystemSystem to which the asset belongs

Examples

This section contains examples of how to use the fuel cell asset in a Macro model.

Multiple fuel cells in different zones

This example shows how to create a set of fuel cells in different zones (SE, MIDAT, and NE), with different costs, capacities, and efficiency rates. Ramp rates and minimum flow fractions are set to 1.0 and 0.1, respectively for all fuel cells.

JSON Format:

Note that the global_data field is used to set the fields and constraints that are common to all instances of the same asset type.

{
    "fuelcell": [
        {
            "type": "FuelCell",
            "global_data": {
                "elec_constraints": {
                    "RampingLimitConstraint": true,
                    "MinFlowConstraint": true
                },
            },
            "instance_data": [
                {
                    "id": "SE_FuelCell",
                    "location": "SE",
                    "efficiency_rate": 0.875111139,
                    "investment_cost": 41412.53426,
                    "fixed_om_cost": 1052.480877,
                    "variable_om_cost": 0.0,
                    "capacity_size": 1.5,
                    "ramp_up_fraction": 1,
                    "ramp_down_fraction": 1,
                    "min_flow_fraction": 0.1
                },
                {
                    "id": "MIDAT_FuelCell",
                    "location": "MIDAT",
                    "efficiency_rate": 0.875111139,
                    "investment_cost": 41123.53426,
                    "fixed_om_cost": 1052.480877,
                    "variable_om_cost": 0.0,
                    "capacity_size": 1.7,
                    "ramp_up_fraction": 1,
                    "ramp_down_fraction": 1,
                    "min_flow_fraction": 0.1
                },
                {
                    "id": "NE_FuelCell",
                    "location": "NE",
                    "efficiency_rate": 0.875111139,
                    "investment_cost": 41123.53426,
                    "fixed_om_cost": 1052.480877,
                    "variable_om_cost": 0.0,
                    "capacity_size": 1.9,
                    "ramp_up_fraction": 1,
                    "ramp_down_fraction": 1,
                    "min_flow_fraction": 0.1
                }
            ]
        }
    ]
}

CSV Format:

Typeidlocationefficiency_rateinvestment_costfixed_om_costvariable_om_costcapacity_sizeramp_up_fractionramp_down_fractionmin_flow_fractionelec_constraints–RampingLimitConstraintelec_constraints–MinFlowConstraint
FuelCellSE_FuelCellSE0.87511113941112.534261052.4808770.01.5110.1truetrue
FuelCellMIDAT_FuelCellMIDAT0.87511113941123.534261052.4808770.01.7110.1truetrue
FuelCellNE_FuelCellNE0.87511113941123.534261052.4808770.01.9110.1truetrue

Best Practices

  1. Use global data for common constraints: Use the global_data field to set the fields and constraints that are common to all instances of the same asset type.
  2. Set realistic efficiency rates: Ensure the fuel cell efficiency is accurate for the technology being modeled
  3. Use meaningful IDs: Choose descriptive identifiers that indicate location and technology type
  4. Consider operational constraints: Set appropriate ramp rates and minimum flow fractions based on technology characteristics
  5. Use constraints selectively: Only enable constraints that are necessary for your modeling needs
  6. Validate costs: Ensure investment and O&M costs are in appropriate units
  7. Test configurations: Start with simple configurations and gradually add complexity
  8. Consider hydrogen availability: Ensure hydrogen supply is available at the specified locations

Input File (Advanced Format)

Macro provides an advanced format for defining fuel cell assets, offering users and modelers detailed control over asset specifications. This format builds upon the standard format and is ideal for those who need more comprehensive customization.

To understand the advanced format, consider the graph representation and the type definition of a fuel cell asset. The input file mirrors this hierarchical structure.

A fuel cell asset in Macro is composed of a transformation component, represented by a Transformation object, and two edges (hydrogen and electricity), each represented by an Edge object. The input file for a fuel cell asset is therefore organized as follows:

{
    "transforms":{
        // ... transformation-specific attributes ...
    },
    "edges":{
        "h2_edge": {
            // ... h2_edge-specific attributes ...
        },
        "elec_edge": {
            // ... elec_edge-specific attributes ...
        }
    }
}

Each top-level key (e.g., "transforms" or "edges") denotes a component type. The second-level keys either specify the attributes of the component (when there is a single instance) or identify the instances of the component (e.g., "elec_edge", "h2_edge", etc.) when there are multiple instances. For multiple instances, a third-level key details the attributes for each instance.

Below is an example of an input file for a fuel cell asset that sets up multiple fuel cells across different regions:

{
    "fuelcell": [
        {
            "type": "FuelCell",
            "global_data": {
                "transforms": {
                    "commodity": "Electricity",
                    "timedata": "Electricity"
                },
                "edges": {
                    "elec_edge": {
                        "type": "Electricity",
                        "unidirectional": true,
                        "has_capacity": true,
                        "can_expand": true,
                        "can_retire": true,
                        "constraints": {
                            "CapacityConstraint": true
                        }
                    },
                    "h2_edge": {
                        "type": "Hydrogen",
                        "unidirectional": true,
                        "has_capacity": false
                    }
                }
            },
            "instance_data": [
                {
                    "id": "fuelcell_SE",
                    "transforms": {
                        "efficiency_rate": 0.875
                    },
                    "edges": {
                        "h2_edge": {
                            "start_vertex": "h2_SE"
                        },
                        "elec_edge": {
                            "end_vertex": "elec_SE",
                            "capacity_size": 1.0,
                            "existing_capacity": 0.0,
                            "fixed_om_cost": 1052,
                            "investment_cost": 41112,
                            "variable_om_cost": 0.0
                        }
                    }
                },
                {
                    "id": "fuelcell_NE",
                    "transforms": {
                        "efficiency_rate": 0.875
                    },
                    "edges": {
                        "h2_edge": {
                            "start_vertex": "h2_NE"
                        },
                        "elec_edge": {
                            "end_vertex": "elec_NE",
                            "capacity_size": 1.0,
                            "existing_capacity": 0.0,
                            "fixed_om_cost": 1052,
                            "investment_cost": 41112,
                            "variable_om_cost": 0.0
                        }
                    }
                }
            ]
        }
    ]
}

Key points

  • The global_data field is utilized to define attributes and constraints that apply universally to all instances of a particular asset type.
  • The start_vertex and end_vertex fields indicate the nodes to which the edges are connected. These nodes must be defined in the nodes.json file.
  • By default, the electricity edge has capacity variables and can be expanded or retired (see note below).
  • For a comprehensive list of attributes that can be configured for the transformation and edge components, refer to the transformation and edges pages of the Macro manual.
The `has_capacity` Edge Attribute

The has_capacity attribute is a flag that indicates whether a specific edge of an asset has a capacity variable, allowing it to be expanded or retired. Typically, users do not need to manually adjust this flag, as the asset creators in Macro have already configured it correctly for each edge. However, advanced users can use this flag to override the default settings for each edge if needed.