gs2crmod 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README.md +4 -0
- data/README.rdoc +19 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/ext/extconf.rb +9 -0
- data/ext/gs2crmod_ext.c +366 -0
- data/gs2crmod.gemspec +98 -0
- data/include/gs2crmod_ext.h +58 -0
- data/lib/gs2crmod/astrogk/astrogk.rb +201 -0
- data/lib/gs2crmod/astrogk/calculations.rb +57 -0
- data/lib/gs2crmod/astrogk/check_convergence.rb +7 -0
- data/lib/gs2crmod/astrogk/deleted_variables.rb +76 -0
- data/lib/gs2crmod/astrogk/graphs.rb +13 -0
- data/lib/gs2crmod/astrogk/gsl_data.rb +13 -0
- data/lib/gs2crmod/astrogk/gsl_tools.rb +182 -0
- data/lib/gs2crmod/astrogk/ingen.rb +18 -0
- data/lib/gs2crmod/astrogk/input_file_tools.rb +7 -0
- data/lib/gs2crmod/astrogk/namelist_tools.rb +14 -0
- data/lib/gs2crmod/astrogk/namelists.rb +2800 -0
- data/lib/gs2crmod/astrogk/properties.rb +17 -0
- data/lib/gs2crmod/astrogk/species_dependent_namelists.rb +228 -0
- data/lib/gs2crmod/astrogk/test_gs2.rb +231 -0
- data/lib/gs2crmod/astrogk.rb +200 -0
- data/lib/gs2crmod/calculations.rb +780 -0
- data/lib/gs2crmod/check_convergence.rb +179 -0
- data/lib/gs2crmod/deleted_variables.rb +916 -0
- data/lib/gs2crmod/graphs.rb +1899 -0
- data/lib/gs2crmod/graphs_rdoc.rb +556 -0
- data/lib/gs2crmod/gs2.rb +1143 -0
- data/lib/gs2crmod/gsl_data.rb +1181 -0
- data/lib/gs2crmod/gsl_data_3d.rb +705 -0
- data/lib/gs2crmod/gsl_tools.rb +187 -0
- data/lib/gs2crmod/ingen.rb +218 -0
- data/lib/gs2crmod/namelists.rb +5142 -0
- data/lib/gs2crmod/properties.rb +22 -0
- data/lib/gs2crmod/species_dependent_namelists.rb +228 -0
- data/lib/gs2crmod/test_gs2.rb +231 -0
- data/lib/gs2crmod.rb +2 -0
- data/lib/gs2crmod_extension.rb +1 -0
- data/test/helper.rb +18 -0
- data/test/test_gs2crmod.rb +7 -0
- metadata +176 -0
@@ -0,0 +1,187 @@
|
|
1
|
+
###################################
|
2
|
+
# GS2 CodeRunner Module: GSL Tools
|
3
|
+
#
|
4
|
+
# Various useful methods for manipulating gsl data.
|
5
|
+
#
|
6
|
+
###################################
|
7
|
+
|
8
|
+
module GSL
|
9
|
+
def self.cache
|
10
|
+
@cache ||= {}
|
11
|
+
@cache
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
class GSL::Vector
|
17
|
+
def pieces(no_pieces)
|
18
|
+
ans = []
|
19
|
+
piece_sizes = []
|
20
|
+
|
21
|
+
for i in 0...no_pieces
|
22
|
+
ans.push []; piece_sizes[i] = 0
|
23
|
+
end
|
24
|
+
for j in 0...size
|
25
|
+
piece_sizes[j % no_pieces] += 1
|
26
|
+
end
|
27
|
+
# p ans, piece_sizes
|
28
|
+
accum = 0
|
29
|
+
piece_sizes.each_with_index do |piece_size, piece|
|
30
|
+
ans[piece] = self.subvector(accum, piece_size)
|
31
|
+
accum += piece_size
|
32
|
+
end
|
33
|
+
return ans
|
34
|
+
end
|
35
|
+
|
36
|
+
def from_box_order
|
37
|
+
size = self.size
|
38
|
+
v1, v2 = self.subvector(0, (size+1)/2), self.subvector((size+1)/2, (size-1)/2)
|
39
|
+
return v2.connect(v1)
|
40
|
+
end
|
41
|
+
def to_box_order
|
42
|
+
size = self.size
|
43
|
+
v1, v2 = self.subvector(0, (size-1)/2), self.subvector((size-1)/2, (size+1)/2)
|
44
|
+
return v2.connect(v1)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
class GSL::Matrix::Complex
|
52
|
+
|
53
|
+
def self.re_im(re, im)
|
54
|
+
raise "Shape of real and imaginary matrices must match" unless re.shape == im.shape
|
55
|
+
rows, cols = re.shape
|
56
|
+
mat = alloc(rows, cols)
|
57
|
+
for i in 0...rows
|
58
|
+
for j in 0...cols
|
59
|
+
mat[i,j] = GSL::Complex.alloc([re[i,j], im[i,j]])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
return mat
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def backward_cols_c2c(normalise = false)
|
67
|
+
gm = self.dup
|
68
|
+
rows, cols = gm.shape
|
69
|
+
table = GSL.cache[[:fft_table, :complex, rows]] ||= GSL::FFT::ComplexWavetable.alloc(rows)
|
70
|
+
work = GSL.cache[[:fft_work, :complex, rows]] ||= GSL::FFT::ComplexWorkspace.alloc(rows)
|
71
|
+
for i in 0...cols
|
72
|
+
vec = gm.col(i)
|
73
|
+
vec.backward!(table, work)
|
74
|
+
for j in 0...rows
|
75
|
+
gm[j,i] = vec[j]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
gm = gm / rows if normalise
|
79
|
+
gm
|
80
|
+
end
|
81
|
+
|
82
|
+
def forward_cols_c2c
|
83
|
+
gm = self.dup
|
84
|
+
rows, cols = gm.shape
|
85
|
+
table = GSL.cache[[:fft_table, :complex, rows]] ||= GSL::FFT::ComplexWavetable.alloc(rows)
|
86
|
+
work = GSL.cache[[:fft_work, :complex, rows]] ||= GSL::FFT::ComplexWorkspace.alloc(rows)
|
87
|
+
for i in 0...cols
|
88
|
+
vec = gm.col(i)
|
89
|
+
vec.forward!(table, work)
|
90
|
+
for j in 0...rows
|
91
|
+
gm[j,i] = vec[j]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
gm
|
95
|
+
end
|
96
|
+
|
97
|
+
def backward_rows_cc2r(normalise = false)
|
98
|
+
gm = self.dup
|
99
|
+
rows, cols = gm.shape
|
100
|
+
# if cols%2 == 0
|
101
|
+
# newcols = cols*2
|
102
|
+
# else
|
103
|
+
# newcols = cols*2 - 1
|
104
|
+
# end
|
105
|
+
was_even = rows.times.inject(true) do |bool, i|
|
106
|
+
bool and (gm[i, cols - 1].imag == 0.0)
|
107
|
+
end
|
108
|
+
# ep was_even
|
109
|
+
|
110
|
+
if was_even
|
111
|
+
newcols = cols * 2 - 2
|
112
|
+
else
|
113
|
+
newcols = cols * 2 - 1
|
114
|
+
end
|
115
|
+
gm_re = GSL::Matrix.alloc(rows, newcols)
|
116
|
+
|
117
|
+
table = GSL.cache[[:fft_table, :real, newcols]] ||= GSL::FFT::RealWavetable.alloc(newcols)
|
118
|
+
work = GSL.cache[[:fft_work, :real, newcols]] ||= GSL::FFT::RealWorkspace.alloc(newcols)
|
119
|
+
row = GSL::Vector::Complex.alloc(cols)
|
120
|
+
# p rows
|
121
|
+
for i in 0...rows
|
122
|
+
# p i
|
123
|
+
# row = gm.row(i)
|
124
|
+
(0...cols).each{|j| row[j] = gm[i,j]}
|
125
|
+
if was_even
|
126
|
+
vec = row.concat(row.subvector(1, row.size - 2).reverse.conjugate) if cols > 2
|
127
|
+
else
|
128
|
+
vec = row.concat(row.subvector(1, row.size - 1).reverse.conjugate) if cols > 1
|
129
|
+
end
|
130
|
+
vec.backward!(table, work)
|
131
|
+
for j in 0...newcols
|
132
|
+
gm_re[i,j] = vec[j].real
|
133
|
+
end
|
134
|
+
end
|
135
|
+
gm_re = gm_re / newcols.to_f if normalise
|
136
|
+
gm_re
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
class GSL::Matrix
|
142
|
+
|
143
|
+
def move_rows_from_box_order
|
144
|
+
rows, cols = self.shape
|
145
|
+
gm1, gm2 = self.view(0,0, (rows + 1)/2, cols), self.view((rows + 1)/2, 0, (rows - 1)/2, cols)
|
146
|
+
return gm2.vertcat(gm1)
|
147
|
+
end
|
148
|
+
def move_cols_from_box_order
|
149
|
+
rows, cols = self.shape
|
150
|
+
gm1, gm2 = self.view(0,0, rows, (cols + 1)/2), self.view(0, (cols + 1)/2, rows, (cols - 1)/2)
|
151
|
+
return gm2.horzcat(gm1)
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
def forward_rows_r2cc
|
156
|
+
gm = self.dup
|
157
|
+
rows, cols = gm.shape
|
158
|
+
if cols%2 == 0
|
159
|
+
newcols = (cols+2)/2
|
160
|
+
else
|
161
|
+
newcols = (cols+1)/2
|
162
|
+
end
|
163
|
+
gm_cc = GSL::Matrix::Complex.alloc(rows, newcols)
|
164
|
+
|
165
|
+
table = GSL.cache[[:fft_table, :real, cols]] ||= GSL::FFT::RealWavetable.alloc(cols)
|
166
|
+
work = GSL.cache[[:fft_work, :real, cols]] ||= GSL::FFT::RealWorkspace.alloc(cols)
|
167
|
+
row = GSL::Vector.alloc(cols)
|
168
|
+
for i in 0...rows
|
169
|
+
(0...cols).each{|j| row[j] = gm[i,j]}
|
170
|
+
# p i
|
171
|
+
# row = gm.get_row(i)
|
172
|
+
# vec_out = GSL::Vector::Complex.alloc(row.size)
|
173
|
+
# (0...row.size).each{|j| vec[j] = row[j]}
|
174
|
+
# if cols%2 == 0
|
175
|
+
# vec_out = vec.concat(vec.subvector(1, vec.size - 2).reverse.conjugate)
|
176
|
+
# else
|
177
|
+
# vec_out = vec.concat(vec.subvector(1, vec.size - 1).reverse.conjugate)
|
178
|
+
# end
|
179
|
+
view = row.forward(table, work).halfcomplex_to_complex
|
180
|
+
for j in 0...newcols
|
181
|
+
gm_cc[i,j] = view[j]
|
182
|
+
end
|
183
|
+
end
|
184
|
+
return gm_cc
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
class CodeRunner
|
2
|
+
class Gs2
|
3
|
+
|
4
|
+
MAX_NAME_SIZE = 310
|
5
|
+
|
6
|
+
|
7
|
+
def warning(message)
|
8
|
+
eputs "Warning: " + message; sleep 0.3
|
9
|
+
end
|
10
|
+
|
11
|
+
class InputFileError < StandardError
|
12
|
+
end
|
13
|
+
|
14
|
+
def error(message)
|
15
|
+
raise InputFileError.new("Error: " + message)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_failed(namelist, var, gs2_var, tst)
|
19
|
+
return <<EOF
|
20
|
+
|
21
|
+
---------------------------
|
22
|
+
Test Failed
|
23
|
+
---------------------------
|
24
|
+
|
25
|
+
Namelist: #{namelist}
|
26
|
+
Variable: #{var}
|
27
|
+
GS2 Name: #{gs2_var}
|
28
|
+
Value: #{send(var)}
|
29
|
+
Test: #{tst[:test]}
|
30
|
+
Explanation: #{tst[:explanation]}
|
31
|
+
|
32
|
+
---------------------------
|
33
|
+
EOF
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def namelist_test_failed(namelist, tst)
|
39
|
+
return <<EOF
|
40
|
+
|
41
|
+
---------------------------
|
42
|
+
Test Failed
|
43
|
+
---------------------------
|
44
|
+
|
45
|
+
Namelist: #{namelist}
|
46
|
+
Test: #{tst[:test]}
|
47
|
+
Explanation: #{tst[:explanation]}
|
48
|
+
|
49
|
+
---------------------------
|
50
|
+
EOF
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
# Checks input parameters for inconsistencies and prints a report.
|
55
|
+
|
56
|
+
def run_namelist_tests(namelist, hash, enum = nil)
|
57
|
+
ext = enum ? "_#{enum}" : ""
|
58
|
+
hash[:must_pass].each do |tst|
|
59
|
+
error(namelist_test_failed(namelist, tst)) unless instance_eval(tst[:test])
|
60
|
+
end if hash[:must_pass]
|
61
|
+
hash[:should_pass].each do |tst|
|
62
|
+
warning(namelist_test_failed(namelist, tst)) unless instance_eval(tst[:test])
|
63
|
+
end if hash[:should_pass]
|
64
|
+
hash[:variables].each do |var, var_hash|
|
65
|
+
gs2_var = (var_hash[:gs2_name] or var)
|
66
|
+
cr_var = var+ext.to_sym
|
67
|
+
if send(cr_var) and (not var_hash[:should_include] or eval(var_hash[:should_include]))
|
68
|
+
var_hash[:must_pass].each do |tst|
|
69
|
+
error(test_failed(namelist, cr_var, gs2_var, tst)) unless send(cr_var).instance_eval(tst[:test])
|
70
|
+
end if var_hash[:must_pass]
|
71
|
+
var_hash[:should_pass].each do |tst|
|
72
|
+
warning(test_failed(namelist, cr_var, gs2_var, tst)) unless send(cr_var).instance_eval(tst[:test])
|
73
|
+
end if var_hash[:should_pass]
|
74
|
+
if (var_hash[:allowed_values] or var_hash[:text_options])
|
75
|
+
tst = {test: "#{(var_hash[:allowed_values] or var_hash[:text_options]).inspect}.include? self", explanation: "The variable must have one of these values"}
|
76
|
+
error(test_failed(namelist, cr_var, gs2_var, tst)) unless send(cr_var).instance_eval(tst[:test])
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
# Eventually, this will be a full port of the tool of the same name in the GS2 folder. At the moment it runs a limited set of tests for common errors in the input parameters (including type checking).
|
85
|
+
|
86
|
+
def ingen
|
87
|
+
|
88
|
+
# Sections
|
89
|
+
|
90
|
+
# Namelist Tests
|
91
|
+
# Grids
|
92
|
+
# Parallelisation
|
93
|
+
# Initialisation
|
94
|
+
# Diagnostics
|
95
|
+
# Misc
|
96
|
+
|
97
|
+
# Namelist Tests
|
98
|
+
|
99
|
+
rcp.namelists.each do |namelist, hash|
|
100
|
+
next if hash[:should_include].kind_of? String and not eval(hash[:should_include])
|
101
|
+
if en = hash[:enumerator]
|
102
|
+
#ep 'en', en, namelist
|
103
|
+
next unless send(en[:name])
|
104
|
+
send(en[:name]).times do |i|
|
105
|
+
run_namelist_tests(namelist, hash, i+1)
|
106
|
+
end
|
107
|
+
else
|
108
|
+
run_namelist_tests(namelist, hash)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# Grid Errors
|
114
|
+
|
115
|
+
# naky
|
116
|
+
warning("Setting naky when non-linear mode is on is not recommended.") if @naky and @nonlinear_mode == "on"
|
117
|
+
|
118
|
+
warning("You have set both ny and naky; naky will override ny.") if @ny and @naky
|
119
|
+
|
120
|
+
error("Boundary options should not be periodic with finite magnetic shear") if @boundary_option == "periodic" and ((@s_hat_input and @s_hat_input.abs > 1.0e-6) or (@shat and @shat.abs > 1.0e-6))
|
121
|
+
|
122
|
+
# delt
|
123
|
+
|
124
|
+
error("Please specify delt") unless @delt
|
125
|
+
error("delt <= 0") if @delt <= 0.0
|
126
|
+
warning("Nonlinear run with delt_minimum unspecified.") if @nonlinear_mode=="on" and not @delt_minimum
|
127
|
+
|
128
|
+
error("delt (#@delt) < delt_minimum") if @delt and @delt_minimum and @delt < @delt_minimum
|
129
|
+
|
130
|
+
# Parallelisation Errors
|
131
|
+
|
132
|
+
|
133
|
+
# Check whether we are parallelising over x
|
134
|
+
warning("Parallelising over x: suggest total number of processors should be: #{max_nprocs_no_x}") if actual_number_of_processors > max_nprocs_no_x and not @grid_option == "single"
|
135
|
+
|
136
|
+
|
137
|
+
# Initialisation Errors
|
138
|
+
|
139
|
+
# Check if restart folder exists
|
140
|
+
if @restart_file and @restart_file =~ /^(?<folder>[^\/]+)\//
|
141
|
+
folder = $~[:folder]
|
142
|
+
warning("Folder #{folder}, specified in restart_file, not present. NetCDF save may fail") unless FileTest.exist?(folder)
|
143
|
+
end
|
144
|
+
|
145
|
+
error("Setting @restart_file as an empty string will result in hidden restart files.") if @restart_file == ""
|
146
|
+
|
147
|
+
error("ginit_option is 'many' but is_a_restart is false") if @ginit_option == "many" and not @is_a_restart
|
148
|
+
|
149
|
+
#Diagnostic errors
|
150
|
+
#
|
151
|
+
#Check whether useful diagnostics have been omitted.
|
152
|
+
|
153
|
+
not_set = [:write_verr, :save_for_restart, :write_nl_flux, :write_final_fields, :write_final_moments].find_all do |diagnostic|
|
154
|
+
not (send(diagnostic) and send(diagnostic).fortran_true?)
|
155
|
+
end
|
156
|
+
|
157
|
+
if not_set.size > 0
|
158
|
+
str = not_set.inject("") do |str, diagnostic|
|
159
|
+
str + "\n\t#{diagnostic} --- " + rcp.namelists[diagnostics_namelist][:variables][diagnostic][:description] rescue str
|
160
|
+
end
|
161
|
+
warning("The following useful diagnostics were not set:" + str) if str.length > 0
|
162
|
+
end
|
163
|
+
|
164
|
+
warning("You are running in nonlinear mode but have not switched the nonlinear flux diagnostic.") if not (@write_nl_flux and @write_nl_flux.fortran_true?) and @nonlinear_mode == "on"
|
165
|
+
|
166
|
+
#{
|
167
|
+
#write_verr: "Velocity space diagnostics will not be output for this run"
|
168
|
+
#}.each do |var, warn|
|
169
|
+
#warning(v"#{var} not set or .false. --- " + warn) unless send(var) and send(var).fortran_true?
|
170
|
+
#end
|
171
|
+
|
172
|
+
warning("You will write out diagnostics less than 50 times") if @nstep/@nwrite < 50
|
173
|
+
|
174
|
+
#Miscellaneous errors.
|
175
|
+
|
176
|
+
error("The run name for this run is too long. Please move some of the variable settings to the local defaults file.") if @relative_directory.size + @run_name.size > MAX_NAME_SIZE
|
177
|
+
|
178
|
+
warning("You are submitting a nonlinear run with no dissipation.") if @nonlinear_mode == "on" and @hyper_option=="none" and @collision_model=="none"
|
179
|
+
|
180
|
+
warning("You have no spacial implicitness: (bakdif) for one of your species. Be prepared for numerical instabilities!") if (1..@nspec).to_a.find{|i| bd = send("bakdif_#{i}") and bd == 0}
|
181
|
+
|
182
|
+
warning("The system will abort with rapid timestep changes...") if !@abort_rapid_time_step_change or @abort_rapid_time_step_change.fortran_true?
|
183
|
+
|
184
|
+
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
# A hash which gives the actual numbers of gridpoints indexed by their corresponding letters in the layout string.
|
189
|
+
|
190
|
+
def gridpoints
|
191
|
+
gridpoints = {'l' => @ngauss, 'e' => @negrid, 's' => @nspec}
|
192
|
+
if @grid_option == "single"
|
193
|
+
gridpoints.absorb({'x'=>1, 'y'=>1})
|
194
|
+
else
|
195
|
+
gridpoints.absorb({'x' => (2.0 * (@nx - 1.0) / 3.0 + 1.0).floor, 'y' => (@naky or ((@ny - 1.0) / 3.0 + 1.0).floor)})
|
196
|
+
end
|
197
|
+
return gridpoints
|
198
|
+
end
|
199
|
+
|
200
|
+
def cumulative_gridpoints
|
201
|
+
c = 1
|
202
|
+
error("Please specify layout") unless @layout
|
203
|
+
@layout.split(//).reverse.inject({}){|hash, let| c*=gridpoints[let]; hash[let] = c; hash}
|
204
|
+
end
|
205
|
+
# ep parallelisation
|
206
|
+
def max_nprocs_no_x
|
207
|
+
parallelisation = cumulative_gridpoints
|
208
|
+
parallelisation[parallelisation.keys[parallelisation.keys.index('x') - 1]]
|
209
|
+
end
|
210
|
+
|
211
|
+
|
212
|
+
def diagnostics_namelist
|
213
|
+
:gs2_diagnostics_knobs
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
|