-
Notifications
You must be signed in to change notification settings - Fork 41
/
classes.tex
1783 lines (1525 loc) · 71.9 KB
/
classes.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{Classes, Predefined Types, and Declarations}\doublelabel{class-predefined-types-and-declarations}
The fundamental structuring unit of modeling in Modelica is the class.
Classes provide the structure for objects, also known as instances.
Classes can contain equations which provide the basis for the executable
code that is used for computation in Modelica. Conventional algorithmic
code can also be part of classes. All data objects in Modelica are
instantiated from classes, including the basic data types---\lstinline!Real!,
\lstinline!Integer!, \lstinline!String!, \lstinline!Boolean!---and enumeration types, which are built-in
classes or class schemata.
Declarations are the syntactic constructs needed to introduce classes
and objects (i.e., components).
\section{Access Control -- Public and Protected Elements}\doublelabel{access-control-public-and-protected-elements}
Members of a Modelica class can have two levels of visibility: \lstinline!public! or
\lstinline!protected!. The default is \lstinline!public! if nothing else is specified
A protected element, \lstinline!P!, in classes and components may not be accessed via dot notation (e.g., \lstinline!A.P!, \lstinline!a.P!, \lstinline!a[1].P!, \lstinline!a.b.P!,
\lstinline!.A.P!; but there is no restriction on using \lstinline!P! or \lstinline!P.x! for a protected element \lstinline!P!). They may not be modified or redeclared except for
modifiers applied to protected elements in a base-class modification (not inside any component or class) and the modifier on the declaration of the protected element.
\begin{example}
\begin{lstlisting}[language=modelica]
package A
model B
protected
parameter Real x;
end B;
protected
model C end C;
public
model D
C c; // Legal use of protected class C from enclosing scope
extends A.B(x=2); // Legal modifier for x in derived class
// also x.start=2 and x(start=2) are legal.
Real y=x; // Legal use of x in derived class
end D;
model E
A.B a(x=2); // Illegal modifier, also x.start=2 and x(start=2) are illegal
A.C c; // Illegal use of protected class C
model F=A.C; // Illegal use of protected class C
end E;
end A;
\end{lstlisting}
\end{example}
All elements defined under the heading \lstinline!protected! are regarded as protected. All other elements (i.e., defined
under the heading \lstinline!public!, without headings or in a separate file) are public (i.e. not protected). Regarding
inheritance of protected and public elements, see \autoref{inheritance-of-protected-and-public-elements}.
\section{Double Declaration not Allowed}\doublelabel{double-declaration-not-allowed}
The name of a declared element shall not have the same name as any other
element in its partially flattened enclosing class. A component shall
not have the same name as its type specifier. However, the internal
flattening of a class can in some cases be interpreted as having two
elements with the same name; these cases are described in \autoref{simultaneous-inner-outer-declarations},
and \autoref{redeclaration}.
\begin{example}
\begin{lstlisting}[language=modelica]
record R
Real x;
end R;
model M // wrong Modelica model
R R; // not correct, since component name and type specifier are identical
equation
R.x = 0;
end M;
\end{lstlisting}
\end{example}
\section{Declaration Order and Usage before Declaration}\doublelabel{declaration-order-and-usage-before-declaration}
Variables and classes can be used before they are declared.
\begin{nonnormative}
In fact, declaration order is only significant for:
\begin{itemize}
\item
Functions with more than one input variable called with positional arguments, \autoref{positional-or-named-input-arguments-of-functions}.
\item
Functions with more than one output variable, \autoref{output-formal-parameters-of-functions}.
\item
Records that are used as arguments to external functions, \autoref{records}.
\item
Enumeration literal order within enumeration types, \autoref{enumeration-types}.
\end{itemize}
\end{nonnormative}
\section{Component Declarations}\doublelabel{component-declarations}
Component declarations are described in this section.
\subsection{Syntax and Examples of Component Declarations}\doublelabel{syntax-and-examples-of-component-declarations}
The formal syntax of a component declaration clause is given by the
following syntactic rules:
\begin{lstlisting}[language=grammar]
component-clause:
type-prefix type-specifier [ array-subscripts ] component-list
type-prefix :
[ flow | stream ]
[ discrete | parameter | constant ] [ input | output ]
type-specifier :
name
component-list :
component-declaration { "," component-declaration }
component-declaration :
declaration [ condition-attribute ] comment
condition-attribute:
if expression
declaration :
IDENT [ array-subscripts ] [ modification ]
\end{lstlisting}
\begin{nonnormative}
The declaration of a component states the type, access,
variability, data flow, and other properties of the component. A
\lstinline!component-clause! i.e., the whole declaration, contains type
prefixes followed by a \lstinline!type-specifier! with optional
\lstinline!array-subscripts! followed by a \lstinline!component-list!.
There is no semantic difference between variables declared in a
single declaration or in multiple declarations. For example, regard the
following single declaration (\lstinline!component-clause!) of two matrix
variables:
\begin{lstlisting}[language=modelica]
Real[2,2] A, B;
\end{lstlisting}
That declaration has the same meaning as the following two
declarations together:
\begin{lstlisting}[language=modelica]
Real[2,2] A;
Real[2,2] B;
\end{lstlisting}
The array dimension descriptors may instead be placed after the
variable name, giving the two declarations below, with the same meaning
as in the previous example:
\begin{lstlisting}[language=modelica]
Real A[2,2];
Real B[2,2];
\end{lstlisting}
The following declaration is different, meaning that the variable
a is a scalar but B is a matrix as above:
\begin{lstlisting}[language=modelica]
Real a, B[2,2];
\end{lstlisting}
\end{nonnormative}
\subsection{Component Declaration Static Semantics}\doublelabel{component-declaration-static-semantics}
If the \lstinline!type-specifier! of the component declaration denotes a built-in
type (\lstinline!RealType!, \lstinline!IntegerType!, etc.), the flattened or instantiated
component has the same type.
If the \lstinline!type-specifier! of the component does not denote a built-in type,
the name of the type is looked up (\autoref{static-name-lookup}). The found type is
flattened with a new environment and the partially flattened enclosing
class of the component. It is an error if the type is partial in a
simulation model, or if a simulation model itself is partial. The new
environment is the result of merging
\begin{itemize}
\item
the modification of enclosing class element-modification with the same
name as the component
\item
the modification of the component declaration
\end{itemize}
in that order.
Array dimensions shall be scalar non-negative parameter expressions of type Integer,
a reference to a type (which must an enumeration type or Boolean, see \autoref{enumeration-types}),
or the colon operator denoting that the array dimension is left unspecified (see \autoref{array-declarations}).
All variants can also be part of short class definitions.
\begin{nonnormative}
Example of variables with array dimensions.
\begin{lstlisting}[language=modelica]
model ArrayVariants
type T=Real[:]; // Unspecified size for type
parameter T x=ones(4);
parameter T y[3]=ones(3, 4);
parameter Real a[2]=ones(2); // Specified using Integer
parameter Real b[2, 0]=ones(2, 0); // Size 0 is allowed
parameter Real c[:]=ones(0); // Unspecified size for variable
parameter Integer n=0;
Real x[n*2]=cat(1,ones(n),zeros(n)};// Parameter expressions are allowed
Boolean notV[Boolean]={true,false}; // Indexing with type
end ArrayVariants;
\end{lstlisting}
\end{nonnormative}
The rules for components in functions are described in \autoref{function-as-a-specialized-class}.
Conditional declarations of components are described in \autoref{conditional-component-declaration}.
\subsubsection{Declaration Equations}\doublelabel{declaration-equations}
An environment that defines the value of a component of built-in type is
said to define a declaration equation associated with the declared
component. For declarations of vectors and matrices, declaration
equations are associated with each element.
Only components of the restricted classes type, record, operator record, and connector, or components of classes inheriting from ExternalObject
may have declaration equations. See also the corresponding rule for algorithms, \autoref{restrictions-on-assigned-variables}.
\subsubsection{Prefix Rules}\doublelabel{prefix-rules}
Variables declared with the \lstinline!flow! or the \lstinline!stream! type prefix shall be a
subtype of Real.
Type prefixes (that is , \lstinline!flow!, \lstinline!stream!, \lstinline!discrete!,
\lstinline!parameter!, \lstinline!constant!,
\lstinline!input!, \lstinline!output!) shall only be applied for type, record and connector
components -- see also record specialized class, \autoref{specialized-classes}.
An exception is \lstinline!input! for components whose type is of the special class
function type (these can only be used for function formal parameters and
has special semantics, see \autoref{functional-input-arguments-to-functions}), and the \lstinline!input! prefix is not
applied to the elements of the component and is allowed even if the
elements have input or output prefix.
In addition, instances of classes extending from ExternalObject may have
type prefixes \lstinline!parameter! and \lstinline!constant!, and in functions also type
prefixes \lstinline!input! and \lstinline!output! - see \autoref{external-objects}.
The type prefixes \lstinline!flow!, \lstinline!stream!, \lstinline!input!
and \lstinline!output! of a structured
component (except as described above) are also applied to the elements
of the component (this is done after verifying that the type prefixes
occurring on elements of the component are correct; e.g. the \lstinline!flow! prefix
can be used on a record component and all the record elements will
generate zero-sum equations, even if elements of a record may not be
declared with the flow prefix). When any of the type prefixes \lstinline!flow!,
\lstinline!stream!, \lstinline!input! and \lstinline!output! are applied for a structured component, no
element of the component may have any of these type prefixes.
The corresponding rules for the type prefixes \lstinline!discrete!,
\lstinline!parameter! and \lstinline!constant! are described in \autoref{variability-of-structured-entities} for structured
components.
\begin{example}
\lstinline!input! can only be used, if none of the elements has a \lstinline!flow!, \lstinline!stream!, \lstinline!input! or
\lstinline!output! type prefix.
\end{example}
The prefixes \lstinline!input! and \lstinline!output! have a slightly different semantic meaning
depending on the context where they are used:
\begin{itemize}
\item
In \emph{functions}, these prefixes define the computational causality
of the function body, i.e., given the variables declared as \lstinline!input!, the
variables declared as \lstinline!output! are computed in the function body, see
\autoref{function-call}.
\item
In \emph{simulation} \emph{models} and \emph{blocks} (i.e., on the top
level of a model or block that shall be simulated), these prefixes
define the interaction with the environment where the simulation model
or block is used. Especially, the \lstinline!input! prefix defines that values for
such a variable have to be provided from the simulation environment
and the \lstinline!output! prefix defines that the values of the corresponding
variable can be directly utilized in the simulation environment, see
the notion of Globally balanced in \autoref{balanced-models}.
\item
In component \emph{models} and \emph{blocks}, the \lstinline!input! prefix defines
that a binding equation has to be provided for the corresponding
variable when the component is utilized in order to guarantee a
locally balanced model (i.e., the number of local equations is
identical to the local number of unknowns), see \autoref{balanced-models}.
\begin{example}
\begin{lstlisting}[language=modelica]
block FirstOrder
input Real u;
...
end FirstOrder;
model UseFirstOrder
FirstOrder firstOrder(u=time); // binding equation for u
...
end UseFirstOrder;
\end{lstlisting}
\end{example}
The \lstinline!output! prefix does not have a particular effect in a model or block
component and is ignored.
\item
In \emph{connectors}, prefixes \lstinline!input! and \lstinline!output! define that the
corresponding connectors can only be connected according to block
diagram semantics, see \autoref{connect-equations-and-connectors} (e.g., a connector with an \lstinline!output!
variable can only be connected to a connector where the corresponding
variable is declared as \lstinline!input!). There is the restriction that
connectors which have at least one variable declared as \lstinline!input! must be
externally connected, see \autoref{balanced-models} (in order to get a locally
balanced model, where the number of local unknowns is identical to the
number of unknown equations). Together with the block diagram
semantics rule this means, that such connectors must be connected
\emph{exactly once externally}.
\item
In \emph{records}, prefixes \lstinline!input! and \lstinline!output! are not allowed, since
otherwise a record could not be, e.g., passed as input argument to a
function.
\end{itemize}
\subsection{Acyclic Bindings of Constants and Parameters}\doublelabel{acyclic-bindings-of-constants-and-parameters}
The unexpanded binding equations for parameters and constants in the
translated model must be acyclic after flattening; except that cycles
are allowed if the cycles disappear when evaluating parameters having
annotation Evaluate=true that are not part of the cycle. Thus it is not
possible to introduce equations for parameters by cyclic dependencies.
\begin{example}
\begin{lstlisting}[language=modelica]
constant Real p=2*q;
constant Real q=sin(p); // Illegal since p=2*q, q=sin(p) are cyclical
model ABCD
parameter Real A[n,n];
parameter Integer n=size(A,1);
end ABCD;
final ABCD a;
// Illegal since cyclic dependencies between size(a.A,1) and a.n
ABCD b(redeclare Real A[2,2]=[1,2;3,4]);
// Legal since size of A is no longer dependent on n.
ABCD c(n=2); // Legal since n is no longer dependent on the size of A.
parameter Real r = 2*sin(r); // Illegal, since r = 2*sin(r) is cyclic
partial model PartialLumpedVolume
parameter Boolean use_T_start = true "= true, use T_start, otherwise h_start"
annotation(Dialog(tab = "Initialization"), Evaluate=true);
parameter Medium.Temperature T_start=if use_T_start then system.T_start else
Medium.temperature_phX(p_start,h_start,X_start)
annotation(Dialog(tab = "Initialization", enable = use_T_start));
parameter Medium.SpecificEnthalpy h_start=if use_T_start then
Medium.specificEnthalpy_pTX(p_start, T_start, X_start) else Medium.h_default
annotation(Dialog(tab = "Initialization", enable = not use_T_start));
end PartialLumpedVolume;
// Cycle for T_start and h_start, but ok since disappears
// when evaluating use_T_start
// Illegal since the unexpanded bindings have cycles for both x and y
// (even if they would disappear if bindings were expanded).
model HasCycles
parameter Integer n=10;
final constant Real A[3,3]=[0,0,0;1,0,0;2,3,0];
parameter Real y[3]=A*y+ones(3);
parameter Real x[n]=cat(1, {3.4}, x[1:(n-1)]);
end HasCycles;
\end{lstlisting}
\end{example}
\subsection{Component Variability Prefixes discrete, parameter, constant}\doublelabel{component-variability-prefixes-discrete-parameter-constant}
The prefixes \lstinline!discrete!, \lstinline!parameter!, \lstinline!constant! of a component declaration
are called variability prefixes and define in which situation the
variable values of a component are initialized (see \autoref{events-and-synchronization} and
\autoref{initialization-initial-equation-and-initial-algorithm}) and when they are changed in transient analysis (= solution
of initial value problem of the hybrid DAE):
\begin{itemize}
\item
A variable \lstinline!vc! declared with \lstinline!constant! prefix remains constant during transient analysis,
with a value that is unaffected by the initialization problem.
\item
A variable \lstinline!vc! declared with the \lstinline!parameter! prefix remains constant during transient analysis,
with a value determined by the initialization problem.
\item
A \emph{discrete-time} variable \lstinline!vd! has a vanishing time derivative between events.
Note that this is not the same as saying that \lstinline!der(vd)=0! almost everywhere,
as the derivative is not even defined at the events, and it is not legal
to apply \lstinline!der! to discrete-time variables as they are not continuous. During transient analysis the variable
can only change its value at event
instants (see \autoref{events-and-synchronization}).
\item
A \emph{continuous-time} variable \lstinline!vn! may have a non-vanishing time
derivative (\lstinline!der(vn)<>0! possible) and may also
change its value discontinuously at any time during transient analysis
(see \autoref{events-and-synchronization}). If there are any discontinuities the variable is
not differentiable.
\end{itemize}
If a \lstinline!Real! variable is declared with the prefix \lstinline!discrete! it must in a
simulation model be assigned in a when-clause, either by an assignment
or an equation. The variable assigned in a when-clause may not be
defined in a sub-component of model or block specialized class.
(This is to keep the property of balanced models.)
A \lstinline!Real! variable assigned in a when-clause is a discrete-time variable,
even though it was not declared with the prefix \lstinline!discrete!. A \lstinline!Real!
variable not assigned in any when-clause and without any type prefix is
a continuous-time variable.
The default variability for \lstinline!Integer!, \lstinline!String!,
\lstinline!Boolean!, or \lstinline!enumeration!
variables is discrete-time, and it is not possible to declare
continuous-time \lstinline!Integer!, \lstinline!String!, \lstinline!Boolean!, or
\lstinline!enumeration! variables.
\begin{nonnormative}
A Modelica translator is able to guarantee this property due to
restrictions imposed on discrete expressions, see \autoref{variability-of-expressions}.
\end{nonnormative}
The variability of expressions and restrictions on variability for
definition equations is given in \autoref{variability-of-expressions}.
\begin{nonnormative}
A discrete-time variable is a piecewise constant signal which
changes its values only at event instants during simulation. Such types
of variables are needed in order that special algorithms, such as the
algorithm of Pantelides for index reduction, can be applied (it must be
known that the time derivative of these variables is identical to zero).
Furthermore, memory requirements can be reduced in the simulation
environment, if it is known that a component can only change at event
instants.
A parameter variable is constant during simulation. This prefix
gives the library designer the possibility to express that the physical
equations in a library are only valid if some of the used components are
constant during simulation. The same also holds for discrete-time and
constant variables. Additionally, the parameter prefix allows a
convenient graphical user interface in an experiment environment, to
support quick changes of the most important constants of a compiled
model. In combination with an if-clause, a parameter prefix allows to
remove parts of a model before the symbolic processing of a model takes
place in order to avoid variable causalities in the model (similar to
\lstinline!#ifdef! in C). Class parameters can be sometimes used as an alternative.
Example:
\begin{lstlisting}[language=modelica]
model Inertia
parameter Boolean state = true;
...
equation
J*a = t1 - t2;
if state then // code which is removed during symbolic
der(v) = a; // processing, if state=false
der(r) = v;
end if;
end Inertia;
\end{lstlisting}
A constant variable is similar to a parameter with the difference
that constants cannot be changed after translation and usually not
changed after they have been given a value. It can be used to represent
mathematical constants, e.g.
\begin{lstlisting}[language=modelica]
final constant Real PI=4*atan(1);
\end{lstlisting}
There are no continuous-time \lstinline!Boolean!, \lstinline!Integer! or \lstinline!String!
variables. In the rare cases they are needed they can be
faked by using \lstinline!Real! variables, e.g.:
\begin{lstlisting}[language=modelica]
Boolean off1, off1a;
Real off2;
equation
off1 = s1 < 0;
off1a = noEvent(s1 < 0); // error, since off1a is discrete
off2 = if noEvent(s2 < 0) then 1 else 0; // possible
u1 = if off1 then s1 else 0; // state events
u2 = if noEvent(off2 > 0.5) then s2 else 0; // no state events
\end{lstlisting}
Since \lstinline!off1! is a discrete-time variable, state events are
generated such that \lstinline!off1! is only changed at event instants.
Variable \lstinline!off2! may change its value during continuous integration.
Therefore, \lstinline!u1! is guaranteed to be continuous during continuous
integration whereas no such guarantee exists for \lstinline!u2!.
\end{nonnormative}
\subsubsection{Variability of Structured Entities}\doublelabel{variability-of-structured-entities}
For elements of structured entities with variability prefixes the most
restrictive of the variability prefix and the variability of the
component wins (using the default variability for the component if there
is no variability prefix on the component).
\begin{example}
\begin{lstlisting}[language=modelica]
record A
constant Real pi=3.14;
Real y;
Integer i;
end A;
parameter A a;
// a.pi is a constant
// a.y and a.i are parameters
A b;
// b.pi is a constant
// b.y is a continuous-time variable
// b.i is a discrete-time variable
\end{lstlisting}
\end{example}
\subsection{Conditional Component Declaration}\doublelabel{conditional-component-declaration}
A component declaration can have a \lstinline!condition-attribute!: \lstinline!if!~\emph{expression}.
\begin{example}
\begin{lstlisting}[language=modelica]
parameter Integer level(min=1)=1;
Motor motor;
Level1 component1(J=J) if level==1 "Conditional component";
Level2 component2 if level==2 "Conditional component";
Level3 component3(J=component1.J) if level<2 "Conditional component";
// Illegal modifier on component3 since component1.J is conditional
// Even if we can see that component1 always exist if component3 exist
equation
connect(component1..., ...) "Connection to conditional component 1";
connect(component2.n, motor.n) "Connection to conditional component 2";
connect(component3.n, motor.n) "Connection to conditional component 3";
component1.u=0; // Illegal
\end{lstlisting}
\end{example}
The \emph{expression} must be a \lstinline!Boolean! scalar expression, and must be a
parameter-expression.
\begin{nonnormative}
A parameter-expression is required since it shall be evaluated at compile time.
\end{nonnormative}
A redeclaration of a component may not include a condition attribute;
and the condition attribute is kept from the original declaration (see
\autoref{interface-compatibility-or-subtyping}).
If the \lstinline!Boolean! expression is false the component (including its modifier) is removed from the flattened DAE, and
connections to/from the component are removed. A component declared with a condition-attribute can only be modified and/or
used in connections
\begin{nonnormative}
Adding the component and then removing it ensures that the component is valid.
If a connect statement defines the connection of a non-conditional component \lstinline!c1! with a conditional
component \lstinline!c2! and \lstinline!c2! is de-activated, then \lstinline!c1! must still be a declared element.
\end{nonnormative}
If the condition is true for a public connector containing flow
variables the connector must be connected from the outside.
\begin{nonnormative}
The reason for this restriction is that the default flow equation is probably incorrect (since it could otherwise
be an unconditional connector) and the model cannot check that connector is connected.
\end{nonnormative}
\section{Class Declarations}\doublelabel{class-declarations}
Essentially everything in Modelica is a class, from the predefined
classes \lstinline!Integer! and \lstinline!Real!, to large packages such as the Modelica
standard library.
\begin{example}
A rather typical structure of a Modelica class is
shown below. A class with a name, containing a number of declarations
followed by a number of equations in an equation section.
\begin{lstlisting}[language=modelica]
class ClassName
Declaration1
Declaration2
...
equation
equation1
equation2
...
end ClassName;
\end{lstlisting}
\end{example}
The following is the formal syntax of class definitions, including the
special variants described in later sections.
\begin{lstlisting}[language=grammar]
class-definition :
[ encapsulated ] class-prefixes
class-specifier
class-prefixes :
[ partial ]
( class | model | [ operator ] record | block | [ expandable ] connector | type |
package | [ ( pure | impure ) ] [ operator ] function | operator )
class-specifier :
long-class-specifier | short-class-specifier | der-class-specifier
long-class-specifier :
IDENT description-string composition end IDENT
| extends IDENT [ class-modification ] description-string composition
end IDENT
short-class-specifier :
IDENT "=" base-prefix name [ array-subscripts ]
[ class-modification ] comment
| IDENT "=" enumeration "(" ( [enum-list] | ":" ) ")" comment
der-class-specifier :
IDENT "=" der "(" name "," IDENT { "," IDENT } ")" comment
base-prefix :
[ input | output ]
enum-list : enumeration-literal { "," enumeration-literal}
enumeration-literal : IDENT comment
composition :
element-list
{ public element-list |
protected element-list |
equation-section |
algorithm-section
}
[ external [ language-specification ]
[ external-function-call ] [ annotation ] ";" ]
[ annotation ";" ]
\end{lstlisting}
\subsection{Short Class Definitions}\doublelabel{short-class-definitions}
A class definition of the form
\begin{lstlisting}[language=modelica]
class IDENT1 = IDENT2 class-modification;
\end{lstlisting}
is identical, except that IDENT2 may be replaceable and for the lexical
scope of modifiers, where the short class definition does not introduce
an additional lexical scope for modifiers, to the longer form
\begin{lstlisting}[language=modelica]
class IDENT1
extends IDENT2 class-modification;
end IDENT1;
\end{lstlisting}
\begin{example}
Demonstrating the difference in scopes:
\begin{lstlisting}[language=modelica]
model Resistor
parameter Real R;
...
end Resistor;
model A
parameter Real R;
replaceable model Load=Resistor(R=R) constrainedby TwoPin;
// Correct, sets the R in Resistor to R from model A.
replaceable model LoadError
extends Resistor(R=R);
// Gives the singular equation R=R, since the right-hand side R
// is searched for in LoadError and found in its base-class Resistor.
end LoadError constrainedby TwoPin;
Load a,b,c;
ConstantSource ...;
...
end A;
\end{lstlisting}
\end{example}
A short class definition of the form
\begin{lstlisting}[language=modelica]
type TN = T[N] (optional modifier);
\end{lstlisting}
where N represents arbitrary array dimensions, conceptually yields an
array class
\begin{lstlisting}[language=modelica]
'array' TN
T[n] _ (optional modifiers);
'end' TN;
\end{lstlisting}
Such an array class has exactly one anonymous component (\_); see also
\autoref{restriction-on-combining-base-classes-and-other-elements}.
When a component of such an array class type is
flattened, the resulting flattened component type is an array type with
the same dimensions as \_ and with the optional modifier applied.
\begin{example}
The types of \lstinline!f1! and \lstinline!f2! are identical:
\begin{lstlisting}[language=modelica]
type Force = Real[3](unit={"Nm","Nm","Nm"});
Force f1;
Real f2[3](unit={"Nm","Nm","Nm"});
\end{lstlisting}
\end{example}
If a short class definition inherits from a partial class the new class
definition will be partial, regardless of whether it is declared with
the keyword partial or not.
\begin{example}
\begin{lstlisting}[language=modelica]
replaceable model Load=TwoPin;
Load R; // Error unless Load is redeclared since TwoPin is a partial class.
\end{lstlisting}
\end{example}
If a short class definition does not specify any specialized class the
new class definition will inherit the specialized class (this rule
applies iteratively and also for redeclare).
A base-prefix applied in the short-class definition does not influence
its type, but is applied to components declared of this type or types
derived from it; see also \autoref{restriction-on-combining-base-classes-and-other-elements}.
\begin{example}
\begin{lstlisting}[language=modelica]
type InArgument = input Real;
type OutArgument = output Real[3];
function foo
InArgument u; // Same as: input Real u
OutArgument y; // Same as: output Real[3] y
algorithm
y:=fill(u,3);
end foo;
Real x[:]=foo(time);
\end{lstlisting}
\end{example}
\subsection{Restriction on combining base-classes and other elements}\doublelabel{restriction-on-combining-base-classes-and-other-elements}
It is not legal to combine other components or base-classes with an
extends from an array class, a class with non-empty base-prefix, a
simple type (Real, Boolean, Integer, String and enumeration types), or
any class transitively extending from an array class, a class with
non-empty base-prefix, or a simple type (Real, Boolean, Integer, String
and enumeration types).
\begin{example}
\begin{lstlisting}[language=modelica]
model Integrator
input Real u;
output Real y=x;
Real x;
equation
der(x)=u;
end Integrator;
model Integrators = Integrator[3]; // Legal
model IllegalModel
extends Integrators;
Real x; // Illegal combination of component and array class
end IllegalModel;
connector IllegalConnector
extends Real;
Real y; // Illegal combination of component and simple type
end IllegalConnector;
\end{lstlisting}
\end{example}
\subsection{Local Class Definitions -- Nested Classes}\doublelabel{local-class-definitions-nested-classes}
The local class should be statically flattenable with the partially
flattened enclosing class of the local class apart from local class
components that are partial or \lstinline!outer!. The environment is the
modification of any enclosing class element modification with the same
name as the local class, or an empty environment.
The unflattened local class together with its environment becomes an
element of the flattened enclosing class.
\begin{example}
The following example demonstrates parameterization of a local class:
\begin{lstlisting}[language=modelica]
model C1
type Voltage = Real(nominal=1);
Voltage v1, v2;
end C1;
model C2
extends C1(Voltage(nominal=1000));
end C2;
\end{lstlisting}
Flattening of class \lstinline!C2! yields a local class \lstinline!Voltage! with
\lstinline!nominal!-modifier \lstinline!1000!. The variables \lstinline!v1! and \lstinline!v2! are
instances of this local class and thus have a nominal value of 1000.
\end{example}
\section{Specialized Classes}\doublelabel{specialized-classes}
Specialized kinds of classes (earlier known as \emph{restricted classes})
\lstinline!record!, \lstinline!type!, \lstinline!model!, \lstinline!block!, \lstinline!package!, \lstinline!function! and \lstinline!connector!
have the properties of a general class, apart from restrictions.
Moreover, they have additional properties called enhancements. The
following table summarizes the definition of the specialized classes
(additional restrictions on inheritance are in \autoref{restrictions-on-the-kind-of-base-class}):
\begin{longtable}{|p{4cm}|p{9cm}|}
\hline \endhead
\lstinline!record! & Only public sections are allowed in the definition or
in any of its components (i.e., equation, algorithm, initial equation,
initial algorithm and protected sections are not allowed). The elements
of a record may not have prefixes \lstinline!input!, \lstinline!output!,
\lstinline!inner!, \lstinline!outer!, \lstinline!stream,!
or \lstinline!flow!. Enhanced with implicitly available record constructor function,
see \autoref{record-constructor-functions}. The components
directly declared in a record may only be of specialized class record
or type.\\ \hline
\lstinline!type! & May only be predefined types, enumerations, array of
type, or classes extending from type.\\ \hline
\lstinline!model! & The normal modeling class in Modelica.\\ \hline
\lstinline!block! & Same as \lstinline!model! with the restriction that each connector
component of a \lstinline!block! must have prefixes \lstinline!input! and/or \lstinline!output! for all
connector variables.
\par
\begin{nonnormative*}
The purpose is to model input/output blocks of block diagrams. Due to the restrictions on \lstinline!input! and \lstinline!output! prefixes,
connections between blocks are only possible according to block diagram semantic.
\end{nonnormative*}
\\ \hline
\lstinline!function! & See \autoref{function-as-a-specialized-class} for restrictions
and enhancements of functions. Enhanced to allow the
function to contain an external function interface.
\par
\begin{nonnormative*}
Non-function specialized classes do not have this property.
\end{nonnormative*}
\\ \hline
\lstinline!connector! & Only public sections are allowed in the definition or in any of its
components (i.e., equation, algorithm, initial equation, initial
algorithm and protected sections are not allowed).
Enhanced to allow \lstinline!connect! to components of connector classes. The
elements of a connector may not have prefixes \lstinline!inner!, or \lstinline!outer!. May only
contain components of specialized class connector, record and
type.\\ \hline
\lstinline!package! & May only contain declarations of classes and
constants. Enhanced to allow \lstinline!import! of elements of packages. (See also
\autoref{packages} on packages.)\\ \hline
\lstinline!operator record! & Similar to record; but operator overloading
is possible, and due to this the typing rules are different -- see
\autoref{interface-or-type-relationships}. It is not legal to extend from an operator record (or
connector inheriting from operator record), except if the new class is
an operator record or connector that is declared as a short class
definition, whose modifier is either empty or only modify the default
attributes for the component elements directly inside the operator
record. An operator record can only extend from an operator record. It is not legal to extend
from any of its enclosing scopes. (See \autoref{overloaded-operators}).
\\ \hline
\lstinline!operator! & Similar to package; but may only contain
declarations of functions. May only be placed directly in an operator
record. (See also \autoref{overloaded-operators}).\\ \hline
\lstinline!operator function! & Shorthand for an
operator with exactly one function; same restriction as function class
and in addition may only be placed directly in an operator
record.
\begin{nonnormative}
A function declaration
\begin{lstlisting}[language=modelica]
operator function foo ... end foo;
\end{lstlisting}
is conceptually treated as
\begin{lstlisting}[language=modelica]
operator foo function foo1
...
end foo1; end foo;
\end{lstlisting}
\end{nonnormative}
\\ \hline
\end{longtable}
Additionally only components which are of specialized classes \lstinline!record!, \lstinline!type!, \lstinline!operator record!, and
connector classes based on any of those can be used as component references in normal expressions and in the left hand
side of assignments, subject to normal type compatibility rules.
Additionally components of connectors may be arguments of connect-statements,
and any component can be used as argument to the \lstinline!ndims! and \lstinline!size!-functions, or for accessing
elements of that component (possibly in combination with array indexing).
\begin{example}
Use of \lstinline!operator!:
\begin{lstlisting}[language=modelica]
operator record Complex
Real re;
Real im;
...
encapsulated operator function '*'
import Complex;
input Complex c1;
input Complex c2;
output Complex result
algorithm
result := Complex(re=c1.re*c2.re - c1.im*c2.im,
im=c1.re*c2.im + c1.im*c2.re);
end '*';
end Complex;
record MyComplex
extends Complex; // not allowed, since extending from enclosing scope
Real k;
end MyComplex;
operator record ComplexVoltage = Complex(re(unit="V"),im(unit="V")); // allowed
\end{lstlisting}
\end{example}
\section{Balanced Models}\doublelabel{balanced-models}
\begin{nonnormative}
In this section restrictions for model and block classes are
present, in order that missing or too many equations can be detected and
localized by a Modelica translator before using the respective model or
block class. A non-trivial case is demonstrated in the following
example:
\begin{lstlisting}[language=modelica]
partial model BaseCorrelation
input Real x;
Real y;
end BaseCorrelation;
model SpecialCorrelation // correct in Modelica 2.2 and 3.0
extends BaseCorrelation(x=2);
equation
y=2/x;
end SpecialCorrelation;
model UseCorrelation // correct according to Modelica 2.2
// not valid according to Modelica 3.0
replaceable model Correlation=BaseCorrelation;
Correlation correlation;
equation
correlation.y=time;
end UseCorrelation;
model Broken // after redeclaration, there is 1 equation too much in Modelica 2.2
UseCorrelation example(redeclare Correlation=SpecialCorrelation);
end Broken;
\end{lstlisting}
In this case one can argue that both \lstinline!UseCorrelation! (adding
an acausal equation) and \lstinline!SpecialCorrelation! (adding a default to
an input) are correct, but still when combined they lead to a model with
too many equations -- and it is not possible to determine which model is
incorrect without strict rules, as the ones defined here.
In Modelica 2.2, model \lstinline!Broken! will work with some models.
However, by just redeclaring it to model \lstinline!SpecialCorrelation!, an
error will occur and it will be very difficult in a larger model to
figure out the source of this error.
In Modelica 3.0, model \lstinline!UseCorrelation! is no longer allowed
and the translator will give an error. In fact, it is guaranteed that a
redeclaration cannot lead to an unbalanced model any more.
\end{nonnormative}
The restrictions below apply after flattening -- i.e. inherited
components are included -- possibly modified. The corresponding
restrictions on connectors and connections are in \autoref{restrictions-of-connections-and-connectors}.
\textbf{Definition 1: Local Number of Unknowns}
The \firstuse{local number of unknowns} of a model or block class is the sum based
on the components:
\begin{itemize}
\item
For each declared component of specialized class \lstinline!type! (Real, Integer,
String, Boolean, enumeration and arrays of those, etc.) or \lstinline!record!, or
\lstinline!operator record! not declared as \lstinline!outer!, it is the number of unknown
variables inside it (i.e., excluding parameters and constants and
counting the elements after expanding all records, operator record,
and arrays to a set of scalars of primitive types).
\item
Each declared component of specialized class \lstinline!type! or record declared
as \lstinline!outer! is ignored.
\begin{nonnormative}
I.e., all variables inside the component are treated as known.
\end{nonnormative}
\item
For each declared component of specialized class \lstinline!connector! component,
it is the number of unknown variables inside it (i.e., excluding
parameters and constants and counting the elements after expanding all
records and arrays to a set of scalars of primitive types).
\item
For each declared component of specialized class \lstinline!block! or \lstinline!model!, it is
the sum of the number of inputs and flow variables in the (top
level) public connector components of these components (and counting
the elements after expanding all records and arrays to a set of
scalars of primitive types).
\end{itemize}
\textbf{Definition 2: Local Equation Size}
The \firstuse{local equation size} of a model or block class is the sum of the
following numbers:
\begin{itemize}
\item
The number of equations defined locally (i.e. not in any model or