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
|
REQUIRE "ivpsystem.a4l"; (* provides a modified version of system.a4l for IVP problems *)
REQUIRE "atoms.a4l";
(* ASCEND modelling environment
Copyright (C) 1998, 2006 Carnegie Mellon University
The ASCEND Modeling Library is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
The ASCEND Modeling Library is distributed in hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*)(*
by Duncan Coffey
This model gives a pretty trivial example of integration using LSODE.
*)
MODEL dyn_tank;
(* List of Variables *)
dM_dt IS_A molar_rate;
M IS_A mole;
input IS_A molar_rate;
output IS_A molar_rate;
Volume IS_A volume;
density IS_A real_constant;
dynamic IS_A boolean;
t IS_A time;
(* Equations *)
dM_dt = input - output;
M = Volume * density;
(* Assignment of values to Constants *)
density :==10 {mol/m^3};
METHODS
METHOD check_self;
IF (input < 1e-4 {mole/s}) THEN
STOP {Input dried up in tank};
END IF;
IF (output < 1e-4 {mole/s}) THEN
STOP {Output dried up in tank};
END IF;
END check_self;
METHOD check_all;
RUN check_self;
END check_all;
METHOD default_self;
dynamic := FALSE;
t :=0 {sec};
dM_dt :=0 {mol/sec};
dM_dt.lower_bound := -1e49 {mol/sec};
input := 1 {mol/sec};
output := 1 {mol/sec};
END default_self;
METHOD default_all;
RUN default_self;
END default_all;
METHOD bound_self;
END bound_self;
METHOD bound_all;
RUN bound_self;
END bound_all;
METHOD scale_self;
END scale_self;
METHOD scale_all;
RUN scale_self;
END scale_all;
METHOD seqmod;
FIX dM_dt;
FREE M;
FIX Volume;
FIX input;
FREE output;
IF dynamic THEN
FREE dM_dt;
FIX M;
FREE Volume;
FIX output;
END IF;
END seqmod;
METHOD specify;
FIX input;
RUN seqmod;
END specify;
METHOD set_ode;
(* set ODE_TYPE -1=independent variable,
0=algebraic variable, 1=state variable,
2=derivative *)
t.ode_type :=-1;
dM_dt.ode_type :=2;
M.ode_type :=1;
(* Set ODE_ID *)
dM_dt.ode_id :=1;
M.ode_id :=1;
END set_ode;
METHOD set_obs;
(* Set OBS_ID to any integer value greater
than 0, the variable will be recorded
(i.e., observed) *)
M.obs_id :=1;
Volume.obs_id :=2;
input.obs_id :=3;
output.obs_id :=4;
END set_obs;
METHOD values;
Volume :=5 {m^3};
input :=100 {mole/s};
END values;
METHOD on_load;
RUN default_self;
dynamic := TRUE;
RUN reset;
RUN specify;
RUN set_obs;
RUN set_ode;
END on_load;
END dyn_tank;
|