Skip to content

Events, Schedules and States

In this tutorial the tank with its level controller becomes a test bench for the Dynamics Manager itself, in DWSIM's Classic UI: event sets with steps and ramps, stored flowsheet states as starting points, a level gauge with alarms, a cause-and-effect matrix that acts on an alarm, and the historian that makes ramps possible. None of it changes the process; all of it changes what a run can ask of the process.

What you will learn

  • The five parts of the Dynamics Manager and how a schedule ties them together
  • Step and ramp transitions, and why a ramp needs the historian and a reference event
  • How a gauge raises alarms, how a cause-and-effect matrix turns an alarm into an action, and how stored states make every run repeatable

Prerequisites

Process Overview

The tank of the previous tutorials, with its level controller LIC-01 (Kp 2, Ki 0.1, setpoint 1 m), plus:

  1. A Level Gauge LI-01 reading T-01 Liquid Level, range 0 to 2 m, alarms LL 0.2 m, L 0.5 m, H 1.3 m, HH 1.6 m
  2. An event set Ramp that raises the inlet from 10 to 15 kg/s over three minutes
  3. An event set Manual that puts LIC-01 in manual and then steps the inlet
  4. A cause-and-effect matrix CE1: when LI-01 raises its H alarm, LIC-01 goes back to automatic

Process Flow Diagram

graph LR
    IN["Inlet<br/>10 → 15 kg/s<br/>(ramp or step)"] --> V1["V-01"]
    V1 --> T["T-01"]
    T --> V2["V-02"]
    V2 --> OUT["Outlet"]
    T -. level .-> LIC["LIC-01"]
    LIC -. opening .-> V2
    T -. level .-> LI["LI-01<br/>(gauge)<br/>H 1.3 m"]
    LI -. H alarm .-> CE["CE1<br/>LIC-01 → auto"]
    CE -. ManualOverride = 0 .-> LIC

Key Design Parameters

Parameter Value Unit
Starting state Steady: level 1.000 m, V-02 28.8 %, inlet 10 kg/s -
Ramp event inlet 10 → 15 kg/s from 1 min to 4 min, linear kg/s
Step events LIC-01 ManualOverride = 1 at 5 s; inlet 15 kg/s at 1 min -
Gauge LI-01 range 0 to 2 m; LL 0.2, L 0.5, H 1.3, HH 1.6 m
Cause and effect LI-01 H alarm → LIC-01 ManualOverride = 0 -
Integrator 5 s step, 10 min -

Step-by-Step in the Classic UI

1. The Dynamics Manager in one look

Dynamics > Dynamics Manager has five tabs. Integrators say how to step (step size, duration, what to monitor). Event Sets say what changes and when. Cause-and-Effect Matrices say what happens when an alarm fires. Monitored Variables live inside each integrator. Schedules put one integrator, an optional event set, an optional matrix and an initial state together into a runnable case. Stored states are kept with Store Current (Flowsheet States group of the toolbar) and listed in the schedule's initial-state box.

2. A ramp

Event Sets: add Ramp with two events on Inlet Mass Flow:

  • start: at 00:01:00, value 10 kg/s, transition Step
  • ramp: at 00:04:00, value 15 kg/s, transition Linear, reference Previous event

Schedule Ramp: Int1, event set Ramp, initial state Steady. Run.

The inlet climbs in a straight line from 10 kg/s at 1 min to 15 kg/s at 4 min. The level never leaves 1.01 m: the controller follows a change this slow without a visible error, and V-02 opens smoothly from 28.8 % to 43.3 %. Compare with the step of the previous tutorial, which pushed the level to 1.062 m.

Why the ramp needs a reference and the historian

A linear transition draws a line from the value the property had at the reference event to the new value at the event's own time. The start event exists only to give the ramp a defined starting point and time; without it the ramp would start from whatever the historian recorded before the first event. The historian is the record of every property at every step (Dynamics Manager > Settings); leave it on, or ramps and any transition other than a step have nothing to read.

A ramp made of two events

3. A gauge with alarms

Drag a Level Gauge from the Object Palette (Indicators) and rename it LI-01. Open it: object T-01, property Liquid Level, units m, minimum 0, maximum 2. Tick the four alarms and set them to 0.2, 0.5, 1.3 and 1.6 m. Tick Show alarms. The gauge draws the level as a bar on the flowsheet and turns its alarm bands on as the level crosses them.

4. A cause-and-effect matrix

Cause-and-Effect Matrices: add CE1 with one item: indicator LI-01, alarm H, action on LIC-01 property ManualOverride, value 0. Read it as a sentence: when the level passes 1.3 m, the controller goes back to automatic.

5. Manual mode, a step, and the matrix

Event Sets: add Manual with LIC-01 ManualOverride = 1 at 00:00:05 and Inlet Mass Flow = 15 at 00:01:00. Schedule CE: Int1, event set Manual, matrix CE1, initial state Steady. Run.

With the controller in manual, V-02 stays at 29 % and the level climbs 0.26 m per minute after the step: 1.14 m at 1.5 min, 1.26 m at 2 min. It crosses 1.3 m shortly after 2 min; the gauge raises its H alarm, the matrix flips LIC-01 to automatic, and the controller, starting bumplessly from 29 %, opens V-02 to bring the level back down to 1.0 m over the following minutes. Without the matrix (run the same schedule without CE1) the level reaches the top of the tank at about 10 min.

The gauge in alarm and the controller back in automatic

6. Stored states as starting points

Every schedule of this and the previous tutorial starts from Steady. Store another state at the end of the Ramp run (level 1.0 m, inlet 15 kg/s, V-02 43 %) as HighFeed, and run Disturbance from it: the step to 15 kg/s no longer changes anything, because that is the state it starts from. A stored state holds every object, the controller's tuning and mode included; that is what makes runs repeatable, and it is also why a tuning change made in the editor is undone by a schedule that starts from a state stored before the change.

7. Results in the spreadsheet

View Results after each run writes the monitored variables to a spreadsheet tab, one column per variable, one row per step; the chart tool draws any column against time. Export the sheet to compare runs made with different event sets.

Results and Validation

Run Level, peak Level, final V-02, final Unit
Ramp 10 → 15 kg/s over 3 min 1.009 1.000 43.3 m, m, %
Step 10 → 15 kg/s (previous tutorial) 1.062 1.000 43.3 m, m, %
Manual + step, no matrix 2.0 (at 10 min) 2.0 29 m, m, %
Manual + step, with CE1 about 1.3, then back to 1.0 1.0 43 m, m, %

Expected results

The ramp shows how a slow change hides inside the loop's bandwidth: 1 cm of deviation against 6 cm for the step. The matrix shows an alarm doing operator's work: the level is caught at 1.3 m, well short of the 2 m overflow.

Understanding the Results

Events, states and matrices are the vocabulary of a dynamic study. An event set is a script of what the outside world does to the process; a stored state is where the script starts; the schedule binds them to an integrator. The same flowsheet can carry a dozen schedules, one per question: what if the feed ramps, what if the controller is in manual, what if the setpoint moves. Keeping the questions in schedules, and the answers in the spreadsheet tabs they produce, is what turns a simulation into a study that someone else can rerun.

The cause-and-effect matrix is the simplest safety layer: no dynamics of its own, just a table of alarm-to-action pairs read on every step. Real plants have interlocks of this shape by the hundred; the matrix is where a simulation says "and this is what the plant does when the operator does nothing".

What the FluentAPI script covers

The script below builds the ramp and stored-state runs and saves the flowsheet with the gauge and the matrix defined. Gauges compute their alarms at every step, before the matrix reads them, so the matrix acts in a headless run through the FluentAPI as it does from Integrator Controls.

Automating This Tutorial

Files in this repository

import os
import sys

import pythonnet
pythonnet.load("netfx")              # DWSIM is a .NET Framework application
import clr  # noqa: E402

DWSIM_BIN = os.environ.get("DWSIM_BIN")
if not DWSIM_BIN:
    raise SystemExit("Set DWSIM_BIN to the DWSIM installation folder before running.")
for sub in ("", "unitops", "ppacks", "extenders"):
    sys.path.append(os.path.join(DWSIM_BIN, sub))
clr.AddReference("DWSIM.Automation")
clr.AddReference("DWSIM.Automation.FluentAPI")
clr.AddReference("DWSIM.UnitOperations")
clr.AddReference("DWSIM.Interfaces")

from DWSIM.Automation.FluentAPI import Flowsheet, Q
from DWSIM.Automation.FluentAPI.Builders import IndicatorKind
from DWSIM.Interfaces.Enums import Dynamics as DynEnums

# start from the level-control flowsheet of the previous tutorial
fs = Flowsheet.Load("dynamic_tank_level_control.dwxmz")
fs.Dynamics.WithHistorian(True, 5000)

# fill to the setpoint and keep that state
fs.RunDynamics("Fill").Execute()
fs.Dynamics.StoreCurrentStateAs("Steady")

# a ramp: a step to the starting value, then a linear change referenced to it
(fs.Dynamics.DefineEventSet("Ramp")
   .AddStepChange("Inlet", "PROP_MS_2", 10.0, Q.Seconds(60.0), "kg/s", "start")
   .AddRamp("Inlet", "PROP_MS_2", 15.0, Q.Seconds(240.0), "kg/s", "ramp"))
fs.Dynamics.DefineSchedule("Ramp").WithIntegrator("Int1").WithEventSet("Ramp").WithInitialState("Steady").MakeCurrent()
r = fs.RunDynamics("Ramp").Execute()
print(f"ramp: level peak {r.GetSeries('level').Max:.3f} m, V-02 final {r.GetSeries('V-02 opening').Final:.1f} %")

# a gauge with alarms and a matrix that returns the controller to automatic on H
(fs.AddIndicator("LI-01", IndicatorKind.Level).Reads("T-01", "Liquid Level", "m")
   .WithRange(0.0, 2.0).WithAlarms(0.2, 0.5, 1.3, 1.6))
(fs.Dynamics.DefineCauseAndEffectMatrix("CE1").AddItem("high level returns LIC-01 to auto")
   .WhenAlarm("LI-01", DynEnums.DynamicsAlarmType.H).Then("LIC-01", "ManualOverride", 0.0, ""))
(fs.Dynamics.DefineEventSet("Manual")
   .AddStepChange("LIC-01", "ManualOverride", 1.0, Q.Seconds(5.0), "", "manual")
   .AddStepChange("Inlet", "PROP_MS_2", 15.0, Q.Seconds(60.0), "kg/s", "feed step"))
(fs.Dynamics.DefineSchedule("CE").WithIntegrator("Int1").WithEventSet("Manual")
   .WithCauseAndEffectMatrix("CE1").WithInitialState("Steady").MakeCurrent())

fs.Dynamics.Schedule("Fill").MakeCurrent()
fs.Save("dynamic_tank_events.dwxmz")   # open in DWSIM and run "CE" from Integrator Controls

Use the dwsim.dynamics.* tools to add event sets (step and linear transitions), store states, define the cause-and-effect matrix and the schedules; add the gauge with dwsim.unitop.add.

Output may vary

Results depend on the LLM's reasoning quality and tool-use accuracy. Always verify the simulation matches your intent before relying on the numbers.

Open the tank level-control flowsheet in DWSIM via the MCP server, run its "Fill"
schedule and store the state as "Steady". Then:

- Define an event set "Ramp" that steps the Inlet mass flow to 10 kg/s at 1 min and
  ramps it linearly to 15 kg/s at 4 min (reference: previous event); run a schedule
  from "Steady" with it and report the peak level and the final V-02 opening
- Add a level gauge LI-01 on T-01 (0 to 2 m, alarms 0.2 / 0.5 / 1.3 / 1.6 m) and a
  cause-and-effect matrix that sets LIC-01 ManualOverride to 0 on the H alarm
- Define an event set "Manual" (LIC-01 ManualOverride = 1 at 5 s, Inlet 15 kg/s at
  1 min) and a schedule "CE" from "Steady" with that event set and the matrix
- Save the flowsheet as dynamic_tank_events.dwxmz

Exercises

  1. Make the ramp ten times faster (from 1 min to 1 min 18 s). Where does the deviation land between the ramp's 1 cm and the step's 6 cm?
  2. Add a second item to CE1: on the LL alarm, set the Inlet mass flow to 20 kg/s. Run a schedule that puts LIC-01 in manual and opens V-02 to 80 % at 5 s. What happens?
  3. Store a state at the top of the Manual run (level near 2 m) and start the Disturbance schedule from it. How long does the controller take to drain the tank back to 1 m, and does V-02 saturate?

Further Reading

Selected references from the DWSIM technical bibliography.

  • D. E. Seborg, T. F. Edgar, D. A. Mellichamp & F. J. Doyle. (2016). Process Dynamics and Control. Wiley
  • IEC 61511. Functional safety: safety instrumented systems for the process industry sector.

Next Steps

In Reactors and Exchangers in Dynamics, the shipped CSTR, PFR and heat exchanger samples show what a reaction holdup and a wall thermal mass add to a dynamic run.