Talk:Event handling

From ASCEND
Jump to navigation Jump to search

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

  1. defining 'edge' events as opposed to 'region conditions'
  2. 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.

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.