gs2crmod 0.11.58 → 0.11.59
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/VERSION +1 -1
- data/gs2crmod.gemspec +7 -5
- data/lib/gs2crmod/gs2.rb +841 -837
- data/lib/gs2crmod/ingen.rb +203 -194
- metadata +64 -42
data/lib/gs2crmod/ingen.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
1
|
class CodeRunner
|
2
|
-
class Gs2
|
2
|
+
class Gs2
|
3
3
|
|
4
|
-
|
4
|
+
MAX_NAME_SIZE = 310
|
5
5
|
|
6
6
|
|
7
7
|
def warning(message)
|
8
|
-
|
8
|
+
eputs "Warning: " + message; sleep 0.3
|
9
9
|
end
|
10
10
|
|
11
11
|
class InputFileError < StandardError
|
12
12
|
end
|
13
13
|
|
14
14
|
def error(message)
|
15
|
-
|
15
|
+
raise InputFileError.new("Error: " + message)
|
16
16
|
end
|
17
17
|
|
18
18
|
def test_failed(namelist, var, gs2_var, tst)
|
19
|
-
|
19
|
+
return <<EOF
|
20
20
|
|
21
21
|
---------------------------
|
22
|
-
|
22
|
+
Test Failed
|
23
23
|
---------------------------
|
24
24
|
|
25
|
-
Namelist: #{namelist}
|
25
|
+
Namelist: #{namelist}
|
26
26
|
Variable: #{var}
|
27
27
|
GS2 Name: #{gs2_var}
|
28
28
|
Value: #{send(var)}
|
@@ -36,13 +36,13 @@ end
|
|
36
36
|
|
37
37
|
|
38
38
|
def namelist_test_failed(namelist, tst)
|
39
|
-
|
39
|
+
return <<EOF
|
40
40
|
|
41
41
|
---------------------------
|
42
|
-
|
42
|
+
Test Failed
|
43
43
|
---------------------------
|
44
44
|
|
45
|
-
Namelist: #{namelist}
|
45
|
+
Namelist: #{namelist}
|
46
46
|
Test: #{tst[:test]}
|
47
47
|
Explanation: #{tst[:explanation]}
|
48
48
|
|
@@ -51,189 +51,189 @@ EOF
|
|
51
51
|
|
52
52
|
end
|
53
53
|
|
54
|
-
# Checks input parameters for inconsistencies and prints a report.
|
54
|
+
# Checks input parameters for inconsistencies and prints a report.
|
55
55
|
|
56
56
|
def run_namelist_tests(namelist, hash, enum = nil)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
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
|
+
value = send(cr_var)
|
68
|
+
if value.kind_of? Array
|
69
|
+
value.each{|v| test_variable(namelist, var, var_hash, ext, v)}
|
70
|
+
else
|
71
|
+
test_variable(namelist, var, var_hash, ext, value)
|
72
|
+
end
|
73
|
+
end
|
74
74
|
end
|
75
75
|
|
76
76
|
def test_variable(namelist, var, var_hash, ext, value)
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
77
|
+
gs2_var = (var_hash[:gs2_name] or var)
|
78
|
+
cr_var = var+ext.to_sym
|
79
|
+
if value and (not var_hash[:should_include] or eval(var_hash[:should_include]))
|
80
|
+
var_hash[:must_pass].each do |tst|
|
81
|
+
error(test_failed(namelist, cr_var, gs2_var, tst)) unless value.instance_eval(tst[:test])
|
82
|
+
end if var_hash[:must_pass]
|
83
|
+
var_hash[:should_pass].each do |tst|
|
84
|
+
warning(test_failed(namelist, cr_var, gs2_var, tst)) unless value.instance_eval(tst[:test])
|
85
|
+
end if var_hash[:should_pass]
|
86
|
+
if (var_hash[:allowed_values] or var_hash[:text_options])
|
87
|
+
tst = {test: "#{(var_hash[:allowed_values] or var_hash[:text_options]).inspect}.include? self", explanation: "The variable must have one of these values"}
|
88
|
+
error(test_failed(namelist, cr_var, gs2_var, tst)) unless value.instance_eval(tst[:test])
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
92
|
end
|
93
93
|
|
94
|
-
|
95
|
-
# Eventually, this will be a full port of the tool
|
96
|
-
|
97
|
-
def
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
# Diagnostics
|
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
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
94
|
+
|
95
|
+
# Eventually, this will be a full port of the ingen tool in the GS2 folder. At the moment it runs a limited set of tests for common errors in the input parameters (including type checking).
|
96
|
+
|
97
|
+
def check_parameters
|
98
|
+
|
99
|
+
# Sections
|
100
|
+
|
101
|
+
# Namelist Tests
|
102
|
+
# Grids
|
103
|
+
# Parallelisation
|
104
|
+
# Initialisation
|
105
|
+
# Diagnostics
|
106
|
+
# Misc
|
107
|
+
|
108
|
+
# Namelist Tests
|
109
|
+
|
110
|
+
rcp.namelists.each do |namelist, hash|
|
111
|
+
next if hash[:should_include].kind_of? String and not eval(hash[:should_include])
|
112
|
+
if en = hash[:enumerator]
|
113
|
+
#ep 'en', en, namelist
|
114
|
+
next unless send(en[:name])
|
115
|
+
send(en[:name]).times do |i|
|
116
|
+
run_namelist_tests(namelist, hash, i+1)
|
117
|
+
end
|
118
|
+
else
|
119
|
+
run_namelist_tests(namelist, hash)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
###############
|
124
|
+
# Grid Errors #
|
125
|
+
###############
|
126
|
+
|
127
|
+
# naky
|
128
|
+
warning("Setting naky when non-linear mode is on is not recommended.") if @naky and @nonlinear_mode == "on"
|
129
|
+
|
130
|
+
warning("You have set both ny and naky; naky will override ny.") if @ny and @naky
|
131
|
+
|
132
|
+
error("abs(shat) should not be less that 1.0e-6") if @shat and @shat.abs < 1.0e-6 and not agk?
|
133
|
+
error("abs(s_hat_input) should not be less that 1.0e-6") if @s_hat_input and @s_hat_input.abs < 1.0e-6 and not agk?
|
134
|
+
|
135
|
+
# delt
|
136
|
+
|
137
|
+
error("Please specify delt") unless @delt
|
138
|
+
error("delt <= 0") if @delt <= 0.0
|
139
|
+
warning("Nonlinear run with delt_minimum unspecified.") if @nonlinear_mode=="on" and not @delt_minimum
|
140
|
+
|
141
|
+
error("delt (#@delt) < delt_minimum") if @delt and @delt_minimum and @delt < @delt_minimum
|
142
|
+
|
143
|
+
# negrid
|
144
|
+
warning('negrid < 8 is not a good idea!') if @negrid and @negrid < 8
|
145
145
|
|
146
146
|
# nakx
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
147
|
+
warning("You have set both nx and ntheta0; ntheta0 will override nx.") if @nx and @ntheta0
|
148
|
+
|
149
|
+
warning("Do you have a reason for setting equal_arc = true (default)? If not set false.") if @equilibrium_option=="eik" and (!@equal_arc or @equal_arc.fortran_true?)
|
150
|
+
|
151
|
+
warning("Recommend nperiod > 1 for linear runs.") if @nonlinear_mode == "off" and (!@nperiod or @nperiod == 1)
|
152
|
+
warning("Recommend nperiod = 1 for nonlinear runs.") if @nonlinear_mode == "on" and (@nperiod > 1)
|
153
|
+
|
154
|
+
warning("Consider using field_option = local and associated optimizations.") if @field_option and @field_option == "implicit"
|
155
|
+
|
156
|
+
#################################
|
157
|
+
# Parallelisation/Layout Errors #
|
158
|
+
#################################
|
159
|
+
|
160
|
+
# Best linear run layout is lexys
|
161
|
+
warning("The best layout for linear runs is usually lexys.") if @nonlinear_mode=="off" and not @layout=="lexys"
|
162
|
+
|
163
|
+
# Best nonlinear run layout is xyles
|
164
164
|
warning("The best layout for nonlinear runs is usually xyles.") if @nonlinear_mode=="on" and not @layout=="xyles"
|
165
165
|
|
166
|
-
|
167
|
-
|
166
|
+
# Check whether we are parallelising over x
|
167
|
+
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"
|
168
168
|
|
169
|
-
|
170
|
-
|
171
|
-
|
169
|
+
#########################
|
170
|
+
# Initialisation Errors #
|
171
|
+
#########################
|
172
172
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
173
|
+
# Check if restart folder exists
|
174
|
+
if @restart_file and @restart_file =~ /^(?<folder>[^\/]+)\//
|
175
|
+
folder = $~[:folder]
|
176
|
+
warning("Folder #{folder}, specified in restart_file, not present. NetCDF save may fail") unless FileTest.exist?(folder)
|
177
|
+
end
|
178
178
|
|
179
|
-
|
179
|
+
error("Setting @restart_file as an empty string will result in hidden restart files.") if @restart_file == ""
|
180
180
|
|
181
|
-
|
181
|
+
error("ginit_option is 'many' but is_a_restart is false") if @ginit_option == "many" and not @is_a_restart
|
182
182
|
|
183
|
-
|
183
|
+
error("chop_side should not be used (remove test if default changes from T to F)") if !@chop_side or @chop_side.fortran_true?
|
184
184
|
|
185
|
-
|
186
|
-
|
187
|
-
|
185
|
+
#####################
|
186
|
+
# Diagnostic errors #
|
187
|
+
#####################
|
188
188
|
|
189
|
-
|
189
|
+
#Check whether useful diagnostics have been omitted.
|
190
190
|
|
191
|
-
|
192
|
-
|
193
|
-
|
191
|
+
not_set = [:write_verr, :save_for_restart, :write_nl_flux, :write_final_fields, :write_final_moments].find_all do |diagnostic|
|
192
|
+
not (send(diagnostic) and send(diagnostic).fortran_true?)
|
193
|
+
end
|
194
194
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
195
|
+
if not_set.size > 0
|
196
|
+
str = not_set.inject("") do |s, diagnostic|
|
197
|
+
s + "\n\t#{diagnostic} --- " + rcp.namelists[diagnostics_namelist][:variables][diagnostic][:description] rescue s
|
198
|
+
end
|
199
|
+
warning("The following useful diagnostics were not set:" + str) if str.length > 0
|
200
|
+
end
|
201
201
|
|
202
|
-
|
202
|
+
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"
|
203
203
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
error("Please specify nwrite") unless @nwrite
|
211
|
-
error("Please specify nstep") unless @nstep
|
204
|
+
#{
|
205
|
+
#write_verr: "Velocity space diagnostics will not be output for this run"
|
206
|
+
#}.each do |var, warn|
|
207
|
+
#warning(v"#{var} not set or .false. --- " + warn) unless send(var) and send(var).fortran_true?
|
208
|
+
#end
|
212
209
|
|
210
|
+
error("Please specify nwrite") unless @nwrite
|
211
|
+
error("Please specify nstep") unless @nstep
|
213
212
|
|
214
|
-
warning("You will write out diagnostics less than 50 times") if @nstep/@nwrite < 50
|
215
|
-
|
216
|
-
########################
|
217
|
-
# Miscellaneous errors #
|
218
|
-
########################
|
219
213
|
|
220
|
-
|
214
|
+
warning("You will write out diagnostics less than 50 times") if @nstep/@nwrite < 50
|
221
215
|
|
222
|
-
|
216
|
+
########################
|
217
|
+
# Miscellaneous errors #
|
218
|
+
########################
|
223
219
|
|
224
|
-
|
220
|
+
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
|
225
221
|
|
226
|
-
|
222
|
+
warning("You are submitting a nonlinear run with no dissipation.") if @nonlinear_mode == "on" and @hyper_option=="none" and @collision_model=="none"
|
227
223
|
|
228
|
-
|
224
|
+
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}
|
229
225
|
|
230
|
-
|
231
|
-
# Boundary Condition Errors #
|
232
|
-
#############################
|
226
|
+
warning("The system will abort with rapid timestep changes...") if !@abort_rapid_time_step_change or @abort_rapid_time_step_change.fortran_true?
|
233
227
|
|
234
|
-
|
228
|
+
warning("local_field_solve is an old variable that should not really be used.") if @local_field_solve and @local_field_solve.fortran_true?
|
235
229
|
|
236
|
-
|
230
|
+
#############################
|
231
|
+
# Boundary Condition Errors #
|
232
|
+
#############################
|
233
|
+
|
234
|
+
error("Boundary options should be linked with finite magnetic shear.") if (!@boundary_option or @boundary_option != "linked") and ((@s_hat_input and @s_hat_input.abs > 1.0e-6) or (@shat and @shat.abs > 1.0e-6))
|
235
|
+
|
236
|
+
error("Set nonad_zero = true.") if @nonad_zero and not @nonad_zero.fortran_true?
|
237
237
|
|
238
238
|
|
239
239
|
###################
|
@@ -246,32 +246,32 @@ def ingen
|
|
246
246
|
end
|
247
247
|
end
|
248
248
|
|
249
|
-
|
250
|
-
|
251
|
-
|
249
|
+
################
|
250
|
+
# Damping Rate #
|
251
|
+
################
|
252
252
|
|
253
|
-
|
253
|
+
error("Linear runs with hyperviscosity are NOT recommended!") if @nonlinear_mode=="off" and (@hyper_option and @hyper_option=="visc_only") and (@d_hypervisc and @d_hypervisc!=0)
|
254
254
|
|
255
|
-
|
255
|
+
warning("Amplitude dependent part of hyperviscosity being ignored since const_amp = true") if (@hyper_option and @hyper_option=="visc_only") and (@const_amp and @const_amp.fortran_true?)
|
256
256
|
|
257
|
-
|
258
|
-
|
259
|
-
|
257
|
+
###################
|
258
|
+
# Geometry Errors #
|
259
|
+
###################
|
260
260
|
|
261
|
-
|
261
|
+
error("You must set bishop = 4 for Miller(local) geometry. Remember also that s_hat_input will override shat") if (@bishop!=4 and (@local_eq and @local_eq.fortran_true?))
|
262
262
|
|
263
|
-
|
264
|
-
|
263
|
+
error("Shift should be > 0 for s-alpha equilibrium.") if @equilibrium_option=="s-alpha" and (@shift and @shift < 0)
|
264
|
+
error("Shift should be < 0 for Miller equilibrium.") if @equilibrium_option=="eik" and @local_eq.fortran_true? and (@shift and @shift > 0)
|
265
265
|
|
266
|
-
|
266
|
+
error("irho must be 2 for Miller equilibrium.") if @equilibrium_option=="eik" and @local_eq.fortran_true? and (@irho and @irho!=2)
|
267
267
|
|
268
|
-
|
268
|
+
warning("Note that shat != s_hat_input") if @shat and @s_hat_input and @shat!=@s_hat_input
|
269
269
|
|
270
|
-
|
271
|
-
|
272
|
-
|
270
|
+
##################
|
271
|
+
# Species Errors #
|
272
|
+
##################
|
273
273
|
|
274
|
-
|
274
|
+
error("Must set z = -1 for electron species.") if (@type_2 and @z_2 and @type_2=='electron' and @z_2 != -1)
|
275
275
|
|
276
276
|
|
277
277
|
end
|
@@ -279,30 +279,39 @@ end
|
|
279
279
|
# A hash which gives the actual numbers of gridpoints indexed by their corresponding letters in the layout string.
|
280
280
|
|
281
281
|
def gridpoints
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
282
|
+
gridpoints = {'l' => @ngauss, 'e' => @negrid, 's' => @nspec}
|
283
|
+
if @grid_option == "single"
|
284
|
+
gridpoints.absorb({'x'=>1, 'y'=>1})
|
285
|
+
else
|
286
|
+
gridpoints.absorb({'x' => (@ntheta0 or (2.0 * (@nx - 1.0) / 3.0 + 1.0).floor), 'y' => (@naky or ((@ny - 1.0) / 3.0 + 1.0).floor)})
|
287
|
+
end
|
288
|
+
return gridpoints
|
289
289
|
end
|
290
290
|
|
291
291
|
def cumulative_gridpoints
|
292
|
-
|
293
|
-
|
292
|
+
c = 1
|
293
|
+
error("Please specify layout") unless @layout
|
294
294
|
@layout.split(//).reverse.inject({}){|hash, let| c*=gridpoints[let]; hash[let] = c; hash}
|
295
295
|
end
|
296
|
-
#
|
297
|
-
def
|
298
|
-
|
299
|
-
|
296
|
+
# ep parallelisation
|
297
|
+
def max_nprocs_no_x
|
298
|
+
parallelisation = cumulative_gridpoints
|
299
|
+
parallelisation[parallelisation.keys[parallelisation.keys.index('x') - 1]]
|
300
300
|
end
|
301
301
|
|
302
302
|
|
303
|
-
|
304
|
-
|
305
|
-
|
303
|
+
def diagnostics_namelist
|
304
|
+
:gs2_diagnostics_knobs
|
305
|
+
end
|
306
|
+
|
307
|
+
# Run the ingen tool on the input file
|
308
|
+
def ingen
|
309
|
+
Dir.chdir(@directory) do
|
310
|
+
ing = File.dirname(File.expand_path(@executable)) + '/ingen'
|
311
|
+
success = system "#{ing} #@run_name.in"
|
312
|
+
warning("Could not run ingen... make sure that ingen is in the same folder as @executable and can be run on the login nodes if you want this to work") unless success
|
313
|
+
end
|
314
|
+
end
|
306
315
|
end
|
307
316
|
end
|
308
317
|
|