Talk:Event handling: Difference between revisions
| Line 30: | Line 30: | ||
The better solution would allow sometime like the [[CONDITIONAL]] statement, as a way to declare ICP equations. That section would in general need to allow conditional syntax such as supported by [[CMSlv]]. | The better solution would allow sometime like the [[CONDITIONAL]] statement, as a way to declare ICP equations. That section would in general need to allow conditional syntax such as supported by [[CMSlv]]. | ||
---- | |||
Syntactic/semantic background to inform our design process: | |||
An underused feature in ascend is that equations, boundaries, and I think even whens | |||
all have *names* and *subatomic children(flags)*, which can be used. | |||
The current declarative language is focused entirely on declaring an algebraic mathematical description with no time or space dependence. All handling of these variations requires discretization over the *domain* of the independent variable by either the model statement itself (a boundary value formulation) or by the solver (initial value formulation). | |||
The ascend language cannot even *name* the state of all the variables in the model at a given value of the independent variable. I'm not particularly aware of *any* small modeling language which allows you to name the solution of the model at arbitrary times. Several quick-hack languages like gproms/modelica allow you to handle implicitly defined values near 'events'. A more general solution is highly desirable and with the cost of computer memory being essentially zero at this point, there is no reason (any longer) to exclude naming states in the modeling language. | |||
---- | |||
== Proposal 1: a quick hack == | == Proposal 1: a quick hack == | ||
Revision as of 20:04, 15 February 2012
Please add new comments below with a ==heading== and signed beneath using ~~~~. If responding to an earlier comment, prefix your comments with ":" so that they are indented, and sign as before.
REINIT and PRE
One basic implementation of boundary events would be to allow a REINIT statement in addition to the USE statement to exist inside WHEN..CASE. REINIT statements would be associated with a particular CASE, and whenever a CASE change occurred, it would trigger an ICP to be created and solved.
PRE could then be added to the language. PRE inside a 'normal' relation would trigger an error. PRE inside a REINIT statement would result in a callback to the solver, which would have to keep a copy of variable values before the current boundary.
REINIT x TO -0.9*pre(x);
This statement would set the new value of 'x' and perhaps remove 'x' from the initial value problem. The derivative of x would still need to be solved for, using the dynamic equations in the problem.
Jpye 10:55, 11 February 2012 (EST)
Initial condition problems
The major issues we have with event handling currently are
- defining 'edge' events as opposed to 'region conditions'
- flexibly declaring initial condition problems (ICPs)
Our current WHEN syntax defines region conditions pretty well. This means that a boundary is defined, and if the solver crosses that boundary, we have to change our equations, reinitialise the DAE system and then continue.
For 'edge' events, we don't necessarily want to change the equations in our system, we just want to be able to be able to reassign values to certain variables, such that instead of the default state-variable continuity being applied, we can create step changes and other effects.
We are currently missing in ASCEND the idea of ICPs in general, which is a precursor to the above. In DAEs, we have <math>n</math> state variables (variables plus derivatives) plus <math>m</math> algebraic equations. Normal integration time-stepping requires <math<n+m</math> equations. ICP solution requires <math>2n+m</math> equations, because we need to solve the initial derivatives as well as the state variables, plus all the algebraics.
In IDA, the ICP is currently solved by assuming the state variables are fixed, and using the DAE equations to solve the derivatives plus the algebraic variables.
More generally, we should be able to set ICPs both for the truly initial conditions, as well as for each time boundaries are crossed. We could use a SWITCH statement inside a METHOD to turn on and off equations in this cases as a first hack. This would require lots of inactive equations to be declared in the model, and in a method initcond we could prepare the initial condition problem, and in a method continue we could restore the DAE problem. Somewhere inside IDA, then, we would detect a boundary and RUN initcond, then run QRSlv, then run continue, the proceed with the integration.
The better solution would allow sometime like the CONDITIONAL statement, as a way to declare ICP equations. That section would in general need to allow conditional syntax such as supported by CMSlv.
Syntactic/semantic background to inform our design process:
An underused feature in ascend is that equations, boundaries, and I think even whens all have *names* and *subatomic children(flags)*, which can be used.
The current declarative language is focused entirely on declaring an algebraic mathematical description with no time or space dependence. All handling of these variations requires discretization over the *domain* of the independent variable by either the model statement itself (a boundary value formulation) or by the solver (initial value formulation).
The ascend language cannot even *name* the state of all the variables in the model at a given value of the independent variable. I'm not particularly aware of *any* small modeling language which allows you to name the solution of the model at arbitrary times. Several quick-hack languages like gproms/modelica allow you to handle implicitly defined values near 'events'. A more general solution is highly desirable and with the cost of computer memory being essentially zero at this point, there is no reason (any longer) to exclude naming states in the modeling language.
Proposal 1: a quick hack
1. Modify the WHEN statement so that a single RUN statement is allow in each CASE:
WHEN var CASE TRUE: RUN mymethod1; USE eq1; CASE FALSE: RUN mymethod2; USE eq2; END WHEN;
2. Modify IDA such that, after running methods named as above, run a general initcond method that would prepare the model for solving the initial condition problem (ICP).
3. Solve the initial problem using QRSlv or CMSlv (switchable as an IDA option).
4. Run a general continue method to restore the DAE problem, the proceed with IDA integration until the next boundary.
This approach is flawed because regions are really not the same as events; we should put the 'RUN' statement in the above inside some other kind of statement -- Proposal 4 below.
Proposal 2: a better approach
1. Modify the declarative syntax to support an INITIAL statement within the declarative section:
INITIAL (* here the missing 'n' equations can be added. if omitted, fall back to default IDA behaviour *) der(x) = 0; y = 5; (* also allow SWITCH statements here and maybe even WHEN and CONDITIONAL *) END INITIAL;
2. Add an ICP API to the the existing integrator API.
3. Modify the WHEN statement to support 'event' actions as well as 'region' behaviour. We would need to work out if the current WHEN statement is overly flexible; perhaps we need to split it somehow, c.f. Modelica 'if...then' as well as 'when' behaviour. Also note Modelica 'when...elsewhen' prioritisation.
WHEN y_is_zero CASE TRUE: (*...*) END WHEN;
3. Modify WHEN statement to support reinitialisation of state variables before the ICP is solved. The problem here is in making sure we can generate consistent ICPs. Do these reinitialisations replace INITIAL equations, or simple reassign values, independently of the ICP solution?
WHEN y_is_zero CASE TRUE: REINIT vel :== -pre(vel); END WHEN;
Need to understand whether we need equivalents of Modelica's 'when-equation' as well as this 'reinit' thing.
4. Add the 'pre' so that REINIT statemnts can access previous values of other variables. This would be some kind of callback to the Integrator.
Proposal 3: EVENT statement
We need to put the event handling separate to the WHEN statements. So for a bouncing ball model,
EVENT x == 0 REINIT xvel :== -pre(xvel); END EVENT;
The 'EVENT' statement needs to fire any time that the boolean expression was previously false, and now becomes true, i.e. a rising edge. So, what is the difference between the above and the following?
EVENT x >= 0 REINIT xvel :== -pre(xvel); END EVENT;
Not sure if there is a difference? Need to clarify.
Proposal 4: EVENT statement with RUN
This is a modification of Proposal 1.
EVENT x == 0 RUN mybouncemethod; END EVENT;
We could implement this without having to first add support for definition of ICPs, which Proposal 3 definitely requires. Hence this is a quick hack that would let us keep working on the solver algorithms, and let the language features catch up afterwards.