-
Notifications
You must be signed in to change notification settings - Fork 41
/
synchronous.tex
1520 lines (1327 loc) · 77 KB
/
synchronous.tex
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
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\chapter{Synchronous Language Elements}\label{synchronous-language-elements}
This chapter defines synchronous
behavior suited for implementation of control systems.
The synchronous behavior relies on an additional kind of discrete-time
variables and equations, as well as an additional kind of when-clause.
The benefits of synchronous behavior is that it allows a model to define large
sampled data systems in a safe way, so that the
translator can provide good diagnostics in case of a modeling error.
The following small example shows the most important elements:
\begin{figure}[H]
\begin{center}
\includegraphics{plantmodel}
\end{center}
\caption{A continuous plant and a sampled data controller connected together with sample and (zero-order) hold elements.}
\end{figure}
\begin{itemize}
\item
A periodic clock is defined with \lstinline!Clock(3)!. The argument
of \lstinline!Clock! defines the sampling interval (for details see \cref{clock-constructors}).
\item
Clocked variables (such as \lstinline!yd!, \lstinline!xd!, \lstinline!ud!) are associated uniquely
with a clock and can only be directly accessed when the associated
clock is active. Since all variables in a clocked equation must belong
to the same clock, clocking errors can be detected at compile time. If
variables from different clocks shall be used in an equation, explicit
cast operators must be used, such as \lstinline!sample! to convert
from continuous-time to clocked discrete-time or \lstinline!hold! to
convert from clocked discrete-time to continuous-time.
\item
A continuous-time variable is sampled at a clock tick with
\lstinline!sample!. The operator returns the value of the
continuous-time variable when the clock is active.
\item
When no argument is defined for \lstinline!Clock!, the clock is
deduced by clock inference.
\item
For a \lstinline!when!-clause with an associated clock, all
equations inside the \lstinline!when!-clause are clocked with the given
clock. All equations on an associated clock are treated together and
in the same way regardless of whether they are inside a
\lstinline!when!-clause or not. This means that automatic sampling and
hold of variables inside the \lstinline!when!-clause does not apply
(explicit sampling and hold is required) and that general equations
can be used in such when-clauses (this is not allowed for
\lstinline!when!-clauses with Boolean conditions, that require a variable
reference on the left-hand side of an equation).
\item
The \lstinline!when!-clause in the controller could also be removed
and the controller could just be defined by the equations:
\begin{lstlisting}[language=modelica]
/* Discrete controller */
E * xd = A * previous(xd) + B * yd;
ud = C * previous(xd) + D * yd;
\end{lstlisting}
\item
\lstinline!previous(xd)! returns the value of \lstinline!xd! at
the previous clock tick. At the first sample instant, the start value
of \lstinline!xd! is returned.
\item
A discrete-time signal (such as \lstinline!ud!) is converted to a continuous-time signal with \lstinline!hold!.
\item
If a variable belongs to a particular clock, then all other
equations where this variable is used, with the exception of as
argument to certain special operators, belong also to this clock, as
well as all variables that are used in these equations. This property
is used for \emph{clock inference} and allows to define an associated
clock only at a few places (above only in the sampler, whereas in the
discrete controller and the hold the sampling period is inferred).
\item
The approach in this chapter is based on the clock calculus and
inference system proposed by (Colaco and Pouzet 2003) and implemented
in Lucid Synchrone version 2 and 3 (Pouzet 2006). However, the
Modelica approach also uses multi-rate periodic clocks based on
rational arithmetic introduced by (Forget et.~al.\ 2008), as an
extension of the Lucid Synchrone semantics. These approaches belong to
the class of synchronous languages (Benveniste et.~al.\ 2002).
\end{itemize}
\section{Rationale for Clocked Semantics}\label{rationale-for-clocked-semantics}
\begin{nonnormative}
Periodically sampled control systems could also be defined with
standard when-clauses, see \cref{when-equations}, and the sample operator, see
\cref{event-related-operators-with-function-syntax}. For example:
\begin{lstlisting}[language=modelica]
when sample(0,3) then
xd = A*pre(xd) + B*y;
u = C*pre(xd) + D*y;
end when;
\end{lstlisting}
Equations in a when-clause with a Boolean condition have the
property that (a) variables on the left hand side of the equal sign are
assigned a value when the when-condition becomes true and otherwise hold
their value, (b) variables not assigned in the when-clause are directly
accessed (= automatic \lstinline!sample! semantics), and (c) the variables
assigned in the when-clause can be directly accessed outside of the
when-clause (= automatic \lstinline!hold! semantics).
Using standard when-clauses works well for individual simple sampled blocks,
but the synchronous approach
using clocks and clocked equations provide the following benefits
(especially for large sampled systems):
\begin{enumerate}
\item
Possibility to detect inconsistent sampling rate, since clock partitioning (see \cref{clock-partitioning}),
replaces the automatic sample and hold semantics. Examples:
\begin{enumerate}
\def\labelenumii{\alph{enumii}.}
\item
If when-clauses in different blocks should belong to the same
controller part, but by accident different when-conditions are
given, then this is accepted (no error is detected).
\item
If a sampled data library such as the
Modelica\_LinearSystems2.Contoller library is used, at every block
the sampling of the block has to be defined as integer multiple of a
base sampling rate. If several blocks should belong to the same
controller part, and different integer multiples are given, then the
translator has to accept this (no error is detected).
\end{enumerate}
Note: Clocked systems can mix different sampling rates
in well-defined ways when needed.
\item
Fewer initial conditions are needed, as only a subset of clocked
variables need initial conditions -- the clocked state variables (see \cref{clocked-state-variables}).
For a standard when-clause all variables
assigned in a when-clause must have an initial value
because they might be used, before they are assigned a value the first
time. As a result, all these variables are ``discrete-time states''
although in reality only a subset of them need an initial
value.
\item
More general equations can be used, compared to standard when-clauses that require
a restricted form of equations where the left hand side has to be a variable, in order
to identify the variables that are assigned in the when-clause.
This restriction can be circumvented for standard when-clauses, but is
absent for clocked equations and make it more convenient to define
nonlinear control algorithms.
\item
Clocked equations allow clock inference,
meaning that the sampling need only be given once for a sub-system.
For a standard when-clause the condition (sampling) must be explicitly
propagated to all blocks, which is tedious and error prone for large systems.
\item
Possible to use general continuous-time models in synchronous models
(e.g.\ some advanced controllers use an inverse model of a
plant in the feedforward path of the controller, see (Thümmel et.~al.\ 2005)).
This powerful feature of Modelica to use a nonlinear plant
model in a controller would require to export the continuous-time
model with an embedded integration method and then import it in an
environment where the rest of the controller is defined. With clocked
equations, clocked controllers with continuous-time models can be
directly defined in Modelica.
\item
Clocked equations are straightforward to optimize because they are
evaluated exactly once at each an event instant.
In contrast a standard when-clause with \lstinline!sample! conceptually
requires several evaluations of the model (in some cases tools
can optimize this to avoid unneeded evaluations).
The problem for the standard when-clause is that after \lstinline!v!
is changed, \lstinline!pre(v)! shall be updated and the model re-evaluated,
since the equations could depend on \lstinline!pre(v)!.
For clocked equations this iteration can be omitted
since \lstinline!previous(v)! can only occur in the clocked equations
that are only run the first event iterations.
\item
Clocked subsystems using arithmetic blocks are straightforward to optimize.
When a standard math-block (e.g.\ addition) is part of a clocked sub-system it is automatically
clocked and only evaluated when the clocked equations trigger.
For standard when-clauses one either needs a separate sampled math-block for each operation, or
it will conceputally be evaluated all the time.
However, tools may perform a similar optimization for standard when-clauses
and it is only relevant in large sampled systems.
\end{enumerate}
\end{nonnormative}
\section{Definitions}\label{definitions}
In this section various terms are defined.
\subsection{Clocks and Clocked Variables}\label{clocks-and-clocked-variables}
% We can't use \subfloat just yet due to LaTeXML issue (fixed on master 2020-06-27):
% https://github.com/brucemiller/LaTeXML/issues/1292 (marked as fixed as of commit 9f5c893b)
%\begin{figure}[tb]
% \centering
% \subfloat[A piecewise-constant variable.]{\includegraphics[width=5cm]{piecewise}\label{fig:piecewise-constant-variable}}
% \subfloat[A clock variable.]{\includegraphics[width=5cm]{clock}\label{fig:clock-variable}}
% \subfloat[A clocked variable.]{\includegraphics[width=5cm]{clocked}\label{fig:clocked-variable}}
% \caption{The different kinds of discrete-time variables. The \lstinline!hold! extrapolation of the clocked variable is illustrated with dashed green lines.}
%\end{figure}
In \cref{discrete-time-expressions} the term \emph{discrete-time} Modelica expression and in \cref{continuous-time-expressions} the term \emph{continuous-time} Modelica expression is defined.
In this chapter, two additional kinds of discrete-time expressions/variables are defined that are associated to clocks and are therefore called \firstuse{clocked discrete-time} expressions. The
different kinds of discrete-time variables in Modelica are defined below.
\begin{definition}[Piecewise-constant variable]
(See \cref{discrete-time-expressions}.) Variables $m(t)$ of base type \lstinline!Real!, \lstinline!Integer!, \lstinline!Boolean!, enumeration, and \lstinline!String! that are
\emph{constant} inside each interval $t_{i} \leq t < t_{i+1}$ (i.e., piecewise constant continuous-time variables). In other words, $m(t)$ changes
value only at events: $m(t) = m(t_{i})$, for $t_{i} \leq t < t_{i+1}$. Such variables depend continuously on time and they are discrete-time variables.
See \cref{fig:piecewise-constant-variable}.
\end{definition}
\begin{figure}[H]
\begin{center}
\includegraphics{piecewise-constant}
\end{center}
\caption{A piecewise-constant variable.}\label{fig:piecewise-constant-variable}
\end{figure}
\begin{definition}[Clock variable]
Clock variables $c(t_{i})$ are of base type \lstinline!Clock!. A clock is either defined by a constructor (such as \lstinline!Clock(3)!) that defines when the clock ticks (is active) at
a particular time instant, or it is defined with clock operators relatively to other clocks, see \cref{base-clock-conversion-operators}. See \cref{fig:clock-variable}.
\end{definition}
\begin{example}
Clock variables:
\begin{lstlisting}[language=modelica]
Clock c1 = Clock($\ldots$);
Clock c2 = c1;
Clock c3 = subSample(c2, 4);
\end{lstlisting}
\end{example}
\begin{figure}[H]
\begin{center}
\includegraphics{clock}
\end{center}
\caption{A clock variable. The value of a clock variable is not defined -- the plot marks only indicate \emph{when} the clock is active.}\label{fig:clock-variable}
\end{figure}
\begin{definition}[Clocked variable]
The elements of clocked variables $r(t_{i})$ are of base type \lstinline!Real!, \lstinline!Integer!, \lstinline!Boolean!, enumeration, \lstinline!String! that are associated uniquely with
a clock $c(t_{i})$. A clocked variable can only be directly accessed at the event instant where the associated clock is active. A constant and a parameter can always be used at a place
where a clocked variable is required.
At time instants where the associated clock is not active, the value of a clocked variable can be inquired by using an explicit cast operator, see below. In such a case \lstinline!hold! semantics is
used, in other words the value of the clocked variable from the last event instant is used. See \cref{fig:clocked-variable}.
\end{definition}
\begin{figure}[H]
\begin{center}
\includegraphics{clocked}
\end{center}
\caption{A clocked variable. The \lstinline!hold! extrapolation of the value at the last event instant is illustrated with dashed green lines.}\label{fig:clocked-variable}
\end{figure}
\subsection{Base-Clock and Sub-Clock Partitions}\label{base-clock-and-sub-clock-partitions}
There are two kinds of \firstuse{clock partitions}:
\begin{definition}[Base-clock partition]
A base-clock partition identifies a set of equations and a set of variables which must be executed together in one task. Different base-clock partitions can be associated to separate tasks for
asynchronous execution.
\end{definition}
\begin{definition}[Sub-clock partition]
A sub-clock partition identifies a subset of equations and a subset of variables of a base-clock partition which are partially synchronized with other sub-clock partitions of the same base-clock
partition, i.e., synchronized when the ticks of the respective clocks are simultaneous.
\end{definition}
\subsection{Argument Restrictions (Component Expression)}\label{argument-restrictions-component-expression}
The built-in operators (with function syntax) defined in the following
sections have partially restrictions on their input arguments that are
not present for Modelica functions. To define the restrictions, the
following term is used.
\begin{definition}[Component expression]\label{def:component-expression}
A Component Reference which is an Expression, i.e.\ does not refer to models or blocks with equations. It is an instance of a (a) base type, (b) derived type, (c) record, (d) an array of such an
instance (a-c), (e) one or more elements of such an array (d) defined by index expressions which are parameter expressions (see below), or (f) an element of records.
\begin{nonnormative}
The essential features are that one or several values are associated with the instance, that start values can be defined on these values, and that no equations are associated with the instance.
A Component Expression can be constant or can vary with time.
\end{nonnormative}
\end{definition}
In the following sections, when defining an operator with function calling syntax, there are some common restrictions being used for the input arguments (operands). For example, an input argument to the operator may be required to be a component expression (\cref{def:component-expression}) or parameter expression (\cref{variability-of-expressions}). To emphasize that there are no such restrictions, an input argument may be said to be just an expression.
\begin{nonnormative}
The reason for restricting an input argument to be a component expression is that the start value of the input argument is returned before the first tick of the clock of the input argument and this
is not possible for a general expression.
The reason for restricting an input argument to be a parameter expression is that the value of the input argument needs to be evaluated during translation, in order that clock analysis can be performed during translation.
\end{nonnormative}
\begin{example}
The input argument to \lstinline!previous! is restricted to be a component expression.
\begin{lstlisting}[language=modelica]
Real u1;
Real u2[4];
Complex c;
Resistor R;
$\ldots$
y1 = previous(u1); // fine
y2 = previous(u2); // fine
y3 = previous(u2[2]); // fine
y4 = previous(c.im); // fine
y5 = previous(2 * u); // error (general expression, no Component Expression)
y6 = previous(R); // error (component, no Component Expression)
\end{lstlisting}
\end{example}
\begin{example}
The named argument \lstinline!factor! of \lstinline!subSample! is restricted to be a parameter expression.
\begin{lstlisting}[language=modelica]
Real u;
parameter Real p=3;
$\ldots$
y1 = subSample(u, factor = 3); // fine (literal)
y2 = subSample(u, factor = 2 * p - 3); // fine (parameter expression)
y3 = subSample(u, factor = 3 * u); // error (general expression)
\end{lstlisting}
\end{example}
Note that the operators defined in this chapter do not automatically vectorize,
but some operate on arrays in a similar way.
\section{Clock Constructors}\label{clock-constructors}
The overloaded constructors listed below are available to generate clocks, and it is possible to call them with the specified named arguments, or with positional arguments (according to the order shown in the details after the table).
\begin{center}
\begin{tabular}{l|l l}
\hline
\tablehead{Expression} & \tablehead{Description} & \tablehead{Details}\\
\hline
\hline
\lstinline!Clock()! & Inferred clock & \Cref{modelica:clock-inferred}\\
\lstinline!Clock(intervalCounter, resolution)! & Rational interval clock & \Cref{modelica:clock-rational}\\
\lstinline!Clock(interval)! & Real interval clock & \Cref{modelica:clock-interval}\\
\lstinline!Clock(condition, startInterval)! & Event clock & \Cref{modelica:clock-event}\\
\lstinline!Clock(c, solverMethod)! & Solver clock & \Cref{modelica:clock-solver}\\
\hline
\end{tabular}
\end{center}
\begin{operatordefinition*}[Clock]\label{modelica:clock-inferred}
\begin{synopsis}\begin{lstlisting}
Clock()
\end{lstlisting}\end{synopsis}
\begin{semantics}
\firstuse{Inferred clock}. The operator returns a clock that is inferred.
\begin{example}
\begin{lstlisting}[language=modelica]
when Clock() then // equations are on the same clock
x = A * previous(x) + B * u;
Modelica.Utilities.Streams.print
("clock ticks at = " + String(sample(time)));
end when;
\end{lstlisting}
Note, in most cases, the operator is not needed and equations could be written without a when-clause (but not in the example above, since the \lstinline!print! statement is otherwise not associated to a clock). This style is useful if a modeler would clearly like to mark the equations that must belong to one clock (although a tool could figure this out as well, if the when-clause is not present).
\end{example}
\end{semantics}
\end{operatordefinition*}
\begin{operatordefinition*}[Clock]\label{modelica:clock-rational}
\begin{synopsis}\begin{lstlisting}
Clock(intervalCounter=$\mathit{intervalCounter}$, resolution=$\mathit{resolution}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
\firstuse{Rational interval clock}. The first input argument, $\mathit{intervalCounter}$, is a clocked Component Expression (see \cref{argument-restrictions-component-expression}) or a parameter expression of type \lstinline!Integer! with \lstinline!min = 0!. The optional second argument $\mathit{resolution}$ (defaults to 1) is a parameter expression of type \lstinline!Integer! with \lstinline!min = 1! and \lstinline!unit = "Hz"!. If $\mathit{intervalCounter}$ is a parameter expression with value zero, the period of the clock is derived by clock inference, see \cref{sub-clock-inferencing}. The result is of base type \lstinline!Clock! that ticks when \lstinline!time! becomes $t_{\mathrm{start}}$, $t_{\mathrm{start}} + \mathit{interval}_{1}$, $t_{\mathrm{start}} + \mathit{interval}_{1} + \mathit{interval}_{2}$, \ldots The clock starts at the start of the simulation $t_{\mathrm{start}}$ or when the controller is switched on. At the start of the simulation, \lstinline!previous($\mathit{intervalCounter}$)! = \lstinline!$\mathit{intervalCounter}$.start! and the clocks ticks the first time. At the first clock tick $\mathit{intervalCounter}$ must be computed and the second clock tick is then triggered at $\mathit{interval}_{1} = \mathit{intervalCounter}/\mathit{resolution}$. At the second clock tick at time $t_{\mathrm{start}} + \mathit{interval}_{1}$, a new value for $\mathit{intervalCounter}$ must be computed and the next clock tick is scheduled at $\mathit{interval}_{2} = \mathit{intervalCounter}/\mathit{resolution}$, and so on. If
interval % This should be "intervalCounter", right?
is a parameter expression, the clock defines a periodic clock.
\begin{nonnormative}
The given interval and time shift % What given "interval" and "time shift"?
can be modified by using the \lstinline!subSample!, \lstinline!superSample!, \lstinline!shiftSample! and \lstinline!backSample! operators on the returned clock, see \cref{sub-clock-conversion-operators}.
\end{nonnormative}
\begin{example}
\begin{lstlisting}[language=modelica]
// first clock tick: previous(nextInterval) = 2
Integer nextInterval(start = 2);
Real y1(start = 0);
Real y2(start = 0);
equation
when Clock(2, 1000) then
// periodic clock that ticks at 0, 0.002, 0.004, ...
y1 = previous(y1) + 1;
end when;
when Clock(nextInterval, 1000) then
// interval clock that ticks at 0, 0.003, 0.007, 0.012, ...
nextInterval = previous(nextInterval) + 1;
y2 = previous(y2) + 1;
end when;
\end{lstlisting}
\end{example}
Note that operator \lstinline!interval(c)! of \lstinline!Clock c = Clock(nextInterval, $\mathit{resolution}$)! returns:\newline
\lstinline!previous($\mathit{intervalCounter}$) / $\mathit{resolution}$! (in seconds)
\end{semantics}
\end{operatordefinition*}
\begin{operatordefinition*}[Clock]\label{modelica:clock-interval}
\begin{synopsis}\begin{lstlisting}
Clock(interval=$\mathit{interval}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
\firstuse{Real interval clock}. The input argument, $\mathit{interval}$, is a clocked Component Expression (see \cref{argument-restrictions-component-expression}) or a parameter expression. The $\mathit{interval}$ must be strictly positive ($\mathit{interval} > 0$) of type \lstinline!Real! with \lstinline!unit = "s"!. The result is of base type \lstinline!Clock! that ticks when \lstinline!time! becomes $t_{\mathrm{start}}$, $t_{\mathrm{start}} + \mathit{interval}_{1}$, $t_{\mathit{start}} + \mathit{interval}_{1} + \mathit{interval}_{2}$, \ldots The clock starts at the start of the simulation $t_{\mathrm{start}}$ or when the controller is switched on. Here the next clock tick is scheduled at $\mathit{interval}_{1}$ = \lstinline!previous($\mathit{interval}$)! = \lstinline!$\mathit{interval}$.start!. At the second clock tick at time $t_{\mathrm{start}} + \mathit{interval}_{1}$, the next clock tick is scheduled at $\mathit{interval}_{2}$ = \lstinline!previous($\mathit{interval}$)!, and so on. If $\mathit{interval}$ is a parameter expression, the clock defines a periodic clock.
\begin{nonnormative}
Note, the clock is defined with \lstinline!previous($\mathit{interval}$)!. Therefore, for sorting the input argument is treated as known. The given interval and time shift can be modified by using the \lstinline!subSample!, \lstinline!superSample!, \lstinline!shiftSample! and \lstinline!backSample! operators on the returned clock, see \cref{sub-clock-conversion-operators}. There are restrictions where this operator can be used, see \lstinline!Clock! expressions below.
\end{nonnormative}
\end{semantics}
\end{operatordefinition*}
\begin{operatordefinition*}[Clock]\label{modelica:clock-event}
\begin{synopsis}\begin{lstlisting}
Clock(condition=$\mathit{condition}$, startInterval=$\mathit{startInterval}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
\firstuse{Event clock}. The first input argument, $\mathit{condition}$, is a continuous-time expression of type \lstinline!Boolean!. The optional $\mathit{startInterval}$ argument (defaults to 0) is the value returned by \lstinline!interval()! at the first tick of the clock, see \cref{initialization-of-clocked-partitions}. The result is of base type \lstinline!Clock! that ticks when \lstinline!edge($\mathit{condition}$)! becomes \lstinline!true!.
\begin{nonnormative}
This clock is used to trigger a clocked partition due to a state event, that is a zero-crossing of a \lstinline!Real! variable, in a continuous-time partition or due to a hardware interrupt that is modeled as \lstinline!Boolean! in the simulation model.
\end{nonnormative}
\begin{example}
\begin{lstlisting}[language=modelica]
Clock c = Clock(angle > 0, 0.1) // before first tick of c:
// interval(c) = 0.1
\end{lstlisting}
\end{example}
\begin{nonnormative}
The implicitly given interval and time shift can be modified by using the \lstinline!subsample!, \lstinline!superSample!, \lstinline!shiftSample! and \lstinline!backSample! operators on the returned clock, see \cref{sub-clock-conversion-operators}, provided the base interval is not smaller than the implicitly given interval.
\end{nonnormative}
\end{semantics}
\end{operatordefinition*}
\begin{operatordefinition*}[Clock]\label{modelica:clock-solver}
\begin{synopsis}\begin{lstlisting}
Clock(c=$c$, solverMethod=$\mathit{solverMethod}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
\firstuse{Solver clock}. The first input argument, $c$, is a clock and the operator returns this clock. The returned clock is associated with the second input argument $\mathit{solverMethod}$ of type \lstinline!String!. The meaning of $\mathit{solverMethod}$ is defined in \cref{solver-methods}. If $\mathit{solverMethod}$ is the empty \lstinline!String!, then this \lstinline!Clock! construct does not associate an integrator with the returned clock.
\begin{example}
\begin{lstlisting}[language=modelica]
Clock c1 = Clock(1, 10) // 100 ms, no solver
Clock c2 = Clock(c1, "ImplicitTrapezoid"); // 100 ms, ImplicitTrapezoid solver
Clock c3 = Clock(c2, ""); // 100 ms, no solver
\end{lstlisting}
\end{example}
\end{semantics}
\end{operatordefinition*}
Besides inferred clocks and solver clocks, one of the following mutually
exclusive associations of clocks are possible in one base partition:
\begin{enumerate}
\item
One or more rational interval clocks, provided they are consistent with each other, see \cref{sub-clock-inferencing}.
\begin{example}
Assume \lstinline!y = subSample(u)!, and \lstinline!Clock(1, 10)! is associated with \lstinline!u! and \lstinline!Clock(2, 10)! is associated with \lstinline!y!, then this is correct, but it would be an error if \lstinline!y! is associated with a \lstinline!Clock(1, 3)!.
\end{example}
\item
Exactly one real interval clock.
\begin{example}
Assume \lstinline!Clock c = Clock(2.5)!, then variables in the same base partition can be associated multiple times with \lstinline!c! but not multiple times with \lstinline!Clock(2.5)!.
\end{example}
\item
Exactly one event clock.
\item
A default clock, if neither a real interval, nor a rational interval nor an event clock is associated with a base partition. In this case the default clock is associated with the fastest sub-clock partition.
\begin{nonnormative}
Typically, a tool will use Clock(1.0) as a default clock and will raise a warning, that it selected a default clock.
\end{nonnormative}
\end{enumerate}
Clock variables can be used in a restricted form of expressions.
Generally, every expression switching between clock variables must have
parametric variability (in order that clock analysis can be
performed when translating a model).
Thus subscripts on Clock-variables and conditions of if-then-else switching between Clock-variables must
be parameter expressions, and there are similar restrictions for sub-clock conversion operators \cref{sub-clock-conversion-operators}.
Otherwise, the following expressions are allowed:
\begin{itemize}
\item
Declaring arrays of clocks.
\begin{example}
\lstinline!Clock c1[3] = {Clock(1), Clock(2), Clock(3)}!
\end{example}
% Ok, that bug in pdflatex was weird: \emph{Example: \lstinline!Clock c1[3] ={Clock(1), Clock(2), Clock(3)}!} {]}
\item
Array constructors of clocks: \lstinline!{}!, \lstinline![]!, \lstinline!cat!.
\item
Array access of clocks.
\begin{example}
\lstinline!sample(u, c1[2])!
\end{example}
\item
Equality of clocks.
\begin{example}
\lstinline!c1 = c2!
\end{example}
\item
If-expressions of clocks in equations.
\begin{example}
\lstinline!Clock c2 = if f>0 then subSample(c1, f) elseif f<0 then superSample(c1, f) else c1!
\end{example}
\item
Clock variables can be declared in models, blocks, connectors, and
records. A \lstinline!Clock! variable can be declared with the prefixes
\lstinline!input!, \lstinline!output!, \lstinline!inner!, \lstinline!outer!, but
\emph{not} with the prefixes \lstinline!flow!, \lstinline!stream!,
\lstinline!discrete!, \lstinline!parameter!, or \lstinline!constant!.
\begin{example}
\lstinline!connector ClockInput = input Clock;!
\end{example}
\end{itemize}
\section{Clocked State Variables}\label{clocked-state-variables}
The previous value of a clocked variable can be accessed with the \lstinline!previous! operator, listed below.
\begin{center}
\begin{tabular}{l|l l}
\hline
\tablehead{Expression} & \tablehead{Description} & \tablehead{Details}\\
\hline
\hline
\lstinline!previous($u$)! & Previous value of clocked state variable & \Cref{modelica:previous} \\
\hline
\end{tabular}
\end{center}
A variable to which \lstinline!previous! has been applied is called a \firstuse{clocked state variable}.
\begin{operatordefinition}[previous]
\begin{synopsis}\begin{lstlisting}
previous($u$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
The input argument $u$ is a \emph{component expression} (see \cref{argument-restrictions-component-expression}) or a parameter expression. The return argument has the same type as the input argument. Input and return arguments are on the same clock. At the first tick of the clock of $u$ or after a reset transition (see \cref{reset-handling}), the start value of $u$ is returned, see \cref{initialization-of-clocked-partitions}. At subsequent activations of the clock of $u$, the value of $u$ from the previous clock activation is returned.
\end{semantics}
\end{operatordefinition}
\section{Partitioning Operators}\label{partitioning-operators}
A set of \emph{clock conversion operators} together act as boundaries
between different clock partitions.
\subsection{Base-clock conversion operators}\label{base-clock-conversion-operators}
The operators listed below convert between a continuous-time and a clocked-time representation and vice versa.
\begin{center}
\begin{tabular}{l|l l}
\hline
\tablehead{Expression} & \tablehead{Description} & \tablehead{Details}\\
\hline
\hline
\lstinline!sample($u$, $\mathit{clock}$)! & Sample continuous-time expression & \Cref{modelica:clocked-sample} \\
\lstinline!hold($u$)! & Zeroth order hold of clocked-time variable & \Cref{modelica:clocked-sample} \\
\hline
\end{tabular}
\end{center}
\begin{operatordefinition*}[sample]\label{modelica:clocked-sample}
\begin{synopsis}\begin{lstlisting}
sample($u$, $\mathit{clock}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
Input argument $u$ is a continuous-time expression according to \cref{continuous-time-expressions}. The optional input argument $\mathit{clock}$ is of type \lstinline!Clock!, and can in a call be given as a named argument (with the name $\mathit{clock}$), or as positional argument. The operator returns a clocked variable that has $\mathit{clock}$ as associated clock and has the value of the left limit of $u$ when $\mathit{clock}$ is active (that is the value of $u$ just before the event of \lstinline!c! is triggered). If argument $\mathit{clock}$ is not provided, it is inferred, see \cref{sub-clock-inferencing}.
\begin{nonnormative}
Since the operator returns the left limit of $u$, it introduces an infinitesimal small delay between the continuous-time and the clocked partition. This corresponds to the reality, where a sampled data system cannot act infinitely fast and even for a very idealized simulation, an infinitesimal small delay is present. The consequences for the sorting are discussed below.
Input argument $u$ can be a general expression, because the argument is continuous-time and therefore has always a value. It can also be a constant, a parameter or a piecewise constant expression.
Note that \lstinline!sample! is an overloaded function: If \lstinline!sample! has two positional input arguments and the second argument is of type \lstinline!Real!, it is the operator from \cref{event-related-operators-with-function-syntax}. If \lstinline!sample! has one input argument, or it has two input arguments and the second argument if of type \lstinline!Clock!, it is the base-clock conversion operator from this section.
\end{nonnormative}
\end{semantics}
\end{operatordefinition*}
\begin{operatordefinition}[hold]
\begin{synopsis}\begin{lstlisting}
hold($u$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
Input argument $u$ is a clocked Component Expression (see \cref{argument-restrictions-component-expression}) or a parameter expression. The operator returns a piecewise constant signal of the same type of $u$. When the clock of $u$ ticks, the operator returns $u$ and otherwise returns the value of $u$ from the last clock activation. Before the first clock activation of $u$, the operator returns the start value of $u$, see \cref{initialization-of-clocked-partitions}.
\begin{nonnormative}
Since the input argument is not defined before the first tick of the clock of $u$, the restriction is present, that it must be a \emph{component expression} (or a parameter expression), in order that the initial value of $u$ can be used in such a case.
\end{nonnormative}
\end{semantics}
\end{operatordefinition}
\begin{example}
Assume there is the following model:
\begin{lstlisting}[language=modelica]
Real y(start=1), yc;
equation
der(y) + y = 2;
yc = sample (y, Clock(0.1));
initial equation
der(y) = 0;
\end{lstlisting}
The value of \lstinline!yc! at the first clock tick is \lstinline!yc=2! (and not \lstinline!yc=1!). The reason is that the continuous-time model \lstinline!der(y)+y=2!
is first initialized and after initialization \lstinline!y! has the value \lstinline!2!. At the first clock tick at time=0, the left limit of \lstinline!y! is \lstinline!2!
and therefore \lstinline!yc = 2!.
Sorting of a simulation model:\\
Since sample(u) returns the left limit of u, and the left limit of u is
a known value, all inputs to a base-clock partition are treated as known
during sorting. Since a periodic and interval clock can tick at most
once at a time instant, and since the left limit of a variable does not
change during event iteration (i.e., re-evaluating a base-clock
partition associated with a condition clock always gives the same result
because the sample(u) inputs do not change and therefore need not to be
re-evaluated) all base-clock partitions, see \cref{base-clock-partitioning}, need
not to be sorted with respect to each other. Instead, at an event
instant, active base-clock partitions can be evaluated first (and once)
in any order. Afterwards, the continuous-time partition is evaluated.
Event iteration takes place only over the continuous-time partition. In
such a scenario, accessing the left limit of u in sample(u) just means
to pick the latest available value of u when the partition is entered,
storing it in a local variable of the partition and only using this
local copy during evaluation of the equations in this partition.
\end{example}
\subsection{Sub-clock conversion operators}\label{sub-clock-conversion-operators}
The operators listed below convert between synchronous clocks.
\begin{center}
\begin{tabular}{l|l l}
\hline
\tablehead{Expression} & \tablehead{Description} & \tablehead{Details}\\
\hline
\hline
\lstinline!subSample($u$, factor)! & Clock that is slower by a factor & \Cref{modelica:subSample}\\
\lstinline!superSample($u$, factor)! & Clock that is faster by a factor & \Cref{modelica:superSample}\\
\lstinline!shiftSample($u$, shiftCounter, resolution)! & Clock with time-shifted ticks & \Cref{modelica:shiftSample}\\
\lstinline!backSample($u$, backCounter, resolution)! & Inverse of \lstinline!shiftSample! & \Cref{modelica:backSample}\\
\lstinline!noClock($u$)! & Clock that is always inferred & \Cref{modelica:noClock}\\
\hline
\end{tabular}
\end{center}
These operators have the following properties:
\begin{itemize}
\item
The input argument $u$ is a clocked expression or an expression of type \lstinline!Clock!. (The operators can operate on all types of clocks.) If $u$ is a clocked expression, the operator returns a clocked variable that has the same type as the expression. If $u$ is an expression of type \lstinline!Clock!, the operator returns a \lstinline!Clock! -- except for \lstinline!noClock! where it is an error.
\item
The optional input arguments \lstinline!factor! (defauls to 0, with \lstinline!min = 0!), and \lstinline!resolution! (defaults to 1, with \lstinline!min = 1!) are parameter expressions of type \lstinline!Integer!.
\item
Calls of the operators can use named arguments for the multi-letter arguments (i.e.\ not for $u$) with the given names, or positional arguments.
\begin{nonnormative}
Named arguments can make the calls easier to understand.
\end{nonnormative}
\item
The input arguments \lstinline!shiftCounter! and \lstinline!backCounter! are parameter expressions of type \lstinline!Integer! with \lstinline!min = 0!.
\end{itemize}
\begin{operatordefinition}[subSample]
\begin{synopsis}\begin{lstlisting}
subSample($u$, factor=$\mathit{factor}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
The clock of \lstinline!y = subSample($u$, $\mathit{factor}$)! is $\mathit{factor}$ times slower than the clock of $u$. At every $\mathit{factor}$ ticks of the clock of $u$, the operator returns the value of $u$. The first activation of the clock of \lstinline!y! coincides with the first activation of the clock of $u$, and then every activation of the clock of \lstinline!y! coincides with the every $\mathit{factor}$-th activativation of the clock of $u$. If argument $\mathit{factor}$ is not provided or is equal to zero, it is inferred, see \cref{sub-clock-inferencing}.
\end{semantics}
\end{operatordefinition}
\begin{operatordefinition}[superSample]
\begin{synopsis}\begin{lstlisting}
superSample($u$, factor=$\mathit{factor}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
The clock of \lstinline!y = superSample($u$, $\mathit{factor}$)! is $\mathit{factor}$ times faster than the clock of $u$. At every tick of the clock of \lstinline!y!, the operator returns the value of $u$ from the last tick of the clock of $u$. The first activation of the clock of \lstinline!y! coincides with the first activation of the clock of $u$, and then the interval between activations of the clock of $u$ is split equidistantly into $\mathit{factor}$ activations, such that the activation $1 + k \cdot \mathit{factor}$ of \lstinline!y! coincides with the $1 + k$ activation of $u$.
\begin{nonnormative}
Thus \lstinline!subSample(superSample($u$, $\mathit{factor}$), $\mathit{factor}$)! = $u$.
\end{nonnormative}
If argument factor is not provided or is equal to zero, it is inferred, see \cref{sub-clock-inferencing}. If an event clock is associated to a base-clock partition, all its sub-clock partitions must have resulting clocks that are sub-sampled with an \lstinline!Integer! factor with respect to this base clock.
\begin{example}
\begin{lstlisting}[language=modelica]
Clock u = Clock(x > 0);
Clock y1 = subSample(u, 4);
Clock y2 = superSample(y1, 2); // fine; y2 = subSample(u, 2)
Clock y3 = superSample(u, 2); // error
Clock y4 = superSample(y1, 5); // error
\end{lstlisting}
\end{example}
\end{semantics}
\end{operatordefinition}
\begin{operatordefinition}[shiftSample]
\begin{synopsis}\begin{lstlisting}
shiftSample($u$, shiftCounter=$k$, resolution=$\mathit{resolution}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
The operator \lstinline!c = shiftSample($u$, $k$, $\mathit{resolution}$)! splits the interval between ticks of $u$ into $\mathit{resolution}$ equidistant intervals $i$. The clock \lstinline!c! then ticks $k$ intervals $i$ after each tick of $u$.
It leads to
\begin{lstlisting}[language=modelica]
shiftSample($u$, $k$, $\mathit{resolution}$) =
subSample(shiftSample(superSample($u$, $\mathit{resolution}$), $k$), $\mathit{resolution}$)
\end{lstlisting}
\begin{nonnormative}
Note, due to the restriction of \lstinline!superSample! on event clocks, \lstinline!shiftSample! can only shift the number of ticks of the event clock, but cannot introduce new ticks. Example:
\begin{lstlisting}[language=modelica]
// Rational interval clock
Clock u = Clock(3, 10); // ticks: 0, 3/10, 6/10, ..
Clock y1 = shiftSample(u, 1, 3); // ticks: 1/10, 4/10,
...
// Event clock
Clock u = Clock(sin(2 * pi * time) > 0, startInterval = 0.0)
// ticks: 0.0, 1.0, 2.0, 3.0, ...
Clock y1 = shiftSample(u, 2); // ticks: 2.0, 3.0, ...
Clock y2 = shiftSample(u, 2, 3); // error (resolution must be 1)
\end{lstlisting}
\end{nonnormative}
\end{semantics}
\end{operatordefinition}
\begin{operatordefinition}[backSample]
\begin{synopsis}\begin{lstlisting}
backSample($u$, backCounter=$\mathit{cnt}$, resolution=$\mathit{res}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
The input argument $u$ is either a \emph{component expression} (see \cref{argument-restrictions-component-expression}) or an expression of type \lstinline!Clock!. This is an inverse of \lstinline!shiftSample! such that \lstinline!Clock y = backSample($u$, $\mathit{cnt}$, $\mathit{res}$)! implicitly defines a clock \lstinline!y! such that \lstinline!shiftSample(y, $\mathit{cnt}$, $\mathit{res}$)! activates at the same times as $u$. It is an error if the clock of \lstinline!y! starts before the base clock of $u$.
At every tick of the clock of \lstinline!y!, the operator returns the value of $u$ from the last tick of the clock of $u$. If $u$ is a clocked Component Expression, the operator returns the start value of $u$, see \cref{initialization-of-clocked-partitions}, before the first tick of the clock of $u$.
\begin{example}
\begin{lstlisting}[language=modelica]
// Rational interval clock 1
Clock u = Clock(3, 10); // ticks: 0, 3/10, 6/10, ..
Clock y1 = shiftSample(u, 3); // ticks: 9/10, 12/10, ..
Clock y2 = backSample(y1, 2); // ticks: 3/10, 6/10,
...
Clock y3 = backSample(y1, 4); // error (ticks before u)
Clock y4 = shiftSample(u, 2, 3); // ticks: 2/10, 5/10,
...
Clock y5 = backSample(y4, 1, 3); // ticks: 1/10, 4/10,
...
// Event clock
Clock u = Clock(sin(2 * pi * time) > 0, startInterval=xx)
// ticks: 0, 1.0, 2.0, 3.0, ....
Clock y1 = shiftSample(u, 3); // ticks: 3.0, 4.0, ...
Clock y2 = backSample(y1, 2); // ticks: 1.0, 2.0, ...
\end{lstlisting}
\end{example}
\end{semantics}
\end{operatordefinition}
\begin{operatordefinition}[noClock]
\begin{synopsis}\begin{lstlisting}
noClock($u$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
The clock of \lstinline!y = noClock($u$)! is always inferred. At every tick of the clock of \lstinline!y!, the operator returns the value of $u$ from the last tick of the clock of $u$. If \lstinline!noClock($u$)! is called before the first tick of the clock of $u$, the start value of $u$ is returned.
\end{semantics}
\end{operatordefinition}
\begin{nonnormative}
Clarification of \lstinline!backSample!:
Let $a$ and $b$ be positive integers with $a < b$, and
\begin{lstlisting}[language=modelica]
yb = backSample (u, $a$, $b$)
ys = shiftSample(u, $b-a$, $b$)
\end{lstlisting}
Then when \lstinline!ys! exists, also \lstinline!yb! exists and \lstinline!ys = yb!.
The variable \lstinline!yb! exists for the above parameterization with \lstinline!a<b! one clock tick before \lstinline!ys!. Therefore, \lstinline!backSample! is
basically a \lstinline!shiftSample! with a different parameterization and the clock of \lstinline!backSample.y! ticks before the clock of \lstinline!u!. Before the
clock of \lstinline!u! ticks, \lstinline!yb = u.start!.
\end{nonnormative}
\begin{nonnormative}
Clarification of \lstinline!noClock! operator:
Note, that \lstinline!noClock(u)! is not equivalent to \lstinline!sample(hold(u))!. Consider the following model:
\begin{lstlisting}[language=modelica]
model NoClockVsSampleHold
Clock clk1 = Clock(0.1);
Clock clk2 = subSample(clk1, 2);
Real x(start = 0), y(start = 0), z(start = 0);
equation
when clk1 then
x = previous(x) + 0.1;
end when;
when clk2 then
y = noClock(x); // most recent value of x
z = sample(hold(x)); // left limit of x (infinitesimally delayed)!
end when;
end NoClockVsSampleHold;
\end{lstlisting}
Due to the infinitesimal delay of sample; \lstinline!z! will not show the current value of \lstinline!x! as \lstinline!clk2! ticks, but will show its previous value (left limit). However, \lstinline!y! will show the current value, since it has no infinitesimal delay.
\end{nonnormative}
Note that it is not legal to compute the derivative of the \lstinline!sample!, \lstinline!subSample!, \lstinline!superSample!, \lstinline!backSample!,
\lstinline!shiftSample!, and \lstinline!noClock! operators.
\section{Clocked When Clause}\label{clocked-when-clause}
In addition to the previously discussed conditional when-clause, a
\emph{clocked} when-clause is introduced:
\begin{lstlisting}[language=modelica,escapechar=!]
when !\emph{clock-expression}! then
!\emph{clocked-equation}!
...
end when;
\end{lstlisting}
The clocked when-clause cannot be nested and does not have any elsewhen
part. It cannot be used inside an algorithm. General equations are
allowed in a clocked when-clause.
For a clocked when-clause, all equations inside the when-clause are
clocked with the same clock given by the \emph{clock-expression}.
\section{Clock Partitioning}\label{clock-partitioning}
This section defines how clock-partitions and clocks associated with
equations are inferred.
\begin{nonnormative}
Typically clock partitioning is performed before sorting the equations. The benefit is that clocking and symbolic transformation errors are separated.
\end{nonnormative}
Every clocked variable is uniquely associated with exactly one clock.
After model flattening, every equation in an equation section, every
expression and every algorithm section is either continuous-time, or it
is uniquely associated with exactly one clock. In the latter case it is
called a clocked equation, a clocked expression or clocked algorithm
section respectively. The associated clock is either explicitly defined
by a when-clause, see \cref{sub-clock-conversion-operators}, or it is implicitly defined by the
requirement that a clocked equation, a clocked expression and a clocked
algorithm section must have the same clock as the variables used in them
with exception of the expressions used as first arguments in the
conversion operators of \cref{partitioning-operators}. Clock inference means to infer the
clock of a variable, an equation, an expression or an algorithm section
if the clock is not explicitly defined and is deduced from the required
properties in the previous two paragraphs.
All variables in an expression without clock conversion operators must
have the same clock to infer the clocks for each variable and
expression. The clock inference works both forward and backwards
regarding the data flow and is also being able to handle algebraic
loops. The clock inference method uses the set of variable incidences of
the equations, i.e., what variables that appear in each equation.
Note that incidences of the first argument of clock conversion operators
of \cref{partitioning-operators} are handled specially.
\subsection{Flattening of Model}\label{flattening-of-model}
The clock partitioning is conceptually performed after model flattening,
i.e., redeclarations have been elaborated, arrays of model components
expanded into scalar model components, and overloading resolved.
Furthermore, function calls to inline functions have been inlined.
\begin{nonnormative}
This is called \emph{conceptually}, because a tool might do this more efficiently in a different way, provided the result is the same as if everything is flattened. For example,
array and matrix equations and records don't not need to be expanded if they have the same clock.
\end{nonnormative}
Furthermore, each non-trivial expression (non-literal, non-constant,
non-parameter, non-variable), expr\textsubscript{i}, appearing as first
argument of a clock conversion operator (except \lstinline!hold! and \lstinline!backSample!)
is recursively replaced by a
unique variable, v\textsubscript{i}, and the equation v\textsubscript{i}
= expr\textsubscript{i} is added to the equation set.
\subsection{Connected Components of the Equations and Variables Graph}\label{connected-components-of-the-equations-and-variables-graph}
Consider the set E of equations and the set V of unknown variables (not
constants and parameters) in a flattened model, i.e.\ M = \textless{}E,
V\textgreater{}. The partitioning is described in terms of an undirected
graph \textless{}N,~F\textgreater{} with the nodes N being the set of
equations and variables, N = E + V. The set \lstinline!incidence(e)! for an equation
\lstinline!e! in E is a subset of V, in general, the unknowns which lexically appear
in e. There is an edge in F of the graph between an equation, e, and a
variable, v, if v = incidence(e):
\begin{equation*}
F = \{(e, v) : e \in E, v \in \text{\lstinline!incidence!}(e)\}
\end{equation*}
A set of clock partitions is the \emph{connected components} (Wikipedia,
\emph{Connected components}) of this graph with appropriate definition of
the incidence operator.
\subsection{Base-clock Partitioning}\label{base-clock-partitioning}
The goal is to identify all clocked equations and variables that should
be executed together in the same task, as well as to identify the
continuous-time partition.
The base-clock partitioning is performed with base-clock inference which
uses the following incidence definition:
\lstinline!incidence(e)! =
\begin{list}{}{\setlength{\leftmargin}{2em}\setlength{\topsep}{-\parskip}}
\item
the \emph{unknown} variables, as well as variables \lstinline!x! in \lstinline!der(x)!, \lstinline!pre(x)!, and \lstinline!previous(x)!, which lexically appear in \lstinline!e!
\begin{list}{}{\setlength{\leftmargin}{2em}\setlength{\topsep}{-\parskip}}
\item
except as first argument of base-clock conversion operators: \lstinline!sample! and \lstinline!hold! and \lstinline!Clock(condition, startInterval)!.
\end{list}
\end{list}\vspace{\parskip}% Compensate for removal of \parskip from \topset.
The resulting set of connected components, is the partitioning of the
equations and variables, B\textsubscript{i} =
\textless{}E\textsubscript{i}, V\textsubscript{i}\textgreater{},
according to base-clocks and continuous-time partitions.
The base clock partitions are identified as \firstuse{clocked} or as \firstuse{continuous-time partitions} according to the following properties:
A variable u in \lstinline!sample(u)!, a variable y in y =
\lstinline!hold(ud)!, and a variable b in \lstinline!Clock(b, startInterval)! where b is of \lstinline!Boolean! type is in a continuous-time partition.
Correspondingly, variables \lstinline!u! and \lstinline!y! in
\lstinline!y = sample(uc)!,
\lstinline!y = subSample(u)!,
\lstinline!y = superSample(u)!,
\lstinline!y = shiftSample(u)!,
\lstinline!y = backSample(u)!,
\lstinline!y = previous(u)!, are in a clocked partition. Equations in a clocked
when clause are also in a clocked partition.
Other partitions where none of the variables in the partition are
associated with any of the operators above have an unspecified partition
kind and are considered continuous-time partitions.
All continuous-time partitions are collected together and form \emph{the} continuous-time partition.
\begin{example}
\begin{lstlisting}[language=modelica]
// Controller 1
ud1 = sample(y,c1);
0 = f1(yd1, ud1, previous(yd1));
// Controller 2
ud2 = superSample(yd1,2);
0 = f2(yd2, ud2);
// Continuous-time system
u = hold(yd2);
0 = f3(der(x1), x1, u);
0 = f4(der(x2), x2, x1);
0 = f5(der(x3), x3);
0 = f6(y, x1, u);
\end{lstlisting}
After base clock partitioning, the following partitions are identified:
\begin{lstlisting}[language=modelica]
// Base partition 1 // clocked partition
ud1 = sample (y,c1); // incidence(e) = {ud1}
0 = f1(yd1, ud1, previous(ud1)); // incidence(e) = {yd1,ud1}
ud2 = superSample (yd1,2); // incidence(e) = {ud2, yd1}
0 = f2(yd2, ud2); // incidence(e) = {yd2, ud2}
// Base partition 2 // continuous-time partition
u = hold (yd2); // incidence(e) = {u}
0 = f3(der(x1), x1, u); // incidence(e) = {x1,u}
0 = f4(der(x2), x2, x1); // incidence(e) = {x2,x1}
0 = f6(y, x1, u); // incidence(e) = {y,x1,u}
// Identified as separate partition, but belonging to partition 2
0 = f5(der(x3), x3); // incidence(e) = {x3}
\end{lstlisting}
\end{example}
\subsection{Sub-clock Partitioning}\label{sub-clock-partitioning}
For each clocked partition B\textsubscript{i}, identified in
\cref{base-clock-partitioning}, the sub-clock partitioning is performed with sub-clock inference
which uses the following incidence definition:
\lstinline!incidence(e)! =
\begin{list}{}{\setlength{\leftmargin}{2em}\setlength{\topsep}{-\parskip}}
\item
the \emph{unknown} variables, as well as variables \lstinline!x! in \lstinline!der(x)!, \lstinline!pre(x)!, and \lstinline!previous(x)!, which lexically appear in e
\begin{list}{}{\setlength{\leftmargin}{2em}\setlength{\topsep}{-\parskip}}
\item
except as first argument of sub-clock conversion operators: \lstinline!subSample!, \lstinline!superSample!, \lstinline!shiftSample!, \lstinline!backSample!, \lstinline!noClock!, and \lstinline!Clock! with first argument of \lstinline!Boolean! type.
\end{list}
\end{list}\vspace{\parskip}% Compensate for removal of \parskip from \topset.
The resulting set of connected components, is the partitioning of the
equations and variables, S\textsubscript{ij} =
\textless{}E\textsubscript{ij}, V\textsubscript{ij}\textgreater{},
according to sub-clocks.
It can be noted that:
$E_{ij} \bigcap E_{kl} = \emptyset~ \forall i\ne{}k, j\ne{}l$
$ V_{ij} \bigcap V_{kl} = \emptyset~ \forall i\ne{}k, j\ne{}l$
$V = \bigcup V_{ij}$
$E = \bigcup E_{ij}$