Table of Contents

Submodels

Submodels are a way of reusing parts of a model to perform specific operations inside other models.

By using them, we can reduce the amount of work we have to put in when creating models that share similar functionalities. They are also an important tool for abstraction, hiding unnecessary details and making it easier to reason about the model concept and its implementation.

Conceptually, a submodel is a combination of functors exporting inputs and outputs to be bound externally, but, from the user point of view, a submodel is used just like any other ordinary functor.

Submodel Overview

Submodels are also first class citizens that can be transferred from one model to another. They can also be modified and updated at any time without breaking the model where they are being used. They can also depend on other submodels, as long as their definitions do not form a cycle — if an operation (creating, updating, or using a submodel) would introduce a dependency cycle, Dinamica detects the potential cycle and prevents the operation from completing.

Submodel Types

Basically, we have four different types of submodels in Dinamica EGO: system submodels, user submodels, local submodels, and store submodels. The different types of submodels are identified by different icon badges on the representation of the corresponding functors on the model.

Note: The storage paths mentioned throughout this page (in the table below and in the Where Submodels Are Stored section) differ between Windows and Linux; both are listed where relevant.
Functor icon is decorated by badge representing local submodel
Type Badge/Decoration Description
System Submodel System submodels are submodels provided by Dinamica itself and cannot be changed by the user. System submodels can be used in models created by any user. On Windows, they are usually located at C:\Program Files\Dinamica EGO <version>\Submodels. On Linux, system submodels are stored inside the application itself, with no corresponding filesystem path.
User Submodel User submodels are submodels created by each user and are available only for that specific user. User submodels can be used in models created only by that user. On Windows, they are usually located at C:\Users\<User>\Documents\Dinamica EGO <version>\Submodels. On Linux, they are usually located at /home/<User>/Dinamica EGO <version>/Submodels.
Local Submodel Local submodels are submodels that are related to a specific model. They are bound to that model and cannot be used in a different model unless they are explicitly transferred to it.
Store Submodel Store submodels are submodels downloaded by the user from the online Submodel Store. They are kept in a SQLite database. On Windows, it is typically located at C:\Users\<User>\AppData\Local\Dinamica EGO <version>\SubmodelDatabase.sqlite. On Linux, it is typically located at /home/<User>/.local/share/Dinamica EGO <version>/SubmodelDatabase.sqlite.
Note: If submodels of different types share the same name, there is a precedence order: local submodels take precedence over user submodels, which in turn take precedence over store submodels.

System and user submodels are presented in the Submodels tab while local submodels are presented in the Local Submodels tab of the Functor Library. Local submodels are only presented when their associated model is opened.

System and user submodels on the functor library tab (left) and local submodels on the functor library tab (right)

In practice, users can only create local submodels. These local submodels can later be promoted to user submodels, making them a definitive part of the user's tool set.

Different Types of Submodels

Where Submodels Are Stored

Local Submodels

Local submodels are stored together with the model script. When using the EGO Script (.ego) or EGOML (.egoml) format, Dinamica creates a folder next to the script named after the script filename, with the extension replaced by _ego or _egoml and _Submodels appended. For example, a model named simulation model.egoml will have its local submodels stored in a subfolder called simulation model_egoml_Submodels, and the script files corresponding to each local submodel are located inside that folder. Using a unique submodel folder for each script guarantees that submodels from one script are completely independent from the submodels of any other script.

Note: If a folder named “Submodels” exists in the same folder as the script, and the script-specific …_Submodels folder described above is not found, Dinamica reads the local submodels from that generic “Submodels” folder instead — this folder is shared among all the scripts located in that folder. This is legacy behavior and may be removed in a future version.

The EGOMLX format works differently: it stores the local submodels and the script together in the same binary file, so no separate submodel folder is used.

User Submodels

User submodels are typically stored in the folder C:\Users\<User>\Documents\Dinamica EGO <version>\Submodels on Windows, or /home/<User>/Dinamica EGO <version>/Submodels on Linux.

Store Submodels

Store submodels — those downloaded by the user from the online Submodel Store — are kept in a SQLite database. On Windows, it is typically located at C:\Users\<User>\AppData\Local\Dinamica EGO <version>\SubmodelDatabase.sqlite. On Linux, it is typically located at /home/<User>/.local/share/Dinamica EGO <version>/SubmodelDatabase.sqlite.

System Submodels

System submodels are provided by Dinamica itself: on Windows they are usually located at C:\Program Files\Dinamica EGO <version>\Submodels, while on Linux they are stored inside the application itself, with no corresponding filesystem path.

Tip: Changing the definition of user submodels may break existing models that use that definition, making those models useless unless the user manually updates each one of them. On the other hand, local submodels can be safely updated since their updates are propagated to all local submodels from the same model and to the main model itself.

Creating Local Submodels

Local submodels can be created by simply selecting the parts of a model that will be converted to a submodel and choosing EditCreate Submodel (K). The selection will be replaced by the new submodel and the visual representation of the new submodel will be available to be edited as a new tab on the script editor.

At any time, the user can make changes to the local submodel and apply those changes by clicking Apply Changes / Edit Submodel Properties on the model toolbar. See the Updating Local Submodels section below for more information.

It is also possible to select parts of a local submodel and create another local submodel using that selection. The new local submodel will be a dependency of the previous one, but the submodel creation process is basically the same.

If the selection is empty, an empty local submodel will be created. The process for updating an empty submodel is the same process used to update any local submodel.

Creating a Submodel Directly as a Script

A submodel does not have to be created through the GUI: any .ego file that declares the right set of @submodel.* properties (name, description, group, and its input/output port declarations) is a valid submodel. See Submodels in the EGO Script reference for the full property syntax.

Whether a hand-written submodel script becomes a local or a user submodel is determined entirely by where the file is placed, following the same storage locations used for submodels created through the GUI — the @submodel.name property, not the filename, is what identifies the submodel.

Instantiating Local Submodels

Local submodels from a model are placed in a special tab on the Functor Library called Local Submodels. These local submodels are grouped by model name.

To instantiate a local submodel as part of a model, just expand the group on the Local Submodels tab corresponding to the current model and drag the submodel functor representation to the model presentation area.

It is worth noting that dragging the functor representation belonging to a different model will import the definition of the local submodel from that model — see Copying (Importing) a Local Submodel Between Models below.

Instantiating functor corresponding to local submodel

Searching for Submodels

The search boxes throughout the interface (for example, in the Explorer or in the Functor Library) support special filters that narrow results down to submodels: is:submodel (any submodel), is:systemsubmodel, is:usersubmodel, is:localsubmodel, and is:storesubmodel. The Also search for additional info option must be enabled in the search box menu for these filters to work.

Navigating between the local submodels and the main model in a script editor can be done by clicking on the corresponding model/submodel tab on the model/submodel tabs or clicking on the submodel overview button above the model/submodel tabs.

Navigating between local submodels

Updating Local Submodels

At any time, the user can add or remove inputs and outputs or even change the combination of functors defining the submodel.

The functor action bar of all functors contained inside a submodel script exhibits additional options for export functor inputs and outputs. Exporting a new input or output can be performed following the steps below:

First, click on the functor whose inputs or outputs will be exported.

Select export functor inputs and outputs on the functor action bar and choose the inputs or outputs that will be exported. It is possible to define the input and output names and their corresponding descriptions. It is also possible to mark an exported input as advanced or optional. Optional inputs can also define an optional value that will be assigned to the port if no explicit value is provided.

Note: Any port from the integer family of types can be declared a light enum, which presents it in the GUI as a labeled dropdown instead of a free-form numeric field, via the Make port available as an enum value control. This is not specific to submodels — it can be set on any carrier functor of an integer value type in any model, provided the carrier has an editor. When such a carrier's port is exported as a submodel input, its light enum configuration carries over into the submodel's interface.

Choose Submodel Options on the model toolbar and then click Apply Changes / Edit Submodel Properties. That brings up the submodel editor dialog where you can define a new name, description, documentation URL, and icon for the submodel, or reorder its inputs and outputs (or even remove some of them). Clicking Ok propagates the changes to all parts of your model (and dependent submodels) where the submodel is used.

The submodel editor dialog also lets you set the submodel's group, which controls where it appears in the Functor Library. A group name can contain subgroups by separating them with a colon (“:”); for example, “Elevation Graph:Tools:Debug” places the submodel in a Debug subgroup, itself inside a Tools subgroup, inside an Elevation Graph group. This is specific to submodels: an ordinary functor's placement in the Library is fixed by its own definition and cannot be changed by the user, but a submodel's group — and therefore whether it appears in a subgroup — is under the control of whoever creates or edits it.

Below you can see two examples of updating the input and output ports of a local submodel:

Beware that connected inputs cannot be exported. They must be disconnected first.

It is also worth noting that it is possible to safely rename inputs and outputs. The connections to the port will be maintained when the changes are propagated.

Tip: Dinamica EGO comes with a set of icons from the Fat Cow Icon Set that can be used to customize the local submodels created by users. The icons come in size 16×16 and 32×32 pixels. The overall color of the chosen icon is automatically used to define the color of the functor representing the submodel on the graphical interface. The set of icons is usually installed in the folder IconSamples in your Dinamica EGO installation folder.

When updating a local submodel, the changes from all dependent local submodels will also be propagated. This means that updating a submodel always updates the whole chain of local submodels that use that submodel as part of their definition.

Removing ports from a local submodel is also similar to updating the exported ports. You can remove the ports using the export functor inputs and outputs option on the functor action bar and unchecking the corresponding port on the Exported Ports dialog, or using the Apply Changes / Edit Submodel Properties dialog.

Changing the order of the input or output ports can only be done by editing the port list on the Apply Changes / Edit Submodel Properties dialog.

Submodel Dependencies

Since submodels can use other submodels as part of their definitions, it is very convenient to know how those dependencies are organized. The dependency viewer is not limited to local submodels — it shows the local, user, store, and system submodels a model uses, and how they depend on each other.

You can open it by clicking the graph icon at the bottom of the model toolbar, or by choosing SubmodelsShow Model Dependencies (Ctrl+U).

Local submodel dependency viewer

On the dependency graph viewer, every submodel involved is represented by its name and corresponding icon. An arrow pointing from a submodel A to a submodel B means that submodel A is used by submodel B. Multiple arrows mean that a submodel is used more than once. Clicking on any local submodel shown in the visualization navigates to it.

Clicking the Remove Unused button removes all local submodels defined by the current model that are not being used, either as part of the model's own definition or by any of its other local submodels.

Copying (Importing) a Local Submodel Between Models

It is possible to copy local submodel definitions between models. Once the submodel is copied from one model to another, the submodels can be modified and updated independently.

You can copy a local submodel definition by dragging a local submodel from the Functor Library to the model presentation area. The process is similar to the instantiation of a regular functor.

It is also possible to copy the submodel definition by clicking the Import submodel definition button on the functor library bar of the local submodel tab of the Functor Library. The definitions of system and user submodels can also be imported using the corresponding Import submodel definition button on the functor library bar of the submodel tab of the Functor Library.

Submodels already used in the model can also be imported through the Submodels menu: SubmodelsImport Selected Submodel (Ctrl+G) imports the definition of the currently selected submodel instance, while SubmodelsImport All Submodels imports the definitions of every system, store, and user submodel used directly or indirectly by the model.

Turning a Local Submodel into a User Submodel (Publishing)

Once your local submodel has been developed and fully tested, you can turn it into a user submodel.

To publish a local submodel into a user submodel, click the Publish Submodel button on the Submodel Options drop-down menu located on the model toolbar.

Turning a local submodel into a user submodel makes reusing the submodel easier — the submodel will always be available to be used in your next models — but it has some drawbacks as well. You are fully responsible for the consequences of updating a user submodel. Beware that, unlike local submodels, your models will not carry a copy of a user submodel as part of their definition. So, if you change a user submodel in a way that breaks compatibility with the models using its definition, those models will not work anymore.

The Submodel Store

The Submodel Store is Dinamica EGO's online repository of submodels shared by the community.

Browsing and Installing Submodels

To browse and install submodels from the Submodel Store, choose SubmodelsSubmodel Store on the model toolbar. Select the desired submodel from the list and click Install Selected to download it; it then becomes available locally as a store submodel.

Versioning and Compatibility

Store submodels are versioned in relation to the Dinamica EGO version active at the time each update is published, rather than through an independent version number. Each time a submodel is published or updated, that update is tagged with the Dinamica EGO version used to make it.

When a user requests a store submodel, they receive the most recently published update that is compatible with their installed version — that is, the newest update, among all updates tagged with a version less than or equal to the user's own, regardless of whether an even newer update exists for a higher, incompatible version. Updating a submodel using the same Dinamica EGO version as a previous update simply overrides that previous update, since both share the same version tag.

This has a subtle consequence: an update published later using an older Dinamica EGO version can still become the newest compatible update for users on a newer version, superseding an update they had previously received — as long as no newer update exists that is tagged with an even higher version. The following worked example illustrates this:

  1. A user on Dinamica 8.10 publishes Submodel X, then updates it twice more, all while still on 8.10. Since every one of these updates shares the same version tag (8.10), each one overrides the previous one, leaving “Submodel X v3” as the current update tagged 8.10.
  2. At this point, both Dinamica 8.10 and Dinamica 8.11 users receive “Submodel X v3” — 8.10 because it is their own version's update, and 8.11 because no update tagged 8.11 exists yet, so the newest compatible update is still the one tagged 8.10.
  3. A user on Dinamica 8.11 now updates Submodel X to “v4”. This creates a new update tagged 8.11. From this point, Dinamica 8.11 users receive “Submodel X v4” (the newest update compatible with 8.11), while Dinamica 8.10 users are unaffected and still receive “Submodel X v3” (the update tagged 8.11 is not compatible with them).
  4. A user on Dinamica 8.10 now updates Submodel X again, to “v3.1”. This overrides the existing update tagged 8.10 (previously “v3”). Dinamica 8.10 users now receive “Submodel X v3.1”. Because this update is more recent than the “v4” update tagged 8.11, it also becomes the newest compatible update for Dinamica 8.11 users — so Dinamica 8.11 users now receive “Submodel X v3.1” too, even though “v4” still exists.

Checking for Updates

To check whether an installed store submodel has a newer, compatible update available (see Versioning and Compatibility above), choose SubmodelsSubmodel Manager (Ctrl+G), then use the Check for Updates option.

Deleting Submodels

Deleting a Local Submodel

To delete a local submodel, select it among the local submodels of the model and choose Remove Submodel on the Submodel Options menu. If the submodel is still being used — either by the main model script or by another local submodel — Dinamica reports this, shows where it is being used, and the removal fails.

Tip: Before attempting to remove a local submodel, it is a good idea to check the dependency viewer (SubmodelsShow Model Dependencies) to confirm the submodel is not being used elsewhere.

Deleting a User or Store Submodel

User and store submodels are both removed through the Submodel Manager dialog (SubmodelsSubmodel Manager): select the submodel in question and click Remove.

Warning: Removing a user submodel will break any model script that uses it as part of its definition, since — unlike local submodels — models do not carry their own copy of a user submodel's definition.

Submodel Expansion and Execution

Before executing a model, Dinamica EGO can expand all submodels used in it, replacing each submodel instance with its internal functor definition. This expansion does not modify the model the user is working on — it is applied to a copy of the model that is submitted for execution, leaving the original model and its submodel instances untouched. This removes data copy constraints caused by submodel usage.

It is also possible to manually expand submodels as part of editing the model itself, replacing a submodel instance — local, user, store, or system — with its internal definition. This can be done for the currently selected submodel via SubmodelsExpand Selected Submodel (Ctrl+E), or for every submodel used directly or indirectly by the model via SubmodelsExpand All Submodels. Unlike the automatic expansion that happens before execution, these options do change the model being edited by the user — the expanded functors permanently replace the submodel instance in the model.


See Also