forked from modelica/ModelicaSpecification
-
Notifications
You must be signed in to change notification settings - Fork 0
/
synchronous.tex
1587 lines (1384 loc) · 88 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 \lstinline!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 a diagnostic 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 \lstinline!when!-clauses (this is not allowed for \lstinline!when!-clauses with \lstinline!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 clock inference and allows defining 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 \textcite{ColacoPouzet2003ClocksFirstClass} and implemented in Lucid Synchrone version 2 and 3 \parencite{Pouzet2006LucidSynchrone30}.
However, the Modelica approach also uses multi-rate periodic clocks based on rational arithmetic introduced by \textcite{ForgetEtAl2008MultiPeriodic}, as an extension of the Lucid Synchrone semantics.
These approaches belong to the class of synchronous languages \parencite{BenvenisteEtAl2003SynchronousTwelveYearsLater}.
\end{itemize}
\section{Rationale for Clocked Semantics}\label{rationale-for-clocked-semantics}
\begin{nonnormative}
Periodically sampled control systems could also be defined with standard \lstinline!when!-clauses, see \cref{when-equations}, and the \lstinline!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 \lstinline!when!-clause with a \lstinline!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 \lstinline!when!-clause are directly
accessed (= automatic \lstinline!sample! semantics), and (c) the variables
assigned in the \lstinline!when!-clause can be directly accessed outside of the
\lstinline!when!-clause (= automatic \lstinline!hold! semantics).
Using standard \lstinline!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 \lstinline!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 \lstinline!when!-clause all variables assigned in a \lstinline!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 \lstinline!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 \lstinline!when!-clause.
This restriction can be circumvented for standard \lstinline!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 \lstinline!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 \textcite{ThummelEtAl2005InverseModels}).
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 event instant.
In contrast a standard \lstinline!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 \lstinline!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 \lstinline!when!-clauses one either needs a separate sampled math-block for each operation, or it will conceptually be evaluated all the time.
However, tools may perform a similar optimization for standard \lstinline!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{piecewise}\label{fig:piecewise-constant-variable}}
% \subfloat[A clock variable.]{\includegraphics{clock}\label{fig:clock-variable}}
% \subfloat[A clocked variable.]{\includegraphics{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 expression]{clocked discrete-time}\index{expression variability!clocked discrete-time} expressions.
The different kinds of discrete-time variables in Modelica are defined below.
\begin{definition}[Piecewise-constant variable]\index{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]\index{clock!variable}
Clock variables $c(t_{i})$ are of base type \lstinline!Clock!\indexinline{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]\label{def:clocked-variable}\index{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.
\begin{nonnormative}
Note that clock variables are not included in this list.
This implies that clock variables cannot be used where clocked variables are required.
\end{nonnormative}
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- and Sub-Partitions}\label{base-clock-and-sub-clock-partitions}
There are two kinds of \firstuse[clock!partition]{clock partitions}:
\begin{definition}[Base-partition]\index{base-partition}\index{clock!partition!base-}
A base-partition identifies a set of equations and a set of variables which must be executed together in one task.
Different base-partitions can be associated to separate tasks for asynchronous execution.
\end{definition}
\begin{definition}[Sub-partition]\index{sub-partition}\index{clock!partition!sub-}
A sub-partition identifies a subset of equations and a subset of variables of a base-partition which are partially synchronized with other sub-partitions of the same base-partition, i.e., synchronized when the ticks of the respective clocks are simultaneous.
\end{definition}
The terminology for the partitions is as follows:
\begin{itemize}
\item
\willintroduce{Clocked base-partitions}.
\begin{itemize}
\item \willintroduce{Discrete-time sub-partitions}.
\item \willintroduce{Discretized sub-partitions}.
\end{itemize}
\item
\willintroduce{Unclocked base-partition}.
\end{itemize}
\begin{nonnormative}
Note that the term \emph{clock partition} refers to these partitions in general, whereas \emph{clocked base-partition} is a specific kind of partition.
Previously the discrete-time sub-partitions were called \emph{clocked discrete-time} (\emph{sub-clock} partition)\index{clocked discrete-time}\index{discrete-time!clocked}.
Further, discretized sub-partitions were called \emph{discretized continuous-time} (\emph{sub-clock} partition)\index{discretized continuous-time}\index{continuous-time!discretized}.
When emphasizing that the partitions are clock partitions, sub-partitions can still be referred to as \emph{sub-clock partitions}\index{sub-clock!partition}; and similarly for base-partition\index{base-clock!partition}.
\end{nonnormative}
\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}\index{component!expression (argument restriction)}
A component expression is a \lstinline[language=grammar]!component-reference! which is a valid expression, i.e., not referring to models or blocks with equations.
% "an element of records" below looks strange:
In detail, 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 evaluable (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 evaluable expression (\cref{variability-of-expressions}).
To emphasize that there are no such restrictions, an input argument may be said to be just an \emph{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 an evaluable expression is to ensure that clock analysis can be performed during translation.
In cases when special handling of parameter expressions is specified, it is an indication that the values are not needed 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, not component expression)
y6 = previous(R); // error (component, not component expression)
\end{lstlisting}
\end{example}
\begin{example}
The named argument \lstinline!factor! of \lstinline!subSample! is restricted to be an evaluable 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 (evaluable expression)
y3 = subSample(u, factor = 3 * u); // error (general expression)
\end{lstlisting}
\end{example}
None of the operators defined in this chapter vectorize, but some can operate directly on array variables (including clocked array variables, but not clock array variables).
They are not callable in functions.
\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}\index{Clock@\robustinline{Clock}!inferred}
\begin{synopsis}\begin{lstlisting}
Clock()
\end{lstlisting}\end{synopsis}
\begin{semantics}
\firstuse[inferred clock]{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 \lstinline!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 \lstinline!when!-clause is not present).
\end{example}
\end{semantics}
\end{operatordefinition*}
\begin{operatordefinition*}[Clock]\label{modelica:clock-rational}\index{Clock@\robustinline{Clock}!rational}
\begin{synopsis}\begin{lstlisting}
Clock(intervalCounter=$\mathit{intervalCounter}$, resolution=$\mathit{resolution}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
\firstuse[rational interval clock]{Rational interval clock}.
The first input argument, $\mathit{intervalCounter}$, is a clocked component expression (\cref{def:component-expression}) or an evaluable expression of type \lstinline!Integer! with \lstinline!min = 0!.
The optional second argument $\mathit{resolution}$ (defaults to 1) is an evaluable expression of type \lstinline!Integer! with \lstinline!min = 1! and \lstinline!unit = "Hz"!.
If $\mathit{intervalCounter}$ is an evaluable expression with value zero, the period of the clock is derived by clock inference, see \cref{sub-clock-inferencing}.
If $\mathit{intervalCounter}$ is an evaluable expression greater than zero, the clock defines a periodic clock.
If $\mathit{intervalCounter}$ is a clocked component expression it must be greater than zero.
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.
\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, $\ldots$
y1 = previous(y1) + 1;
end when;
when Clock(nextInterval, 1000) then
// interval clock that ticks at 0, 0.003, 0.007, 0.012, $\ldots$
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}\index{Clock@\robustinline{Clock}!interval}
\begin{synopsis}\begin{lstlisting}
Clock(interval=$\mathit{interval}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
\firstuse[real interval clock]{Real interval clock}.
The input argument, $\mathit{interval}$, is a clocked component expression (\cref{def: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.
Note that $\mathit{interval}$ does not have to an evaluable expression, since different real interval clocks are never compared.
\end{nonnormative}
\end{semantics}
\end{operatordefinition*}
\begin{operatordefinition*}[Clock]\label{modelica:clock-event}\index{Clock@\robustinline{Clock}!event}
\begin{synopsis}\begin{lstlisting}
Clock(condition=$\mathit{condition}$, startInterval=$\mathit{startInterval}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
\firstuse[event clock]{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 base-partition due to a state event (that is a zero-crossing of a \lstinline!Real! variable) in an unclocked base-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}\index{Clock@\robustinline{Clock}!solver}
\begin{synopsis}\begin{lstlisting}
Clock(c=$c$, solverMethod=$\mathit{solverMethod}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
\firstuse[solver clock]{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 periodic 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 non-periodic rational interval clock.
\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-partition.
\begin{nonnormative}
Typically, a tool will use \lstinline!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 be an evaluable expression (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 evaluable 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
\lstinline!if!-expressions of clocks in equations.
\begin{example}
\begin{lstlisting}[language=modelica]
Clock c2 =
if f > 0 then
subSample(c1, f)
elseif f < 0 then
superSample(c1, f)
else
c1;
\end{lstlisting}
\lstinline!!
\end{example}
\item
Clock variables can be declared in models, blocks, connectors, and records.
A 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}
\begin{lstlisting}[language=modelica]
connector ClockInput = input Clock;
\end{lstlisting}
\end{example}
\end{itemize}
\section{Clocked State Variables}\label{clocked-state-variables}
\begin{definition}[Clocked state variable]\label{def:clocked-state-variable}\index{clocked!state variable}\index{state variable!clocked}
A component expression which is not a parameter, and to which \lstinline!previous! has been applied.
\end{definition}
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 variable & \Cref{modelica:previous} \\
\hline
\end{tabular}
\end{center}
\begin{operatordefinition}[previous]
\begin{synopsis}\begin{lstlisting}
previous($u$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
The input argument $u$ is a component expression (\cref{def:component-expression}).
If $u$ is a parameter, its value is returned.
Otherwise:
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}
\begin{nonnormative}
At a clock tick only the (previous) values of the clocked state variables are needed to compute the new values of all clocked variables on that clock.
This roughly corresponds to state variables in continuous time.
\end{nonnormative}
\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}\index{base-clock!conversion-operators}\index{conversion-operators!base-clock}
The operators listed below convert between a clocked and an unclocked 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 unclocked expression & \Cref{modelica:clocked-sample} \\
{\lstinline!hold($u$)!} & Zeroth order hold of clocked-time variable & \Cref{modelica:hold} \\
\hline
\end{tabular}
\end{center}
\begin{operatordefinition*}[sample]\label{modelica:clocked-sample}\index{sample@\robustinline{sample}!clocked}
\begin{synopsis}\begin{lstlisting}
sample($u$, $\mathit{clock}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
Input argument $u$ is in an unclocked base-partition, and there are no variability restrictions, i.e., it is continuous-time 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 $\mathit{clock}$ is triggered).
If $\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 unclocked 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 unclocked 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 is 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 (\cref{def:clocked-variable}) component expression (\cref{def:component-expression}) or a parameter expression.
The operator returns a piecewise constant signal of the same type as $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 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 $\text{\lstinline!yc!} = 2$ (and not $\text{\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 2.
At the first clock tick at $\text{\lstinline!time!} = 0$, the left limit of \lstinline!y! is 2 and therefore $\text{\lstinline!yc!} = 2$.
\end{example}
\subsubsection{Sorting of a Simulation Model}
\begin{nonnormative}
Since \lstinline!sample(u)! returns the left limit of \lstinline!u!, and the left limit of \lstinline!u! is a known value, all inputs to a base-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-partition associated with a condition clock always gives the same result because the \lstinline!sample(u)! inputs do not change and therefore need not to be re-evaluated), all base-partitions, see \cref{base-clock-partitioning}, need not to be sorted with respect to each other.
Instead, at an event instant, active base-partitions can be evaluated first (and once) in any order.
Afterwards, the unclocked base-partition is evaluated.
Event iteration takes place only over the unclocked base-partition.
In such a scenario, accessing the left limit of \lstinline!u! in \lstinline!sample(u)! just means to pick the latest available value of \lstinline!u! when the base-partition is entered, storing it in a local variable of the base-partition and only using this local copy during evaluation of the equations in this base-partition.
\end{nonnormative}
\subsection{Sub-Clock Conversion Operators}\label{sub-clock-conversion-operators}\index{sub-clock!conversion-operators}\index{conversion-operators!sub-clock}
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! (defaults to 0, with \lstinline!min = 0!), and \lstinline!resolution! (defaults to 1, with \lstinline!min = 1!) are evaluable 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 evaluable 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 $\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 $\mathit{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-partition, all its sub-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, $\ldots$
Clock y1 = shiftSample(u, 1, 3); // ticks: 1/10, 4/10, $\ldots$
// Event clock
Integer revolutions = integer(time);
Clock u = Clock(change(revolutions), startInterval = 0.0);
// ticks: 0.0, 1.0, 2.0, 3.0, $\ldots$
Clock y1 = shiftSample(u, 2); // ticks: 2.0, 3.0, $\ldots$
Clock y2 = shiftSample(u, 2, 3); // error (resolution must be 1)
\end{lstlisting}
Additional example showing the full form:
\begin{lstlisting}[language=modelica]
Integer intervalCnt(start=2);
Integer cnt(start=0);
Clock u = Clock(intervalCnt,1);
Clock s1 = shiftSample(u, 3, 2);
equation
when u then
cnt = previous(cnt) + 1;
intervalCnt = if (cnt>=2) then 1 else previous(intervalCnt);
end when;
\end{lstlisting}
Here \lstinline!u! ticks at 0, 2, 3, 4, 5, 6.
First you \lstinline!superSample! to split each sampling interval in two equal parts leading to the ticks 0.0, 1.0, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0.
Then the simple \lstinline!shiftSample! removes the first three ticks giving 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0.
And finally every other point is removed by \lstinline!subSample!, and \lstinline!s1! ticks at 2.5, 3.5, 4.5, 5.5.
\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 component expression (\cref{def: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, $\ldots$
Clock y1 = shiftSample(u, 3); // ticks: 9/10, 12/10, $\ldots$
Clock y2 = backSample(y1, 2); // ticks: 3/10, 6/10, $\ldots$
Clock y3 = backSample(y1, 4); // error (ticks before u)
Clock y4 = shiftSample(u, 2, 3); // ticks: 2/10, 5/10, $\ldots$
Clock y5 = backSample(y4, 1, 3); // ticks: 1/10, 4/10, $\ldots$
// Event clock
Integer revolutions = integer(time);
Clock u = Clock(change(revolutions), startInterval = xx)
// ticks: 0, 1.0, 2.0, 3.0, $\ldots$
Clock y1 = shiftSample(u, 3); // ticks: 3.0, 4.0, $\ldots$
Clock y2 = backSample(y1, 2); // ticks: 1.0, 2.0, $\ldots$
\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, and $u$ must be part of the same base-clock as \lstinline!y!.
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 \lstinline!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 \lstinline!when!-equation (see \cref{when-equations}), a \emph{clocked} \lstinline!when!-clause\index{clocked!when-clause@\robustinline{when}-clause}\index{when-clause@\robustinline{when}-clause!clocked} is introduced:
% TODO: Can't have angle brackets and \emph in the same mathescape due to LaTeXML issue:
% - https://github.com/brucemiller/LaTeXML/issues/1477
% Once we cut the MathJax dependency, change to single mathescape for better character spacing.
\begin{lstlisting}[language=modelica]
when $\mathit{clockExpression}$ then
$\langle$$\mbox{\emph{clocked equations}}$$\rangle$
$\ldots$
end when;
\end{lstlisting}
The clocked \lstinline!when!-clause cannot be nested and does not have any \lstinline!elsewhen! part.
It cannot be used inside an algorithm.
General equations are allowed in a clocked \lstinline!when!-clause.
For a clocked \lstinline!when!-clause, all equations inside the \lstinline!when!-clause are clocked with the same clock given by the $\mathit{clockExpression}$.
\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 unclocked, or it is uniquely associated with exactly one clock.
% Warning: The uses of \firstuse below aren't the first time these terms are used.
In the latter case it is called a \firstuse[clocked!equation]{clocked equation}\index{equation!clocked}, a \willintroduce{clocked expression} or \firstuse[clocked!algorithm]{clocked algorithm}\index{algorithm!clocked} section respectively.
The associated clock is either explicitly defined by a \lstinline!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}.
\firstuse[clock!inference]{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.
\begin{nonnormative}
As clock partitions are solely determined by the equations, two different clock partitions can have clocks defined by the same expressions.
It is a quality of implementation issue that such partitions are executed synchronously, e.g., by putting them in the same task in a real-time simulation context.
\end{nonnormative}
\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), $\mathit{expr}_{i}$, appearing as first argument of a clock conversion operator (except \lstinline!hold! and \lstinline!backSample!) is recursively replaced by a unique variable, $v_{i}$, and the equation $v_{i} = \mathit{expr}_{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 = \left\langle E,\, V \right\rangle$.
The partitioning is described in terms of an undirected graph $\left\langle N,\, F \right\rangle$ with the nodes $N$ being the set of equations and variables, $N = E \cup V$.
The set $\operatorname{incidence}(e)$ for an equation $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 \in \operatorname{incidence}(e)$:
\begin{equation*}
F = \{(e, v) : e \in E, v \in \operatorname{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.
A special case is the built-in variable \lstinline!time! (see \cref{built-in-variable-time}).
Each use of \lstinline!time! is conceptually included as a separate variable in this analysis, $\mathit{time}_i$ with $\text{\lstinline!der!}(\mathit{time}_{i}) = 1$.
\begin{nonnormative}
This means that \lstinline!time! can be used in different partitions without any restrictions.
Additionally, it means that every sub-partition directly referencing \lstinline!time! contains a call to \lstinline!der!.
\end{nonnormative}
\subsection{Base-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 unclocked base-partition.
The base-partitioning is performed with base-clock inference which uses the following incidence definition:
$\operatorname{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 base-clock conversion operators: \lstinline!sample! and \lstinline!hold! and \lstinline!Clock(condition=$\ldots$, startInterval=$\ldots$)!.
\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_{i} = \left\langle E_{i},\, V_{i} \right\rangle$, according to base-clocks and unclocked partitions.
The base partitions are identified as \firstuse[clocked!base-clock partition]{clocked}\index{base-clock partition!clocked} or as \firstuse[base-clock partition!unclocked]{unclocked partitions}\index{partition!unclocked} according to the following properties:
A variable \lstinline!u! in \lstinline!sample(u)!, a variable \lstinline!y! in \lstinline!y = hold(ud)!, and a variable \lstinline!b! in \lstinline!Clock(b, startInterval=$\ldots$)! where the \lstinline!Boolean! \lstinline!b! is in an unclocked 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 base-partition.
Equations in a clocked \lstinline!when!-clause are also in a clocked base-partition.
Other base-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 to be unclocked base-partitions.
All unclocked base-partitions are collected together and form \firstuse[unclocked!base-partition@base-partition, \emph{the}]{the unclocked base-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);
// Unclocked 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-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 -- unclocked partition