Modellers frequently classify their model as being one type or another: “differential equation model”, “matrix model”, “individual-based model”, and so on. Simile is capable of handling most of these model types — sometimes directly, sometimes with some recasting. The aim of this section is to consider some of the more common model types, and how they are handled in Simile. It should be remembered, however, that a model in Simile can combine what would normally be considered distinct and non-combinable modelling approaches. Thus, in Simile, it is quite possible to have a model that combines, for example, differential-equation, matrix, and individual-based modelling.
System Dynamics (SD) is a widely-used graphical notation for representing continuous systems. A System Dynamics diagram typically contains four main types of element: compartments, flows, variables and influences. Compartments represent storages of material, and the flows represent movement of the material into, out of and between compartments. Simile was designed as a “System Dynamics plus objects” language, so naturally it is straightforward to represent standard System Dynamics models in Simile.
Some other visual System Dynamics modelling packages, such as Stella, introduce new symbols which extend the System Dynamics language (such as “oven” and “boxcar”). Simile does not have these, but their behaviour can be reproduced using Simile’s core set of model-building elements.
System Dynamics is nothing more than a palatable front-end to a set of Differential-Algebraic Equations (DAEs): i.e. a set of differential equations, with a set of subsidiary algebraic equations for defining intermediate and rate quantities. Each compartment is a state variable, and each flow contributes to the rate-of-change expression for the associated state variable(s). Therefore, implementing a published differential-equation model in Simile is straightforward: you simply add one compartment for every state variable, give each compartment a single inflow, and enter the differential equation as the flow expression, having first added the required influence arrows.
Since Simile can use simple Euler integration for numerically solving its set of differential equations, handling sets of difference equations is no different: the only difference is when you come to run the model, when you set the time step to 1 rather than some small value.
“Disaggregation” refers to modelling in which some component is divided into a number of parts. For example, a lumped (non-disaggregated) model of soil water dynamics might use a single compartment to represent the amount of water in the soil. A disaggregated version of the same model might divide the soil into a number of layers, and represent the amount of water in each layer. Or: a population may be divided into age-classes; an area may be divided into subareas; a single “vegetation” component may be divided into the separate species. It is a very common and important modelling technique, required to capture dynamics that would be lost in a lumped model of the same system.
In conventional programming and in the other visual modelling packages, disaggregation is handled by declaring certain variables to be arrays rather than scalars (single-valued variables). This is a tedious approach, reflecting the design approach of the earlier programming languages (Fortran, BASIC), which is difficult to read visually.
Simile encourages a quite different approach. You use a submodel to represent one of the disaggregated elements: a single soil layer, a single population class, a single subarea, or a single vegetation species. This submodel is then made into a multiple-instance submodel, so that it now represents all the soil layers, all the population classes, etc. Finally, you add the links that relate one element to the next: e.g. the flow of water from one layer to the next.
Models based on matrix algebra are frequently used in ecology for modelling population dynamics, with the population disaggregated into age- or size-classes. Simile does have the ability to do matrix calculations with arrays but, as mentioned above, a more appropriate way of handling such problems is to view a class as being an object, and then specify that there are as many instances as there are classes. Class attributes, such as age-specific fecundity and mortality rates, can then be expressed as attributes of each instance.
Modelling the individuals that constitute a population is an extreme form of disaggregation. It is being increasingly recognised as a highly effective approach, for two main reasons. First, it enables the modeller to capture interactions critical to system behaviour that are lost in any more aggregated approach. Second, it frequently is much easier to construct individual-based models, since the behaviour of and interactions between individuals are frequently quite simple, but can lead to complex patterns of behaviour of the whole population (e.g. ant colonies).
If you have a fixed number of individuals, then you can use Simile’s fixed-membership submodel. If, as is likely to be the case, the number of individuals in the population changes dynamically, then you would use Simile’s population submodel, adding the three symbols needed to specify the initial number of individuals in the population, the way in which new individuals are created, and the way in which individuals are killed off.
In a discrete-event simulation, all change occurs at instants in time, rather than over periods. The fundamental components are states and events. States can change as a result of events, and events can occur at pre-set times or be triggered by other events, conditionally on states, possibly after a delay.
Pure discrete-event models do not need a regular time step. Instead, the time of the next event can be calculated after each event, and the simulation jumps directly to that time. Typical domains for discrete event simulation include network, traffic and queueing systems.
Simile can run pure discrete-event models, but allows their components to be mixed with system dynamics components to build hybrid models. Obviously values can be passed between states and system-dynamics components, but there are special constructs for integrating events themselves with system dynamics:
An example of a simple system requiring hybrid modelling is a bouncing ball. While the ball is flying, its behaviour is governed by continuous processes modelled with system dynamics, but bouncing is an event involving instantaneous change, and calculating the time of the bounce involves a continuously varying quantity reaching a limit.
The term “object-oriented” has a formal meaning in software engineering: it is not just “modelling with objects” in the sense of individual-based modelling. Rather, it reflects a commitment to a number of principles which together characterise the object-oriented approach, including message-passing, encapsulation (hiding internal detail), inheritance (from class to subclass), and polymorphism (the same procedure can operate on different data types). There is a strong movement towards the adoption of object-oriented software engineering approaches in ecological modelling.
It may come as some surprise, therefore, that not only does Simile not incorporate most of the characteristic features of the object-oriented approach, but that we have deliberately decided not to incorporate them. This is a controversial area, which we won’t develop here. But briefly:
Rejecting encapsulation does not mean that we are against modularity or re-use of components: quite the opposite. We are just against the principle that you really should not know what is inside a modelled component.
Simile does, however, support certain object-oriented design concepts. A Simile diagram with submodels corresponds closely to a UML class diagram. The Simile notation of placing one submodel inside another to indicate containership corresponds closely to a composition association. And Simile provides explicit notation for an association between classes.
The term “spatial modelling” refers to a particular form of disaggregation, in which an area is divided into a number (often a large number) of similar units: typically grid squares or polygons. The model may be linked to a GIS for data input and display. The transition from non-spatial to spatial modelling is often considered to be pretty significant, and there are a number of modelling packages that advertise their spatial modelling capabilities: indeed, many are labelled as landscape or landuse modelling tools.
Simile is rather odd in that it can do spatial modelling — in fact, it can do it rather well — while having no explicit spatial modelling constructs! All you need to use are the standard Simile model-design elements. It is only the use of maps for displaying model results (and potentially inputting information into the model) that reveal that it is a spatial model - and all the Simile input/output tools (helpers) are quite independent of the basic simulation engine.
In Simile, a spatial unit is just like any other unit. You define a single instance in a submodel, and then specify that you have many instances. The only difference now is that each instance will have two attributes specifying its x and y coordinates. These enable any display tool to locate each unit in the appropriate part of the display (map). They may also be used in spatial reasoning within the model: e.g. for working out the distance between two spatial units to calculate seed dispersal or shading.
The model itself does not “know” if a spatial unit is a square, a polygon, a hexagon or whatever (in fact, it does not even know that it contains spatial units). It is up to the modeller to model each type in a way which is consistent with what is intended. Thus, if the units are grid squares, then they should all have the same value for an “area” attribute, and the rule for defining which units are neighbours of which other units can be defined in terms of the column and row attributes. If they are polygons, then both the area of each unit and its neighbours will (typically) be defined in a data file. And in either case, the user of the model would need to choose a display tool that is appropriate to the type of unit being modelled.
As of version 6.1, we did introduce pre-defined array types for rectangular and hexagonal grids. Such grids are a very common methodology in ecological modelling, and it makes more sense to allow a modeller to select a pre-defined type and thus get access to functions providing each grid square instance with values from particular neighbouring grid squares, than have to figure out how to create a neighbour relationship to provide access to these values. We would hope that this feature encourages modellers to experiment, and perhaps lead on to use of the full power of the association submodel methodology.
The term “modular modelling” usually refers to the use of interchangeable components (or modules) in a model. The component may be a single equation, but typically it is a large component: for example, a plant submodel or a soil water submodel. There have been calls for the development of modular modelling approaches for some two decades, and some working systems, motivated by the advantages that this would confer on the modelling process in terms of model construction, testing and reuseability of components. In addition, a major motive for the adoption of object-oriented software engineering approaches has been its support for modularity in modelling.
The purest form is “plug-and-play” modularity, in which the interfacing between a module and the main model is pre-defined (like the pins on an integrated circuit chip). All the modeller needs to do is to load the module, and it is automatically part of the model. Simile enables you to do this, as a two-step operation. First, you load the module (a Simile model, loaded into a submodel window). Then you select an Interface Specification File which defines the links between the submodel and the rest of the model. This approach has considerable merits: it means that the same Simile model can be inserted as a module in a range of other models, with different interfacing for each one.
At the other extreme, Simile supports “free-form” modularity, in which it is entirely up to the modeller to decide how the inserted submodel links to the rest of the model. This means that the modeller has access to a much greater range of models to use as submodels — ones that were developed with no intention that they be used as a submodel in someone else’s model. This removes the need for careful defining of interfaces which plagues current modular (and indeed object-oriented) systems.
You will probably by now appreciate that you have a variety of options when it comes to modelling population dynamics. You can adopt a lumped approach in System Dynamics, using a compartment to represent population size, and flows to represent demographic processes of reproduction, migration and mortality. Or, you can adopt a disaggregated System Dynamics approach, using a compartment-flow structure to represent the dynamics of one age/size/sex class, embedded in a multiple-instance submodel to represent all the classes. In this case, you will need to have additional flows for modelling the movement of individuals between age or size classes. Or you use a population submodel to represent every individual in the population, adding in rules for specifying the creation of new individuals and the death of existing ones. In this case, it is optional whether your model contains any System Dynamics at all: you might decide to use a compartment-flow structure to represent, for example, the body weight of each individual, but you certainly don’t have to.