Difference between revisions of "Numerus Simulation Architecture"

From Numerus
Jump to navigation Jump to search
Line 11: Line 11:
Consequently, the unadorned reference ''pop'' is ambiguous: do we mean the object or the value? In order to make this precise we introduce the concept of '''scope'''. Each simulator (Capsule, AgemtVector, CellMatrix, etc.) has a ''scope'' object which is contained in its scope property. The scope is property list<ref>A ''property list'' associates property names, which are strings, with values. For example, if ''P'' is a property list containing values for properties ''a'', ''b'', and ''c'', then the notation <code>P.a</code>, <code>P.b</code>, and <code>P.c</code> is used to extract the property values from the list. Alternatively we could use <code>P["a"]</code>, <code>P["b"]</code> and <code>P["c"]</code>.</ref> mapping the names of all components in the Simulator to its current value. The scope also contains references to primitive operators (primops) and properties germane to that Simulator.
Consequently, the unadorned reference ''pop'' is ambiguous: do we mean the object or the value? In order to make this precise we introduce the concept of '''scope'''. Each simulator (Capsule, AgemtVector, CellMatrix, etc.) has a ''scope'' object which is contained in its scope property. The scope is property list<ref>A ''property list'' associates property names, which are strings, with values. For example, if ''P'' is a property list containing values for properties ''a'', ''b'', and ''c'', then the notation <code>P.a</code>, <code>P.b</code>, and <code>P.c</code> is used to extract the property values from the list. Alternatively we could use <code>P["a"]</code>, <code>P["b"]</code> and <code>P["c"]</code>.</ref> mapping the names of all components in the Simulator to its current value. The scope also contains references to primitive operators (primops) and properties germane to that Simulator.


The scope also contains a special property, '''_cap_'''<ref>in Nova 2 this was called Self</ref>. Thus if ''Y'' is the scope object for Simulator ''X'', then <code>Y._cap_</code> will produce X. Thus we have a way of going from Simulator to scope (using the "scope" property) and from scope to Simulator (using the "_cap_" property). This provides a means for retrieving either the component object or its value from any component in a Capsule.   
The scope also contains a special property, '''_cap_'''<ref>in Nova 2 this was called '''Self'''</ref>. Thus if ''Y'' is the scope object for Simulator ''X'', then <code>Y._cap_</code> will produce X. Thus we have a way of going from Simulator to scope (using the "scope" property) and from scope to Simulator (using the "_cap_" property). This provides a means for retrieving either the component object or its value from any component in a Capsule.   


Example:  Assume Capsule ''C'' contains components ''a'', ''b'' and ''c'', with current values 10, 20 and 30, respectively. Let ''CS'' be the scope of ''C''. Then
Example:  Assume Capsule ''C'' contains components ''a'', ''b'' and ''c'', with current values 10, 20 and 30, respectively. Let ''CS'' be the scope of ''C''. Then

Revision as of 18:10, 9 June 2018

Numerus supports a multi-level architecture comprised of Simulators. The lowest level atomic simulator is called a Capsule, and it is composed of simulation components (Stocks, Flows, etc.). Containers are component simulators that contain Capsule instances as elements.

A Numerus model is called a project. At a minimum a project contains a top-level Capsule instance called main. The main Capsule will contain components, some of which may be Containers. Each Container contains 1 or more instances of some Capsule (or Agent, Cell, or Node, which are extend versions of the Capsule for use with specific Containers). The contents of such a Capsule may contain its own Containers, and so we obtain a hierarchical structure, as described here.

Simulators and Aggregators

The simplest Container is the Chip, which wraps a Capsule for insertion as a component in a parent Capsule. Other containers are called aggregators since they bind together multiple Capsule elements in a specific topology. Currently there are 5 aggregators: CellMatrix, AgentVector, SimWorld, NodeNetwork and NetWorld. Each of these is described in detail elsewhere. The Capsule types used in each aggregator is an extension to the fundamental Capsule type which complements the topology introduced by that aggregator. For example, the contents of a CellMatrix are of a Cell type which is a Capsule that is aware of its row/column location.

Components and Scope

Every value-producing component (Stock, Term, Flow, etc.) is part of the architecture in two ways. First there is the component object itself which holds the machinery for producing its value, and then there is the value itself. So if a particular component pop is part of some Capsule, we might refer to pop either to obtain its current value (such references are almost always used in the equations defining the model); or we might need to obtain a reference to the component object to, say, look up an old value or access some parameter[1]. While the latter is uncommon, such situations occasionally arise.

Consequently, the unadorned reference pop is ambiguous: do we mean the object or the value? In order to make this precise we introduce the concept of scope. Each simulator (Capsule, AgemtVector, CellMatrix, etc.) has a scope object which is contained in its scope property. The scope is property list[2] mapping the names of all components in the Simulator to its current value. The scope also contains references to primitive operators (primops) and properties germane to that Simulator.

The scope also contains a special property, _cap_[3]. Thus if Y is the scope object for Simulator X, then Y._cap_ will produce X. Thus we have a way of going from Simulator to scope (using the "scope" property) and from scope to Simulator (using the "_cap_" property). This provides a means for retrieving either the component object or its value from any component in a Capsule.

Example: Assume Capsule C contains components a, b and c, with current values 10, 20 and 30, respectively. Let CS be the scope of C. Then

 C.scope == CS
 CS._cap_ == C
 CS.a == 10
 CS.b == 20
 CS.c == 30
 C.a == a
 C.b == b
 C.c == c
 CS._cap_.a == a
 CS._cap_.a.value() == 10

etc.

Notes

  1. Given a component object c, its current value is obtained using c.value()
  2. A property list associates property names, which are strings, with values. For example, if P is a property list containing values for properties a, b, and c, then the notation P.a, P.b, and P.c is used to extract the property values from the list. Alternatively we could use P["a"], P["b"] and P["c"].
  3. in Nova 2 this was called Self