Modules

Structuring an SD DSL model into modules - named parts of a model whose elements carry the module’s name, and how modules that read each other are set up
Keywords

system dynamics, systemdynamics, sd dsl, module, namespace, fully qualified name, bptk, bptk-py, python, business simulation

Modules

A model of a supply chain has an inventory at the shop and one at the factory; a model of a firm has a headcount in every department. Written as one flat model, every element needs a name of its own, and the names soon read like shopInventory, factoryInventory, salesHeadcount.

A module is a named part of a model. Every element created through it carries the module’s name in front of its own - shop.inventory, factory.inventory - and the module is a Python class, so the same structure can be built several times. The Beer Game builds its four players from one module class this way.

Elements in a Module

A Module takes the model and a name. Its stock, flow, biflow, conveyor, converter and constant create the element in the model, under the module’s name:

The model knows the stock as shop.inventory, and that is the name to use everywhere outside the module: in plot_scenarios, in run_scenarios and in a scenario’s constants. Asking the module for inventory again returns the same stock.

A module can sit inside another one, given as parent; the names then nest:

'supply_chain.retailer.inventory'

fqn gives the fully qualified name of an element, the name the model knows it by.

Modules That Read Each Other

Modules are rarely independent: the shop’s inventory fills with what the factory ships. A module class therefore splits its work in two:

  • __init__ creates the elements other modules read - the module’s exports. It calls super().__init__ first.
  • initialize creates everything else and writes every equation. It takes the modules it reads as arguments.

The two steps keep the order simple: first every module is created, so every export exists; then each one is initialized, and may refer to any export, whichever module was created first.

Building the model is then two lines per module - create, then initialize:

A scenario sets a module’s constant by its full name, here shop.demand. The factory ships 20 units a day; move the demand above that and the shop’s inventory drains:

Things to Watch Out For

  • A name is a name in the model. Two modules called shop share their elements: the second one’s inventory is the first one’s stock.
  • A module is a way of naming, not a separate model. The model the modules write into is one model, and it runs on either engine like any other.
  • An XMILE model with modules becomes a model with the same names: the transpiler writes cash.cash for the stock cash of the module cash, as The Same Model in Stella shows.

Every method of the class is on the Module API page.