An Agent-Based Model of the Energy System in Mathematica

Understanding Possible Energy Futures

Charles M. Macal

Argonne National Laboratory

The Advanced Analysis Framework (AAF) is an agent-based model of the integrated energy system

Comprised of models of the individual fuel cycles

Petroleum

Natural gas

Coal

Electricity

Nuclear

Biomass

World Petroleum Market

The Ethanol Cycle

Petroleum Fuel Cycle

Petroleum Fuel Cycle Model

The rules of business and economics are at least as important as the rules of physics in determining the patterns of energy flow

Agent-based model of the energy system

Approach to modeling the energy system “from the ground up,” assembling the larger model of the energy system from individual models of physical processes and behavioral models of individual decision-making agents.

Agent behaviors are described by decision rules that agents in the energy system are likely to use, based on plausible business decision heuristics and principals.

Factors most relevant to decision - making are be considered such as cost, price, risk, and experience.

Decisions based on finance and economics will be interwoven with constraints such as those presented by environmental and safety factors that facilitate or impede the evolution of the energy system.

An Agent-Based View of the Energy System

Structured Modeling with Mathematica

Scalable

Clear organizational structure for the program code allows adding more components and functionality without sacrificing understandability of the program

Modular

Essential for large-scale systems.

"O-O-like"

Supplement O-O features with Mathematica's functional programming, symbolic manipulation, and term relacement when most appropriate.

Multiple-Model Approach

Two (or more) models of the system exist, generally in different implementations, programming languages and/or platforms

Node Patterns

Data Types

Data types separate specification from implementation

Constants: building blocks of data structures

Constructors: build elements of data types

Selectors: return components of data types (makes algorithms independent of implementation)

Other things in the formal definition

A pattern (data type, class) definition, for generator:

generator[name_String,nodeID_,
generatorGenCo[g_],outOfState_,
capacity_,summerCapMW_,
winterCapMW_,minimumCap_,
type_,generatorFuel[fuel_],fuelCost_,
cF_,generatorBlock[generatorBlockL__List],
fOM_,vOM_,
fOR_,pOR_,
spinningReserve_,maxUPrampRate_,
maxDownRampRate_,startuptime_,
downTime_,startUpCost_,
shutDownCost_,coord[{lon_,lat_}]
];

Notes: (1) pattern names are important although not unique to the data type, (2) objects reference other objects, (3) n:m relationships are implied, (4) containers are used for convenience.

Relationships Among Data Types

A plant has generators.

A generator has (uses) a fuel.

A generator has blocks.

A generation company has (owns) plants.

A generator has blocks.

An electric power network has plants, buses, loads, and transmission links.

A plant is a node.

A transmission link is a link.

Now that we have the data ... Constructing Data Types and Objects

Given clean generator data, structure it into a form defined by a data pattern consisting only of the location of the plant and a list of the generators that make up the plant.

dataPattern={loc:{_,_},genAtLoc:{__String}}(* data pattern for plant *)

Transform data to an instance of the data type using a transformation rule.

ruleDataToObject=dataPattern:>plant[
getPlantName[Characters[First[genAtLoc]]],plantGenCo[getPlantGenCo[genAtLoc,generatorObjectStore]],
Length[genAtLoc],
getPlantCap[genAtLoc,generatorObjectStore,generatorPattern],plantFuel[getPlantFuel[genAtLoc,generatorObjectStore]],
getPlantInState[genAtLoc,generatorObjectStore,generatorPattern],
plantGenerator[genAtLoc],
coord[loc]
]

Where the plant data type is described by the pattern.

plantPattern=plant[name_String,plantGenCo[g_],numGenerators_,capacity_,plantFuel[f_],inState_,plantGenerator[plantGeneratorL_List],coord[loc_]];

Apply the constructor to the entire plant data set to create instances of the plant data type.

plantObjectStore=Fold[constructor[#2,ruleDataToObject,#1]&,{},data];

Where the constructor is generally applicable to any class.

constructor[anyDataItem_,ruleDataToObject_,anyObjectStore_]:=Join[anyObjectStore,{anyDataItem/.ruleDataToObject}];

Defining Methods

As an example, the getter method for plant capacity is defined as:

getCapacity[p_plant]:=p/.getPattern@plant:>capacity;

Note 1: In the expression above, getPattern@plant returns the pattern for plant that is stored along with all the object definitions in the object store:

Where getCapacity above gets the plant pattern, which includes the named patterns for the plant's data fields:

getPattern@plant(* evaluate this! *)

Note 2: the getCapacity method is overloaded and applies to a plant object or any other object having a named pattern capacity.  An object's attributes can only be accessed using getter methods.

Here we get an arbitrary genCo out of the object store to demonstrate getting its capacity also using getCapacity:

getAnObject@genCo(* evaluate this! *)
getCapacity@getAnObject@genCo

Modeling the business / decision / economic

Define business objects

Add ownership relations and connect with physical layer

Identify relevant business decisions

Decision on pricing

Decision on what to offer into the market (q, p)

Decision on which market to participate in

Decsion on capacity expansion (decomissioning)

Where or from whom to get inputs/market outputs

Decision Making Affects Multiple Facilities Operations and Investment

Visualization of Energy Supply

Spatially Distributed Electric Power Grid for Illinois

Power Plant and Owner Layer

Power Plants in Operation (Animation)

Visualization of Energy Demand

Electicity Load by Hour for January

Daily Load by Sector for Year (Animation)

Side-by-Side Comparison of LMPs for April and July (Animation)