The EVENT statement in ASCEND is used to declare named events in a dynamic system model. The event is triggered by an inequality going from being false to being true. This is part of our work to support integration of conditional models, and was implemented in ASCEND by Ksenija. The syntax is
event_name: EVENT(bool1) CASE TRUE: USE rel1; CASE FALSE: USE rel2; OTHERWISE: USE rel3; END EVENT;
The boolean variable bool1 would be defined using our normal conditional modelling syntax. Normally, a CONDITIONAL statement is required to express the condition as an inequality with real-valued variables, and then optionally there can be some boolean logic, and then a single boolean variable is used to trigger the event.
The CASE TRUE applies when the value of bool1 changes from FALSE to TRUE.
The CASE FALSE case applies when the value of bool1 changes from TRUE to FALSE.
The OTHERWISE case requires some careful explanation. Any relations listed here are excluded from the system before solving the boundary problem.
How events are handled
- A change in a boolean variable associated with an EVENT is detected by our solver (at present: IDA)
- Any relations named by USE statements in the OTHERWISE clause of the EVENT are removed from the system model (de-activated).
- Any relations named by USE statements in the active CASE are added to the system model (activated).
- Any METHOD that belongs in the same model as the EVENT and which carries the same name as the event (event_name in the above example is run. Normally these methods are used to FIX/FREE variables to assist in the solution of the boundary equations included via the USE statements in the EVENT.
- The QRSlv solver is run on the model, in order to solve the EVENT equations. Currently, the whole system model is solved by QRSlv in this way. Perhaps there is a faster/better way to do this with a reduced problem being passed to QRSlv.
- Any METHOD carrying the name event_name_end is run. This would normally allow the model to be restored to its former condition, to allow integration to continue.
Special 'previous value' variables can be declared on an as-needed basis. These 'pre(x)' variables must be explicitly declared before they will be allowed to exist. This is done using the PREVIOUS statement. After being declared, event equations can be used that refer to the declared variable.
(* 'bouncing' of a ball: the velocity reverses *) PREVIOUS v; rel1: v = -pre(v)*0.9;
A 'pre(x)' variable will always be fixed, and the solver will only bother to change its value at the boundaries. If the user tries to FIX/FREE/assign a value to a 'pre(x)' variable, the changes will be ignored and lost as soon as IDA arrives at a boundary that it needs to solve.
The best starter example is the ksenija2:models/ksenija/bball_event3.a4c bouncing-ball model. It is complete and solves well.
Another nice easy example is the ksenija2:models/ksenija/thermostat.a4c thermostat model.
Note that currently the required solver code to run these models is only present in the ksenija2: branch of ASCEND; we haven't yet included in the trunk code.
For more detail see ksenija2:doc/howto-events.lyx (in LyX format)