Thermal Ammonia (with and without CCS)

Contents

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

Overview

In Macro, the Thermal Ammonia pathway represents natural gas-based ammonia production facilities using the Haber-Bosch process. This technology uses natural gas (or other fossil fuels) as a feedstock to produce ammonia through steam methane reforming, followed by the Haber-Bosch synthesis reaction. The process consumes electricity and natural gas, and emits CO₂ as a byproduct.

Two variants are available:

  • Thermal Ammonia (without CCS): Standard thermal ammonia production with direct CO₂ emissions.
  • Thermal Ammonia with CCS: Thermal ammonia production with carbon capture and storage (CCS) technology, capturing approximately 95% of CO₂ emissions. This variant consumes more electricity due to the energy requirements of the capture process.

These assets are defined using either JSON or CSV input files placed in the assets directory, typically named with descriptive identifiers like thermal_ammonia.json or thermal_ammonia_ccs.json.

Asset Structure

A Thermal Ammonia plant (with and without CCS) is made of the following components:

  • 1 Transformation component, representing the thermal ammonia production process (with or without CCS).
  • 4-5 Edge components (depending on CCS variant):
    • 1 incoming Fuel Edge, representing natural gas (or other fuel) supply. The fuel commodity type can be specified (e.g., NaturalGas, Hydrogen).
    • 1 incoming Electricity Edge, representing electricity consumption.
    • 1 outgoing Ammonia Edge, representing ammonia production.
    • 1 outgoing CO₂ Edge, representing CO₂ emissions (residual emissions for CCS variant).
    • 1 outgoing CO₂Captured Edge, representing captured CO₂ (only if CCS is present).

Here is a graphical representation of the Thermal Ammonia asset without CCS:

%%{init: {'theme': 'base', 'themeVariables': { 'background': '#D1EBDE' }}}%% flowchart BT subgraph ThermalAmmonia direction BT A1(("**NaturalGas**")) e1@-->B{{"**ThermalAmmonia**"}} A2(("**Electricity**")) e2@-->B{{"**ThermalAmmonia**"}} B{{"**ThermalAmmonia**"}} e3@-->C1(("**Ammonia**")) B{{"**ThermalAmmonia**"}} e4@-->C2(("**CO2**")) e1@{ animate: true } e2@{ animate: true } e3@{ animate: true } e4@{ animate: true } end style A1 font-size:15px,r:46px,fill:#005F6A,stroke:black,color:black,stroke-dasharray: 3,5; style A2 font-size:15px,r:46px,fill:#FFD700,stroke:black,color:black,stroke-dasharray: 3,5; style B fill:white,stroke:black,color:black; style C1 font-size:15px,r:46px,fill:#566573,stroke:black,color:black,stroke-dasharray: 3,5; style C2 font-size:15px,r:46px,fill:lightgray,stroke:black,color:black,stroke-dasharray: 3,5; linkStyle 0 stroke:#005F6A, stroke-width: 2px; linkStyle 1 stroke:#FFD700, stroke-width: 2px; linkStyle 2 stroke:#566573, stroke-width: 2px; linkStyle 3 stroke:lightgray, stroke-width: 2px;

Here is a graphical representation of the Thermal Ammonia asset with CCS:

%%{init: {'theme': 'base', 'themeVariables': { 'background': '#D1EBDE' }}}%% flowchart BT subgraph ThermalAmmoniaCCS direction BT A1(("**NaturalGas**")) e1@-->B{{"**ThermalAmmoniaCCS**"}} A2(("**Electricity**")) e2@-->B{{"**ThermalAmmoniaCCS**"}} B{{"**ThermalAmmoniaCCS**"}} e3@-->C1(("**Ammonia**")) B{{"**ThermalAmmoniaCCS**"}} e4@-->C2(("**CO2**")) B{{"**ThermalAmmoniaCCS**"}} e5@-->C3(("**CO2Captured**")) e1@{ animate: true } e2@{ animate: true } e3@{ animate: true } e4@{ animate: true } e5@{ animate: true } end style A1 font-size:15px,r:46px,fill:#005F6A,stroke:black,color:black,stroke-dasharray: 3,5; style A2 font-size:15px,r:46px,fill:#FFD700,stroke:black,color:black,stroke-dasharray: 3,5; style B fill:white,stroke:black,color:black; style C1 font-size:15px,r:46px,fill:#566573,stroke:black,color:black,stroke-dasharray: 3,5; style C2 font-size:15px,r:46px,fill:lightgray,stroke:black,color:black,stroke-dasharray: 3,5; style C3 font-size:15px,r:46px,fill:#2ECC71,stroke:black,color:black,stroke-dasharray: 3,5; linkStyle 0 stroke:#005F6A, stroke-width: 2px; linkStyle 1 stroke:#FFD700, stroke-width: 2px; linkStyle 2 stroke:#566573, stroke-width: 2px; linkStyle 3 stroke:lightgray, stroke-width: 2px; linkStyle 4 stroke:#2ECC71, stroke-width: 2px;

Flow Equations

The Thermal Ammonia asset (with and without CCS) follows these stoichiometric relationships:

Without CCS:

\[\begin{aligned} \phi_{fuel} &= \phi_{nh3} \cdot \epsilon_{fuel\_consumption} \\ \phi_{elec} &= \phi_{nh3} \cdot \epsilon_{electricity\_consumption} \\ \phi_{co2} &= \phi_{fuel} \cdot \epsilon_{emission\_rate} \\ \end{aligned}\]

With CCS:

\[\begin{aligned} \phi_{fuel} &= \phi_{nh3} \cdot \epsilon_{fuel\_consumption} \\ \phi_{elec} &= \phi_{nh3} \cdot \epsilon_{electricity\_consumption} \\ \phi_{co2} &= \phi_{fuel} \cdot \epsilon_{emission\_rate} \\ \phi_{co2\_captured} &= \phi_{fuel} \cdot \epsilon_{capture\_rate} \\ \end{aligned}\]

Where:

  • $\phi$ represents the flow of each commodity
  • $\epsilon$ represents the stoichiometric coefficients defined in the Conversion Process Parameters section.

Input File (Standard Format)

The easiest way to include a Thermal Ammonia 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/
│   ├── thermal_ammonia.json    # or thermal_ammonia.csv (without CCS)
│   ├── thermal_ammonia_ccs.json    # or thermal_ammonia_ccs.csv (with CCS)
│   ├── 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. Examples of input JSON files are shown in the Examples section.

The following tables outline the attributes that can be set for a Thermal Ammonia asset.

Transform Attributes

Essential Attributes

FieldTypeDescription
TypeStringAsset type identifier: "ThermalAmmonia" or "ThermalAmmoniaCCS"
idStringUnique identifier for the asset instance
locationStringGeographic location/node identifier
timedataStringTime resolution for the time series data linked to the transformation

Conversion Process Parameters

FieldTypeDescriptionUnitsDefault (without CCS)Default (with CCS)
fuel_consumptionFloat64Fuel consumption per MWh of ammonia output$MWh_{fuel}/MWh_{NH_3}$0.00.0
electricity_consumptionFloat64Electricity consumption per MWh of ammonia output$MWh_{elec}/MWh_{NH_3}$0.00.0
emission_rateFloat64CO₂ emissions per MWh of fuel input$t_{CO_2}/MWh_{fuel}$0.00.0
capture_rateFloat64CO₂ capture rate per MWh of fuel input (CCS only)$t_{CO_2}/MWh_{fuel}$-0.0

General Attributes

FieldTypeValuesDefaultDescription
typeStringAny Macro commodity type matching the commodity of the edgeRequiredCommodity of the edge. E.g. "Electricity".
start_vertexStringAny node id present in the system matching the commodity of the edgeRequiredID of the starting vertex of the edge. The node must be present in the nodes.json file. E.g. "elec_node_1".
end_vertexStringAny node id present in the system matching the commodity of the edgeRequiredID of the ending vertex of the edge. The node must be present in the nodes.json file. E.g. "nh3_node_1".
availabilityDictAvailability file path and headerEmptyPath to the availability file and column name for the availability time series to link to the edge. E.g. {"timeseries": {"path": "assets/availability.csv", "header": "ThermalAmmonia"}}.
has_capacityBoolBoolfalseWhether capacity variables are created for the edge.
integer_decisionsBoolBoolfalseWhether capacity variables are integers.
unidirectionalBoolBoolfalseWhether the edge is unidirectional.
Asset expansion

As a modeling decision, only the Ammonia edge is allowed to expand. Therefore, both the has_capacity and constraints attributes can only be set for that edge. For all other edges, these attributes are pre-set to false and an empty list, respectively, to ensure the correct modeling of the asset.

Unit Commitment

The nh3_edge can optionally support unit commitment constraints. If uc is set to true in the edge data, the edge will be created as an EdgeWithUC type, and unit commitment constraints (MinUpTimeConstraint, MinDownTimeConstraint) will be automatically applied.

Investment Parameters

FieldTypeDescriptionUnitsDefault
can_retireBooleanWhether capacity can be retired-true
can_expandBooleanWhether capacity can be expanded-true
existing_capacityFloat64Initial installed capacityMWh NH₃0.0

Economic Parameters

FieldTypeDescriptionUnitsDefault (without CCS)Default (with CCS)
investment_costFloat64CAPEX per unit capacity$/MW0.00.0
fixed_om_costFloat64Fixed O&M costs$/MW-yr0.00.0
variable_om_costFloat64Variable O&M costs$/MWh NH₃0.00.0

Constraints Configuration

Thermal Ammonia 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.
output_constraintsDict{String,Bool}List of constraints applied to the output edge component.

For example, if the user wants to apply the BalanceConstraint to the transformation component and the CapacityConstraint to the output edge, the constraints fields should be set as follows:

{
    "transform_constraints": {
        "BalanceConstraint": true
    },
    "edges":{
        "nh3_edge": {
            "constraints": {
                "CapacityConstraint": true,
                "RampingLimitConstraint": true
            }
        }
    }
}

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 the different components of a Thermal Ammonia asset.

Default constraints

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

Types - Asset Structure

The Thermal Ammonia asset (without CCS) is defined as follows:

struct ThermalAmmonia{T} <: AbstractAsset
    id::AssetId
    thermalammonia_transform::Transformation
    nh3_edge::Union{Edge{<:Ammonia},EdgeWithUC{<:Ammonia}}
    elec_edge::Edge{<:Electricity}
    fuel_edge::Edge{<:T}
    co2_edge::Edge{<:CO2}
end

The Thermal Ammonia with CCS asset is defined as follows:

struct ThermalAmmoniaCCS{T} <: AbstractAsset
    id::AssetId
    thermalammoniaccs_transform::Transformation
    nh3_edge::Union{Edge{<:Ammonia},EdgeWithUC{<:Ammonia}}
    elec_edge::Edge{<:Electricity}
    fuel_edge::Edge{<:T}
    co2_edge::Edge{<:CO2}
    co2_captured_edge::Edge{<:CO2Captured}
end

Where T is a generic type parameter that can be any Commodity type (typically NaturalGas).

Constructors

Factory constructor (without CCS)

make(asset_type::Type{ThermalAmmonia}, data::AbstractDict{Symbol,Any}, system::System)

Factory constructor (with CCS)

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

Stoichiometry balance data (without CCS)

thermalammonia_transform.balance_data = Dict(
    :energy => Dict(
        nh3_edge.id => get(transform_data, :fuel_consumption, 0.0),
        fuel_edge.id => 1.0,
    ),
    :electricity => Dict(
        nh3_edge.id => get(transform_data, :electricity_consumption, 0.0),
        elec_edge.id => 1.0
    ),
    :emissions => Dict(
        fuel_edge.id => get(transform_data, :emission_rate, 0.0),
        co2_edge.id => 1.0,
    ),
)

Stoichiometry balance data (with CCS)

thermalammoniaccs_transform.balance_data = Dict(
    :energy => Dict(
        nh3_edge.id => get(transform_data, :fuel_consumption, 0.0),
        fuel_edge.id => 1.0,
    ),
    :electricity => Dict(
        nh3_edge.id => get(transform_data, :electricity_consumption, 0.0),
        elec_edge.id => 1.0
    ),
    :emissions => Dict(
        fuel_edge.id => get(transform_data, :emission_rate, 0.0),
        co2_edge.id => 1.0,
    ),
    :capture => Dict(
        fuel_edge.id => get(transform_data, :capture_rate, 0.0),
        co2_captured_edge.id => 1.0,
    ),
)
Dictionary keys must match

In the code above, each get function call looks up a parameter in the transform_data dictionary using a symbolic key such as :fuel_consumption or :capture_rate. These keys must exactly match the corresponding field names in your input asset .json or .csv files. Mismatched key names between the constructor file and the asset input will result in missing or incorrect parameter values (defaulting to the values shown above).

Examples

Example 1: Thermal Ammonia without CCS

This example illustrates a basic Thermal Ammonia configuration (without CCS) in JSON format:

{
    "ThermalAmmonia": [
        {
            "type": "ThermalAmmonia",
            "global_data":{
                "nodes": {},
                "transforms": {
                    "timedata": "Ammonia"
                },
                "edges":{
                    "nh3_edge": {
                        "commodity": "Ammonia",
                        "unidirectional": true,
                        "has_capacity": true,
                        "can_retire": true,
                        "can_expand": true,
                        "integer_decisions": false
                    },
                    "elec_edge": {
                        "commodity": "Electricity",
                        "unidirectional": true,
                        "has_capacity": false
                    },
                    "fuel_edge": {
                        "commodity": "NaturalGas",
                        "unidirectional": true,
                        "has_capacity": false
                    },
                    "co2_edge": {
                        "commodity": "CO2",
                        "unidirectional": true,
                        "has_capacity": false,
                        "end_vertex": "co2_sink"
                    }
                }
            },
            "instance_data":[
                {
                    "id": "thermal_ammonia_1",
                    "transforms":{
                        "fuel_consumption": 1.3095,
                        "electricity_consumption": 0.03787,
                        "emission_rate": 0.181048235160161
                    },
                    "edges":{
                        "nh3_edge": {
                            "end_vertex": "nh3_node_1",
                            "existing_capacity": 0.0,
                            "investment_cost": 2093045.41,
                            "fixed_om_cost": 84025.0649,
                            "variable_om_cost": 0.9015
                        },
                        "elec_edge": {
                            "start_vertex": "elec_node_1"
                        },
                        "fuel_edge": {
                            "start_vertex": "natgas_node_1"
                        },
                        "co2_edge": {
                            "end_vertex": "co2_sink"
                        }
                    }
                }
            ]
        }
    ]
}

Example 2: Thermal Ammonia with CCS

This example illustrates a basic Thermal Ammonia with CCS configuration in JSON format:

{
    "ThermalAmmoniaCCS": [
        {
            "type": "ThermalAmmoniaCCS",
            "global_data":{
                "nodes": {},
                "transforms": {
                    "timedata": "Ammonia"
                },
                "edges":{
                    "nh3_edge": {
                        "commodity": "Ammonia",
                        "unidirectional": true,
                        "has_capacity": true,
                        "can_retire": true,
                        "can_expand": true,
                        "integer_decisions": false
                    },
                    "elec_edge": {
                        "commodity": "Electricity",
                        "unidirectional": true,
                        "has_capacity": false
                    },
                    "fuel_edge": {
                        "commodity": "NaturalGas",
                        "unidirectional": true,
                        "has_capacity": false
                    },
                    "co2_edge": {
                        "commodity": "CO2",
                        "unidirectional": true,
                        "has_capacity": false,
                        "end_vertex": "co2_sink"
                    },
                    "co2_captured_edge": {
                        "commodity": "CO2Captured",
                        "unidirectional": true,
                        "has_capacity": false
                    }
                }
            },
            "instance_data":[
                {
                    "id": "thermal_ammonia_ccs_1",
                    "transforms":{
                        "fuel_consumption": 1.3095,
                        "electricity_consumption": 0.07342,
                        "emission_rate": 0.0091,
                        "capture_rate": 0.17195
                    },
                    "edges":{
                        "nh3_edge": {
                            "end_vertex": "nh3_node_1",
                            "existing_capacity": 0.0,
                            "investment_cost": 2720959.03,
                            "fixed_om_cost": 109232.584,
                            "variable_om_cost": 1.17195
                        },
                        "elec_edge": {
                            "start_vertex": "elec_node_1"
                        },
                        "fuel_edge": {
                            "start_vertex": "natgas_node_1"
                        },
                        "co2_edge": {
                            "end_vertex": "co2_sink"
                        },
                        "co2_captured_edge": {
                            "end_vertex": "co2_captured_node_1"
                        }
                    }
                }
            ]
        }
    ]
}

See Also

  • Edges - Components that connect Vertices and carry flows
  • Transformations - Processes that transform flows of several Commodities
  • Nodes - Network nodes that allow for import and export of commodities
  • Vertices - Network nodes that edges connect
  • Assets - Higher-level components made from edges, nodes, storage, and transformations
  • Commodities - Types of resources stored by Commodities
  • Time Data - Temporal modeling framework
  • Constraints - Additional constraints for Storage and other components
  • Synthetic Ammonia - Electrochemical ammonia production