forked from modelica/ModelicaSpecification
-
Notifications
You must be signed in to change notification settings - Fork 0
/
synchronous.tex
1577 lines (1399 loc) · 71 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}\doublelabel{synchronous-language-elements}
This section presents language elements for describing synchronous
behavior suited for implementation of control systems.
\section{Introduction}\doublelabel{introduction2}
\subsection{Overview}\doublelabel{overview}
\begin{nonnormative}
This chapter defines additional kinds of discrete-time
variables and equations, as well as an additional kind of when-clause,
in order to define 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]
\caption{A continuous plant and a sampled data controller connected
together with sample and (zero-order) hold elements}
\begin{center}
\includegraphics[width=7in,height=4in]{plantmodel}
\end{center}
\end{figure}
\begin{itemize}
\item
A periodic clock is defined with \textbf{Clock}(3). The argument
of \textbf{Clock}(..) defines the sampling interval (for details see \autoref{clock-constructors}).
\item
Clocked variables (such as yd, xd, 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 \textbf{sample}(..) to convert
from continuous-time to clocked discrete-time or \textbf{hold}(..) to
convert from clocked discrete-time to continuous-time.
\item
A continuous-time variable is sampled at a clock tick with the
\textbf{sample}(..) operator. The operator returns the value of the
continuous-time variable when the clock is active.
\item
When no argument is defined for \textbf{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
The operator \textbf{previous}(xd) returns the value of xd at
the previous clock tick. At the first sample instant, the start value
of xd is returned.
\item
A discrete-time signal (such as ud) is converted to a
continuous-time signal with the \textbf{hold}(..) operator.
\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}
\end{nonnormative}
\subsection{Rationale for Clocked Semantics}\doublelabel{rationale-for-clocked-semantics}
\begin{nonnormative}
Periodically sampled control systems could also be defined with
standard when-clauses, see \autoref{when-equations}, and the sample operator, see
\autoref{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). This approach to define
periodically sample data systems has the following drawbacks that are
not present with the solution in this chapter using clocks and clocked
equations:
\begin{enumerate}
\item
It is not possible to detect sampling errors due to 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}
\item
Due to the automatic sample and hold semantics, all variables
assigned in a when-clause of the above kind 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 small subset of them need an initial
value.
\item
Only a restricted form of equations can be used in a standard
when-clause, since the left hand side has to be a variable, in order
to identify the variables that are assigned in the when-clause. This
is a severe restriction, especially if nonlinear control algorithms
shall be defined. This restriction is not present for clocked
equations.
\item
All equations belonging to a discrete controller must be in a
when clause. If the controller is built-up with several building
blocks, then the clock condition (sampling) must be explicitly
propagated to all blocks. This is tedious and error prone. With
clocked equations, the clock condition need to be defined only at one
place, and otherwise is automatically propagated by clock inference.
\item
It is not possible to use a continuous-time model in when
clauses (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
At a sample instant, an event iteration occurs (as for any other
event). A clocked partition, as well as a when-clause with a
sample(..) is evaluated exactly once at such an event instant.
However, the continuous-time model to which the sampled data
controller is connected, will be evaluated several times when the
overall system is simulated. With when-clauses, the continuous-time
part is typically evaluated three times at a sample instant (once,
when the sample instant is reached, once to evaluate the continuous
equations at the sample instant, and once when an event iteration
occurs since a discrete variable v is changed and \textbf{pre}(v)
appears in the equations). With clocked equations, no event iteration
is triggered if a clocked variable v is changed and
\textbf{previous}(v) appears in the equations, because the event
iteration cannot change the value of v. As a result, typically the
simulation model is evaluated twice at a sample instant and therefore
the simulation is more efficient with clocked equations.
\end{enumerate}
\end{nonnormative}
\section{Definitions}\doublelabel{definitions}
In this section various terms are defined.
\subsection{Clocks and Clocked Variables}\doublelabel{clocks-and-clocked-variables}
In \autoref{discrete-time-expressions} the term \emph{discrete-time} Modelica expression and in
\autoref{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:
\begin{longtable}[]{|p{7.3cm}|p{7.3cm}|}
\hline
\multicolumn{2}{|p{14.6cm}|}{\textbf{The different kinds of discrete-time variables in Modelica}}\\ \hline
\endhead
\begin{tabular}{p{7cm}}
\includegraphics[width=3in,height=1.875in]{piecewise}
\end{tabular}&\begin{tabular}{p{7cm}}\textbf{Piecewise-constant variables (see \autoref{discrete-time-expressions})}
% henrikt-ma: Get rid of the use of \underline below.
Variables \textbf{m}(t) of base type Real, Integer, Boolean,
enumeration, and String that are \underline{constant} inside each interval
t\textsubscript{i} $\le$ t \textless{} t\textsubscript{i+1} (= piecewise
constant continuous-time variables). In other words, \textbf{m}(t)
\underline{changes} value \underline{only at events}. This means, \textbf{m}(t) =
\textbf{m}(t\textsubscript{i}), for t\textsubscript{i} $\le$ t \textless{}
t\textsubscript{i+1}. Such variables depend continuously on time and
they are discrete-time variables.
\end{tabular}\\ \hline
\begin{tabular}{p{7cm}}
\includegraphics[width=3in,height=1.875in]{clock}
\end{tabular}&
\begin{tabular}{p{7cm}}\textbf{Clock variables}
Clock variables \textbf{c}(t\textsubscript{i}) are of base type Clock. A
clock is either defined by a constructor (such as 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 \autoref{base-clock-conversion-operators}.
\begin{example}
\begin{lstlisting}[language=modelica]
Clock c1 = Clock(...);
Clock c2 = c1;
Clock c3 = subSample(c2,4);
\end{lstlisting}
\end{example}
\end{tabular}\\ \hline
\begin{tabular}{p{7cm}}
\includegraphics[width=3in,height=1.875in]{clocked}
\end{tabular}&
\begin{tabular}{p{7cm}}\textbf{Clocked variables}
The elements of clocked variables \textbf{r}(t\textsubscript{i}) are of
base type Real, Integer, Boolean, enumeration, String that are
associated uniquely with a clock \textbf{c}(t\textsubscript{i}). A
clocked variable can only be directly accessed at the event instant
where the associated clock is \textbf{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.
\par
\begin{nonnormative*}
This is visualized in the left figure with the dashed green lines.
\end{nonnormative*}
\end{tabular}\\ \hline
\end{longtable}
{]}
\subsection{Base-Clock and Sub-Clock Partitions}\doublelabel{base-clock-and-sub-clock-partitions}
The following concepts are used:
\begin{itemize}
\item
A \firstuse{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.
\item
A \firstuse{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{itemize}
\subsection{Argument Restrictions (Component Expression)}\doublelabel{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 defined:
\begin{description}
\item[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{description}
In the following sections the following notation is partially used when
defining the operators:
% This should ideally be a set of definitions instead
\begin{description}
\item[The input argument is a \emph{component expression}:]
The meaning is that the input argument when calling the operator must
be a \emph{component expression}.
\begin{nonnormative}
The reason for this restriction 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.
\end{nonnormative}
\begin{example}
\begin{lstlisting}[language=modelica]
Real u1;
Real u2[4];
Complex c;
Resistor R;
...
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}
\item[The input argument is a \emph{parameter expression}:]
The meaning is that the input argument when calling the operator must
have parameter variability, that is the argument must depend directly
or indirectly only on parameters, constants or literals, see
\autoref{variability-of-expressions}.
\begin{nonnormative}
The reason for this restriction 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}
\begin{lstlisting}[language=modelica]
Real u;
parameter Real p=3;
...
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}
\item[The input argument is an \emph{expression}:]
There is no restriction on the input argument when calling the
operator. This notation is used to emphasis when a standard function
call is used (is an \emph{expression}), instead of restricting the input
(is a \emph{component expression}).
\end{description}
Note that the operators defined in this chapter do not automatically vectorize,
but some operate on arrays in a similar way.
\section{Clock Constructors}\doublelabel{clock-constructors}
The following overloaded constructors 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 below):
\begin{longtable}[]{|p{3cm}|p{12cm}|}
\hline \endhead
\textbf{Clock}()
&
\begin{tabular}{@{}p{119mm}@{}}
\textbf{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{tabular}\\ \hline
\begin{tabular}{@{}p{29mm}@{}}
\textbf{Clock}(\newline
intervalCounter,\newline
resolution)
\end{tabular}
&
\begin{tabular}{@{}p{119mm}@{}}
\textbf{Clock with Rational Interval}\\
The first input argument, \lstinline!intervalCounter!, is a clocked Component
Expression (see \autoref{argument-restrictions-component-expression}) or a parameter expression of type
\textbf{Integer} with min=0. The optional second argument \lstinline!resolution!
(default=1) is a parameter expression of type Integer with \lstinline!min=1! and
\lstinline!unit="Hz"!. If \lstinline!intervalCounter! is a parameter expression with value
zero, the period of the clock is derived by clock inference, see
\autoref{sub-clock-inferencing}. The output argument is of base type Clock that ticks when time
becomes t\textsubscript{start}, t\textsubscript{start}+interval1,
t\textsubscript{start}+interval1+interval2, ... The clock starts at the
start of the simulation t\textsubscript{start} or when the controller is
switched on. At the start of the simulation, previous(intervalCounter) =
intervalCounter.start and the clocks ticks the first time. At the first
clock tick intervalCounter must be computed and the second clock tick is
then triggered at interval1=intervalCounter/resolution. At the second
clock tick at time tstart+interval1, a new value for intervalCounter
must be computed and the next clock tick is scheduled at interval2 =
intervalCounter/resolution, and so on. If interval is a parameter
expression, the clock defines a periodic clock.
\begin{nonnormative}
The given interval and time shift can be modified by using the subSample, superSample, shiftSample and backSample operators on the returned clock, see \autoref{sub-clock-conversion-operators}.
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{nonnormative}
Note that operator interval(c) of Clock c =
Clock(nextInterval,resolution) returns:\newline
previous(intervalCounter)/resolution; // in seconds
\end{tabular}\\ \hline
\textbf{Clock}(interval)
&
\begin{tabular}{@{}p{119mm}@{}}
\textbf{Clock with Real Interval}\\
The input argument, \lstinline!interval!, is a clocked Component Expression (see
\autoref{argument-restrictions-component-expression}) or a parameter expression.
The \lstinline!interval! must be strictly positive (\lstinline!interval>0.0!) of type \textbf{Real} with \lstinline!unit="s"!.
The output argument is of base type Clock that
ticks when time becomes t\textsubscript{start},
t\textsubscript{start}+interval1,
t\textsubscript{start}+interval1+interval2, ... The clock starts at the
start of the simulation t\textsubscript{start} or when the controller is
switched on. Here the next clock tick is scheduled at interval1 =
\textbf{previous}(interval) = interval.start. At the second clock tick
at time t\textsubscript{start}+interval1, the next clock tick is
scheduled at interval2 = \textbf{previous}(interval), and so on. If
interval is a parameter expression, the clock defines a periodic clock.
\begin{nonnormative}
Note, the clock is defined with \textbf{previous}(interval). Therefore, for sorting the input argument is treated as known. The given interval and time shift can be modified
by using the subSample, superSample, shiftSample and backSample operators on the returned clock, see \autoref{sub-clock-conversion-operators}. There are restrictions where this
operator can be used, see Clock expressions below.
\end{nonnormative}
\end{tabular}\\ \hline
\begin{tabular}{@{}p{29mm}@{}}
\textbf{Clock}(\newline
condition,\newline
startInterval)
\end{tabular}
&
\begin{tabular}{@{}p{119mm}@{}}
\textbf{Event Clock}\\
The input argument, \lstinline!condition!, is a continuous-time expression of type
Boolean. The optional \lstinline!startInterval! argument (default = 0.0) is the
value returned by the operator \textbf{interval}() at the first tick of
the clock, see \autoref{initialization-of-clocked-partitions}. The output argument is of base type Clock
that ticks when \textbf{edge}(condition) becomes true.
\begin{nonnormative}
This clock is used to trigger a clocked partition due to a state event, that is a zero-crossing of a Real variable, in a continuous-time partition or due to a hardware interrupt
that is modeled as Boolean in the simulation model. Example:
\begin{lstlisting}[language=modelica]
Clock c = Clock(angle > 0, 0.1) // before first tick of c:
// interval(c) = 0.1
\end{lstlisting}
The implicitly given interval and time shift can be modified by
using the subsample, superSample, shiftSample and backSample operators
on the returned clock, see \autoref{sub-clock-conversion-operators}, provided the base
interval is not smaller than the implicitly given interval.
\end{nonnormative}
\end{tabular}\\ \hline
\begin{tabular}{@{}p{29mm}@{}}
\textbf{Clock}(\newline
c,\newline
solverMethod)\newline
\end{tabular}
&
\begin{tabular}{@{}p{119mm}@{}}
\textbf{Solver Clock}\\
The first input argument \lstinline!c! is a clock and the operator returns this
clock. The returned clock is associated with the second input argument
of type String \lstinline!solverMethod!. The meaning of solverMethod is defined
in \autoref{solver-methods}. If the second input argument solverMethod is an empty
String, then this 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}
\strut
\end{tabular}
\\ \hline
\end{longtable}
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 \autoref{sub-clock-inferencing}.
\begin{nonnormative}
For 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{nonnormative}
\item
Exactly one Real interval clock.
\begin{nonnormative}
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{nonnormative}
\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 \autoref{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!{}, [], 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{Discrete States}\doublelabel{discrete-states}
The previous value of a clocked variable can be accessed with the
previous operator. Such a variable is called a clocked state variable.
\begin{longtable}[]{|l|p{12cm}|}
\hline \endhead
\textbf{previous}(u) & The input argument is a \emph{component expression} (see
\autoref{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 \autoref{reset-handling}), the start value of u is returned, see
\autoref{initialization-of-clocked-partitions}. At subsequent activations of the clock of u, the value of
u from the previous clock activation is returned.\\ \hline
\end{longtable}
\section{Partitioning Operators}\doublelabel{partitioning-operators}
A set of \emph{clock conversion operators} together act as boundaries
between different clock partitions.
\subsection{Base-clock conversion operators}\doublelabel{base-clock-conversion-operators}
The following operators convert between a continuous-time and a
clocked-time representation and vice versa:
\begin{longtable}[]{|l|p{12cm}|}
\hline \endhead
\textbf{sample}(u, clock) &
Input argument u is a continuous-time expression according to
\autoref{continuous-time-expressions}. The optional input argument clock is of type Clock, and can in a call be given as a named argument (with the name clock),
or as positional argument.
The operator
returns a clocked variable that has clock as associated clock and has the
value of the left limit of u when clock is active (that is the value of u
just before the event of c is triggered). If argument clock is not provided,
it is inferred, see \autoref{sub-clock-inferencing}.
\par
\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 \textbf{sample}() is an overloaded function: If
\textbf{sample}(..) has two positional input arguments and the second argument is
of type Real, it is the operator from \autoref{event-related-operators-with-function-syntax}. If
\textbf{sample}(..) has one input argument, or it has two input
arguments and the second argument if of type Clock, it is the base-clock
conversion operator from this section.
\end{nonnormative*}
\\ \hline
\textbf{hold}(u) &
Input argument u is a clocked Component Expression (see \autoref{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 \autoref{initialization-of-clocked-partitions}.
\par
\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*}
\\ \hline
\end{longtable}
\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 \autoref{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}\doublelabel{sub-clock-conversion-operators}
The following operators convert between synchronous clocks:
\begin{longtable}[]{|p{4cm}|p{11cm}|}
\hline \endhead
\multicolumn{2}{|p{15cm}|}{
The operators in this table have the following properties:
The input argument u is a clocked expression or an expression of type
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
Clock, the operator returns a Clock - except for noClock where it is an error.
The optional input arguments \lstinline!factor! (default=0, min=0), and \lstinline!resolution!
(default=1, min=1) are parameter expressions of type Integer.
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}
The input arguments \lstinline!shiftCounter! and \lstinline!backCounter! are parameter
expressions of type Integer (min=0).}
\\ \hline
\textbf{subSample}(u, factor)
&
The clock of y = \textbf{subSample}(u,factor) is factor-times slowerthan the clock of u. At every factor ticks of the clock of u, the
operator returns the value of u.. The first activation of the clock of y
coincides with the first activation of the clock of u, and then every activation of the clock of y
coincides with the every factor-th activativation of the clock of u. If argument
factor is not provided or is equal to zero, it is inferred, see
\autoref{sub-clock-inferencing}.
\\ \hline
\textbf{superSample}(u, factor)
&
The clock of y = \textbf{superSample}(u,factor) is factor-times faster
than the clock of u. At every tick of the clock of y, the operator
returns the value of u from the last tick of the clock of u. The first
activation of the clock of 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 factor activations, such that the activation 1+k*factor of y coincides with the 1+k activation of u.
\begin{nonnormative}
Thus \lstinline!subSample(superSample(u, factor), factor)=u!
\end{nonnormative}
If argument factor is not provided or is equal to zero, it
is inferred, see \autoref{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 Integer factor with respect to this
base clock.
\par
\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*}
\\ \hline
\begin{tabular}{@{}p{4cm}@{}}
\textbf{shiftSample}(u,\\
shiftCounter, resolution)
\end{tabular}
& The operator \lstinline!c=shiftSample(u,k,resolution)! splits the interval between
ticks of \lstinline!u! into \lstinline!resolution! equidistant intervals \lstinline!i!.
The clock \lstinline!c! then ticks \lstinline!k! intervals \lstinline!i! after each tick of \lstinline!u!.
It leads to
\begin{lstlisting}[language=modelica]
shiftSample(u,k,resolution)=subSample(shiftSample(superSample(u,resolution),k),resolution)
\end{lstlisting}
\par
\begin{nonnormative*}
Note, due to the restriction of superSample on Event clocks, 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*}
\\ \hline
\begin{tabular}{@{}p{4cm}@{}}
\textbf{backSample}(u,\\
backCounter, resolution)
\end{tabular}
&
The input argument u is either a \emph{component expression} (see
\autoref{argument-restrictions-component-expression}) or an expression of type Clock.
This is an inverse of shiftSample such that \lstinline!Clock y=backSample(u, cnt, res)! implicitly defines
a clock y such that \lstinline!shiftSample(y, cnt, res)! activates at the same times as u.
It is an
error, if the clock of y starts before the base clock of u.
At every
tick of the clock of 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 \autoref{initialization-of-clocked-partitions}, before the
first tick of the clock of u.
\par
\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*}
\\ \hline
\textbf{noClock}(u)
&
The clock of y = \textbf{noClock}(u) is always inferred. At every tick
of the clock of y, the operator returns the value of u from the last
tick of the clock of u. If \textbf{noClock}(u) is called before the
first tick of the clock of u, the start value of u is returned.\\ \hline
\end{longtable}
\begin{nonnormative}
Clarification of backSample(..) operator:
Let a and b be positive integers with a \textless{} 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 noClock(..) operator:
Note, that noClock(u) is not equivalent to 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; z will not show the current value of x as clk2 ticks, but will show its previous value (left limit). However, 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}\doublelabel{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}\doublelabel{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 \autoref{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 \autoref{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 \autoref{partitioning-operators} are handled specially.
\subsection{Flattening of Model}\doublelabel{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}\doublelabel{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):
$$F = \{(e, v) : e \in E , v \in \text{incidence}(e)\}$$
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}\doublelabel{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:
% This is not how you are supposed to format things in LaTeX
\begin{tabular}{p{1cm}p{1cm}p{1cm}p{12cm}}
\multicolumn{4}{p{15cm}}{\textbf{incidence}(e) = the \emph{unknown} variables, as well as
variables x in \textbf{der}(x), \textbf{pre}(x), and \textbf{previous}(x),}\\
&\multicolumn{3}{p{14cm}}{which lexically appear in e}\\
&&\multicolumn{2}{p{13cm}}{except as first argument of base-clock conversion operators: sample() and hold() and Clock(condition,startInterval).}
\end{tabular}
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 \textbf{clocked} or as
\textbf{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 u and y in y = \textbf{sample}(uc), y =
\textbf{subSample}(u), y = \textbf{superSample}(u), y =
\textbf{shiftSample}(u), y = \textbf{backSample}(u), y =
\textbf{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));