redshift 1.3.21 → 1.3.22
Sign up to get free protection for your applications and to get access to all the features.
- data/RELEASE-NOTES +14 -0
- data/bench/algebraic.rb +61 -0
- data/bench/bench +3 -0
- data/bench/connect.rb +75 -0
- data/bench/linked-flows.rb +71 -0
- data/examples/step-discrete-hook.rb +201 -0
- data/lib/redshift/component.rb +4 -1
- data/lib/redshift/meta.rb +2 -0
- data/lib/redshift/mixins/zeno-debugger.rb +1 -1
- data/lib/redshift/redshift.rb +48 -11
- data/lib/redshift/syntax.rb +9 -1
- data/lib/redshift/target/c/component-gen.rb +185 -91
- data/lib/redshift/target/c/flow-gen.rb +11 -9
- data/lib/redshift/target/c/flow/algebraic.rb +32 -37
- data/lib/redshift/target/c/flow/delay.rb +34 -32
- data/lib/redshift/target/c/flow/derivative.rb +30 -33
- data/lib/redshift/target/c/flow/euler.rb +24 -22
- data/lib/redshift/target/c/flow/expr.rb +40 -43
- data/lib/redshift/target/c/flow/rk4.rb +28 -32
- data/lib/redshift/target/c/library.rb +2 -8
- data/lib/redshift/target/c/world-gen.rb +31 -35
- data/lib/redshift/world.rb +6 -0
- metadata +12 -14
- data/.bnsignore +0 -27
- data/bench/after-flow-cache +0 -66
- data/bench/before-flow-cache +0 -66
@@ -8,7 +8,7 @@ module RedShift
|
|
8
8
|
end
|
9
9
|
|
10
10
|
module RedShift; class Flow
|
11
|
-
def translate flow_fn, result_var,
|
11
|
+
def translate flow_fn, result_var, cl, rk_level = nil, orig_formula = nil
|
12
12
|
translation = {}
|
13
13
|
setup = [] ## should use accumulator
|
14
14
|
|
@@ -43,7 +43,7 @@ module RedShift; class Flow
|
|
43
43
|
|
44
44
|
ct_struct = make_ct_struct(flow_fn, cl)
|
45
45
|
|
46
|
-
link_type_ssn = link_type.
|
46
|
+
link_type_ssn = link_type.shadow_struct_name
|
47
47
|
ct_struct.declare link_cname => "#{link_type_ssn} *#{link_cname}"
|
48
48
|
flow_fn.setup link_cname => "ct.#{link_cname} = shadow->#{link}"
|
49
49
|
end
|
@@ -77,7 +77,8 @@ module RedShift; class Flow
|
|
77
77
|
}
|
78
78
|
}
|
79
79
|
# The d_tick assignment is explained in component-gen.rb.
|
80
|
-
|
80
|
+
rk = rk_level || "shadow->world->rk_level"
|
81
|
+
setup << "#{var_cname} = #{cont_var}.value[#{rk}];"
|
81
82
|
|
82
83
|
elsif (kind = cl.input_variables[varsym])
|
83
84
|
# x ==> var_x
|
@@ -157,7 +158,7 @@ module RedShift; class Flow
|
|
157
158
|
else
|
158
159
|
ct_struct = sf.declare_struct(CT_STRUCT_NAME)
|
159
160
|
|
160
|
-
ct_struct.declare :shadow => "#{cl.
|
161
|
+
ct_struct.declare :shadow => "#{cl.shadow_struct_name} *shadow"
|
161
162
|
|
162
163
|
flow_fn.declare :ct => "#{CT_STRUCT_NAME} ct"
|
163
164
|
flow_fn.setup :ct_shadow => "ct.shadow = shadow"
|
@@ -166,7 +167,7 @@ module RedShift; class Flow
|
|
166
167
|
ct_struct
|
167
168
|
end
|
168
169
|
|
169
|
-
# l.x ==> get_l__x()->
|
170
|
+
# l.x ==> get_l__x()->value[n]
|
170
171
|
def translate_link(link, var, translation, flow_fn, cl, expr, rk_level)
|
171
172
|
link_type, link_strictness = cl.link_variables[link.intern]
|
172
173
|
raise(NameError, "No such link, #{link}") unless link_type
|
@@ -208,7 +209,7 @@ module RedShift; class Flow
|
|
208
209
|
end
|
209
210
|
|
210
211
|
if var_type == :continuous
|
211
|
-
link_cs_ssn = link_type.cont_state_class.
|
212
|
+
link_cs_ssn = link_type.cont_state_class.shadow_struct_name
|
212
213
|
link_cs_cname = "link_cs_#{link}"
|
213
214
|
ct_struct.declare link_cs_cname => "#{link_cs_ssn} *#{link_cs_cname}"
|
214
215
|
end
|
@@ -218,7 +219,7 @@ module RedShift; class Flow
|
|
218
219
|
|
219
220
|
unless translation[link]
|
220
221
|
translation[link] = link_cname
|
221
|
-
link_type_ssn = link_type.
|
222
|
+
link_type_ssn = link_type.shadow_struct_name
|
222
223
|
ct_struct.declare link_cname => "#{link_type_ssn} *#{link_cname}"
|
223
224
|
flow_fn.setup link_cname => "ct.#{link_cname} = shadow->#{link}"
|
224
225
|
end ## same as below
|
@@ -256,7 +257,8 @@ module RedShift; class Flow
|
|
256
257
|
}
|
257
258
|
} ## algebraic test is same as above
|
258
259
|
|
259
|
-
|
260
|
+
rk = rk_level || "shadow->world->rk_level"
|
261
|
+
translation[expr] = "#{get_var_cname}(&ct)->value[#{rk}]"
|
260
262
|
|
261
263
|
when :constant
|
262
264
|
sf.declare get_var_cname => %{
|
@@ -270,7 +272,7 @@ module RedShift; class Flow
|
|
270
272
|
translation[expr] = "#{get_var_cname}(&ct)"
|
271
273
|
|
272
274
|
when :link
|
273
|
-
link_link_type_ssn = link_link_type.
|
275
|
+
link_link_type_ssn = link_link_type.shadow_struct_name
|
274
276
|
sf.declare get_var_cname => %{
|
275
277
|
inline static #{link_link_type_ssn} *#{get_var_cname}(#{CT_STRUCT_NAME} *ct) {
|
276
278
|
if (!ct->#{link_cname})
|
@@ -1,20 +1,27 @@
|
|
1
1
|
module RedShift; class AlgebraicFlow
|
2
|
-
def
|
3
|
-
|
4
|
-
|
5
|
-
flow_name = "flow_#{CGenerator.make_c_name cl.name}_#{var_name}_#{state}"
|
2
|
+
def make_generator cl, state
|
3
|
+
@fname = "flow_#{CGenerator.make_c_name cl.name}_#{var}_#{state}"
|
4
|
+
@inspect_str = "#{cl.name}:#{state}: #{var} = #{formula}"
|
6
5
|
|
7
|
-
|
8
|
-
|
6
|
+
@generator = proc do
|
7
|
+
sl = cl.shadow_library
|
8
|
+
ssn = cl.shadow_struct_name
|
9
|
+
cont_state_ssn = cl.cont_state_class.shadow_struct_name
|
10
|
+
|
11
|
+
## use an accumulator for these
|
12
|
+
sl.init_library_function.body \
|
13
|
+
"s_init_flow(#{fname}, #{fname.inspect}, #{inspect_str.inspect}, ALGEBRAIC);"
|
9
14
|
|
10
|
-
|
11
|
-
cont_state_ssn = cl.cont_state_class.shadow_struct.name
|
15
|
+
include_file, source_file = sl.add_file fname
|
12
16
|
|
13
17
|
# We need the struct
|
14
|
-
|
18
|
+
source_file.include(cl.shadow_library_include_file)
|
15
19
|
|
16
|
-
|
20
|
+
flow = self
|
21
|
+
var_name = @var
|
22
|
+
source_file.define(fname).instance_eval do
|
17
23
|
arguments "ComponentShadow *comp_shdw"
|
24
|
+
scope :extern
|
18
25
|
declare :shadow => %{
|
19
26
|
struct #{ssn} *shadow;
|
20
27
|
struct #{cont_state_ssn} *cont_state;
|
@@ -28,45 +35,31 @@ module RedShift; class AlgebraicFlow
|
|
28
35
|
|
29
36
|
setup :shadow => %{
|
30
37
|
shadow = (#{ssn} *)comp_shdw;
|
31
|
-
cont_state = (#{cont_state_ssn} *)shadow->cont_state;
|
38
|
+
cont_state = (struct #{cont_state_ssn} *)shadow->cont_state;
|
32
39
|
var = &cont_state->#{var_name};
|
33
40
|
assert(var->algebraic);
|
34
|
-
if (shadow->world->alg_nest >
|
41
|
+
if (shadow->world->alg_nest > shadow->world->alg_depth_limit) {
|
35
42
|
shadow->world->alg_nest = 0;
|
36
43
|
rs_raise(#{exc}, shadow->self, #{msg.inspect});
|
37
44
|
}
|
38
45
|
shadow->world->alg_nest++;
|
39
46
|
}
|
40
|
-
## 100 not always enough, so could increase limit exponentially,
|
41
|
-
## and look in subsequent iterations for repeats of this [var, obj].
|
42
47
|
|
43
|
-
## optimization: it might be possible to translate once and
|
44
|
-
## use gsub to make each of the four versions, or use a template.
|
45
48
|
body %{
|
49
|
+
#{flow.translate(self,
|
50
|
+
"var->value[shadow->world->rk_level]", cl) {|strict|
|
51
|
+
flow.instance_eval {@strict = strict}
|
52
|
+
}.join("
|
53
|
+
")};
|
54
|
+
|
46
55
|
switch (shadow->world->rk_level) {
|
47
56
|
case 0:
|
48
|
-
#{flow.translate(self, "var->value_0", 0, cl).join("
|
49
|
-
")};
|
50
57
|
var->d_tick = shadow->world->d_tick;
|
51
58
|
break;
|
52
59
|
|
53
60
|
case 1:
|
54
|
-
#{flow.translate(self, "var->value_1", 1, cl).join("
|
55
|
-
")};
|
56
|
-
var->rk_level = shadow->world->rk_level;
|
57
|
-
break;
|
58
|
-
|
59
61
|
case 2:
|
60
|
-
#{flow.translate(self, "var->value_2", 2, cl).join("
|
61
|
-
")};
|
62
|
-
var->rk_level = shadow->world->rk_level;
|
63
|
-
break;
|
64
|
-
|
65
62
|
case 3:
|
66
|
-
#{flow.translate(self, "var->value_3", 3, cl){|strict|
|
67
|
-
flow.instance_eval {@strict = strict}
|
68
|
-
}.join("
|
69
|
-
")};
|
70
63
|
var->rk_level = shadow->world->rk_level;
|
71
64
|
break;
|
72
65
|
|
@@ -77,12 +70,14 @@ module RedShift; class AlgebraicFlow
|
|
77
70
|
|
78
71
|
shadow->world->alg_nest--;
|
79
72
|
}
|
80
|
-
end # Case 0 applies during discrete update.
|
81
|
-
# alg flows are lazy
|
82
|
-
|
83
|
-
define_c_method :calc_function_pointer do
|
84
|
-
body "shadow->flow = &#{flow_name}", "shadow->algebraic = 1"
|
85
73
|
end
|
74
|
+
# Case 0 applies during discrete update.
|
75
|
+
# Alg flows are lazy.
|
76
|
+
# Note that @strict does not need to propagate to wrapper
|
77
|
+
# (as it does in CexprGuard) since checking is done statically
|
78
|
+
# in Component.define_flow.
|
86
79
|
end
|
80
|
+
|
81
|
+
return self
|
87
82
|
end
|
88
83
|
end; end
|
@@ -1,24 +1,22 @@
|
|
1
1
|
module RedShift; class DelayFlow
|
2
|
-
def
|
3
|
-
var_name = @var
|
4
|
-
flow = self
|
5
|
-
flow_name = "flow_#{CGenerator.make_c_name cl.name}_#{var_name}_#{state}"
|
2
|
+
def make_generator cl, state
|
6
3
|
delay_by = @delay_by
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
"#{var_name} = #{flow.formula} [delay: #{delay_by}]"
|
4
|
+
@fname = "flow_#{CGenerator.make_c_name cl.name}_#{var}_#{state}"
|
5
|
+
@inspect_str =
|
6
|
+
"#{cl.name}:#{state}: " +
|
7
|
+
"#{var} = #{formula} [delay: #{delay_by}]"
|
12
8
|
|
13
|
-
|
14
|
-
|
9
|
+
@generator = proc do
|
10
|
+
sl = cl.shadow_library
|
11
|
+
ssn = cl.shadow_struct_name
|
12
|
+
cont_state_ssn = cl.cont_state_class.shadow_struct_name
|
15
13
|
|
16
14
|
require "redshift/target/c/flow/buffer"
|
17
15
|
RedShift.library.define_buffer
|
18
16
|
|
19
|
-
bufname = "#{
|
20
|
-
delayname = "#{
|
21
|
-
tsname = "#{
|
17
|
+
bufname = "#{var}_buffer_data"
|
18
|
+
delayname = "#{var}_delay"
|
19
|
+
tsname = "#{var}_time_step"
|
22
20
|
|
23
21
|
cl.class_eval do
|
24
22
|
shadow_attr_accessor bufname => "RSBuffer #{bufname}"
|
@@ -37,11 +35,19 @@ module RedShift; class DelayFlow
|
|
37
35
|
private :"#{delayname}="
|
38
36
|
end
|
39
37
|
|
38
|
+
sl.init_library_function.body \
|
39
|
+
"s_init_flow(#{fname}, #{fname.inspect}, #{inspect_str.inspect}, NONALGEBRAIC);"
|
40
|
+
|
41
|
+
include_file, source_file = sl.add_file fname
|
42
|
+
|
40
43
|
# We need the struct
|
41
|
-
|
44
|
+
source_file.include(cl.shadow_library_include_file)
|
42
45
|
|
43
|
-
|
46
|
+
flow = self
|
47
|
+
var_name = @var
|
48
|
+
source_file.define(fname).instance_eval do
|
44
49
|
arguments "ComponentShadow *comp_shdw"
|
50
|
+
scope :extern
|
45
51
|
declare :shadow => %{
|
46
52
|
struct #{ssn} *shadow;
|
47
53
|
struct #{cont_state_ssn} *cont_state;
|
@@ -53,7 +59,7 @@ module RedShift; class DelayFlow
|
|
53
59
|
}
|
54
60
|
setup :shadow => %{
|
55
61
|
shadow = (#{ssn} *)comp_shdw;
|
56
|
-
cont_state = (#{cont_state_ssn} *)shadow->cont_state;
|
62
|
+
cont_state = (struct #{cont_state_ssn} *)shadow->cont_state;
|
57
63
|
var = &cont_state->#{var_name};
|
58
64
|
}
|
59
65
|
setup :rk_level => %{
|
@@ -64,7 +70,7 @@ module RedShift; class DelayFlow
|
|
64
70
|
begin
|
65
71
|
"delay = #{Float(delay_by)}"
|
66
72
|
rescue ArgumentError
|
67
|
-
flow.translate(self, "delay",
|
73
|
+
flow.translate(self, "delay", cl, 0, delay_by)
|
68
74
|
end
|
69
75
|
|
70
76
|
include World.shadow_library_include_file
|
@@ -101,7 +107,7 @@ module RedShift; class DelayFlow
|
|
101
107
|
len = steps*4;
|
102
108
|
|
103
109
|
if (!ptr) {
|
104
|
-
#{flow.translate(self, "fill",
|
110
|
+
#{flow.translate(self, "fill", cl, 0).join("
|
105
111
|
")};
|
106
112
|
|
107
113
|
rs_buffer_init(&shadow->#{bufname}, len, fill);
|
@@ -115,12 +121,12 @@ module RedShift; class DelayFlow
|
|
115
121
|
offset = shadow->#{bufname}.offset;
|
116
122
|
}
|
117
123
|
|
118
|
-
var->
|
119
|
-
var->
|
120
|
-
var->
|
121
|
-
var->
|
124
|
+
var->value[0] = ptr[offset];
|
125
|
+
var->value[1] = ptr[offset + 1];
|
126
|
+
var->value[2] = ptr[offset + 2];
|
127
|
+
var->value[3] = ptr[offset + 3];
|
122
128
|
|
123
|
-
#{flow.translate(self, "ptr[offset]",
|
129
|
+
#{flow.translate(self, "ptr[offset]", cl, 0).join("
|
124
130
|
")};
|
125
131
|
break;
|
126
132
|
|
@@ -133,15 +139,15 @@ module RedShift; class DelayFlow
|
|
133
139
|
len = shadow->#{bufname}.len;
|
134
140
|
offset = shadow->#{bufname}.offset;
|
135
141
|
|
136
|
-
#{flow.translate(self, "ptr[offset+1]",
|
142
|
+
#{flow.translate(self, "ptr[offset+1]", cl, 1).join("
|
137
143
|
")};
|
138
|
-
#{flow.translate(self, "ptr[offset+2]",
|
144
|
+
#{flow.translate(self, "ptr[offset+2]", cl, 2).join("
|
139
145
|
")};
|
140
|
-
#{flow.translate(self, "ptr[offset+3]",
|
146
|
+
#{flow.translate(self, "ptr[offset+3]", cl, 3).join("
|
141
147
|
")};
|
142
148
|
|
143
149
|
offset = (offset + 4) % len;
|
144
|
-
var->
|
150
|
+
var->value[0] = ptr[offset];
|
145
151
|
shadow->#{bufname}.offset = offset;
|
146
152
|
break;
|
147
153
|
|
@@ -154,10 +160,6 @@ module RedShift; class DelayFlow
|
|
154
160
|
var->rk_level = shadow->world->rk_level;
|
155
161
|
}
|
156
162
|
end
|
157
|
-
|
158
|
-
define_c_method :calc_function_pointer do
|
159
|
-
body "shadow->flow = &#{flow_name}"
|
160
|
-
end
|
161
163
|
end
|
162
164
|
end
|
163
165
|
end; end
|
@@ -1,26 +1,32 @@
|
|
1
1
|
module RedShift; class DerivativeFlow
|
2
|
-
def
|
3
|
-
|
4
|
-
|
5
|
-
flow_name = "flow_#{CGenerator.make_c_name cl.name}_#{var_name}_#{state}"
|
6
|
-
feedback = @feedback
|
7
|
-
|
8
|
-
Component::FlowWrapper.make_subclass flow_name do
|
9
|
-
@inspect_str = "#{cl.name}:#{state}: #{var_name} = #{flow.formula}'"
|
2
|
+
def make_generator cl, state
|
3
|
+
@fname = "flow_#{CGenerator.make_c_name cl.name}_#{var}_#{state}"
|
4
|
+
@inspect_str = "#{cl.name}:#{state}: #{var} = #{formula}"
|
10
5
|
|
11
|
-
|
12
|
-
|
6
|
+
@generator = proc do
|
7
|
+
sl = cl.shadow_library
|
8
|
+
ssn = cl.shadow_struct_name
|
9
|
+
cont_state_ssn = cl.cont_state_class.shadow_struct_name
|
10
|
+
|
11
|
+
sl.init_library_function.body \
|
12
|
+
"s_init_flow(#{fname}, #{fname.inspect}, #{inspect_str.inspect}, NONALGEBRAIC);"
|
13
|
+
|
14
|
+
include_file, source_file = sl.add_file fname
|
13
15
|
|
14
16
|
# We need the struct
|
15
|
-
|
17
|
+
source_file.include(cl.shadow_library_include_file)
|
16
18
|
|
17
|
-
init_rhs_name
|
19
|
+
init_rhs_name = "#{var}_init_rhs"
|
18
20
|
cl.class_eval do
|
19
21
|
shadow_attr_accessor init_rhs_name => "double #{init_rhs_name}"
|
20
22
|
end
|
21
23
|
|
22
|
-
|
24
|
+
flow = self
|
25
|
+
var_name = @var
|
26
|
+
feedback = @feedback
|
27
|
+
source_file.define(fname).instance_eval do
|
23
28
|
arguments "ComponentShadow *comp_shdw"
|
29
|
+
scope :extern
|
24
30
|
declare :shadow => %{
|
25
31
|
struct #{ssn} *shadow;
|
26
32
|
struct #{cont_state_ssn} *cont_state;
|
@@ -30,7 +36,7 @@ module RedShift; class DerivativeFlow
|
|
30
36
|
}
|
31
37
|
setup :shadow => %{
|
32
38
|
shadow = (#{ssn} *)comp_shdw;
|
33
|
-
cont_state = (#{cont_state_ssn} *)shadow->cont_state;
|
39
|
+
cont_state = (struct #{cont_state_ssn} *)shadow->cont_state;
|
34
40
|
var = &cont_state->#{var_name};
|
35
41
|
scratch = &shadow->#{init_rhs_name};
|
36
42
|
time_step = shadow->world->time_step;
|
@@ -42,10 +48,10 @@ module RedShift; class DerivativeFlow
|
|
42
48
|
body %{
|
43
49
|
switch (shadow->world->rk_level) {
|
44
50
|
case 0:
|
45
|
-
#{flow.translate(self, "antiddt",
|
51
|
+
#{flow.translate(self, "antiddt", cl, 0).join("
|
46
52
|
")};
|
47
|
-
var->
|
48
|
-
var->
|
53
|
+
var->value[0] = var->value[1] =
|
54
|
+
var->value[2] = var->value[3] =
|
49
55
|
(antiddt - *scratch) / time_step;
|
50
56
|
*scratch = antiddt;
|
51
57
|
}
|
@@ -54,31 +60,26 @@ module RedShift; class DerivativeFlow
|
|
54
60
|
}
|
55
61
|
else
|
56
62
|
body %{
|
63
|
+
#{flow.translate(self, "antiddt", cl).join("
|
64
|
+
")};
|
65
|
+
|
57
66
|
switch (shadow->world->rk_level) {
|
58
67
|
case 0:
|
59
|
-
|
60
|
-
")};
|
61
|
-
var->value_1 = var->value_0;
|
68
|
+
var->value[1] = var->value[0];
|
62
69
|
*scratch = antiddt;
|
63
70
|
break;
|
64
71
|
|
65
72
|
case 1:
|
66
|
-
|
67
|
-
")};
|
68
|
-
var->value_2 = (antiddt - *scratch) / (time_step/2);
|
73
|
+
var->value[2] = (antiddt - *scratch) / (time_step/2);
|
69
74
|
*scratch = antiddt;
|
70
75
|
break;
|
71
76
|
|
72
77
|
case 2:
|
73
|
-
|
74
|
-
")};
|
75
|
-
var->value_3 = (antiddt - *scratch) / (time_step/2);
|
78
|
+
var->value[3] = (antiddt - *scratch) / (time_step/2);
|
76
79
|
break;
|
77
80
|
|
78
81
|
case 3:
|
79
|
-
|
80
|
-
")};
|
81
|
-
var->value_0 = (antiddt - *scratch) / (time_step/2);
|
82
|
+
var->value[0] = (antiddt - *scratch) / (time_step/2);
|
82
83
|
break;
|
83
84
|
|
84
85
|
default:
|
@@ -91,10 +92,6 @@ module RedShift; class DerivativeFlow
|
|
91
92
|
}
|
92
93
|
end
|
93
94
|
end
|
94
|
-
|
95
|
-
define_c_method :calc_function_pointer do
|
96
|
-
body "shadow->flow = &#{flow_name}"
|
97
|
-
end
|
98
95
|
end
|
99
96
|
end
|
100
97
|
|
@@ -1,21 +1,26 @@
|
|
1
1
|
module RedShift; class EulerDifferentialFlow
|
2
|
-
def
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
flow_name = "flow_#{CGenerator.make_c_name cl.name}_#{var_name}_#{state}"
|
7
|
-
|
8
|
-
Component::FlowWrapper.make_subclass flow_name do
|
9
|
-
@inspect_str = "#{cl.name}:#{state}: #{var_name} = #{flow.formula}"
|
2
|
+
def make_generator cl, state
|
3
|
+
@fname = "flow_#{CGenerator.make_c_name cl.name}_#{var}_#{state}"
|
4
|
+
@inspect_str = "#{cl.name}:#{state}: #{var} = #{formula}"
|
10
5
|
|
11
|
-
|
12
|
-
|
6
|
+
@generator = proc do
|
7
|
+
sl = cl.shadow_library
|
8
|
+
ssn = cl.shadow_struct_name
|
9
|
+
cont_state_ssn = cl.cont_state_class.shadow_struct_name
|
10
|
+
|
11
|
+
sl.init_library_function.body \
|
12
|
+
"s_init_flow(#{fname}, #{fname.inspect}, #{inspect_str.inspect}, NONALGEBRAIC);"
|
13
|
+
|
14
|
+
include_file, source_file = sl.add_file fname
|
13
15
|
|
14
16
|
# We need the struct
|
15
|
-
|
17
|
+
source_file.include(cl.shadow_library_include_file)
|
16
18
|
|
17
|
-
|
19
|
+
flow = self
|
20
|
+
var_name = @var
|
21
|
+
source_file.define(fname).instance_eval do
|
18
22
|
arguments "ComponentShadow *comp_shdw"
|
23
|
+
scope :extern
|
19
24
|
declare :shadow => %{
|
20
25
|
struct #{ssn} *shadow;
|
21
26
|
struct #{cont_state_ssn} *cont_state;
|
@@ -30,7 +35,7 @@ module RedShift; class EulerDifferentialFlow
|
|
30
35
|
} ## optimization: in rk_level==4 case, don't need to calc deps
|
31
36
|
setup :shadow => %{
|
32
37
|
shadow = (#{ssn} *)comp_shdw;
|
33
|
-
cont_state = (#{cont_state_ssn} *)shadow->cont_state;
|
38
|
+
cont_state = (struct #{cont_state_ssn} *)shadow->cont_state;
|
34
39
|
var = &cont_state->#{var_name};
|
35
40
|
time_step = shadow->world->time_step;
|
36
41
|
} # return is necessary--else shadow, cont_state, var are uninitialized
|
@@ -40,18 +45,18 @@ module RedShift; class EulerDifferentialFlow
|
|
40
45
|
body %{
|
41
46
|
switch (shadow->world->rk_level) {
|
42
47
|
case 0:
|
43
|
-
#{flow.translate(self, "ddt_#{var_name}",
|
48
|
+
#{flow.translate(self, "ddt_#{var_name}", cl, 0).join("
|
44
49
|
")};
|
45
50
|
|
46
|
-
var->
|
47
|
-
var->
|
48
|
-
var->
|
49
|
-
var->
|
51
|
+
var->value[1] = var->value[2] =
|
52
|
+
var->value[0] + ddt_#{var_name} * time_step/2;
|
53
|
+
var->value[3] =
|
54
|
+
var->value[0] + ddt_#{var_name} * time_step;
|
50
55
|
var->rk_level = 3;
|
51
56
|
break;
|
52
57
|
|
53
58
|
case 3:
|
54
|
-
var->
|
59
|
+
var->value[0] = var->value[3];
|
55
60
|
var->rk_level = 4;
|
56
61
|
break;
|
57
62
|
}
|
@@ -59,9 +64,6 @@ module RedShift; class EulerDifferentialFlow
|
|
59
64
|
shadow->world->rk_level++;
|
60
65
|
}
|
61
66
|
end
|
62
|
-
define_c_method :calc_function_pointer do
|
63
|
-
body "shadow->flow = &#{flow_name}"
|
64
|
-
end
|
65
67
|
end
|
66
68
|
end
|
67
69
|
end; end
|