forked from modelica/ModelicaStandardLibrary
-
Notifications
You must be signed in to change notification settings - Fork 1
/
OpenTank.mo
134 lines (133 loc) · 5.39 KB
/
OpenTank.mo
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
within Modelica.Thermal.FluidHeatFlow.Components;
model OpenTank "Model of a tank under ambient pressure"
extends FluidHeatFlow.BaseClasses.SinglePortBottom(final Exchange=true);
parameter SI.Area ATank(start=1) "Cross section of tank";
parameter SI.Length hTank(start=1) "Height of tank";
parameter SI.Pressure pAmbient(start=0) "Ambient pressure";
parameter SI.Acceleration g(final min=0)=Modelica.Constants.g_n "Gravitation";
parameter Boolean useHeatPort = false "= true, if HeatPort is enabled"
annotation(Evaluate=true, HideResult=true, choices(checkBox=true));
SI.Mass m "Mass of medium in tank";
protected
SI.Enthalpy H "Enthalpy of medium";
SI.HeatFlowRate Q_flow "Heat flow at the optional heatPort";
public
Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort(final T=T, final Q_flow=Q_flow) if useHeatPort
"Optional port for cooling or heating the medium in the tank"
annotation (Placement(transformation(extent={{-110,-110},{-90,-90}}),
iconTransformation(extent={{-110,-110},{-90,-90}})));
Modelica.Blocks.Interfaces.RealOutput level(quantity="Length", unit="m", start=0)
"Level of medium in tank" annotation (Placement(transformation(
extent={{10,-10},{-10,10}},
rotation=180,
origin={110,0})));
Modelica.Blocks.Interfaces.RealOutput TTank(quantity="Temperature", unit="K", displayUnit="degC")
"Temperature of medium in tank" annotation (Placement(transformation(
extent={{10,-10},{-10,10}},
rotation=180,
origin={110,-60})));
equation
//output medium temperature
TTank = T;
//optional heating/cooling
if not useHeatPort then
Q_flow = 0;
end if;
//check level
assert(level>=0, "Tank got empty!");
assert(level<=hTank, "Tank got full!");
//mass balance
m = medium.rho*ATank*level;
der(m) = flowPort.m_flow;
//energy balance
H = m*h;
der(H) = flowPort.H_flow + Q_flow;
//pressure at bottom
flowPort.p = pAmbient + m*g/ATank;
annotation (Icon(graphics={
Ellipse(
extent={{-80,-60},{80,-100}},
fillColor={170,170,255},
fillPattern=FillPattern.Sphere),
Rectangle(
extent={{-80,80},{80,-80}},
fillPattern=FillPattern.VerticalCylinder,
fillColor={255,255,255}),
Rectangle(
extent=DynamicSelect({{-80,0},{80,-80}},
{{-80,(-80+160*level/hTank)},{80,-80}}),
fillPattern=FillPattern.VerticalCylinder,
fillColor={170,170,255}),
Ellipse(
extent=DynamicSelect({{-80,20},{80,-20}},
{{-80,(-60+160*level/hTank)},{80,(-100+160*level/hTank)}}),
fillColor={170,170,255},
fillPattern=FillPattern.Sphere),
Ellipse(
extent={{-80,100},{80,60}},
fillColor={255,255,255},
fillPattern=FillPattern.Sphere),
Line(points={{100,0},{80,0}}, thickness=0.5),
Line(points={{100,-60},{80,-60}},
color={238,46,47},
thickness=0.5),
Ellipse(
extent={{72,-56},{80,-64}},
lineColor={238,46,47},
lineThickness=0.5,
fillColor={238,46,47},
fillPattern=FillPattern.Solid),
Ellipse(visible=useHeatPort,
extent={{-80,-74},{-68,-86}},
lineColor={238,46,47},
lineThickness=0.5,
fillColor={170,170,255},
fillPattern=FillPattern.Solid),
Ellipse(visible=useHeatPort,
extent={{-68,-78},{-56,-90}},
lineColor={238,46,47},
lineThickness=0.5,
fillColor={170,170,255},
fillPattern=FillPattern.Solid),
Ellipse(visible=useHeatPort,
extent={{-56,-82},{-44,-94}},
lineColor={238,46,47},
lineThickness=0.5,
fillColor={170,170,255},
fillPattern=FillPattern.Solid),
Ellipse(visible=useHeatPort,
extent={{-44,-84},{-32,-96}},
lineColor={238,46,47},
lineThickness=0.5,
fillColor={170,170,255},
fillPattern=FillPattern.Solid),
Line(visible=useHeatPort,
points={{-90,-100},{-56,-100},{-56,-88}},
color={238,46,47},
thickness=0.5),
Text(
extent={{-95,50},{95,30}},
textString="level ="),
Text(
extent={{-95,-30},{95,-50}},
textString=DynamicSelect("%level.start", String(
level,
minimumLength=1,
significantDigits=2)))}),
Documentation(info="<html>
<p>This is a simple model of an open tank with volume A*h. The level and the temperature of the medium are measured and provided as output.</p>
<p>Note: If the level of the medium reaches 0 (minimum) or h (maximum), an assertion is triggered.</p>
<p>Note: The flowPort is assumed to be at the bottom. Therefore the pressure at the flowPort is ambient pressure + level*rho*g.</p>
<ul>
<li>If the mass flow rate at the port goes into the tank the level increases and the mixing rule is applied to obtain the temperature change of the medium in the tank.</li>
<li>If the mass flow rate at the port goes out of the tank the level decreases,
the temperature of the outflowing medium is defined by the the temperature of the medium in the tank.</li>
</ul>
<p>
It is assumed that the medium in the tank has the same temperature over the whole volume, i.e. mixed thoroughly.
</p>
<p>
Via the optional heatPort the medium in the tank can be cooled or heated.
</p>
</html>"));
end OpenTank;