1 |
REQUIRE "ivpsystem.a4l"; |
2 |
REQUIRE "atoms.a4l"; |
3 |
REQUIRE "johnpye/thermo_types.a4c"; |
4 |
REQUIRE "johnpye/datareader/testtmy3.a4c"; |
5 |
REQUIRE "johnpye/moltensalt.a4c"; |
6 |
|
7 |
(* |
8 |
This is a proof-of-concept test of a model for solar power plant |
9 |
dynamics in ASCEND. The system being modelled has a lossless solar thermal |
10 |
collector, a perfectly mixed storage tank, and a turbine that produces |
11 |
electricity. |
12 |
|
13 |
The boundaries defined are |
14 |
(1) if solar GHI: > 300 W/m2, then the collector provides heat to the tank |
15 |
< 200 W/m2, then the collector switches off. |
16 |
(2) if the tank temperature: exceeds 550C, then turbine switches on |
17 |
drops below 400C, then turbine switches off. |
18 |
|
19 |
The data file mentioned below can be downloaded from |
20 |
http://rredc.nrel.gov/solar/old_data/nsrdb/1991-2005/data/tmy3/723815TYA.CSV |
21 |
*) |
22 |
MODEL solardynamics; |
23 |
t IS_A time; |
24 |
INDEPENDENT t; |
25 |
|
26 |
(* Weather data reader *) |
27 |
dr IS_A tmy3; |
28 |
dr.tmydata.filename :== 'johnpye/datareader/723815TYA.CSV'; |
29 |
dr.t, t ARE_THE_SAME; |
30 |
T_amb ALIASES dr.T; |
31 |
G ALIASES dr.GHI; |
32 |
(* |
33 |
T_amb IS_A temperature; |
34 |
G IS_A power_per_area; |
35 |
*) |
36 |
|
37 |
(* Solar collector *) |
38 |
C IS_A factor; |
39 |
A IS_A area; |
40 |
Qdot_abs IS_A energy_rate; |
41 |
col_on: Qdot_abs = C*A*G; |
42 |
col_off: Qdot_abs = 0; |
43 |
|
44 |
(* Storage *) |
45 |
m IS_A mass; |
46 |
TA IS_A moltensalt_fluid; |
47 |
h ALIASES TA.h; |
48 |
T ALIASES TA.T; |
49 |
DERIVATIVE OF h; |
50 |
Qdot_elec IS_A energy_rate; |
51 |
m * der(h) = Qdot_abs - Qdot_elec; |
52 |
|
53 |
(* Power block *) |
54 |
Wdot_elec, Qdot_elec_des IS_A energy_rate; |
55 |
eta IS_A fraction; |
56 |
(* power cycle efficiency: chambadal novikov efficiency *) |
57 |
eta = 1 - sqrt(T_amb / T); |
58 |
Qdot_elec*eta = Wdot_elec; |
59 |
pow_on: Qdot_elec = Qdot_elec_des; |
60 |
pow_off: Qdot_elec = 0; |
61 |
|
62 |
(* Switching logic *) |
63 |
is_G_high, is_G_low, is_T_start, is_T_stop IS_A boolean_var; |
64 |
CONDITIONAL |
65 |
G_high: G > 300 {W/m^2}; |
66 |
G_low: G < 200 {W/m^2}; |
67 |
T_start: T > (550 {K} + 273.15 {K}); |
68 |
T_stop: T < (400 {K} + 273.15 {K}); |
69 |
END CONDITIONAL; |
70 |
is_G_high == SATISFIED(G_high); |
71 |
is_G_low == SATISFIED(G_low); |
72 |
is_T_start == SATISFIED(T_start); |
73 |
is_T_stop == SATISFIED(T_stop); |
74 |
ev1: EVENT (is_G_high) |
75 |
CASE TRUE: USE col_on; |
76 |
END EVENT; |
77 |
ev2: EVENT (is_G_low) |
78 |
CASE TRUE: USE col_off; |
79 |
END EVENT; |
80 |
ev3: EVENT (is_T_start) |
81 |
CASE TRUE: USE pow_on; |
82 |
END EVENT; |
83 |
ev4: EVENT (is_T_stop) |
84 |
CASE TRUE: USE pow_off; |
85 |
END EVENT; |
86 |
METHODS |
87 |
METHOD obs_init; |
88 |
G.obs_id := 1; |
89 |
T_amb.obs_id := 2; |
90 |
T.obs_id := 3; |
91 |
Wdot_elec.obs_id := 4; |
92 |
END obs_init; |
93 |
METHOD specify; |
94 |
FIX C := 2000; |
95 |
FIX Qdot_elec_des := 1 {MW}; |
96 |
FIX A := 2000 {m^2}; |
97 |
FIX TA.p := 1 {bar}; |
98 |
t := 0 {s}; |
99 |
T := 300 {K} + 273.15 {K}; |
100 |
is_G_high := FALSE; |
101 |
is_G_low := TRUE; |
102 |
is_T_start := FALSE; |
103 |
is_T_stop := TRUE; |
104 |
END specify; |
105 |
METHOD on_load; |
106 |
RUN specify; |
107 |
RUN obs_init; |
108 |
END on_load; |
109 |
END solardynamics; |