~jdpipe/ascend/trunk-old

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;