Adapt an EMX element

This package is based on EnergyModelsBase, and therefore several aspects of creating a new element are covered in its documentation. In this page, we will focus on the specific requirements for the introduction of new AbstractElements in the receding horizon framework.

Initialization settings

An element that presents dynamic states (e.g., storage levels, ...) must have these states explicitly initialized. In this package, this is done by the introduction of an AbstractInitData object. AbstractInitData is an abstract type, and the concrete type InitData is provided with the minimum expected functionality for such an object. The AbstractInitData must be used in the model equations to calculate the initial states of the corresponding element.

It is possible to initialize a node through dispatch on EMB.constraints_data. An example of such implementation is provided in the test files for the creation of a new node IncrementInitNode, see the file nodewithinitial_data.jl. However, care must be taken when defining the initial state as such, so as to not overspecify the system of equations.

Some nodes have a more specialized way of initialization, such as Storage nodes. Here, we implement the RecedingAccumulating behavior, where the initial level state can be defined through an StorageInitData object. Initialization here is defined by dispatching on previous_level, which is already used in the core Storage functionality (see the EnergyModelsBase documentation).

Additionally, one must create dispatches upon update_init_data! for new implementations of AbstractInitData, as well as on other functions, see page on problem initialization for the full list. This is not needed for elements that can use InitData and its default functionalities.

Elements with special constructors

For elements with specific constructor needs, it is necessary to dispatch on Accessors.ConstructionBase.constructorof. This includes elements with parametric types for which the parametric input cannot be deduced from the fields (e.g., Storage nodes), as well as elements with inner constructors. An example of how this can be done is shown in the package for the Storage node (see the constructorof dispatch).