redshift 1.3.21 → 1.3.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|