1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
|
.. _event_driven:
Event-Driven schemes
====================
General Principle
-----------------
The principle of the event-driven is based on the time-decomposition of the dynamics in modes, time-intervals where the dynamics is smooth, and discrete events, times where the dynamics are nonsmooth. From the numerical point of view, the event-driven scheme use the decomposition in time of the dynamics in order to
* detect and solve the non smooth dynamics at events with a reinitialization rule of the state,
* integrate the smooth dynamics between two events with any ODE solvers with root-findings and possibly bilateral constraints on the state.
Event Driven implementation
---------------------------
Integration of the smooth dynamics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Between events, the dynamics are integrated thanks to Lsodar algorithm and with the function EventDriven::integrate.
Considering two given functions f(x,t) and g(x,t), a call to::
integrate(tinit, tend, tout, iout)
results in the integration of the function f(x,t) between tinit and tend, and search for roots of the function g(x,t). If roots are found, integration stops, and last time is saved in tout.
The in-out parameter iout is an indicator that must be set to 1 at first call. If no root was found, it is equal to 2 if so to 3.
Thus for an EventDriven simulation:
* the dynamics of all the concerned DynamicalSystems is rewritten as :math:`\dot = f(x,t)`
* the relations are used to defined the g(x,t) functions
Once again the proper definition of f and g depends on the system type as described below.
Events
^^^^^^
In Siconos the object Event just handle a type (see below) and a long int which corresponds to the time of occurrence of the event. A process function is also defined, which action depends on the event type.
The possible types (derived classes) are:
* TimeDiscretisationEvent: event that corresponds to user-defined time discretisation points. These events are created and schedule when the EventDriven simulation is initialized. Process function call results in :
* update (compute) output for all the concerned Interactions
* save current values (DynamicalSystems states and Interactions input/output) in memory vectors. Last saved values become initial values for next integration.
* NonSmoothEvent: "points" where the dynamics are non smooth and which required a special treatment. These events are detected thanks to a roots-finding algorithm, and corresponds to violation of some given constraints (relation). The action of the process function is roughly (the full process depends on the system type and is described in \ref docSimuEDDetails):
* update (compute) output for all the concerned Interactions
* update the index sets
* formalize and solve one or more non-smooth problems
* save current values (DynamicalSystems states and Interactions input/output) in memory vectors. Last saved values become initial values for next integration.
The Events manager
^^^^^^^^^^^^^^^^^^
To handle all the events, a specific object is built: the EventsManager. It belongs to the EventDriven class and holds two eventsContainers (sets of Events):
- pastEvents: for all the Events that has already been treated
- unProcessedEvents: for the future events, already scheduled but not treated
We also denote "currentEvent" the last processed event, which corresponds to the initial point of the current integration, and "nextEvent" the event following "currentEvent".
The events manager is initialized with time-discretisation events, from the user time-discretisation. Then, each time a new event is detected (added by user or when a root is found during integration) it is scheduled in the manager.
The manager has also a \link EventsManager::processEvents processEvents \endlink function, which moves currentEvent to past events set, processes nextEvent and prepare the next step.
Other useful functions are:
- \link EventsManager::startingTime() startingTime \endlink, \link EventsManager::nextTime() nextTime \endlink
The Simulation process
----------------------
Thus, a general step of integration for EventDriven will looks like:
"While there are some events in the unProcessedEvents set, integrate the smooth dynamics between current and next event and then process with the behavior at event".
Or:
code-block:: c++
// Assume a NonSmoothDynamicalSystem nsds and
// a TimeDiscretisation td ...
SP::EventDriven s(new EventDriven(nsds, td));
// ...
// We get the events manager
SP::EventsManager eventsManager = s->eventsManager();
// while there are some events ...
while(eventsManager->hasNextEvent())
{
// integrate between current and next event
s->advanceToEvent();
// solve the non-smooth dynamics, if necessary ...
eventsManager->processEvents();
}
// Or in one step:
while(eventsManager->hasNextEvent())
{
s->computeOneStep();
}
.. _event_driven_lagrange:
Event Driven algorithm for Lagrangian systems
---------------------------------------------
At the time, the only available event-driven algorithm in Siconos is for Lagrangian dynamical systems, subjected to perfect unilateral constraints and with the Newton impact rules.
Because of the unilateral constraints, the evolution of the considered system may be non-smooth. Some jumps can occur in the velocity and the "acceleration" may not be defined everywhere. The generalized coordinates, assumed to be absolutely continuous are:
.. math::
q(t) = q(t_0) +\int_{t_0}^t v^+(t)dt \ with \ v = \dot q
We will index with "+" and "-" right and left values of the variable at discontinuity.
The equations of motion are written in terms of a measure differential equation:
.. math::
M(q)dv + F_{int}(t, q, v^+)dt=F_{ext}(t) + dr
r being the generalized force due the unilateral constraints.
Using the Lebesgue decomposition theorem and its variants, the differential measure dv and dr are decomposed in:
.. math::
dv = \gamma dt + (v^+-v^-)\sum_i\delta_{t_i} + dv_s \\
dr = fdt + \sum_ip_i\delta_{t_i}+dr_s
First term of the decomposition corresponds to the smooth part, with :math:`\gamma =\ddot q`, the acceleration in the usual sense. The second term corresponds to the behavior at times of discontinuities, ( :math:`\delta_{t_i}`: Dirac), and the last term, a singular measure, will be neglected.
Thanks to these decompositions, the non-smooth Dynamics can be split into "impact equations", that will correspond to the non-smooth events, and some "smooth Dynamics". These equations are completed by the constraints, formulated at different kinematics levels, as shown in the following paragraphs.
The impact equations
^^^^^^^^^^^^^^^^^^^^
The impact equations can be written at the time :math:`t_i` of discontinuities:
.. math::
M(q(t_i))(v^{+}(t_i)- v^{-}(t_i)) = p_i,
:math:`p_i` is like an impulsion.
This equation will be solved at the time of impact together with an impact law. That is for a Newton impact law
.. math::
M(q(t_i))(v^{+}(t_i)- v^{-}(t_i)) = p_i, \\
\dot y^{+}(t_i) = \nabla_q h(q(t_i)) v^{+}(t_i) \\
\dot y^{-}(t_i) = \nabla_q h(q(t_i)) v^{-}(t_i) \\
p_i = \nabla_q^T h(q(t_i)) P_{N,i}\\
0\leq \dot y^{+}(t_i)+ e \dot y^{-}(t_i) \perp P_{N,i} \geq 0
This problem can be reduced on the local unknowns :math:`\dot y^{+}(t_i),P_{N,i}` if the matrix :math:`M(q(t_i))` is assumed to be invertible, leading to the following Linear Complementarity Problem at time :math:`t_i` of discontinuities of v:
.. math::
\dot y^{+}(t_i) = \nabla_q h(q(t_i)) (M(q(t_i)))^{-1} \nabla_q^T h(q(t_i)) P_{N,i} + \dot y^{-}(t_i) \\
0\leq \dot y^{+}(t_i)+ e \dot y^{-}(t_i) \perp P_{N,i} \geq 0
Later this system will be identified as "LCP at velocity level".
The smooth Dynamics
^^^^^^^^^^^^^^^^^^^
The smooth dynamics which is valid almost everywhere for the Lebesgue measure :math:`dt` is governed by the following equation:
.. math::
M(q) \ddot q^+ + F_{int}(t, q, v^+)&= F_{ext}(t) + f^+ \quad (dt-a.e.)
where we assume that :math:`f^+=f^-=f\, (dt-a.e.)`.
The following smooth systems are then to be solved:
.. math::
M(q(t)) \ddot q^{+}(t) + F_{int}(t, q, v^+)= F_{ext}(t) + f^{+}(t)\\
y = h(q(t)) \\
f^+ = \nabla_q h(q(t))^T F^+(t) \\
0 \leq y \perp F^+(t) \geq 0
To solve these systems, at each time, i.e. to known the configuration after each events and to integrate it numerically, it is useful to express the complementarity laws at different kinematics level. We also introduce the pre-defined index sets (about index sets, see \ref docSimuIndexSets):\n
:math:`I_0` is the set of all the potential UnitaryRelations (UR).
:math:`I_1 = \{ ur_\alpha\in I_{0} , y_{\alpha} = 0 \}` (or if the UR is in :math:`I_1` then contact occurs).
:math:`I_2 = \{ ur_\alpha\in I_{1} , \dot y_{\alpha} = 0 \}` (or if the UR is in :math:`I_2`, contact remains, no take off).
This results in the new writing of the <b>Bilateral Smooth Dynamics</b>:
.. math::
M(q) \ddot q^{+} + F_{int}(t, q, v)= F_{ext} + \nabla_q h(q)^T F^+\\ \\
\ddot y^+ = \nabla_q h(q) \ddot q^+ + \dot{ \nabla_q h(q)} v^+ \\ \\
F^{+,\alpha} = 0, \quad \forall \alpha \in I_0-I_2 \\ \\
\ddot y^{+,\alpha} = 0 \quad \forall \alpha \in I_2
which can be reduced on variable :math:`\ddot y^+` and :math:`F^+`, if M(q) is invertible, when :math:`\alpha \in I_2`:
.. math::
\ddot y^{+,\alpha} = \nabla_q h(q) M^{-1}(q)(- F_{int}(t, q, v^+)+ F_{ext}(t) ) + \dot{ \nabla_q h(q)} v^+ +\nabla_q h(q) M^{-1} \nabla_q h(q(t))^T F^{+,\alpha}(t) \\ \\
0 \leq \ddot y^{+,\alpha} \perp F^{+,\alpha} \geq 0
Later this system will be identified as <b>"LCP at acceleration level"</b>.
The algorithm
-------------
Finally, the event-driven algorithm will be:
knowing the value of :math:`y, \dot y` and :math:`I_1, I_2` at the beginning of the time step :math:`[t_k, t_{k+1}]`:
-# <b> Integration of the Bilateral Smooth Dynamics </b> up to an event given by the root-finding of the following function :
.. math::
y^\alpha =0,\quad \forall \alpha \in I_0 - I_2 \\
or \\
F^{+,\alpha} = 0, \quad \forall \alpha \in I_2
This results in the computation of :math:`y, \dot y` at this new point and to an update of the index sets :math:`I_1` and :math:`I_2`.
-# if :math:`I_1 - I_2 \neq \emptyset` then Impacts occur:
- Formalize and solve the <b>"LCP at velocity level"</b>
- Update the index sets :math:`I_1` and :math:`I_2` and check that :math:`I_1 - I_2 =\emptyset`
endif
-# if :math:`I_2\neq \emptyset` then
- Formalize and solve the <b>"LCP at acceleration level"</b>
- for :math:`\alpha \in I_2` do
if :math:`\ddot y_{\alpha} >0, F_{\alpha} = 0` remove :math:`\alpha` from :math:`I_2` and :math:`I_1`
else if :math:`\ddot y_{\alpha} =0, F_{\alpha}=0` then undetermined case.
endif\n
endfor\n
endif\n
-# go to the next time step.
Implementation in Siconos
^^^^^^^^^^^^^^^^^^^^^^^^^
According to \ref doc_lagds, in Siconos, the Dynamics of Lagrangian systems is written as:
.. math::
M(q) \ddot q + fGyr(\dot q, q) + F_{Int}(\dot q , q , t) &= F_{Ext}(t) + p \\
Next,:math:`fGyr` term will be forget and considered as included in :math:`F_{Int}`.
And Lagrangian relations are (see \ref docRelationLag):
.. math::
y &= h(Q) \\
\dot y &= \nabla_q h(Q)\dot Q \\
P &= \nabla_q h(Q)^t\lambda
Q (resp. P) being a collection of all the q (resp. p) of the Dynamical Systems involved in the Interaction.
As we have seen in the previous section, the notion of kinematics level is really important. We introduce this in Siconos thanks to
"[i]" notation. More precisely, for each Unitary Relation, we define y[i] as the derivative number i of variable y, according to time.
In the same way, we denote :math:`\lambda[i]` the variable that is linked with y[i] through a Non-Smooth law (usually a complementarity).
Finally to each :math:`\lambda[i]` corresponds a p[i].
To make things clearer, let us rewrite the previous defined systems with Siconos notations:
- <b>Bilateral Smooth Dynamics</b>:
.. math::
M(q) \ddot q + F_{int}(t, q, \dot q)= F_{ext} + \nabla_q h(q)^T \lambda[2] \\ \\
y[2] = \nabla_q h(q) \ddot q + \dot{ \nabla_q h(q)} \dot q \\ \\
\lambda[2]_{\alpha} = 0, \quad \forall \alpha \in I_0-I_2 \\ \\
y[2]_{\alpha} = 0 \quad \forall \alpha \in I_2
with roots finding of:
.. math::
g(x,t) = y[0]_\alpha,\quad \forall \alpha \in I_0 - I_2 \\
or \\
g(x,t) = \lambda[2]_\alpha, \quad \forall \alpha \in I_2
- <b>"LCP at velocity level"</b>
.. math::
y[1]^{+} = \nabla_q h(q(t_i)) (M(q(t_i)))^{-1} \nabla_q^T h(q(t_i))\lambda[1] + y[1]^{-} \\
0\leq y[1]^{+} + e y[1]^{-} \perp \lambda[1] \geq 0
- <b>"LCP at acceleration level"</b>
.. math::
y[2]_{\alpha} = \nabla_q h(q) M^{-1}(q)(- F_{int}(t, q, \dot q)+ F_{ext}(t) ) + \dot{ \nabla_q h(q)} \dot q +\nabla_q h(q) M^{-1} \nabla_q h(q(t))^T \lambda[2]_{\alpha} \\ \\
0 \leq y[2]_{\alpha}\perp \lambda[2]_{\alpha} \geq 0
Then, to build an EventDriven simulation, it is necessary to define two OneStepNSProblems, one at velocity and one at acceleration level.
So here is a classical code for simulation construction::
EventDriven* s = new EventDriven(ball);
// -- Time discretisation --
TimeDiscretisation * t = new TimeDiscretisation(timeStep,s);
// -- OneStepIntegrators --
OneStepIntegrator * OSI = new Lsodar(setOfDS,s);
// -- OneStepNsProblem --
OneStepNSProblem * impact = new LCP(s, "impact",solverName,101, 0.0001,"max",0.6);
OneStepNSProblem * acceleration = new LCP(s, "acceleration",solverName,101, 0.0001,"max",0.6);
Finally, the algorithm described earlier is:
-# Integration of the Bilateral Smooth Dynamics:
To integrate these systems thanks to lsodar, we need to define f(x,t) and g(x,t).
To compute f(x,t), we:
- formalize and solve a "LCP at acceleration level" to compute :math:`(y[2],lambda[2])`
- collect and rewrite the Dynamics of all the Dynamical Systems as a first order system, including the result of the LCP computation.
The function g(x,t) is given by:
.. math::
g(x,t) &= y[0], \quad \forall \alpha \in I_0 - I_2 \\
\\
g(x,t) &= \lambda[2], \quad \forall \alpha \in I_2
Corresponding code::
s->advanceToEvent()
// This results in a call to Lsodar->integrate and to schedule of new non-smooth events if necessary
The next steps are done during call to eventsManager->processEvents(), but they will be detailed below.
-# Compute y[0] and y[1] and update the index sets::
simulation->updateOutput(0, 1);
simulation->updateIndexSets();
-# if :math:`I_1 - I_2 \neq \emptyset`, formalize and solve a LCP at velocity level::
simulation->computeOneStepNSProblem("impact");
-# compute p[1], post-impact velocity, y[1] and indexSet[2]::
simulation->update(1);
-# if :math:`I_2 \neq \emptyset`, formalize and solve a LCP at acceleration level, and update index sets with some conditions::
simulation->computeOneStepNSProblem("acceleration");
simulation->updateIndexSetsWithDoubleCondition();
-# next time step::
simulation->nextStep();
|