9. Customizing MATPOWER

With the object-oriented MATPOWER core architecture and its explicit three layer modeling outlined in Section 3, the flexibility and customizability of MATPOWER has increased dramatically.

New functionality can be added or existing functionality modified simply by adding new classes and/or subclassing existing ones. This approach can be used to add or modify elements, problem formulations, and tasks.

9.1. Default Class Determination

In order to customize the behavior it is important to understand how MATPOWER selects which classes to instantiate when running a particular task. There are default specifications for each of the various types of objects, as well as several ways to override those defaults. The default, described below, is illustrated in Figure 9.1.

Determination of Default Classes

Figure 9.1 Determination of Default Classes

9.1.1. Task Class

First of all, at the top level, the task class is specified directly by the user through the function used to invoke the run. In fact, run_pf(), run_cpf(), and run_opf() are simple one-line wrappers around the run_mp() function. The only difference between the three is the value of the task_class argument, a handle to the corresponding task constructor, passed into run_mp().

This means that a new task class can be used simply by invoking run_mp(), either directly or via a new wrapper, with the task constructor as the task_class argument.

9.1.2. Model and Data Converter Classes

The task class has methods that determine the classes used to create the data model converter and the three model objects. For each, there are two methods involved in determining the specific class to use, a main method and a default method. The main method calls the default method to get a handle to the constructor for the task’s default class, but then allows that value to be overridden by MATPOWER extensions or MATPOWER options.

Table 9.1 Class Specification Methods of a Task

Method

Description

dm_converter_class()

Returns the final class for the data model converter, after any overrides of the default.

data_model_class()

Returns the final class for the data model, after any overrides of the default.

network_model_class()

Returns the final class for the network model, after any overrides of the default.

math_model_class()

Returns the final class for the math model, after any overrides of the default.

dm_converter_class_mpc2_default()

Returns the default class for the data model converter for this task. Note that this is specific to the data format. Each data format would have it’s own “default” method.

data_model_class_default()

Returns the default class for the data model for this task.

network_model_class_default()

Returns the default class for the network model for this task.

math_model_class_default()

Returns the default class for the math model for this task.

Table 9.1 shows the methods that determine the classes for each of the 4 objects. Each method returns a handle to a class constructor. In general, the main methods (the first 4 in the table) are inherited from mp.task and only the default methods (the last 4) would be overridden to customize a task with new model or data model converter classes.

9.1.3. Element Classes

Each of the element container objects, that is the data model converter and the 3 model objects, contains a set of elements. The classes used to construct these elements are determined by the container class. Each container class inherits from mp.element_container, and as such it has an element_classes property, which is a cell array populated by the constructor with handles to constructors for the elements. This means that a container subclass can, by overriding its constructor, modify the list of element classes provided by its parent.

The elements are instantiated by a call to the container object’s build() method, so the resulting set can be customized at runtime by modifying the list in element_classes after the container object is created and before its build() method is called.

This is done using element class modifiers, specified either by MATPOWER extensions or MATPOWER options. There are 3 types of element class modifiers, for adding, deleting or replacing an entry in an element_classes property. The 3 types are described in Table 9.2.

Table 9.2 Element Class Modifiers

Action

Value

Description

add

@new_class

Appends @new_class to the end of the list.

delete

'old_class'

For each element E in the list, if isa(E(), 'old_class') is true, element E is deleted from the list.

replace

{@new_class, 'old_class'}

For each element E in the list, if isa(E(), 'old_class') is true, element E is replaced with @new_class.

Typically, multiple element class modifiers can be provided in a cell array and they are processed sequentially to modify the existing list by the modify_element_classes() from mp.element_container.

9.2. Customization via MATPOWER Options

In addition to the MATPOWER options previously available that affect the formulation of the problem (e.g. polar vs. cartesian voltage representation, or current vs. power balance), there are several experimental options that can be used to directly modify the classes coming from the default class selection process outlined above. These options, summarized in Table 9.3, are specified by assigning them directly to an existing MATPOWER options struct mpopt as optional fields in mpopt.exp. They must be assigned directly, since mpoption() does not recognize them.

Table 9.3 Class Customization Options

Option

Description

dm_converter_class

function handle for data model converter constructor

data_model_class

function handle for data model constructor

network_model_class

function handle for network model constructor

math_model_class

function handle for math model constructor

dmc_element_classes

element class modifier(s) [1] for data model converter elements

dm_element_classes

element class modifier(s) [1] for data model elements

nm_element_classes

element class modifier(s) [1] for network model elements

mm_element_classes

element class modifier(s) [1] for math model elements

exclude_elements

cell array of names of elements to exclude from all four container objects, i.e. char arrays that match the name property of the element(s) to be excluded

9.3. MATPOWER Extensions

The flexible MATPOWER framework summarized in Section 3.3 introduces a MATPOWER extension API as a way to bundle a set of class additions and modifications together into a single named package.

For example, the mp.xt_reserves class and those it references, adds co-optimization of fixed zonal reserves to the standard OPF problem, as previously implemented by toggle_reserves() and run_opf_w_res() in MATPOWER 7.1 and earlier using its legacy OPF callback functions. To invoke an OPF with the mp.xt_reserves extension, you simply pass the extension object as an optional argument into the run_opf() function.

run_opf(mpc, mpopt, 'mpx', mp.xt_reserves);

A MATPOWER extension is a subclass of mp.extension, which implements a very simple interface consisting of nine methods. Five of them return a single class constructor handle, and the other four return a cell array of element class modifiers, described above in Table 9.2.

The methods are summarized in Table 9.4

Table 9.4 MATPOWER Extension Methods

Method

Description

task_class()

Returns a handle to the constructor for the task object.

dm_converter_class()

Returns a handle to the constructor for the data model converter.

data_model_class()

Returns a handle to the constructor for the data model.

network_model_class()

Returns a handle to the constructor for the network model.

math_model_class()

Returns a handle to the constructor for the math model.

dmc_element_classes()

Returns a cell array of element class modifiers for data model converter elements.

dm_element_classes()

Returns a cell array of element class modifiers for data model elements.

nm_element_classes()

Returns a cell array of element class modifiers for network model elements.

mm_element_classes()

Returns a cell array of element class modifiers for math model elements.

Even something as complex as adding three-phase unbalanced buses, lines, loads and generators for multiple formulations of PF, CPF, and OPF problems can be implemented in terms of a single MATPOWER extension. Please see mp.xt_3p for an example.