Designing a GridLAB module

In general a module is a solver that can compute the steady state of a collection of objects given a specific boundary condition. For example, a power flow solver makes sense as a module because the steady state of a flow network can be directly computed. However, a market clearing system and a load simulation doesn't make sense because the market is influenced not only by demand from loads, but also by supply. As a general rule, if a set of simultaneous equations can be solved to obtain the state of a system, the system is suitable for implementation as a module.

Modules must be able to implement a least three capabilities:

  1. they must be able to create objects on demand (see create)

  2. they must be able to initialize objects on demand (see init)

  3. they must be able to compute the state of individual objects at a specified date and time on demand (see sync)

In addition, modules generally should be able to implement the following

It turns out that implementing these capabilities is not as easy as it at first seems. In particular, the synchronization has typically been one of the most challenging concepts for programmers to understand. Given the amount of time spend in sync calls, it is recommended that considerable time and effort be put into its design.

Basic Synchronization

An object's sync method actually performs two essential functions. First, it updates the state of an object to a designated point in time, and second it lets the core know when the object is next expected to change state. This is vital for the core to know because the core's clock will be advanced to the time of the next expected state change, and all objects will be synchronized to that time.

In general a sync() function should be aware of three times:

If no state change is ever anticipated then $ t_2 = $ TS_NEVER is returned, indicating that barring any changes to its boundary condition, the object is in steady state.

If an object's sync() method determines that the object is not yet in steady state (i.e., the module has not converged), then $ t_2 = t_1 $ is returned.

If an object's sync() method determines that it cannot update to $ t_1 $ as required, the simulation has failed. It can either throw an exception using GL_THROW() or return $ t_2 < t_1 $ to indicate the time at which the problem is believed to have occurred.

The time window $ t_1 - t_0 $ is the past window and the sync() method must implement all behaviors during that time as though they have already occurred.

The time window $ t_2 - t_1 $ is the future window and the sync function must not implement behaviors in this window yet, as they have not yet occurred.

It is a non-trivial fact that if all objects in all modules in GridLAB model return $ t_2 = $ TS_NEVER, then the simulation stops successfully. This is because the system has completely settle to a steady state and there is nothing further to compute.

Control Code

One very important aspect of synchronization behavior is how control code is handled when object behavior goes beyond the mere physics of its response to its boundary condition. It is quite easy to implement control code that is integrated with the physical model. However, this would prevent users from altering the control code without altering the source code of the object's implementation.

To address this problem, objects can implement default control code that is disabled if a PLC object is attached later. The ability to alter control code should be made available when implemented for any object for which this is a realistic possibility, which is very nearly always.

To implement default PLC code for an object, the module must expose a plc() method that will be called immediately before sync() is called, but only if not external PLC method is provided in the model. This plc() method may be written as though it was integrated with the physics implemented in sync(), but the physics must be able to update even when the default PLC code is not run.


GridLAB-DTM Version 1.0
An open-source project initiated by the US Department of Energy