Sign in to start building system dynamics models
or
Sign In
or
☁ Save As

Save this model to your account. You can open it from any device.

📁 My Models
Loading…
About
S.I.M.P.L.E. SD
www.simple-sd.com
Version 2.0.26
© 2026 S.I.M.P.L.E. SD. All rights reserved.
Output Log
untitled.simple
Ready
Editor
0 errors Ln 1, Col 1
Diagram
Run:
100%
Run a model to see data here.
📈 Plot Tab Help

Plot Tab Overview

The Plot tab displays simulation results as a retro printer-paper style time-series chart. Run a model first, then use the controls to explore the data visually.

Controls

ControlDescription
Run dropdownSelect which simulation run to display. Only runs that have a PLOT statement appear in this dropdown.
Lines checkboxShow continuous line traces for each selected variable.
Letters checkboxShow letter symbols on the chart at regular intervals. Each variable is assigned a letter from the PLOT statement (e.g., PLOT POP=P) or auto-assigned.

Variable Chips

Below the controls, colored chips appear for each plottable variable. Click a chip to toggle that variable on/off in the chart. Selected chips are highlighted with a blue border.

If units are defined (via U statements), they appear in the chip label and in chart tooltips.

Chart Interaction

  • Hover over the chart to see tooltips with precise values for each variable at that time step.
  • Values are displayed with appropriate formatting — scientific notation for very large or very small numbers.
  • When variables have very different scales, the chart auto-normalizes them to a 0–1 range so all traces are visible.

Diagram Plot Nodes

In addition to the Plot tab, you can add Plot nodes directly on the diagram via the Plot button in the diagram toolbar (or Insert → Plot). These are mini time-series charts that live on the diagram canvas, each associated with a specific run. After running the model, they fill with simulation data. Click a plot node to edit which variables it displays; drag the corner handle to resize.

PLOT Statement

Use the PLOT statement in your model to assign letter symbols and optional scales:

PLOT  POP=P(0,5000)/BIRTH=B(0,100)

Variables separated by / share the same scale group. The letter after = is the symbol shown on the chart.

Y-Axis Scale (lo,hi)

The (lo,hi) values set the Y-axis range for a variable or group of variables. This is essential when plotting variables with very different magnitudes together — for example, a population level in the thousands and a birth rate below 100.

Without explicit scales, a small variable will appear as a flat line at the bottom of the chart because the Y-axis is dominated by the large variable. Setting separate (lo,hi) scales causes each group to be normalized independently so all traces are visible and use the full chart height. The actual scale range is shown in the legend.

You can also set these values from the lo and hi fields in the Plot configuration panel on the diagram.

Each run can have its own PLOT statement. If a run does not have a PLOT statement, it will not appear in the Plot tab’s run dropdown.

You can also configure plot variables visually by clicking a Plot node on the diagram and using the context panel.

📊 Data Tab Help

Data Tab Overview

The Data tab shows the raw numerical output from your simulation in a tabular format. Run a model to populate the table. Only runs that have a PRINT statement appear in the data table.

Table Contents

  • The first column is RUN — the name of the simulation run.
  • The second column is TIME — the simulation time at each output step.
  • Subsequent columns show the value of each PRINT-listed variable at that time.
  • Output rows are spaced according to PRTPER (print period) from the SPEC statement. If PRTPER=0, every time step is shown.

Configuring Print Variables

There are two ways to configure which variables appear in the Data tab:

  1. PRINT statement: Type PRINT POP,BIRTH,DEATH directly in the editor.
  2. Print button: Click the Print button on the diagram toolbar (or Insert → Print). A popup opens showing all model variables with checkboxes — select the ones you want, then click Apply. This writes or updates the PRINT line for the currently active run.

Each run can have its own PRINT statement. If a run has no PRINT statement, it will not appear in the data table at all.

CSV Export

Click the 💾 CSV button to download the data table as a comma-separated values file, ready for import into spreadsheets or other analysis tools. Only runs with PRINT statements are included in the export.

PRINT Statement

Control which variables appear in the data table:

PRINT POP,BIRTH,DEATH

Only variables listed in PRINT will appear as columns.

Tips

  • You can select and copy data from the table for use in spreadsheets.
  • Use PRTPER to control how many rows are output. A larger value means fewer rows and a more compact table.
  • Very large or very small values are shown in scientific notation.
  • Use the CSV button for a clean export that preserves all precision.
  • Use the diagram toolbar’s Print button to quickly select print variables with checkboxes, rather than typing the PRINT line manually.
🗘 Diagram Help

Getting Started

The diagram is a stock-and-flow visual representation of your model. It syncs both ways with the editor — build your model visually, textually, or both.

Quick-Start: Build a Simple Model

POP BIRTHS DEATHS BR DR info wire pipe (flow)

Example: Simple population model with births and deaths

  1. Click Level in the toolbar to add a stock (e.g., POPULATION). Name it, enter a formula like POP.K=POP.J+DT*(BIRTHS.JK-DEATHS.JK), set an initial value, and click Apply.
  2. Click Rate to add a flow (e.g., BIRTHS). Name it, set its formula (e.g., BIRTHS.KL=POP.K*BR), and Apply.
  3. Click Constant to add a parameter (e.g., BR=0.03). Apply.
  4. Use Wire Connector to draw a dependency from POP to BIRTHS, and from BR to BIRTHS, to show that BIRTHS reads those values.
  5. Use Pipe Connector to draw a material flow pipe from POP to BIRTHS (since births flow into the population stock).
  6. Click Fit View to center everything.

Toolbar Reference

ButtonWhat It Does
Fit ViewZooms and pans so the entire diagram fits in the viewport.
Undo / RedoUndo or redo the last editor change. Works for both typed edits and programmatic changes from the diagram (editing a node, adding equations, etc.). Also available via Ctrl+Z / Ctrl+Y (or Ctrl+Shift+Z).
Edit/MoveDefault mode — click to select and drag to reposition nodes.
Wire ConnectorEnter wire-drawing mode. Click source, then target, to create an information link.
Pipe ConnectorEnter pipe-drawing mode. Connect a Level ↔ Rate to show material flow.
Level / Rate / Auxiliary / Table / ConstantAdd a new node of the chosen type. Opens the properties panel to set name, formula, etc.
ArrayAdd an Array Level node — a subscripted family of similar stocks (e.g., age cohorts). See Working with Arrays below.
Add GhostCreate a ghost (visual duplicate) of an existing variable to shorten long wires.
PlotAdd a Plot node to the diagram showing simulation time-series for the active run.
PrintConfigure which variables appear in the Data tab. Opens a popup to select variables for the active run’s PRINT line.
NoteAdd a text annotation to the diagram. Notes are stored as NOTE lines in the editor, scoped to the active run.
Macro ▾Open the macro dropdown. Click + New Macro to create a reusable equation template, or click an existing macro to edit or delete it. Macros are written as MACRO..MEND blocks at the top of the editor.
Hidden (N)Shows the count of hidden nodes. Click to reveal the list and unhide them.
Run dropdown / + RunSelect the active run section. All diagram edits target this run. Click + Run to add a new scenario.

Node Types

LEVEL Stock Rate AUX Auxiliary TBL Table CONST Constant ARRAY Array Level Array Rate T CONST Array Constant
TypeShapeColorWhen to Use
LevelRectangle■ BlueAnything that accumulates over time: population, inventory, capital, knowledge. Requires an initial value (N line) and at least one rate flowing in or out.
RateBowtie◆ GoldControls how fast a level changes: birth rate, production rate, spending rate. Always connect to a level via a pipe.
Array LevelStacked rectangles■ BlueAn array of levels — multiple stocks sharing the same equation structure, indexed by a FOR variable. Displays as stacked rectangles with a size badge. Example: age cohorts in a population model.
Array RateStacked bowties◆ GoldAn array of rates — multiple flows sharing the same equation structure. Created automatically when connecting a pipe from an Array Level to a plain Rate, or by clicking the Array button and switching to a rate.
AuxiliaryCircle● GreenIntermediate calculations that combine other variables: ratios, gaps, desired values. Keeps formulas clean by breaking complex logic into steps.
TableCircle with lines● PurpleNonlinear lookup relationships where you define the curve by data points, e.g., how crowding affects death rate. The built-in chart editor lets you shape the curve visually.
ConstantHorizontal line■ GreyFixed parameters that don’t change during a run: birth fraction, normal lifetime, policy thresholds. Easy to identify and adjust for scenario testing.
Array ConstantHorizontal line■ GreyA constant with multiple values — one per array element (e.g., age-specific death rates). Uses a T line in the editor. Created by converting a Table Lookup via the ⇌ Array Const button, or parsed automatically from T lines that aren’t used by a TABLE() function.

How to Connect Nodes

Drawing Wires (Information Links)

Wires show that one variable reads another’s value. For example, if BIRTHS depends on POP, draw a wire from POP to BIRTHS.

  1. Click Wire Connector in the toolbar (it highlights when active).
  2. Click the source node (the variable being read).
  3. Click the target node (the variable that uses the value).
  4. Repeat for more wires, or press Escape to exit wire mode.

Shortcut: Hold Shift and drag from one node to another for a one-off quick-wire without entering wire mode.

Drawing Pipes (Material Flows)

Pipes represent physical material flowing between a stock and a valve. For example, water flowing from a TANK through a DRAIN rate.

  1. Click Pipe Connector in the toolbar.
  2. Click a Level, then click a Rate (or vice versa). Pipes only connect Levels ↔ Rates.
  3. The pipe appears as a solid colored line (distinct from dashed wires).

Wire vs Pipe — When to Use Which

AUX RATE Wire (reads value) LVL Pipe (material flows)
Wire ConnectorPipe Connector
Meaning“A reads the value of B”“Material flows from stock through valve”
AppearanceDashed arrowSolid colored pipe
Valid betweenAny node → any nodeLevel ↔ Rate only
ExamplePOP → BIRTHS (births depends on population size)POP → DEATHS (people physically leaving the population)

Reshaping Curved Wires

A B Straight (default) drag A B Curved (dragged)

Drag a wire sideways to bend it into an arc

Wire arrows start straight. To bend one into an arc:

  1. Hover over the wire — it highlights blue when grabbable.
  2. Click and drag the wire sideways. It bends into a circular arc following your mouse.
  3. To straighten it back, drag it near the midpoint between the two nodes.

The system also auto-curves wires that would pass through other nodes.

Moving and Navigating

ActionHow
Move a nodeClick and drag it. All connected edges follow in real-time.
Pan the viewClick and drag on empty canvas space.
ZoomScroll the mouse wheel. Zooms toward cursor position. Range: 5% – 800%.
Fit everythingClick Fit View in the toolbar.
Select a nodeClick it. Opens the properties panel.
DeselectClick empty space or press Escape.

Editing Node Properties

Click any node to open the properties panel on the right. Here’s how to use each field:

Properties — POP Type Level ▾ Name POP Formula POP.J+(DT)*(BIRTHS.JK-DEATHS.JK) + - * / ( ) DT TIME.K SQRT ABS ... ← insert toolbar Initial 1000 Units persons Hide in diagram Connections → BIRTHS → DEATHS ← BIRTHS(pipe) ← DEATHS(pipe) Apply Duplicate Cancel Delete

Properties panel layout for a Level node

Basic Fields

FieldHow to Use
TypeChange between Level, Rate, Auxiliary, Table, Constant. Changing type updates the equation prefix in the editor automatically.
NameThe variable name (auto-uppercased). Renaming a variable here updates every reference throughout your entire model.
FormulaThe right-hand side of the equation. Type directly, or use the insert buttons below the field to add functions and variable references with correct time subscripts.
Initial Value(Levels only) The starting value at time zero. Generates the N line in the editor.
Table Name / Data(Table nodes only) The lookup table name and slash-separated output values. See Table Chart below.
UnitsOptional unit annotation (e.g., persons, $/year). Used for dimensional analysis and shown in data headers.
Hide in diagramVisually hides the node without deleting it. Useful for reducing clutter with constants.

Formula Insert Toolbar

Below the formula field, clickable buttons let you insert operators and functions at the cursor position. Click any button to insert the function template with placeholder arguments.

Ops — Basic Operators

ButtonDescription
+ - * /Arithmetic operators — addition, subtraction, multiplication, division.
( )Grouping parentheses for controlling order of operations.
DTThe simulation time step. Used in Level equations: POP.J+(DT)*(BIRTHS.JK).
TIME.KThe current simulation time. Use to create time-dependent behavior.

Math — Mathematical Functions

FunctionDescription
SQRT(x)Square root of x.
ABS(x)Absolute value of x.
SIN(x)Sine of x (x in radians).
COS(x)Cosine of x (x in radians).
EXP(x)e raised to the power x (natural exponential).
LOG(x)Natural logarithm (base e) of x.
MAX(a,b)Returns the larger of a and b.
MIN(a,b)Returns the smaller of a and b.

Tables — Nonlinear Lookup Functions

FunctionDescription
TABLE(T,x,lo,hi,step)Standard table lookup. Looks up the value of x in table data T, with X axis ranging from lo to hi in increments of step. Linearly interpolates between data points. Returns the boundary value if x is outside the range.
TABHL(T,x,lo,hi,step)Table with Hard Limits. Same as TABLE but clamps the output strictly — returns exactly the first or last table value if x is outside the range (no extrapolation).
TABXT(T,x,lo,hi,step)Table with eXTrapolation. Like TABLE but linearly extrapolates beyond the defined range using the slope at the boundary.
TABPL(T,x,lo,hi,step)Table with Point-by-point Lookup. Looks up using the provided points directly as X/Y pairs rather than uniform spacing.

Logic — Conditional Functions

FunctionDescription
CLIP(val1,val2,thresh,x)Returns val1 if xthresh, otherwise returns val2. Use for policy switches that activate at a threshold.
SWITCH(val1,val2,test)Returns val1 if test = 0, otherwise returns val2. A simple on/off toggle.
FIFZE(val1,val2,test)First If Zero — returns val1 if test = 0, otherwise returns val2.
FIFGE(val1,val2,test)First If Greater or Equal — returns val1 if test ≥ 0, otherwise returns val2.

Time — Time-Varying Input Functions

FunctionDescription
STEP(height,stime)Outputs 0 before time stime, then jumps to height and stays there. Use for sudden policy changes or shocks.
RAMP(slope,stime,etime)Outputs 0 before stime, then increases linearly at slope per time unit until etime (then holds constant). Use for gradual changes.
PULSE(height,first,interval)Outputs height for one DT at time first, then repeats every interval time units. Use for periodic injections or impulse testing.
NOISE()Returns a random number from a normal distribution (mean 0, std dev 1) at each time step. Use for stochastic disturbances.
SAMPLE(x,s,i)Samples the value of x at time s, then re-samples every i time units. Holds the sampled value constant between samples. Use for discrete periodic measurements.

Delays — Smoothing & Delay Functions

FunctionDescription
DELAY1(input,delay)First-order exponential delay (one stock). Output lags behind input with an average delay of delay time units. Equivalent to a single level being filled by the input.
DELAY3(input,delay)Third-order exponential delay (three cascaded stocks). Produces an S-shaped delay response — output stays near zero initially, then rises to match input. More realistic than DELAY1 for material pipelines.
SMOOTH(input,delay)Exponential smoothing (identical to DELAY1). Output tracks input but smoothed over delay time units. Use for perceived or averaged quantities.
DLINF3(input,delay)Third-order information delay. Like DELAY3 but specifically for information (perception) rather than material. Separates reporting delays from physical delays.

Tip: For Table nodes, only the Ops and Table groups are shown to reduce clutter.

Connections List

At the bottom of the panel, the Connections section shows all incoming and outgoing edges. Click any connection name to jump to that node in the diagram and highlight it. This is a fast way to navigate between related variables.

Action Buttons

  • Apply — Saves your changes. The equation lines in the editor update, and the diagram rebuilds.
  • Duplicate — Creates a ghost copy of this node (see Ghost Nodes below).
  • Cancel — Closes the panel without saving. Your edits are discarded.
  • Delete — Permanently removes the node and all its equation lines from the model.

Working with Table Nodes

Table nodes define nonlinear lookup curves. When you select a table node, an interactive chart appears:

1.0 0.75 0.50 0.25 0 0 1 2 3 4 1.0 0.9 0.6 0.25 0.1

Drag any point (pink = active) in any direction to reshape the curve

Editing the Curve

  • Drag any point in any direction to reshape the curve. The Y value (output) and X axis parameters update in real-time as you drag.
  • + button — Adds a new point at the end of the curve.
  • − button — Removes the last point.
  • Right-click a point — Removes that specific point.

Data Grid

Below the chart is an editable table showing Input (X) and Output (Y) values for each point:

  • Edit Input values to change the X axis range. Changing the first point adjusts the lower bound, the last adjusts the upper bound, and middle points adjust the step size. All points re-space evenly (DYNAMO tables require uniform spacing).
  • Edit Output values to set exact Y values numerically. The chart updates when you press Enter or tab away.

How the Formula Works

A table formula looks like: TABLE(TABNAME,INPUT.K,lo,hi,step)

  • TABNAME — references the table data (defined on a T line).
  • INPUT.K — the variable whose value is looked up.
  • lo, hi, step — the X axis range and spacing. These update automatically when you edit Input values or drag points horizontally.

Working with Arrays

Arrays (subscripted variables) let you define families of levels and rates that share equation structure. In the diagram, array elements are collapsed into a single node shown as stacked shapes with a size badge (e.g., [3]).

Creating an Array from the Diagram

  1. Click Array in the toolbar. An Array Level node appears with a default size of 3.
  2. Name it (e.g., POP) and configure the Array Configuration panel:
    • Size — Number of elements (2–20).
    • Index Variable — The FOR loop variable name (e.g., AGE).
    • Element Names — Comma-separated aliases for each index value (e.g., YOUNG,ADULT,OLD).
  3. Enter a formula using the index variable in subscripts, e.g., POP.J(AGE)+DT*(BIN.JK(AGE)-BOUT.JK(AGE)).
  4. Click Apply. The corresponding I, FOR, L, and N lines are generated in the editor.

Element Tabs — Per-Element Editing

Below the Array Configuration, clickable element tabs let you view and edit individual elements:

  • Shared — Shows the FOR-parameterized formula that applies to all elements. When all elements use the same formula, a single shared equation with the index variable is written to the editor.
  • Element tabs (labeled with aliases like YOUNG, ADULT, OLD or numbers 1, 2, 3) — Click to see that specific element’s formula. You can give each element a different formula.

When you click Apply, if all element formulas are identical, a single FOR-parameterized equation is written. If any differ, separate per-element equations with numeric subscripts are written instead.

The Initial Values field also switches per element: on the Shared tab it shows all values separated by /, on an element tab it shows just that element’s value.

Array Rates

Array rates are created in two ways:

  • Automatic promotion: When you draw a Pipe from an Array Level to a plain Rate, the rate is automatically promoted to an Array Rate and inherits the level’s array configuration (size, index variable, element names).
  • From existing code: If the editor already contains array rate equations (e.g., R BIN.KL(AGE)=...), the diagram detects them and displays them as stacked bowties.

Array Constants (T Lines)

Constants that vary across array elements use T (table) lines, not C lines. A C line holds a single scalar value, but a T line holds multiple slash-separated values — one per element:

T     DTHRT=.002/.005/.02

These appear on the diagram as a single constant node (grey horizontal line) wired to any array that references them.

Converting Between Table Lookup and Array Constant

A Table Lookup node uses a TABLE() function with a curve. An Array Constant just stores slash-separated values for each element. You can convert between them:

DTHRT Table Lookup TABLE(DTHRTT,...) ⇌ Array Const button in properties DTHRT Array Constant .002/.005/.02 BOUT [3] Array Rate

Click ⇌ Array Const in the properties panel to convert a Table Lookup into a simple array constant (and back)

How to use:

  1. Select a Table Lookup node on the diagram.
  2. In the properties panel, click the ⇌ Array Const button next to the Type dropdown.
  3. The node changes to a Constant (grey line). The formula field now shows the slash-separated values (e.g., .002/.005/.02). The lookup chart is removed.
  4. Edit the values directly in the formula field and click Apply.
  5. The editor line changes from A to T: T DTHRT=.002/.005/.02

To convert back, click ⇌ Table Lookup. The values become table data and a TABLE() formula is generated.

When to use which:

Array ConstantTable Lookup
DataOne fixed value per array elementCurve with many points for interpolation
ExampleT DTHRT=.002/.005/.02 (3 values for 3 age groups)A EFFECT.K=TABLE(EFFT,RATIO.K,0,2,0.5)
Diagram shapeGrey line (constant)Purple circle with lines (table)
Editor lineT prefixA prefix + separate T data line

Shared FOR Variables

Multiple arrays can share the same FOR variable (e.g., both POP and BIN use AGE). The diagram handles this correctly:

  • When you delete one array, the I and FOR lines are preserved if any other array still uses that index variable.
  • When you create a new array that uses an existing FOR variable, duplicate I/FOR lines are not inserted.

Ghost Nodes

Ghost nodes are visual duplicates of existing variables. They don’t create new equations — they just provide a second reference point on the diagram to reduce long crossing wires.

VAR Original long wire ✗ VAR short wire ✓ Ghost (dashed)

Use ghosts to replace long wires with short local connections

When to Use Ghosts

If a widely-used variable (like POPULATION) has wires stretching across the entire diagram, create a ghost near the variables that need it. The long wires become short local connections.

How to Create a Ghost

  1. Toolbar: Click Add Ghost → pick a variable from the searchable dropdown. The ghost appears near the original.
  2. Properties Panel: Select a node and click Duplicate.

How Ghosts Behave

  • Ghosts appear with a dashed outline and semi-transparent fill so you can tell them apart from originals.
  • When created, nearby wires are automatically rerouted to originate from the ghost instead of the distant original.
  • Click a ghost to see which connections use it, and manually toggle consumers between the ghost and original.
  • Ghosts persist across editor rebuilds and are saved with the model layout.

Run Management

DYNAMO supports multiple runs — different scenarios that share the same base model but override specific parameters. The run dropdown in the diagram toolbar lets you manage these.

BASE L POP.K=POP.J+... R BR.KL=POP.K*BRN C BRN=0.03 RUN BASE inherits HIGH BIRTH C BRN=0.05 ← overrides base RUN HIGH BIRTH BASE ▾ ▸ BASE HIGH BIRTH Run dropdown Full model equations Only overrides + Run

Runs share the base model; override runs contain only changed parameters

Run Dropdown

The run dropdown at the top of the diagram toolbar shows all runs defined in the model. It controls which run section your diagram edits target.

ActionHow
Switch active runSelect a different run from the dropdown. All subsequent diagram edits (adding nodes, changing formulas, editing SPEC, PLOT lines, etc.) are scoped to that run’s section in the editor.
Add a new runClick the + Run button. You’ll be prompted for a name. A new RUN line is appended to the editor, creating a new scenario section.

How Runs Work in the Editor

A multi-run DYNAMO file has this structure:

*     MY MODEL
L     POP.K=POP.J+(DT)*(BR.JK)
R     BR.KL=POP.K*BRN
N     POP=1000
C     BRN=0.03
SPEC  DT=1,LENGTH=100,PRTPER=1,PLTPER=1
PLOT  POP=P
RUN   BASE
C     BRN=0.05
SPEC  DT=1,LENGTH=100,PRTPER=1,PLTPER=1
RUN   HIGH BIRTH
  • The first run (BASE) contains the full model: all equations, SPEC, PLOT, and a RUN line.
  • Subsequent runs (HIGH BIRTH) contain only the overrides — parameters that differ from the base — plus their own SPEC, PLOT, and RUN line.
  • When the dropdown is set to a non-base run, editing a variable on the diagram inserts an override in that run’s section rather than modifying the base definition.

What Is Run-Scoped

When you select a non-base run in the dropdown, all diagram operations are scoped to that run’s section:

  • Node edits — formula, initial value, table data, and unit changes insert overrides in the active run.
  • Adding nodes — new equations are placed in the active run’s section.
  • Deleting nodes — removes lines only from the active run’s section.
  • SPEC settings — applying settings from the Settings dialog updates the SPEC line in every run.
  • PLOT lines — the plot configuration is written to the active run’s section.
  • Plot nodes — each plot node is tagged with its run and uses that run’s simulation data.

Plot Nodes

Plot nodes are mini time-series charts that live on the diagram, showing real simulation results. Each plot node is associated with a specific run — its title shows which run it belongs to (e.g., “PLOT — HIGH BIRTH”).

PLOT — BASE 5000 3750 2500 1250 0 25 50 75 100 POP BR

Plot node showing POP growth over time with resize handle in the corner

How to Use

  1. Click the Plot toolbar button to add a plot node. It is automatically associated with the currently selected run in the dropdown.
  2. Run the model (Ctrl+Enter) — the chart fills with actual simulation data from its associated run.
  3. Drag the plot node to reposition it. Drag the corner handle to resize.
  4. Click the plot node to edit which variables are displayed.

Y-Axis Scale (lo & hi)

In the plot configuration panel, each variable has lo and hi fields that set its Y-axis range. Use these when plotting variables with very different magnitudes together (e.g., a large level and a small rate). Without explicit scales, the smaller variable will appear flat because the Y-axis is stretched to fit the larger one.

When variables have different scale ranges, the chart automatically normalizes each trace to its own range so all are visible. The Y-axis shows 0–100% and the legend displays each variable’s actual scale. These values correspond to the (lo,hi) in the PLOT statement: PLOT POP=P(0,5000)/BIRTH=B(0,100).

Print Data

The Print toolbar button configures which variables appear in the Data tab (the tabular output after running the model). It manages the PRINT line in the editor for the currently active run.

How to Use

  1. Click Print in the toolbar. A popup opens showing all model variables with checkboxes.
  2. Check the variables you want printed — these will appear as columns in the Data tab after running the model.
  3. Click Apply. The PRINT line for the active run is updated in the editor.

If a run has no PRINT line, it won’t appear in the Data tab’s run dropdown. You can also configure print variables by typing PRINT VAR1,VAR2,... directly in the editor.

Note Nodes

Note nodes are text annotations that live on the diagram. They are ideal for documenting assumptions, labeling diagram sections, or leaving explanatory comments visible alongside the model structure.

Assumes 3% annual birth rate constant BRN BIRTHS

Note nodes use dashed borders and can be placed beside related variables

How to Use

  1. Click Note in the toolbar to add a note node. It appears on the diagram with placeholder text.
  2. Click the note to open the context panel where you can edit the text.
  3. Type your annotation text and click Apply. The note updates on the diagram and a NOTE line is written to the editor in the active run’s section.
  4. Drag the note to reposition it. Drag the corner handle to resize.

Notes in the Editor

Notes map to NOTE lines prefixed with a marker (e.g., NOTE :n1: Your text here). They are run-scoped — each run can have its own annotations. Editing a note in the editor automatically updates the diagram, and vice versa.

Notes render with a transparent background and dashed border, using theme-aware colors that adapt to light and dark mode.

Working with Macros

Macros are reusable equation templates that let you define a pattern once and invoke it multiple times with different arguments. They are managed from the diagram toolbar but do not appear as nodes on the diagram — only the variables that call the macro appear as normal equation nodes.

Macro ▾ + New Macro MYSMOOTH(OUT,IN,AVG) Edit × MACRO ... INTRN RT R ... MEND

The Macro button opens a dropdown to create or edit macros, which sync to MACRO..MEND blocks in the editor

Creating a Macro

  1. Click the Macro ▾ button in the toolbar.
  2. Click + New Macro in the dropdown panel.
  3. The context panel opens with fields for:
    • Macro Name — a unique identifier (e.g., MYSMOOTH)
    • Arguments — comma-separated parameter names (e.g., OUT, IN, AVG)
    • Internal Variables — private helpers unique per expansion (e.g., RT)
    • Body Equations — the equation template lines (e.g., R RT.KL=(IN.K-OUT.K)/AVG)
  4. Click Create. A complete MACRO..MEND block is written to the top of the editor.
New Macro × Macro Name MYSMOOTH Arguments OUT, IN, AVG Internal Variables RT Body Equations R RT.KL=(IN.K-OUT.K)/AVG Create Cancel

The macro context panel with fields for name, arguments, internals, and body equations

Editing and Deleting Macros

  • Click Macro ▾ to see all defined macros listed in the dropdown.
  • Click a macro name or its Edit button to reopen the context panel with pre-filled values.
  • Click the × button next to a macro to delete it (removes the MACRO..MEND block from the editor).
  • Changes are immediately synced to the editor text.

How Macros Appear in the Model

Macros themselves are not diagram nodes. When an equation calls a macro (e.g., A SAVG.K=MYSMOOTH(SAVG,ORDERS.K,8)), the interpreter expands it into real equations with unique internal variable names. Those expanded variables appear as regular nodes on the diagram.

Units work normally with macros — define U lines for the variables you pass as arguments, and the unit-inference engine propagates through the expanded equations.

Bidirectional Sync

  • Diagram → Editor: Creating or editing a macro in the context panel writes the MACRO..MEND block at the top of the editor (following DYNAMO convention).
  • Editor → Diagram: Editing macros in the editor text is reflected in the Macro dropdown the next time it is opened. The diagram rebuilds automatically to incorporate any changes.

Hiding & Showing Nodes

BR DR ALT Cluttered ✗ hide POP BIRTHS Hidden (3) Clean ✓

Hide constants and parameters to declutter your diagram

Complex models can have dozens of constants cluttering the view. To hide them:

  1. Select a node and check “Hide in diagram” in the properties panel. Click Apply.
  2. The node disappears from the diagram but stays in the model.
  3. A Hidden (N) button appears in the toolbar showing how many are hidden.
  4. Click it to see the list and unhide individual nodes, or click “Show all” to reveal everything.

Editor ↔ Diagram Sync

Editor L POP.K=POP.J+... R BR.KL=POP.K*BRN N POP=1000 C BRN=0.03 auto sync Diagram POP BRN

Changes in either pane are reflected automatically in the other

The diagram and editor stay in sync automatically in both directions:

  • Typing in the editor rebuilds the diagram after a short delay. Node positions, ghost nodes, and edge curves are preserved.
  • Editing in the properties panel and clicking Apply updates the corresponding equation lines in the editor instantly. Renaming a variable updates all references everywhere.
  • Deleting a node from the diagram removes its equation lines from the editor.

Exporting the Diagram

Go to File → Export Diagram and choose a format:

  • SVG — Scalable vector graphics. Editable in Inkscape, Illustrator, or any SVG editor. Best for publications and reports.
  • PNG — Raster image. Good for quick sharing and presentations.
  • PDF — Portable document. Good for printing.

Layout Persistence

Save NOTE :LAYOUT: {"POP":{x:150,y:80}, "BR":{x:50,y:120}, "edges":[...], "hidden":[...]} positions, curves, ghosts, and hidden state stored in editor

When you save a model (File → Save), the diagram layout is stored as a NOTE :LAYOUT: line in the file. This includes node positions, edge curves, hidden nodes, and ghost nodes. The layout is automatically restored when you reopen the model.

Simulation Settings Window

The Model Settings window (⚙) lets you configure the core simulation parameters before you run. Open it via Simulation → Settings, or it appears automatically when you create a new model.

Settings Window Overview

⚙ Model Settings ? MODEL TITLE WORLD DYNAMICS DT (TIME STEP) LENGTH (DURATION) 0.5 200 PRTPER (PRINT PERIOD) PLTPER (PLOT PERIOD) 5 1 RUN NAME BASE TIME UNIT YEARS INTEGRATION METHOD Runge-Kutta (3rd order) RELATIVE ERROR (REL_ERR) ABSOLUTE ERROR (ABS_ERR) 0.01 0.001 Cancel Apply

Field Reference

FieldDYNAMO CodeDescription
Model Title* titleA descriptive name for the model. Written as a comment (*) at the top of the file.
DTSPEC DT=0.5The simulation time step. Smaller values increase accuracy but slow down the run.
LENGTHSPEC LENGTH=200Total simulation duration in time units.
PRTPERSPEC PRTPER=5Print period — how often data rows appear in the Data tab. Set to 0 to print every DT.
PLTPERSPEC PLTPER=1Plot period — how often plot points are recorded. Set to 0 for every DT.
RUN NameRUN BASEA label for this simulation run. Use multiple RUN statements for scenario analysis.
Time UnitU DT=yearsThe unit of the time step (e.g. days, years, hours). Used for rate-unit inference.
Integration MethodChoose between Euler (1st order) and Runge-Kutta (3rd order). Euler is fast and simple. Runge-Kutta uses adaptive step sizes for higher accuracy.
REL_ERRC REL_ERR=0.01Relative error tolerance for the RK3 solver. The solver adjusts its internal step size to keep the local error below this fraction of the variable value. Typical: 0.001–0.05.
ABS_ERRC ABS_ERR=0.001Absolute error tolerance for the RK3 solver. Prevents overly tiny steps when variable values are near zero. Typical: 0.0001–0.01.

Euler vs. Runge-Kutta Integration

The Euler method (1st order) computes the next value using only the current rate: LEVEL.K = LEVEL.J + DT * RATE.JK. It is simple and fast but can accumulate error, especially with large DT values or rapidly changing rates.

The Runge-Kutta method (3rd order, Bogacki–Shampine variant) evaluates the rates at multiple sub-points within each DT step and compares a 2nd-order and 3rd-order estimate to gauge accuracy. If the estimated error exceeds your tolerances, the solver automatically shrinks the internal step size; if accuracy is easily met, it increases the step. This adaptive approach gives you higher accuracy without manually tuning DT.

When to use RK3: Models with stiff dynamics, exponential growth, or highly non-linear feedback loops benefit from RK3. If your Euler results change significantly when you halve DT, that’s a sign the model would benefit from adaptive integration.

When Euler is fine: Simple models with smooth, slowly changing rates. Euler is faster per time step and easier to reason about.

Bidirectional Sync

All settings sync both ways with the editor:

  • Change a value in the settings window → the corresponding code line is updated in the editor.
  • Edit SPEC, RUN, C REL_ERR=, or U DT= lines directly in the editor → the settings window reflects them when reopened.

Keyboard Shortcuts

ShortcutAction
Ctrl+ZUndo the last editor change.
Ctrl+Y or Ctrl+Shift+ZRedo the last undone change.
Ctrl+EnterRun the model.
Ctrl+NNew model.
Ctrl+OOpen model file.
Ctrl+SSave model (quick save if already saved, otherwise Save As).
Ctrl+Shift+SSave As — save with a new name.
EscapeDeselect, close properties panel, or exit draw mode.
Shift + DragQuick wire-draw from one node to another.
Mouse WheelZoom in/out centered on cursor.

Tips

  • Organize left-to-right: Place levels (stocks) in the center, rates (flows) on either side, and auxiliaries/constants around the periphery.
  • Hide constants: Constants often clutter the view. Hide them and rely on the formula text to know their values.
  • Use ghosts liberally: If a wire crosses more than a few nodes, a ghost is usually cleaner.
  • Bend wires: Drag wires into arcs to avoid crossing through unrelated nodes.
  • Table chart: Drag points on the chart for rough shaping, then fine-tune exact values in the data grid below.
  • Fit View: If you lose track of your diagram, click Fit View or zoom out with the scroll wheel.
❓ S.I.M.P.L.E. Language Reference

S.I.M.P.L.E. Language Reference

S.I.M.P.L.E. (Simulation of Industrial Management Problems with Lots of Equations) is a system dynamics modeling language based on DYNAMO 6. A model consists of equations that describe how variables change over time, organized by line prefixes (modes). This implementation supports macros, arrays, adaptive Runge-Kutta integration, and the ** exponentiation operator.

Statement Types (Line Prefixes)

PrefixNameDescriptionExample
*TitleModel title (first line)* MY EPIDEMIC MODEL
NOTEComment / AnnotationComment ignored by interpreter. Also used for diagram annotations (NOTE :n1: text) and layout persistence (NOTE :LAYOUT: ...).NOTE This is a comment
LLevelStock / accumulator — integrates flows over timeL POP.K=POP.J+DT*(BIRTH.JK-DEATH.JK)
RRateFlow equation — determines rate of changeR BIRTH.KL=POP.K*BR
AAuxiliaryHelper variable computed each time stepA RATIO.K=SICK.K/TOTAL
SSupplementaryOutput-only variable (not used in other equations)S OUTPUT.K=POP.K*1000
CConstantFixed value for the entire simulationC BR=0.03
NInitialStarting value for a levelN POP=1000
TTableLookup table data (values separated by /). Also used for array constants — values that apply across array elements (e.g., T AGDLY=15/25/1E30 gives one value per element). Use T instead of C whenever a constant has multiple values for an array.T MYTAB=0/2.8/5.5/8/9.5/10
XContinuationContinues the previous line (for long equations)X +RECOV.JK)
UUnitsUnits annotation for dimensional analysisU POP=persons,BR=persons/year
FORArray IndexDefines an array index variable with range and optional element namesFOR AGE=1,4=YOUTH,YADLT,MDLAG,OLDST
IInteger ConstantDefines integer constants for array subscriptsI NAGES=4/YOUTH=1/YADLT=2
MACROMacro StartBegin a reusable equation templateMACRO DELAY1(IN,DEL)
MENDMacro EndCloses a MACRO definitionMEND
INTRNMacro InternalsDeclares internal (local) variables inside a macroINTRN LV,RT
SPECSpecificationSimulation parametersSPEC DT=0.25,LENGTH=50,PRTPER=5,PLTPER=0.5
PRINTPrintVariables to include in print outputPRINT POP,BIRTH,DEATH
PLOTPlotVariables to plot with symbol and Y-axis scale. The (lo,hi) sets the Y-axis range for that group — use separate / groups with different scales when plotting variables of very different magnitudes (e.g., a level in the thousands and a rate below 100) so each is normalized and visible.PLOT POP=P(0,5000)/BIRTH=B(0,100)
RUNRunExecute the model with a given nameRUN BASELINE
EDITEditModify a previously run model and re-runEDIT BASELINE

Variable Indexing (Time Notation)

S.I.M.P.L.E. uses index suffixes to indicate when a variable is evaluated:

IndexMeaningUsed In
.KCurrent time step ("now")Levels, Auxiliaries (left & right side)
.JPrevious time step ("last")Levels (right side only)
.KLRate from current to nextRates (left side)
.JKRate from previous to currentRates (right side of level equations)

Constants and initials have no index suffix.

Level Equation Pattern

L     STOCK.K = STOCK.J + DT * (INFLOW.JK - OUTFLOW.JK)

This reads: "the stock now = the stock before + time_step × (inflow − outflow)"

Operators

OperatorDescriptionExample
+AdditionA+B
-Subtraction (also unary minus)A-B
*MultiplicationA*B
/DivisionA/B
**Exponentiation (power)X**2 — X squared

Note: Division precedence follows DYNAMO convention — A/B+C is interpreted as (A/B)+C, not A/(B+C). Use parentheses to be explicit.

Simulation Parameters (SPEC)

ParameterDescriptionDefault
DTTime step size (upper bound for adaptive integration)0.1
LENGTHTotal simulation time10
PRTPERPrint output period (0 = every step)0
PLTPERPlot output period (0 = every step)0
REL_ERRRelative error tolerance for adaptive RK3 integration (e.g. 0.01 = 1%)0.01
ABS_ERRAbsolute error tolerance for adaptive RK3 integration0.001

Set these via SPEC or as individual C constants. You can also configure them from the Simulation → Settings dialog, which includes an Integration Method dropdown to switch between Euler and Runge-Kutta.

When REL_ERR is set (or Runge-Kutta is selected in the settings), the simulation uses 3rd-order Runge-Kutta adaptive integration (Bogacki–Shampine variant). This automatically adjusts the step size within each DT for higher accuracy. Otherwise, standard Euler integration is used. See Diagram Help → Simulation Settings for a detailed guide.

Units & Dimensional Analysis (U)

The U statement assigns measurement units to variables. The editor performs real-time dimensional analysis — unit mismatches are flagged with red wavy underlines as you type.

U     POP=persons,BR=persons/year,DT=years

Multiple variables can share one U line (comma-separated), or you can use separate U lines. Units can also be edited per-node in the diagram properties panel.

What is checked:

  • Left-hand side vs. right-hand side unit consistency in each equation.
  • Addition and subtraction operands must have compatible units.
  • Rate units are automatically inferred from their associated level and DT.

Built-in Functions

Math Functions

FunctionDescriptionExample
SQRT(X)Square rootA Y.K=SQRT(X.K)
SIN(X)Sine (radians)A Y.K=SIN(TIME.K)
COS(X)Cosine (radians)A Y.K=COS(TIME.K)
EXP(X)Exponential (e^x)A Y.K=EXP(-0.1*TIME.K)
LOG(X)Natural logarithm (base e)A Y.K=LOG(X.K)
LOGN(X)Natural logarithm (alias for LOG)A Y.K=LOGN(X.K)
ABS(X)Absolute valueA Y.K=ABS(X.K)
MAX(X,Y)Maximum of two valuesA Z.K=MAX(A.K,B.K)
MIN(X,Y)Minimum of two valuesA Z.K=MIN(A.K,B.K)

Conditional Functions

FunctionDescriptionReturns
CLIP(A,B,X,Y)If X ≥ Y return A, else BA or B
SWITCH(A,B,X)If X = 0 return A, else BA or B
FIFZE(A,B,X)If X = 0 return A, else BA or B
FIFGE(A,B,X)If X ≥ 0 return A, else BA or B

Input / Test Functions

FunctionDescriptionExample
STEP(H,T)Returns H when TIME ≥ T, else 0R IN.KL=STEP(100,10)
RAMP(S,T)Returns S×(TIME-T) when TIME ≥ T, else 0R IN.KL=RAMP(5,10)
PULSE(H,W,T,P)Pulse of height H, width W, first at T, repeating every P (DYNAMO IV format)R IN.KL=PULSE(50,1,10,20)
NOISE()Random value in [-0.5, 0.5]A N.K=NOISE()
NORMRN(M,S)Normal random number with mean M and standard deviation SA N.K=NORMRN(0,1)
SAMPLE(X)Sample and hold a valueA S.K=SAMPLE(X.K)

Table Lookup Functions

FunctionDescription
TABLE(name,X,lo,hi,step)Linear interpolation; clamps outside range
TABHL(name,X,lo,hi,step)Same as TABLE (alias)
TABXT(name,X,lo,hi,step)Linear extrapolation outside range
TABPL(name,X,lo,hi,step)Polynomial interpolation inside range

Usage: Define a table with T, then reference it:

T     MYTAB=0/10/30/50/40/20
A     Y.K=TABLE(MYTAB,X.K,0,50,10)

This looks up X.K in MYTAB over the range 0–50 with step 10.

Delay & Smoothing Functions

FunctionDescriptionExample
DELAY1(rate.JK,D)First-order exponential delay of D time unitsR OUT.KL=DELAY1(IN.JK,5)
DELAY3(rate.JK,D)Third-order exponential delay (smoother)R OUT.KL=DELAY3(IN.JK,5)
DELAYP(rate.JK,D)Pipeline (fixed) delay — 6-stage boxcar train preserving input shape delayed by DR OUT.KL=DELAYP(IN.JK,5)
SMOOTH(var.K,D)Exponential smoothing with delay DA AVG.K=SMOOTH(X.K,10)
DLINF3(level.K,D)Third-order information delayA INFO.K=DLINF3(DATA.K,5)

Array Functions

FunctionDescriptionExample
SUM(A(*))Sum all elements of array AA TOT.K=SUM(POP.K(*))
SUMV(A(*),lo,hi)Sum elements of A from index lo to hiA SUB.K=SUMV(POP.K(*),2,5)
PRDV(A(*),lo,hi)Product of elements of A from lo to hiA PRD.K=PRDV(FACT.K(*),1,N)
SCLPRD(A(*),B(*),lo,hi)Scalar (dot) product of two arrays from lo to hiA DOT.K=SCLPRD(X.K(*),Y.K(*),1,N)
SHIFTL(A(*),n,lo,hi)Shift array left by n positionsA SH.K=SHIFTL(X.K(*),1,1,N)
SHIFTC(A(*),n,lo,hi)Circular shift of array by n positionsA SH.K=SHIFTC(X.K(*),1,1,N)

Macros (Reusable Equation Templates)

A macro is a copy-paste template that the computer fills in for you. You define a pattern of equations once, then stamp it out as many times as you need with different inputs.

Why Use Macros?

Suppose you need to smooth three different variables. Without macros you’d write the same three equations (Level + Init + Rate) three times — 9 lines of near-identical code. With a macro, you write the pattern once and call it in one line each time.

Anatomy of a Macro

MACRO MYSMOOTH(INPUT,DELAY)
INTRN RT
L     MYSMOOTH.K=MYSMOOTH.J+DT*RT.JK
N     MYSMOOTH=INPUT
R     RT.KL=(INPUT.K-MYSMOOTH.K)/DELAY
MEND
LineWhat It Does
MACRO MYSMOOTH(INPUT,DELAY)Declares a macro named MYSMOOTH with two dummy arguments: INPUT and DELAY. These are placeholders — they can be any name you choose.
INTRN RTLists internal variables — helpers that are private to each expansion. Each call gets its own unique version (e.g., _M1_RT, _M2_RT) so they don’t collide.
L … / N … / R …The body equations — standard DYNAMO equations that use the dummy arguments. The macro name (MYSMOOTH) is automatically the output variable.
MENDEnd of the macro definition.

Calling a Macro

Use the macro name like a function, passing real variables and constants in place of the dummy arguments:

A     SAVG.K=MYSMOOTH(SALES.K,4)
A     PAVG.K=MYSMOOTH(PRICE.K,8)
A     CAVG.K=MYSMOOTH(COST.K,6)

Each call triggers a find-and-replace behind the scenes:

DummyCall 1Call 2Call 3
INPUTSALESPRICECOST
DELAY486
MYSMOOTH (output)SAVG_MO1PAVG_MO2CAVG_MO3
RT (internal)_M1_RT_M2_RT_M3_RT

You never see these expanded equations — the interpreter generates them automatically.

Rules

  • Dummy arguments (INPUT, DELAY) are just placeholder names. They are not real variables — they get replaced before any equations run. Don’t give them time suffixes like .K in the MACRO header.
  • Internal variables listed on INTRN get unique names per call. Any helper variable in the body that isn’t a dummy argument or the macro name should be declared INTRN.
  • The macro name (e.g., MYSMOOTH) is the output. It automatically becomes a uniquely-named variable in each expansion. Don’t list it on INTRN.
  • Inside the body, use standard equations (L, R, A, N, C, S, T) with correct DYNAMO time notation (.K, .J, .JK, .KL).
  • When calling, time suffixes on arguments are stripped automatically. MYSMOOTH(SALES.K,4) and MYSMOOTH(SALES,4) both work the same way.
  • Macros must be defined before they are called (place them at the top of your model).

Arrays (Subscripted Variables)

Arrays let you define families of similar equations indexed by one or more subscripts. Use FOR to define index ranges and I for integer constants.

Defining Arrays

I     NAGES=4
FOR   AGE=1,NAGES=YOUTH,YADLT,MDLAG,OLDST

This defines a FOR variable AGE ranging from 1 to 4, with named aliases.

Using Arrays in Equations

L     POP.K(AGE)=POP.J(AGE)+DT*(BIRTH.JK(AGE)-DEATH.JK(AGE))
N     POP(AGE)=INITPOP(AGE)
T     INITPOP(*)=100/200/150/80

The interpreter expands AGE over its full range, generating one equation per element (e.g. POP_1, POP_2, POP_3, POP_4). Subscripts are flattened to underscore notation internally.

Array Subscript Rules

  • Subscripts can be FOR variables, I constants, or literal integers.
  • Simple arithmetic in subscripts is supported: POP(AGE-1).
  • Use * for the wildcard subscript on table data: T TAB(*)=...
  • Maximum 3 dimensions, subscript values from 1 to 999.

DYNAMO IV: Adaptive Integration

When REL_ERR is set (e.g. C REL_ERR=0.01), the simulator uses 3rd-order Runge-Kutta adaptive step-size integration instead of Euler. This automatically reduces DT where needed for accuracy and restores it when possible.

ParameterDescription
REL_ERRRelative error tolerance per level (default 0.01 = 1%)
ABS_ERRAbsolute error tolerance for all levels (default 0.001). Used when levels approach zero.

Total tolerable error per step = REL_ERR × |level| + ABS_ERR

Stiffness: If the solver must reduce DT excessively, it reports CAUSING STIFFNESS AT TIME = and STIFFNESS ENDED AT TIME =. If the error tolerance forces DT too small, a fatal error is reported.

EDIT: Modifying a Previous Run

Use EDIT to take a previously run model, change or add equations, then run again:

RUN   BASELINE
NOTE  Now modify and re-run:
EDIT  BASELINE
C     BR=0.05
RUN   SCENARIO2

Error Messages

The interpreter produces DYNAMO-standard error and warning messages:

CategoryExample Messages
MathSQRT OF A NEGATIVE NUMBER, LOG OF A NEGATIVE NUMBER, EXP ARGUMENT TOO LARGE, TRIED TO DIVIDE BY ZERO, EXPONENT OVERFLOW
SyntaxNO =. LINE IGNORED, TOO MANY =, LEFT OF = IMPROPER, TOO FEW ), TOO MANY ), MISPLACED TIMESCRIPT
NamesX NOT DEFINED, X DEFINED PREVIOUSLY, X NOT USED, X REQUIRES INITIAL VALUE
TablesABOVE/BELOW RANGE OF TABLE (AT TIME), TOO FEW/MANY VALUES IN TABLE
MacrosNO MEND CARD, WRONG NUMBER OF ARGUMENTS IN CALL TO MACRO
ArraysERRONEOUS FOR STATEMENT, SUBSCRIPT MUST BE > 0, RANGE IMPROPER IN SUMV/PRDV
ModelSIMULTANEOUS EQNS IN N/A EQNS, INCONSISTENT FIRST VALUES, NO OR INCOMPLETE SPEC CARD
IntegrationCAUSING STIFFNESS AT TIME =, ERROR TOLERANCE FORCES DT TOO SMALL, EXTENT OF DENOMINATOR AMBIGUOUS

Complete Example

*     SIMPLE EPIDEMIC MODEL
L     SUSC.K=SUSC.J+DT*(-INF.JK)
N     SUSC=988
R     INF.KL=SICK.K*CNTCTS.K*FRSICK
C     FRSICK=0.05
L     SICK.K=SICK.J+DT*(INF.JK-CURE.JK)
N     SICK=2
A     CNTCTS.K=TABLE(TABCON,SUSC.K/TOTAL,0,1,0.2)
T     TABCON=0/2.8/5.5/8/9.5/10
N     TOTAL=SUSC+SICK+RECOV
R     CURE.KL=SICK.K/DUR
C     DUR=10
L     RECOV.K=RECOV.J+DT*CURE.JK
N     RECOV=10
U     SUSC=persons,SICK=persons,RECOV=persons,DT=days
U     DUR=days,FRSICK=1/days
SPEC  DT=0.25,LENGTH=50,PRTPER=5,PLTPER=0.5
PRINT SUSC,SICK,RECOV,INF,CURE
RUN   SIMPLE

Array Example

*     AGE-COHORT POPULATION MODEL
I     NAGES=3
FOR   AGE=1,NAGES=YOUNG,ADULT,OLD
L     POP.K(AGE)=POP.J(AGE)+DT*(BIN.JK(AGE)-BOUT.JK(AGE))
N     POP(1)=500
N     POP(2)=300
N     POP(3)=200
R     BIN.KL(1)=BRTHRT*POP.K()
R     BIN.KL(2)=POP.K(1)/AGDLY(1)
R     BIN.KL(3)=POP.K(2)/AGDLY(2)
R     BOUT.KL(AGE)=(POP.K(AGE)/AGDLY(AGE))+(DTHRT(AGE)*POP.K(AGE))
C     BRTHRT=0.03
T     AGDLY=15/25/1E30
T     DTHRT=.002/.005/.02
A     TOTAL.K=SUM(POP.K)
SPEC  DT=1/LENGTH=100/PRTPER=1/PLTPER=1
PLOT  POP.K(1)=Y,POP.K(2)=A,POP.K(3)=O/TOTAL.K=T
PRINT TOTAL
RUN   COHORT

This model tracks three age cohorts (YOUNG, ADULT, OLD) as array elements. BIN (births in) has per-element equations — newborns enter the youngest cohort, while older cohorts receive population from the previous age group. BOUT (births out) uses a shared FOR-parameterized equation with age-specific death rates from a table lookup. SUM(POP.K) totals all cohorts.

Note: AGDLY and DTHRT are constants that vary across array elements, so they use T (table) lines instead of C. In DYNAMO, C defines a single scalar value, while T can hold multiple slash-separated values — one per array element. Use T whenever a constant needs a different value for each element of an array.

Macro Example

This complete model defines a custom smoothing macro and uses it to smooth incoming orders for a simple inventory system. Paste it into the editor and press Ctrl+Enter to run.

*     INVENTORY MODEL WITH CUSTOM SMOOTH MACRO
*
*     ---- Define the macro (template) ----
*     MYSMOOTH smooths a signal over a time delay.
*     INPUT = the signal to smooth (dummy argument)
*     DELAY = averaging time in time units (dummy argument)
*     RT    = internal rate variable (private to each call)
MACRO MYSMOOTH(INPUT,DELAY)
INTRN RT
L     MYSMOOTH.K=MYSMOOTH.J+DT*RT.JK
N     MYSMOOTH=INPUT
R     RT.KL=(INPUT.K-MYSMOOTH.K)/DELAY
MEND
*
*     ---- Main model ----
*     Inventory rises with production and falls with shipments.
*     Production follows smoothed demand (not raw orders).
L     INV.K=INV.J+DT*(PROD.JK-SHIP.JK)
N     INV=400
R     PROD.KL=DPROD.K
R     SHIP.KL=ORDERS.K
*     Call the macro: smooth ORDERS over ADJT time units
A     DPROD.K=MYSMOOTH(ORDERS.K,ADJT)
*     Orders jump from 200 to 300 at time 10
A     ORDERS.K=200+STEP(100,10)
C     ADJT=5
SPEC  DT=0.5,LENGTH=50,PRTPER=1,PLTPER=1
PLOT  INV=I,ORDERS=O,DPROD=D
PRINT INV,ORDERS,DPROD,SHIP
RUN   MACRO TEST

What happens: At time 10, orders jump instantly from 200 to 300. But production (DPROD) ramps up gradually over ~5 time units because the macro smooths the step change. Shipments respond immediately, so inventory dips temporarily before recovering. You’ll see the lag clearly on the plot.

Editor Features

FeatureDescription
Syntax highlightingKeywords, variable names, comments, and units are color-coded. Recognizes all DYNAMO 6 statement types including FOR, I, MACRO, MEND, INTRN.
AutocompleteAs you type, a popup suggests variable names, functions (including array functions), and keywords. Use arrow keys to navigate, Enter to accept, Escape to dismiss.
Auto-uppercaseAll text is automatically uppercased (S.I.M.P.L.E. convention).
Real-time error checkingSyntax errors, subscript mismatches, undefined variables, and unit inconsistencies are flagged with red wavy underlines as you type. Hover over an error line to see the message.
Error badgeThe ⚠ N errors badge in the toolbar shows the total error count. Click it to see all errors listed in the output log.
Line/Col indicatorBottom-right of the toolbar shows current cursor position (Ln X, Col Y).

Application Features

FeatureDescription
File → New / Open / SaveCreate, load, and save .dynamo / .simple model files.
File → Export DiagramExport the diagram as SVG, PNG, or PDF.
File → Example ModelLoad a built-in example to get started quickly.
Edit → Undo / RedoUndo and redo editor changes. Uses a custom undo stack that tracks both typed edits and programmatic changes from the diagram (adding nodes, editing formulas, etc.). Also accessible via Ctrl+Z / Ctrl+Y and the Undo/Redo buttons on the diagram toolbar.
Insert menuAdd new Level, Rate, Auxiliary, Table, Constant, Plot, Print (Data), or Note elements.
Simulation → SettingsOpen the settings dialog to configure DT, LENGTH, PRTPER, PLTPER, RUN name, and time unit.
Simulation → Run ModelExecute the model (same as the ▶ Run button or Ctrl+Enter).
Theme toggleSwitch between light and dark modes.
Output LogClick the status bar to see compilation messages, warnings, and runtime output.
Split panelsDrag the divider between Editor and Diagram to resize. Collapse either panel with its toggle button.

Keyboard Shortcuts

ShortcutAction
Ctrl + EnterRun model
Ctrl + NNew model
Ctrl + OOpen model file
Ctrl + SSave model file
Ctrl + ZUndo
Ctrl + Y or Ctrl + Shift + ZRedo
TabInsert 6 spaces (S.I.M.P.L.E. column alignment)
EscapeClose popups, exit draw mode, deselect

Tips

  • Variable names are uppercase, up to 21 characters.
  • Equations must have no spaces in the formula (spaces in the prefix column are fine).
  • The prefix (L, R, etc.) must be followed by spaces, then the equation.
  • Use X (continuation) lines to split long equations across multiple lines.
  • Multiple constants can be on one line: C A=1,B=2,C=3
  • Use ** for exponentiation: X**2 means X squared.
  • DT should be less than double the smallest first-order delay for stability.
  • For adaptive integration, set C REL_ERR=0.01 to enable 3rd-order Runge-Kutta.
  • Level equations must follow the pattern: L.K = L.J + DT * (something).
  • All level variables require an N (initial value) equation.
  • Add U (unit) lines to catch dimensional errors — the editor flags mismatches in real time.
  • Use the Plot tab to visually inspect results — click variable chips to toggle them. The run dropdown only shows runs that have a PLOT statement.
  • Use the Data tab to see raw numbers or export as CSV. Only runs with a PRINT statement appear in the data table.
  • Use Note elements (Insert → Note or the diagram toolbar) to add text annotations directly on the diagram. Notes are stored as NOTE lines and are run-scoped.
  • The diagram and editor stay in sync — edit in whichever is most convenient.

🚀 Welcome to S.I.M.P.L.E. SD

Choose how to get started:

⚙ Model Settings
Element Properties

Running model...

This may take a moment for large models