forked from modelica/ModelicaSpecification
-
Notifications
You must be signed in to change notification settings - Fork 2
/
stream.tex
422 lines (381 loc) · 19.9 KB
/
stream.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
\chapter{Stream Connectors}\doublelabel{stream-connectors}
The two basic variable types in a connector --- \emph{potential} (or \emph{across})
variable and \emph{flow} (or \emph{through}) variable --- are not sufficient to
describe in a numerically sound way the bi-directional flow of matter
with convective transport of specific quantities, such as specific
enthalpy and chemical composition. The values of these specific
quantities are determined from the upstream side of the flow, i.e., they
depend on the flow direction. When using across and through variables,
the corresponding models would include nonlinear systems of equations
with Boolean unknowns for the flow directions and singularities around
zero flow. Such equation systems cannot be solved reliably in general.
The model formulations can be simplified when formulating two different
balance equations for the two possible flow directions. This is not
possible with across and through variables though.
This fundamental problem is addressed in Modelica by introducing a third
type of connector variable, called stream variable, declared with the
prefix \lstinline!stream!. A stream variable describes a quantity that is
carried by a flow variable, i.e., a purely convective transport
phenomenon. The value of the stream variable is the specific property
inside the component close to the boundary, assuming that matter flows
out of the component into the connection point. In other words, it is
the value the carried quantity would have if the fluid was flowing out
of the connector, irrespective of the actual flow direction.
The rationale of the definition and typical use cases are described in
\autoref{derivation-of-stream-equations}.
\section{Definition of Stream Connectors}\doublelabel{definition-of-stream-connectors}
If at least one variable in a connector has the \lstinline!stream! prefix,
the connector is called \firstuse{stream connector} and the corresponding
variable is called \firstuse{stream variable}. The following definitions hold:
\begin{itemize}
\item
The \lstinline!stream! prefix can only be used in a connector
declaration.
\item
A stream connector must have exactly one scalar variable with the \lstinline!flow! prefix.
\begin{nonnormative}
The idea is that all stream variables of a connector are associated with this flow variable.
\end{nonnormative}
\item
For every outside connector (see \autoref{inside-and-outside-connectors}), one
equation is generated for every variable with the \lstinline!stream!
prefix (to describe the propagation of the stream variable
along a model hierarchy). For the exact definition, see the end of
\autoref{stream-operator-instream-and-connection-equations}.
\item
For inside connectors (see \autoref{inside-and-outside-connectors}), variables
with the \lstinline!stream! prefix do not lead to connection equations.
\item
Connection equations with stream variables are generated in a model when using \lstinline!inStream! or \lstinline!actualStream!,
see \autoref{stream-operator-instream-and-connection-equations} and \autoref{stream-operator-actualstream}.
\end{itemize}
\begin{example}
\begin{lstlisting}[language=modelica]
connector FluidPort
replaceable package Medium =
Modelica.Media.Interfaces.PartialMedium;
Medium.AbsolutePressure p "Pressure in connection point";
flow Medium.MassFlowRate m_flow "> 0, if flow into component";
stream Medium.SpecificEnthalpy h_outflow "h close to port if m_flow < 0";
stream Medium.MassFraction X_outflow[Medium.nX] "X close to port if m_flow < 0";
end FluidPort;
\end{lstlisting}
\lstinline!FluidPort! is a stream connector, because some connector variables
have the \lstinline!stream! prefix. The Medium definition and the stream
variables are associated with the only flow variable (\lstinline!m_flow!) that
defines a fluid stream. The Medium and the stream variables are
transported with this flow variable. The stream variables \lstinline!h_outflow! and
\lstinline!X_outflow! are the stream properties inside the component close to the
boundary, when fluid flows out of the component into the connection
point. The stream properties for the other flow direction can be
inquired with the built-in \lstinline!inStream!. The value of
the stream variable corresponding to the actual flow direction can be
inquired through the built-in \lstinline!actualStream!, see
\autoref{stream-operator-actualstream}.
\end{example}
\section{Stream Operator inStream and Connection Equations}\doublelabel{stream-operator-instream-and-connection-equations}
In combination with the stream variables of a connector, \lstinline!inStream! is designed to describe in a numerically
reliable way the bi-directional transport of specific quantities carried
by a flow of matter.
\lstinline!inStream(v)! is only allowed on stream variables \lstinline!v! and is
informally the value the stream variable has, assuming that the flow is
from the connection point into the component. This value is computed
from the stream connection equations of the flow variables and of the
stream variables.
For the following definition it is assumed that $N$ inside connectors
\lstinline!$m_{j}$.c! ($j = 1, 2, \ldots, N$) and $M$ outside connectors
\lstinline!$c{k}$! ($k = 1, 2, \ldots, M$) belonging to the same connection set
(see definition in \autoref{inside-and-outside-connectors}) are connected
together and a stream variable \lstinline!h_outflow! is associated with a flow
variable \lstinline!m_flow! in connector \lstinline!c!.
\begin{lstlisting}[language=modelica]
connector FluidPort
...
flow Real m_flow "Flow of matter; m_flow > 0 if flow into component";
stream Real h_outflow "Specific variable in component if m_flow < 0"
end FluidPort
model FluidSystem
...
FluidComponent $m_1$, $m_2$, ..., $m_N$;
FluidPort $c_1$, $c_2$, ..., $c_M$;
equation
connect($m_1$.c, $m_2$.c);
connect($m_1$.c, $m_3$.c);
...
connect($m_1$.c, $m_N$.c);
connect($m_1$.c, $c_1$);
connect($m_1$.c, $c_2$);
...
connect($m_1$.c, $c_M$);
...
end FluidSystem;
\end{lstlisting}
\begin{figure}[H]
\caption{Examplary FluidSystem with $N$=3 and $M$=2}
\begin{center}
\includegraphics[width=2.3in,height=2.08125in]{fluidsystem}
\end{center}
\end{figure}
\begin{nonnormative}
The connection set represents an infinitesimally small control
volume, for which the stream connection equations are equivalent to the
conservation equations for mass and energy.
\end{nonnormative}
With these prerequisites, the semantics of the expression
\lstinline!inStream($m_{i}$.c.h_outflow)! is given implicitly by
defining an additional variable $\mathit{h\_mix\_in}_{i}$, and by
adding to the model the conservation equations for mass and energy
corresponding to the infinitesimally small volume spanning the
connection set. The connection equation for the flow variables has
already been added to the system according to the connection semantics
of flow variables defined in \autoref{generation-of-connection-equations}.
\begin{lstlisting}[language=modelica]
// Standard connection equation for flow variables
0 = sum($m_{j}$.c.m_flow for j in 1:N) + sum(-$c_{k}$.m_flow for k in 1:M);
\end{lstlisting}
Whenever \lstinline!inStream! is applied to a stream variable of an inside connector, the balance equation of the transported
property must be added under the assumption of flow going into the connector
\begin{lstlisting}[language=modelica]
// Implicit definition of inStream applied to inside connector $i$
0 =
sum($m_{j}$.c.m_flow *
(if $m_{j}$.c.m_flow > 0 or $j$==$i$ then $\mathit{h\_mix\_in}_{i}$ else $m_{j}$.c.h_outflow)
for $j$ in 1:N) +
sum(-$c_{k}$.m_flow *
(if -$c_{k}$.m_flow > 0 then $\mathit{h\_mix\_in}_{i}$ else inStream($c_{k}$.h_outflow)
for $k$ in 1:M);
inStream($m_{i}$.c.h_outflow) = $\mathit{h\_mix\_in}_{i}$;
\end{lstlisting}
Note that the result of
\lstinline!inStream($m_{i}$.c.h_outflow)! is different
for each port $i$, because the assumption of flow entering the port is
different for each of them.
Additional equations need to be generated for the stream variables of
outside connectors.
\begin{lstlisting}[language=modelica]
// Additional connection equations for outside connectors
for q in 1:M loop
0 =
sum($m_j$.c.m_flow *
(if $m_j$.c.m_flow > 0 then $\mathit{h\_mix\_out}_{q}$ else $m_j$.c.h_outflow)
for j in 1:N) +
sum(-$c_k$.m_flow *
(if -$c_k$.m_flow > 0 or k==q then $\mathit{h\_mix\_out}_{q}$ else inStream($c_k$.h_outflow))
for k in 1:M);
$c_q$.h_outflow = $\mathit{h\_mix\_out}_{q}$;
end for;
\end{lstlisting}
Neglecting zero flow conditions, the solution of the above-defined
stream connection equations for \lstinline!inStream! values of inside connectors and
outflow stream variables of outside connectors is (for a derivation, see
\autoref{derivation-of-stream-equations}):
\begin{lstlisting}[language=modelica]
inStream($m_i$.c.h_outflow) :=
(sum(max(-$m_j$.c.m_flow,0)*$m_j$.c.h_outflow for j in cat(1, 1:i-1, i+1:N) +
sum(max( $c_k$.m_flow,0)*inStream($c_k$.h_outflow) for k in 1:M))
/
(sum(max(-$m_j$.c.m_flow,0) for j in cat(1, 1:i-1, i+1:N) +
sum(max( $c_k$.m_flow ,0) for k in 1:M));
// Additional equations to be generated for outside connectors q
for q in 1:M loop
$c_q$.h_outflow :=
(sum(max(-$m_j$.c.m_flow,0)*$m_j$.c.h_outflow for j in 1:N) +
sum(max( $c_k$.m_flow,0)*inStream($c_k$.h_outflow) for k in cat(1, 1:q-1, q+1:M))
/
(sum(max(-$m_j$.c.m_flow,0) for j in 1:N) +
sum(max( $c_k$.m_flow ,0) for k in cat(1, 1:q-1, q+1:M)));
end for;
\end{lstlisting}
\begin{nonnormative}
Note, that \lstinline!inStream($c_{k}$.h_outflow)! is computed from the connection set that is present one hierarchical level above. At this higher level
\lstinline!$c_{k}$.h_outflow! is no longer an outside connector, but an inside connector and then the formula from above for inside connectors can be used
to compute it.
\end{nonnormative}
If the argument of \lstinline!inStream! is an array, the implicit
equation system holds elementwise, i.e., \lstinline!inStream! is
vectorizable.
The stream connection equations have singularities and/or multiple
solutions if one or more of the flow variables become zero. When all the
flows are zero, a singularity is always present, so it is necessary to
approximate the solution in an open neighbourhood of that point.
\begin{nonnormative}
For example, assume that \lstinline!$m_{j}$.c.m_flow = $c_{k}$.m_flow = 0!, then all equations above are identically fulfilled and \lstinline!inStream! can have any value.
\end{nonnormative}
However, specific optimizations may be applied to avoid the regularization if the flow through one port is zero or non-negative, see \autoref{derivation-of-stream-equations}.
It is required that \lstinline!inStream! is appropriately approximated when regularization is needed and the approximation must fulfill the following requirements:
\begin{enumerate}
\item
\lstinline!inStream($m_{i}$.c.h_outflow)! and
\lstinline!inStream($c_{k}$.h_outflow)! must be unique with
respect to all values of the flow and stream variables in the
connection set, and must have a continuous dependency on them.
\item
Every solution of the implicit equation system above must fulfill the
equation system identically (upto the usual numerical
accuracy), provided the absolute value of every flow variable in
the connection set is greater than a small value
($\abs{m_{i}\text{\lstinline!.c.m_flow!}} > \text{\lstinline!eps!}$ for $1 \leq i \leq N$ and
$\abs{c_{i}\text{\lstinline!.m_flow!}} > \text{\lstinline!eps!}$ for $1 \leq i \leq M$).
\end{enumerate}
\begin{nonnormative}
Based on the above requirements, the following implementation is recommended:
\begin{itemize}
\item $N = 1,\, M = 0$:\hfill
\begin{lstlisting}[language=modelica]
inStream($m_1$.c.h_outflow) = $m_1$.c.h_outflow;
\end{lstlisting}
\item $N = 2,\, M = 0$:\hfill
\begin{lstlisting}[language=modelica]
inStream($m_1$.c.h_outflow) = $m_2$.c.h_outflow;
inStream($m_2$.c.h_outflow) = $m_1$.c.h_outflow;
\end{lstlisting}
\item $N = 1,\, M = 1$:\hfill
\begin{lstlisting}[language=modelica]
inStream($m_1$.c.h_outflow) = inStream($c_1$.h_outflow);
// Additional equation to be generated
$c_1$.h_outflow = $m_1$.c.h_outflow;
\end{lstlisting}
\item $N = 0,\, M = 2$:\hfill
\begin{lstlisting}[language=modelica]
// Additional equation to be generated
$c_{1}$.h_outflow = inStream($c_{2}$.h_outflow);
$c_{2}$.h_outflow = inStream($c_{1}$.h_outflow);
\end{lstlisting}
\item All other cases:\hfill
\begin{lstlisting}[language=modelica]
if $m_j$.c.m_flow.min >= 0 for all j = 1:N with j <> i and
$c_k$.m_flow.max <= 0 for all k = 1:M
then
inStream($m_i$.c.h_outflow) = $m_i$.c.h_outflow;
else
si = sum (max(-$m_j$.c.m_flow,0) for j in cat(1,1:i-1, i+1:N) +
sum(max( $c_k$.m_flow ,0) for k in 1:M);
inStream($m_i$.c.h_outflow) =
(sum(positiveMax(-$m_j$.c.m_flow,$s_i$)*$m_j$.c.h_outflow)
+ sum(positiveMax($c_k$.m_flow,s_i)*inStream($c_k$.h_outflow)))/
(sum(positiveMax(-$m_j$.c.m_flow,s_i))
+ sum(positiveMax($c_k$.m_flow,s_i)))
for j in 1:N and i <> j and $m_j$.c.m_flow.min < 0,
for k in 1:M and $c_k$.m_flow.max > 0
// Additional equations to be generated
for q in 1:M loop
if $m_j$.c.m_flow.min >= 0 for all j = 1:N and
$c_k$.m_flow.max <= 0 for all k = 1:M and k <> q
then
$c_q$.h_outflow = 0;
else
$s_q$ = (sum(max(-$m_j$.c.m_flow,0) for j in 1:N) +
sum(max( $c_k$.m_flow ,0) for k in cat(1,1:q-1, q+1:M)));
$c_q$.h_outflow = (sum(positiveMax(-$m_j$.c.m_flow,s_q)*$m_j$.c.h_outflow) +
sum(positiveMax($c_k$.m_flow,$s_q$)* inStream($c_k$.h_outflow)))/
(sum(positiveMax(-$m_j$.c.m_flow,s_q)) +
sum(positiveMax($c_k$.m_flow,s_q)))
for j in 1:N and $m_j$.c.m_flow.min < 0,
for k in 1:M and k <> q and $c_k$.m_flow.max > 0
end for;
\end{lstlisting}
\end{itemize}
The operator
\lstinline!positiveMax(-$m_{j}$.c.m_flow, $s_{i}$)!
should be such that:
\begin{itemize}
\item
\lstinline!positiveMax(-$m_{j}$.c.m_flow, $s_{i}$)! =
\lstinline!-$m_{j}$.c.m_flow! if
$-m_{j}\text{\lstinline!.c.m_flow!} > \mathit{eps1}_{j} \geq 0$,
where $\mathit{eps1}_{j}$ are small flows, compared to typical
problem-specific values,
\item
all denominators should be greater than $\mathit{eps2} > 0$,
where $\mathit{eps2}$ is also a small flow, compared to typical problem-specific
values.
\end{itemize}
Trivial implementation of \lstinline!positiveMax! guarantees continuity of \lstinline!inStream!:
\begin{lstlisting}[language=modelica]
postiveMax(-$m_j$.c.m_flow, $s_i$) = max(-$m_j$.c.m_flow, $\mathit{eps1}$); // so $s_i$ is not needed
\end{lstlisting}
More sophisticated implementation, with smooth approximation, applied only when {all} flows are small:
\begin{lstlisting}[language=modelica,escapechar=!]
// Define a "small number" eps (nominal(v) is the nominal value of v - see !\autoref{attributes-start-fixed-nominal-and-unbounded}!)
eps := relativeTolerance*min(nominal($m_j$.c.m_flow));
// Define a smooth curve, such that alpha($s_i>=eps$)=1 and alpha($s_i<0$)=0
alpha := smooth(1, if $s_i$ > eps then 1
else if $s_i$ > 0 then ($s_i$/eps)^2*(3-2* $s_i$/eps)
else 0);
// Define function positiveMax(v,s_i) as a linear combination of max (v,0)
// and of eps along alpha
positiveMax((-$m_j$.c.m_flow,s_i) := alpha*max(-$m_j$.c.m_flow,0) + (1-alpha)*eps;
\end{lstlisting}
The derivation of this implementation is discussed in
\autoref{derivation-of-stream-equations}. Note that in the cases $N = 1,\, M = 0$ (unconnected port,
physically corresponding to a plugged-up flange), and $N = 2,\, M = 0$
(one-to-one connection), the result of \lstinline!inStream! is trivial
and no non-linear equations are left in the model, despite the fact that
the original definition equations are nonlinear.
The following properties hold for this implementation:
\begin{itemize}
\item
\lstinline!inStream! is continuous (and differentiable),
provided that \lstinline!$m_{j}$.c.h_outflow!,
\lstinline!$m_{j}$.c.m_flow!, \lstinline!$c_{k}$.h_outflow!, and
\lstinline!$c_{k}$.m_flow! are continuous and differentiable.
\end{itemize}
\begin{itemize}
\item
A division by zero can no longer occur (since \lstinline!sum(positiveMax(-$m_{j}$.c.m_flow, $s_{i}$))! $\geq \mathit{eps2} > 0$),
so the result is always well-defined.
\item
The balance equations are exactly fulfilled if the denominator is not close to zero (since the exact formula is used, if
\lstinline!sum(positiveMax(-$m_{j}$.c.m_flow, $s_{i}$))! $> \mathit{eps}$).
\item
If all flows are zero,
\lstinline!inStream($m_{i}$.c.h_outflow)! =
\lstinline!sum($m_{j}$.c.h_outflow for $j \neq{} i$ and $m_{j}$.c.m_flow.min < 0) / $N_{\mathrm{p}}$!,
i.e., it is the mean value of all the $N_{\mathrm{p}}$ variables
\lstinline!$m_{j}$.c.h_outflow!, such that $j \neq i$ and
$m_{j}\text{\lstinline!.c.m_flow.min!} < 0$. This is a
meaningful approximation, considering the physical diffusion effects
that are relevant at small flow rates in a small connection volume
(thermal conduction for enthalpy, mass diffusion for mass fractions).
\end{itemize}
The value of \lstinline!relativeTolerance! should be larger than the relative
tolerance of the nonlinear solver used to solve the implicit algebraic
equations.
As a final remark, further symbolic simplifications could be
carried out by taking into account equations that affect the flows in
the connection set (i.e., equivalent to $m_{j}\text{\lstinline!.c.m_flow!} =
0$, which then implies $m_{j}\text{\lstinline!.c.m_flow.min!} \geq 0$). This is interesting, e.g., in the case of a valve when the stem
position is set identically to closed by its controller.
\end{nonnormative}
\section{Stream Operator actualStream}\doublelabel{stream-operator-actualstream}
\lstinline!actualStream! is provided for convenience, in
order to return the actual value of the stream variable, depending on
the actual flow direction. The only argument of this built-in operator
needs to be a reference to a stream variable. The operator is
vectorizable, in the case of vector arguments. For the following
definition it is assumed that an (inside or outside) connector \lstinline!c!
contains a stream variable \lstinline!h_outflow! which is associated with a flow
variable \lstinline!m_flow! in the same connector \lstinline!c!:
\begin{lstlisting}[language=modelica]
actualStream(c.h_outflow) = if c.m_flow > 0 then inStream(c.h_outflow) else c.h_outflow;
\end{lstlisting}
\begin{nonnormative}
\lstinline!actualStream! is typically used in two contexts:
\begin{lstlisting}[language=modelica]
der(U) = c.m_flow * actualStream(c.h_outflow); // (1) energy balance equation
h_c = actualStream(c.h); // (2) monitoring the enthalpy at port c
\end{lstlisting}
In the case of equation (1), although \lstinline!actualStream!
is discontinuous, the product with the flow variable is not, because
\lstinline!actualStream! is discontinuous when the flow is zero by construction.
Therefore, a tool might infer that the expression is \lstinline!smooth(0, $\ldots$)!
automatically, and decide whether or not to generate an event. If a user
wants to avoid events entirely, he/she may enclose the right-hand side
of (1) with \lstinline!noEvent!.
Equations like (2) might be used for monitoring purposes (e.g.\ plots), in order to inspect what the actual enthalpy of the fluid flowing through a port is.
In this case, the user will probably want to see the change due to flow reversal at the exact instant, so an event should be generated. If the user doesn't
bother, then he/she should enclose the right-hand side of (2) with \lstinline!noEvent!. Since the output of \lstinline!actualStream! will be discontinuous,
it should not be used by itself to model physical behaviour (e.g., to compute densities used in momentum balances) --- \lstinline!inStream! should be used
for this purpose. \lstinline!actualStream! should be used to model physical behaviour only when multiplied by the corresponding flow variable (like in the
above energy balance equation), because this removes the discontinuity.
\end{nonnormative}