gs2crmod 0.12.9 → 0.12.10
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/README.md +13 -1
- data/VERSION +1 -1
- data/gs2crmod.gemspec +5 -7
- data/lib/gs2crmod/calculations.rb +94 -131
- data/lib/gs2crmod/graphs.rb +2332 -2342
- data/lib/gs2crmod/gs2.rb +31 -40
- data/lib/gs2crmod/gsl_data.rb +320 -326
- metadata +40 -22
- checksums.yaml +0 -7
data/lib/gs2crmod/gsl_data.rb
CHANGED
@@ -4,8 +4,6 @@
|
|
4
4
|
#########################
|
5
5
|
#
|
6
6
|
|
7
|
-
#
|
8
|
-
|
9
7
|
class NumRu::NetCDF
|
10
8
|
aliold :var
|
11
9
|
def var(*args)
|
@@ -15,10 +13,10 @@ class NumRu::NetCDF
|
|
15
13
|
return old_var(*args)
|
16
14
|
end
|
17
15
|
end
|
16
|
+
|
18
17
|
class CodeRunner
|
19
18
|
class Gs2
|
20
19
|
|
21
|
-
|
22
20
|
eval(File.read(File.dirname(__FILE__) + '/gsl_tools.rb'), GLOBAL_BINDING, File.dirname(__FILE__) + '/gsl_tools.rb')
|
23
21
|
|
24
22
|
# def gsl_vector(name, options={})
|
@@ -50,14 +48,11 @@ def netcdf_filename
|
|
50
48
|
@directory + '/' + @run_name + '.out.nc'
|
51
49
|
end
|
52
50
|
|
53
|
-
|
54
51
|
def ncclose
|
55
52
|
cache[:netcdf_file].close
|
56
53
|
cache.delete(:netcdf_file)
|
57
54
|
end
|
58
55
|
|
59
|
-
|
60
|
-
|
61
56
|
module FixNormOption
|
62
57
|
#class << self
|
63
58
|
def fix_norm_action(options)
|
@@ -225,6 +220,7 @@ module GSLVectors
|
|
225
220
|
return fix_norm(vec, 1, options)
|
226
221
|
end
|
227
222
|
end
|
223
|
+
|
228
224
|
def apar2_over_time_gsl_vector(options)
|
229
225
|
|
230
226
|
Dir.chdir(@directory) do #Necessary options: ky
|
@@ -247,6 +243,7 @@ module GSLVectors
|
|
247
243
|
options[:direction] = :ky
|
248
244
|
transient_es_heat_flux_amplification_over_kxy_gsl_vector(options)
|
249
245
|
end
|
246
|
+
|
250
247
|
def transient_es_heat_flux_amplification_over_kxy_gsl_vector(options)
|
251
248
|
Dir.chdir(@directory) do # i.e. phi2_by_ky_vs_time or phi2_by_kx_vs_time
|
252
249
|
kxy = options[:direction].to_sym
|
@@ -262,10 +259,12 @@ module GSLVectors
|
|
262
259
|
options[:direction] = :kx
|
263
260
|
transient_amplification_over_kxy_gsl_vector(options)
|
264
261
|
end
|
262
|
+
|
265
263
|
def transient_amplification_over_ky_gsl_vector(options)
|
266
264
|
options[:direction] = :ky
|
267
265
|
transient_amplification_over_kxy_gsl_vector(options)
|
268
266
|
end
|
267
|
+
|
269
268
|
def transient_amplification_over_kxy_gsl_vector(options)
|
270
269
|
Dir.chdir(@directory) do # i.e. phi2_by_ky_vs_time or phi2_by_kx_vs_time
|
271
270
|
kxy = options[:direction]
|
@@ -276,102 +275,96 @@ module GSLVectors
|
|
276
275
|
end
|
277
276
|
private :transient_amplification_over_kxy_gsl_vector
|
278
277
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
end
|
278
|
+
# The growth rate of the fluctuations, calculated from the potential, indexed by time and normalised to vth_1/a.
|
279
|
+
# :kx or :kx_index must be specified in options
|
280
|
+
def growth_rate_by_kx_over_time_gsl_vector(options)
|
281
|
+
options[:direction] = :kx
|
282
|
+
growth_rate_by_kxy_over_time_gsl_vector(options)
|
283
|
+
end
|
286
284
|
|
287
|
-
|
288
|
-
|
285
|
+
# The growth rate of the fluctuations, calculated from the potential, indexed by time and normalised to vth_1/a.
|
286
|
+
# :ky or :ky_index must be specified in options
|
287
|
+
def growth_rate_by_ky_over_time_gsl_vector(options)
|
288
|
+
options[:direction] = :ky
|
289
|
+
growth_rate_by_kxy_over_time_gsl_vector(options)
|
290
|
+
end
|
291
|
+
|
292
|
+
def growth_rate_by_kxy_over_time_gsl_vector(options)
|
293
|
+
# i.e. time_dependent_gr_by_ky_vs_time or phi2_by_kx_vs_time
|
289
294
|
|
290
|
-
|
291
|
-
options[:direction] = :ky
|
292
|
-
growth_rate_by_kxy_over_time_gsl_vector(options)
|
293
|
-
end
|
294
|
-
def growth_rate_by_kxy_over_time_gsl_vector(options)
|
295
|
-
# i.e. time_dependent_gr_by_ky_vs_time or phi2_by_kx_vs_time
|
295
|
+
kxy = options[:direction]
|
296
296
|
|
297
|
-
|
297
|
+
phi = gsl_vector("phi2_by_#{kxy}_over_time", options).log / 2.0
|
298
298
|
|
299
|
-
|
299
|
+
size = phi.size
|
300
|
+
dphi = phi.subvector(1, size - 1) - phi.subvector(0, size-1)
|
301
|
+
# NB dt already has norm fixed, dphi is dimensionless
|
302
|
+
return fix_norm(dphi/gsl_vector('dt'), 0, options)
|
303
|
+
end
|
300
304
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
305
|
+
# The real frequency of the fluctuations, read from the .out file, indexed by time and normalised to vth_1/a.
|
306
|
+
# :ky_index or :kx_index must be specified in options.
|
307
|
+
def frequency_by_kx_over_time_gsl_vector(options)
|
308
|
+
options[:direction] = :kx
|
309
|
+
frequency_by_kxy_over_time_gsl_vector(options)
|
310
|
+
end
|
306
311
|
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
if kxy == :kx
|
345
|
-
# You need to be careful when testing equality of the desired k with the k in the .out file
|
346
|
-
# since the .out file is only written to ~ 5 significant digits:
|
347
|
-
omega_reals << omr if ((desired_kxy - akx).abs/(desired_kxy.abs + 1e-7) < 1e-4)
|
348
|
-
else
|
349
|
-
omega_reals << omr if ((desired_kxy - aky).abs/(desired_kxy.abs + 1e-7) < 1e-4)
|
350
|
-
end
|
351
|
-
end
|
352
|
-
end
|
353
|
-
end
|
354
|
-
raise "No real frequencies found in the .out file for the desired k" if (omega_reals.size==0)
|
355
|
-
GSL::Vector.alloc(omega_reals)
|
356
|
-
end
|
357
|
-
# </MJL>
|
358
|
-
|
359
|
-
|
360
|
-
# The size of each time step, indexed by time, normalised to a/v_th1.
|
361
|
-
|
362
|
-
def dt_gsl_vector(options)
|
363
|
-
t = gsl_vector('t', options)
|
364
|
-
size = t.size
|
365
|
-
# NB t already has norm fixed
|
366
|
-
return t.subvector(1, size - 1) - t.subvector(0, size-1)
|
312
|
+
def frequency_by_ky_over_time_gsl_vector(options)
|
313
|
+
options[:direction] = :ky
|
314
|
+
frequency_by_kxy_over_time_gsl_vector(options)
|
315
|
+
end
|
316
|
+
|
317
|
+
def frequency_by_kxy_over_time_gsl_vector(options)
|
318
|
+
kxy = options[:direction]
|
319
|
+
kxy_index = kxy + :_index
|
320
|
+
kxys = get_list_of(kxy)
|
321
|
+
desired_kxy = kxys[options[kxy_index]]
|
322
|
+
raise "No k found at the desired index" if desired_kxy.nil?
|
323
|
+
|
324
|
+
omega_reals = []
|
325
|
+
File.open(@run_name+".out",'r') do |fileHandle|
|
326
|
+
fileHandle.each_line do |fileLine|
|
327
|
+
if fileLine.include?('aky=') # Only examine the lines of the .out file that contain frequency information.
|
328
|
+
|
329
|
+
index = fileLine.index('akx=')
|
330
|
+
raise "akx wasn't found where it was expected in the .out file." if index.nil?
|
331
|
+
akx = fileLine[(index+4)..-1].to_f
|
332
|
+
|
333
|
+
index = fileLine.index('aky=')
|
334
|
+
raise "aky wasn't found where it was expected in the .out file." if index.nil?
|
335
|
+
aky = fileLine[(index+4)..-1].to_f
|
336
|
+
|
337
|
+
index = fileLine.index('om=')
|
338
|
+
raise "om wasn't found where it was expected in the .out file." if index.nil?
|
339
|
+
omr = fileLine[(index+3)..-1].to_f
|
340
|
+
if kxy == :kx
|
341
|
+
# You need to be careful when testing equality of the desired k with the k in the .out file
|
342
|
+
# since the .out file is only written to ~ 5 significant digits:
|
343
|
+
omega_reals << omr if ((desired_kxy - akx).abs/(desired_kxy.abs + 1e-7) < 1e-4)
|
344
|
+
else
|
345
|
+
omega_reals << omr if ((desired_kxy - aky).abs/(desired_kxy.abs + 1e-7) < 1e-4)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
367
349
|
end
|
350
|
+
raise "No real frequencies found in the .out file for the desired k" if (omega_reals.size==0)
|
351
|
+
GSL::Vector.alloc(omega_reals)
|
352
|
+
end
|
368
353
|
|
369
|
-
|
354
|
+
# The size of each time step, indexed by time, normalised to a/v_th1.
|
355
|
+
def dt_gsl_vector(options)
|
356
|
+
t = gsl_vector('t', options)
|
357
|
+
size = t.size
|
358
|
+
# NB t already has norm fixed
|
359
|
+
return t.subvector(1, size - 1) - t.subvector(0, size-1)
|
360
|
+
end
|
361
|
+
|
362
|
+
# The growth rate, calculated from the potential, indexed by kx. Only makes sense in linear calculations.
|
370
363
|
def growth_rate_over_kx_gsl_vector(options)
|
371
364
|
options[:direction] = :kx
|
372
365
|
growth_rate_over_kxy_gsl_vector(options)
|
373
366
|
end
|
374
|
-
|
367
|
+
# The growth rate, calculated from the potential, indexed by ky. Only makes sense in linear calculations.
|
375
368
|
def growth_rate_over_ky_gsl_vector(options)
|
376
369
|
options[:direction] = :ky
|
377
370
|
growth_rate_over_kxy_gsl_vector(options)
|
@@ -380,9 +373,7 @@ module GSLVectors
|
|
380
373
|
def growth_rate_over_kxy_gsl_vector(options)
|
381
374
|
Dir.chdir(@directory) do # i.e. phi2_by_ky_vs_time or phi2_by_kx_vs_time
|
382
375
|
kxy = options[:direction]
|
383
|
-
# ep :growth_rate_at_ + kxy
|
384
376
|
return GSL::Vector.alloc(send(:growth_rate_at_ + kxy).values)
|
385
|
-
|
386
377
|
end
|
387
378
|
end
|
388
379
|
private :growth_rate_over_kxy_gsl_vector
|
@@ -406,16 +397,11 @@ module GSLVectors
|
|
406
397
|
end
|
407
398
|
end
|
408
399
|
|
409
|
-
# Frequency, indexed over ky, taken direct from the gs2 output file
|
410
|
-
def frequency_over_ky_gsl_vector(options)
|
411
|
-
options.convert_to_index(self, :kx)
|
412
|
-
return GSL::Vector.alloc(gsl_vector('ky').to_a.map{|ky| frequency_at_ky_at_kx[ky].values[options[:kx_index]-1]})
|
413
|
-
end
|
414
|
-
|
415
400
|
def es_heat_flux_by_kx_over_time_gsl_vector(options)
|
416
401
|
options[:direction] = :kx
|
417
402
|
es_heat_flux_by_kxy_over_time_gsl_vector(options)
|
418
403
|
end
|
404
|
+
|
419
405
|
def es_heat_flux_by_ky_over_time_gsl_vector(options)
|
420
406
|
options[:direction] = :ky
|
421
407
|
es_heat_flux_by_kxy_over_time_gsl_vector(options)
|
@@ -453,6 +439,7 @@ module GSLVectors
|
|
453
439
|
options[:direction] = :kx
|
454
440
|
es_heat_flux_over_kxy_gsl_vector(options)
|
455
441
|
end
|
442
|
+
|
456
443
|
def es_heat_flux_over_ky_gsl_vector(options)
|
457
444
|
options[:direction] = :ky
|
458
445
|
es_heat_flux_over_kxy_gsl_vector(options)
|
@@ -490,14 +477,17 @@ module GSLVectors
|
|
490
477
|
end
|
491
478
|
end
|
492
479
|
end
|
480
|
+
|
493
481
|
def phi2_by_kx_over_time_gsl_vector(options)
|
494
482
|
options[:direction] = :kx
|
495
483
|
phi2_by_kxy_over_time_gsl_vector(options)
|
496
484
|
end
|
485
|
+
|
497
486
|
def phi2_by_ky_over_time_gsl_vector(options)
|
498
487
|
options[:direction] = :ky
|
499
488
|
phi2_by_kxy_over_time_gsl_vector(options)
|
500
489
|
end
|
490
|
+
|
501
491
|
def phi2_by_kxy_over_time_gsl_vector(options)
|
502
492
|
Dir.chdir(@directory) do
|
503
493
|
# i.e. phi2_by_ky_vs_time or phi2_by_kx_vs_time
|
@@ -508,32 +498,20 @@ module GSLVectors
|
|
508
498
|
end
|
509
499
|
kxy_index = kxy + :_index
|
510
500
|
|
511
|
-
|
512
501
|
#Necessary options: :ky or :kx
|
513
502
|
#Optional options: :t_index_window
|
514
|
-
# eputs "got here"
|
515
|
-
#options[:begin_element], options[:end_element] = (options[:t_index_window] ? options[:t_index_window].map{|ind| ind -1} : [0, -1])
|
516
503
|
phi_t_array=nil
|
517
504
|
if @grid_option == "single"
|
518
505
|
phi_t_array = netcdf_file.var('phi2').get('start' => [options[:begin_element]], 'end' => [options[:end_element]]).to_a.flatten
|
519
506
|
else
|
520
|
-
# value = options[:ky]
|
521
|
-
# eputs value
|
522
|
-
# get_list_of(:ky)
|
523
|
-
# index = @ky_list.find{|index,val| (val-value).abs < Float::EPSILON}[0]
|
524
|
-
# ep options
|
525
507
|
options.convert_to_index(self, kxy)
|
526
|
-
#ep options
|
527
508
|
phi_t_array = netcdf_file.var("phi2_by_#{kxy}").get('start' => [options[kxy_index] - 1, options[:begin_element]], 'end' => [options[kxy_index] - 1, options[:end_element]]).to_a.flatten
|
528
|
-
# eputs 'phi_t_array.size', phi_t_array.size
|
529
509
|
end
|
530
510
|
return GSL::Vector.alloc(phi_t_array)
|
531
|
-
|
532
511
|
end
|
533
512
|
end
|
534
513
|
private :phi2_by_kxy_over_time_gsl_vector
|
535
514
|
|
536
|
-
|
537
515
|
def phi2_by_mode_over_time_gsl_vector(options)
|
538
516
|
Dir.chdir(@directory) do #Necessary options: :ky and :kx
|
539
517
|
#Optional options: :t_index_window
|
@@ -611,7 +589,6 @@ module GSLVectors
|
|
611
589
|
options.convert_to_index(self, :kx, :ky)
|
612
590
|
phi0_array = netcdf_file.var('phi0').get.to_a.map{|arr| arr[options[:kx_index] - 1][options[:ky_index] - 1][options[:ri]]}
|
613
591
|
return GSL::Vector.alloc(phi0_array)
|
614
|
-
|
615
592
|
end
|
616
593
|
end
|
617
594
|
|
@@ -707,6 +684,7 @@ module GSLVectors
|
|
707
684
|
end
|
708
685
|
end
|
709
686
|
end
|
687
|
+
|
710
688
|
def kpar_gsl_vector(options)
|
711
689
|
|
712
690
|
Dir.chdir(@directory) do
|
@@ -832,93 +810,120 @@ module GSLVectors
|
|
832
810
|
end
|
833
811
|
end
|
834
812
|
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
end
|
813
|
+
def hflux_tot_over_time_gsl_vector(options)
|
814
|
+
Dir.chdir(@directory) do
|
815
|
+
options.setup_time_window
|
816
|
+
narr = netcdf_file.var('hflux_tot').get('start' => [options[:begin_element]], 'end' => [options[:end_element]])
|
817
|
+
#eputs 'Got narr'
|
818
|
+
#ep 'hflux_tot', hflux
|
819
|
+
#eputs "fixing norm"
|
820
|
+
return fix_heat_flux_norm(GSL::Vector.alloc(narr.to_a), options)
|
844
821
|
end
|
845
|
-
|
846
|
-
|
847
|
-
|
822
|
+
end
|
823
|
+
alias :hflux_tot_gsl_vector :hflux_tot_over_time_gsl_vector
|
824
|
+
|
825
|
+
def es_heat_flux_over_time_gsl_vector(options)
|
826
|
+
Dir.chdir(@directory) do
|
848
827
|
|
849
|
-
|
850
|
-
|
851
|
-
end
|
828
|
+
options.setup_time_window
|
829
|
+
return GSL::Vector.alloc(netcdf_file.var('es_heat_flux').get('start' => [options[:species_index].to_i - 1, options[:begin_element]], 'end' => [options[:species_index].to_i - 1, options[:end_element]]).to_a.flatten)
|
852
830
|
end
|
853
|
-
|
854
|
-
|
831
|
+
end
|
832
|
+
|
833
|
+
def es_heat_par_over_time_gsl_vector(options)
|
834
|
+
Dir.chdir(@directory) do
|
855
835
|
|
856
|
-
|
857
|
-
|
858
|
-
end
|
836
|
+
options.setup_time_window
|
837
|
+
return GSL::Vector.alloc(netcdf_file.var('es_heat_par').get('start' => [options[:species_index].to_i - 1, options[:begin_element]], 'end' => [options[:species_index].to_i - 1, options[:end_element]]).to_a.flatten)
|
859
838
|
end
|
860
|
-
|
861
|
-
|
862
|
-
|
839
|
+
end
|
840
|
+
alias :es_heat_par_gsl_vector :es_heat_par_over_time_gsl_vector
|
841
|
+
|
842
|
+
def es_heat_perp_over_time_gsl_vector(options)
|
843
|
+
Dir.chdir(@directory) do
|
863
844
|
|
864
|
-
|
865
|
-
|
866
|
-
end
|
845
|
+
options.setup_time_window
|
846
|
+
return GSL::Vector.alloc(netcdf_file.var('es_heat_perp').get('start' => [options[:species_index].to_i - 1, options[:begin_element]], 'end' => [options[:species_index].to_i - 1, options[:end_element]]).to_a.flatten)
|
867
847
|
end
|
868
|
-
|
869
|
-
|
870
|
-
|
848
|
+
end
|
849
|
+
alias :es_heat_perp_gsl_vector :es_heat_perp_over_time_gsl_vector
|
850
|
+
|
851
|
+
def es_heat_flux_over_time_gsl_vector(options)
|
852
|
+
Dir.chdir(@directory) do
|
871
853
|
|
872
|
-
|
873
|
-
|
874
|
-
end
|
875
|
-
end
|
876
|
-
def es_mom_flux_over_time_gsl_vector(options)
|
877
|
-
Dir.chdir(@directory) do
|
878
|
-
options.setup_time_window
|
879
|
-
return GSL::Vector.alloc(netcdf_file.var('es_mom_flux').get('start' => [options[:species_index].to_i - 1, options[:begin_element]], 'end' => [options[:species_index].to_i - 1, options[:end_element]]).to_a.flatten)
|
880
|
-
end
|
881
|
-
end
|
882
|
-
def es_part_flux_over_time_gsl_vector(options)
|
883
|
-
Dir.chdir(@directory) do
|
884
|
-
options.setup_time_window
|
885
|
-
return GSL::Vector.alloc(netcdf_file.var('es_part_flux').get('start' => [options[:species_index].to_i - 1, options[:begin_element]], 'end' => [options[:species_index].to_i - 1, options[:end_element]]).to_a.flatten)
|
886
|
-
end
|
887
|
-
end
|
888
|
-
# Velocity space diagnostics: fraction of dist func in higher
|
889
|
-
# pitch angle harmonics
|
890
|
-
def lpc_pitch_angle_gsl_vector(options)
|
891
|
-
raise "Velocity space lpc diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.lpc"
|
892
|
-
lpc = GSL::Vector.filescan("#@directory/#@run_name.lpc")
|
893
|
-
return lpc[1]
|
854
|
+
options.setup_time_window
|
855
|
+
return GSL::Vector.alloc(netcdf_file.var('es_heat_flux').get('start' => [options[:species_index].to_i - 1, options[:begin_element]], 'end' => [options[:species_index].to_i - 1, options[:end_element]]).to_a.flatten)
|
894
856
|
end
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
return
|
857
|
+
end
|
858
|
+
|
859
|
+
def es_mom_flux_over_time_gsl_vector(options)
|
860
|
+
Dir.chdir(@directory) do
|
861
|
+
options.setup_time_window
|
862
|
+
return GSL::Vector.alloc(netcdf_file.var('es_mom_flux').get('start' => [options[:species_index].to_i - 1, options[:begin_element]], 'end' => [options[:species_index].to_i - 1, options[:end_element]]).to_a.flatten)
|
901
863
|
end
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
return
|
864
|
+
end
|
865
|
+
|
866
|
+
def es_part_flux_over_time_gsl_vector(options)
|
867
|
+
Dir.chdir(@directory) do
|
868
|
+
options.setup_time_window
|
869
|
+
return GSL::Vector.alloc(netcdf_file.var('es_part_flux').get('start' => [options[:species_index].to_i - 1, options[:begin_element]], 'end' => [options[:species_index].to_i - 1, options[:end_element]]).to_a.flatten)
|
908
870
|
end
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
871
|
+
end
|
872
|
+
|
873
|
+
# Velocity space diagnostics: fraction of dist func in higher
|
874
|
+
# pitch angle harmonics
|
875
|
+
def lpc_pitch_angle_gsl_vector(options)
|
876
|
+
raise "Velocity space lpc diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.lpc"
|
877
|
+
lpc = GSL::Vector.filescan("#@directory/#@run_name.lpc")
|
878
|
+
return lpc[1]
|
879
|
+
end
|
880
|
+
|
881
|
+
# Velocity space diagnostics: fraction of dist func in higher
|
882
|
+
# energy harmonics
|
883
|
+
def lpc_energy_gsl_vector(options)
|
884
|
+
raise "Velocity space lpc diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.lpc"
|
885
|
+
lpc = GSL::Vector.filescan("#@directory/#@run_name.lpc")
|
886
|
+
return lpc[2]
|
887
|
+
end
|
888
|
+
|
889
|
+
# Velocity space diagnostics: integral error due to
|
890
|
+
# pitch angle resolution
|
891
|
+
def vres_pitch_angle_gsl_vector(options)
|
892
|
+
raise "Velocity space vres diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vres"
|
893
|
+
vres = GSL::Vector.filescan("#@directory/#@run_name.vres")
|
894
|
+
return vres[1]
|
895
|
+
end
|
896
|
+
|
897
|
+
# Velocity space diagnostics: integral error due to
|
898
|
+
# energy resolution
|
899
|
+
def vres_energy_gsl_vector(options)
|
900
|
+
raise "Velocity space vres diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vres"
|
901
|
+
vres = GSL::Vector.filescan("#@directory/#@run_name.vres")
|
902
|
+
return vres[2]
|
903
|
+
end
|
904
|
+
|
905
|
+
def par_mom_flux_over_time_gsl_vector(options)
|
906
|
+
Dir.chdir(@directory) do
|
907
|
+
|
908
|
+
options.setup_time_window
|
909
|
+
# This is a hack... one day some one will put it in the NetCDF file (haha).
|
910
|
+
momlines = `grep parmom #@run_name.out`
|
911
|
+
mom = []
|
912
|
+
momlines.scan(Regexp.new("#{LongRegexen::FLOAT.to_s}$")) do
|
913
|
+
mom.push $~[:float].to_f
|
915
914
|
end
|
916
|
-
|
917
|
-
|
915
|
+
options[:end_element] = (mom.size + options[:end_element]) if options[:end_element] < 0
|
916
|
+
# p options
|
917
|
+
return GSL::Vector.alloc(mom).subvector(options[:begin_element], options[:end_element] - options[:begin_element] + 1)
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
def perp_mom_flux_over_time_gsl_vector(options)
|
918
922
|
|
923
|
+
Dir.chdir(@directory) do
|
919
924
|
options.setup_time_window
|
920
925
|
# This is a hack... one day some one will put it in the NetCDF file (haha).
|
921
|
-
momlines = `grep
|
926
|
+
momlines = `grep perpmom #@run_name.out`
|
922
927
|
mom = []
|
923
928
|
momlines.scan(Regexp.new("#{LongRegexen::FLOAT.to_s}$")) do
|
924
929
|
mom.push $~[:float].to_f
|
@@ -927,165 +932,154 @@ module GSLVectors
|
|
927
932
|
# p options
|
928
933
|
return GSL::Vector.alloc(mom).subvector(options[:begin_element], options[:end_element] - options[:begin_element] + 1)
|
929
934
|
end
|
930
|
-
|
935
|
+
end
|
931
936
|
|
932
|
-
|
937
|
+
def scan_parameter_value_gsl_vector(options)
|
938
|
+
return GSL::Vector.alloc(netcdf_file.var('scan_parameter_value').get.to_a)
|
939
|
+
end
|
940
|
+
|
941
|
+
def spectrum_over_kx_gsl_vector(options)
|
942
|
+
options[:direction] = :kx
|
943
|
+
spectrum_over_kxy_gsl_vector(options)
|
944
|
+
end
|
933
945
|
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
946
|
+
def spectrum_over_kx_avg_gsl_vector(options)
|
947
|
+
options[:direction] = :kx
|
948
|
+
spectrum_over_kxy_avg_gsl_vector(options)
|
949
|
+
end
|
950
|
+
|
951
|
+
def spectrum_over_ky_gsl_vector(options)
|
952
|
+
options[:direction] = :ky
|
953
|
+
spectrum_over_kxy_gsl_vector(options)
|
954
|
+
end
|
955
|
+
|
956
|
+
def spectrum_over_ky_avg_gsl_vector(options)
|
957
|
+
options[:direction] = :ky
|
958
|
+
spectrum_over_kxy_avg_gsl_vector(options)
|
959
|
+
end
|
960
|
+
|
961
|
+
def spectrum_over_kxy_gsl_vector(options)
|
962
|
+
Dir.chdir(@directory) do
|
963
|
+
# i.e. spectrum_over_ky or spectrum_over_kx
|
964
|
+
kxy = options[:direction]
|
965
|
+
# eputs options[:t_index]
|
966
|
+
raise "Spectrum makes no sense for single modes" if @grid_option == "single"
|
947
967
|
|
948
|
-
|
949
|
-
|
950
|
-
end
|
951
|
-
def spectrum_over_kx_gsl_vector(options)
|
952
|
-
options[:direction] = :kx
|
953
|
-
spectrum_over_kxy_gsl_vector(options)
|
954
|
-
end
|
968
|
+
options.convert_to_index(:t) if options[:t] or options[:t_element]
|
969
|
+
# eputs options[:t_index]
|
955
970
|
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
options[:
|
962
|
-
|
963
|
-
end
|
964
|
-
def spectrum_over_ky_avg_gsl_vector(options)
|
965
|
-
options[:direction] = :ky
|
966
|
-
spectrum_over_kxy_avg_gsl_vector(options)
|
967
|
-
end
|
968
|
-
def spectrum_over_kxy_gsl_vector(options)
|
969
|
-
Dir.chdir(@directory) do
|
970
|
-
# i.e. spectrum_over_ky or spectrum_over_kx
|
971
|
-
kxy = options[:direction]
|
972
|
-
# eputs options[:t_index]
|
973
|
-
raise "Spectrum makes no sense for single modes" if @grid_option == "single"
|
974
|
-
|
975
|
-
options.convert_to_index(:t) if options[:t] or options[:t_element]
|
976
|
-
# eputs options[:t_index]
|
977
|
-
|
978
|
-
options[:t_index] ||= list(:t).keys.max
|
979
|
-
# eputs options[:t_index]
|
980
|
-
phi_array = netcdf_file.var("phi2_by_#{kxy}").get('start' => [0, options[:t_index] - 1], 'end' => [-1, options[:t_index] - 1]).to_a.flatten
|
981
|
-
v = GSL::Vector.alloc(phi_array)
|
982
|
-
v = v.from_box_order if kxy == :kx
|
983
|
-
v = v.mul(gsl_vector(kxy).square) unless options[:phi2_only]
|
984
|
-
return v
|
985
|
-
end
|
971
|
+
options[:t_index] ||= list(:t).keys.max
|
972
|
+
# eputs options[:t_index]
|
973
|
+
phi_array = netcdf_file.var("phi2_by_#{kxy}").get('start' => [0, options[:t_index] - 1], 'end' => [-1, options[:t_index] - 1]).to_a.flatten
|
974
|
+
v = GSL::Vector.alloc(phi_array)
|
975
|
+
v = v.from_box_order if kxy == :kx
|
976
|
+
v = v.mul(gsl_vector(kxy).square) unless options[:phi2_only]
|
977
|
+
return v
|
986
978
|
end
|
979
|
+
end
|
987
980
|
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
981
|
+
#spectrum averaged in time
|
982
|
+
def spectrum_over_kxy_avg_gsl_vector(options)
|
983
|
+
Dir.chdir(@directory) do
|
984
|
+
# i.e. spectrum_over_ky or spectrum_over_kx
|
985
|
+
kxy = options[:direction]
|
986
|
+
raise "Spectrum makes no sense for single modes" if @grid_option == "single"
|
994
987
|
|
995
|
-
|
988
|
+
phi_array = netcdf_file.var("phi2_by_#{kxy}").get('start' => [0, 0], 'end' => [-1, -1]) #index = [kx or ky, t]
|
996
989
|
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
end
|
1003
|
-
|
1004
|
-
v = GSL::Vector.alloc(phi_av)
|
1005
|
-
v = v.from_box_order if kxy == :kx
|
1006
|
-
v = v.mul(gsl_vector(kxy).square) unless options[:phi2_only]
|
1007
|
-
return v
|
990
|
+
shape = phi_array.shape
|
991
|
+
phi_av = [];
|
992
|
+
#average over time for each kx or ky individually
|
993
|
+
for i in 0...shape[0]
|
994
|
+
phi_av[i] = phi_array[i,0..-1].sum / shape[1]
|
1008
995
|
end
|
1009
|
-
end
|
1010
996
|
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
#ep 'lx', lx
|
1016
|
-
nx = options[:nakx]||kx.size
|
1017
|
-
GSL::Vector.indgen(nx, 0, lx/nx)
|
1018
|
-
end
|
1019
|
-
def y_gsl_vector(options)
|
1020
|
-
raise "options naky and interpolate_y are incompatible" if options[:naky] and options[:interpolate_y]
|
1021
|
-
ky = gsl_vector(:ky, options)
|
1022
|
-
ly = 2*Math::PI/ky[1]
|
1023
|
-
ny = options[:naky]||ky.size
|
1024
|
-
ysize = ny*2-2+ny%2
|
1025
|
-
GSL::Vector.indgen(ysize, 0, ly/ysize)
|
997
|
+
v = GSL::Vector.alloc(phi_av)
|
998
|
+
v = v.from_box_order if kxy == :kx
|
999
|
+
v = v.mul(gsl_vector(kxy).square) unless options[:phi2_only]
|
1000
|
+
return v
|
1026
1001
|
end
|
1002
|
+
end
|
1027
1003
|
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1004
|
+
def x_gsl_vector(options)
|
1005
|
+
raise "options nakx and interpolate_x are incompatible" if options[:nakx] and options[:interpolate_x]
|
1006
|
+
kx = gsl_vector(:kx, options)
|
1007
|
+
lx = 2*Math::PI/kx.to_box_order[1]
|
1008
|
+
#ep 'lx', lx
|
1009
|
+
nx = options[:nakx]||kx.size
|
1010
|
+
GSL::Vector.indgen(nx, 0, lx/nx)
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
def y_gsl_vector(options)
|
1014
|
+
raise "options naky and interpolate_y are incompatible" if options[:naky] and options[:interpolate_y]
|
1015
|
+
ky = gsl_vector(:ky, options)
|
1016
|
+
ly = 2*Math::PI/ky[1]
|
1017
|
+
ny = options[:naky]||ky.size
|
1018
|
+
ysize = ny*2-2+ny%2
|
1019
|
+
GSL::Vector.indgen(ysize, 0, ly/ysize)
|
1020
|
+
end
|
1033
1021
|
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
If using numerical equil use the option :kxfac to override calculation.") unless @qinp or (@pk and @eps) or options[:kxfac]
|
1022
|
+
#This function reads in the 'drhodpsi' variable from the netcdf file.
|
1023
|
+
def drhodpsi_gsl_vector(options)
|
1024
|
+
drhodpsi = netcdf_file.var('drhodpsi').get()[0]
|
1025
|
+
return drhodpsi
|
1026
|
+
end
|
1040
1027
|
|
1041
|
-
|
1042
|
-
|
1028
|
+
#This function returns the zonal flow velocity as a function of x (the radial coordinate).
|
1029
|
+
#This is v_ZF = kxfac*IFT(i k_x phi_imag), where kxfac = (qinp/rhoc)*grho(rhoc).
|
1030
|
+
def zf_velocity_over_x_gsl_vector(options)
|
1031
|
+
Dir.chdir(@directory) do
|
1032
|
+
raise CRFatal.new("Need either qinp or pk and epsl specified in order to calculate kxfac.
|
1033
|
+
If using numerical equil use the option :kxfac to override calculation.") unless @qinp or (@pk and @eps) or options[:kxfac]
|
1043
1034
|
|
1044
|
-
|
1045
|
-
|
1046
|
-
options[:t_index] = it
|
1047
|
-
phi += gsl_vector_complex('phi_zonal', options)
|
1048
|
-
end
|
1049
|
-
phi /= gsl_vector(:t).size
|
1050
|
-
|
1051
|
-
if @qinp
|
1052
|
-
kxfac = (@qinp/@rhoc)/drhodpsi
|
1053
|
-
elsif @pk and @epsl
|
1054
|
-
kxfac = (@epsl/@pk)/drhodpsi
|
1055
|
-
elsif options[:kxfac]
|
1056
|
-
kxfac = options[:kxfac]
|
1057
|
-
end
|
1035
|
+
kx = gsl_vector(:kx).to_box_order
|
1036
|
+
drhodpsi = gsl_vector('drhodpsi')
|
1058
1037
|
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1038
|
+
phi = GSL::Vector.alloc(kx.size)
|
1039
|
+
for it in 0...gsl_vector(:t).size
|
1040
|
+
options[:t_index] = it
|
1041
|
+
phi += gsl_vector_complex('phi_zonal', options)
|
1042
|
+
end
|
1043
|
+
phi /= gsl_vector(:t).size
|
1044
|
+
|
1045
|
+
if @qinp
|
1046
|
+
kxfac = (@qinp/@rhoc)/drhodpsi
|
1047
|
+
elsif @pk and @epsl
|
1048
|
+
kxfac = (@epsl/@pk)/drhodpsi
|
1049
|
+
elsif options[:kxfac]
|
1050
|
+
kxfac = options[:kxfac]
|
1063
1051
|
end
|
1052
|
+
|
1053
|
+
vec_zf_vel = GSL::Vector.alloc(kx.size)
|
1054
|
+
#Take imaginary part since i k_x will lead to imaginary part being real
|
1055
|
+
vec_zf_vel = 0.5*kxfac*(phi*kx).backward.imag
|
1056
|
+
return vec_zf_vel
|
1064
1057
|
end
|
1058
|
+
end
|
1065
1059
|
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
end
|
1060
|
+
#This function returns the mean flow velocity as a function of x (the radial coordinate).
|
1061
|
+
#This is v_g_exb = (x - x(centre))*g_exb. The x-x(centre) ensures that the flow is zero
|
1062
|
+
#at the middle of the box.
|
1063
|
+
def mean_flow_velocity_over_x_gsl_vector(options)
|
1064
|
+
Dir.chdir(@directory) do
|
1065
|
+
raise CRFatal.new("Need to have g_exb > 0 to have a mean flow.") unless @g_exb
|
1066
|
+
x = gsl_vector(:x)
|
1067
|
+
|
1068
|
+
vec_exb_vel = GSL::Vector.alloc(x.size)
|
1069
|
+
#Take imaginary part since i k_x will lead to imaginary part being real
|
1070
|
+
vec_exb_vel = (x - x[x.size/2])*@g_exb
|
1071
|
+
return vec_exb_vel
|
1079
1072
|
end
|
1073
|
+
end
|
1080
1074
|
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
end
|
1075
|
+
def zonal_spectrum_gsl_vector(options)
|
1076
|
+
Dir.chdir(@directory) do
|
1077
|
+
gmzf = gsl_matrix('spectrum_over_ky_over_kx',options)
|
1078
|
+
veczf = GSL::Vector.alloc(gmzf.shape[1])
|
1079
|
+
gmzf.shape[1].times{|i| veczf[i] = gmzf[0,i]}
|
1080
|
+
return veczf
|
1088
1081
|
end
|
1082
|
+
end
|
1089
1083
|
|
1090
1084
|
end # module GSLVectors
|
1091
1085
|
include GSLVectors
|
@@ -1109,7 +1103,7 @@ module GSLVectorComplexes
|
|
1109
1103
|
options.convert_to_index(self, :ky)
|
1110
1104
|
if options[:t_index] or options[:t]
|
1111
1105
|
#extra option required is t_index
|
1112
|
-
raise CRFatal.new("write_phi_over_time is not enabled so this function won't work") unless @write_phi_over_time
|
1106
|
+
raise CRFatal.new("write_phi_over_time is not enabled so this function won't work") unless (@write_phi_over_time and @write_phi_over_time.fortran_true?)
|
1113
1107
|
|
1114
1108
|
options.convert_to_index(self, :t)
|
1115
1109
|
case @grid_option
|
@@ -1192,6 +1186,7 @@ def gsl_matrix(name, options={})
|
|
1192
1186
|
end
|
1193
1187
|
|
1194
1188
|
module GSLMatrices
|
1189
|
+
|
1195
1190
|
def growth_rate_over_ky_over_kx_gsl_matrix(options)
|
1196
1191
|
if @growth_rate_at_ky_at_kx.nil?
|
1197
1192
|
raise("The CodeRunner variable growth_rate_at_ky_at_kx does not seem to have been calculated for this run. This may result when the environment variable GS2_CALCULATE_ALL is not set when the run was analyzed. Try setting GS2_CALCULATE_ALL and then re-analyze the run using, e.g. from the command line,\n $ coderunner rc 'cgrf\' -j #{@id}")
|
@@ -1199,10 +1194,12 @@ module GSLMatrices
|
|
1199
1194
|
array = @growth_rate_at_ky_at_kx.values.map{|h| h.values}
|
1200
1195
|
return GSL::Matrix.alloc(array.flatten, array.size, array[0].size)
|
1201
1196
|
end
|
1197
|
+
|
1202
1198
|
def transient_amplification_over_ky_over_kx_gsl_matrix(options)
|
1203
1199
|
array = @transient_amplification_at_ky_at_kx.values.map{|h| h.values}
|
1204
1200
|
return GSL::Matrix.alloc(array.flatten, array.size, array[0].size)
|
1205
1201
|
end
|
1202
|
+
|
1206
1203
|
def es_heat_flux_over_ky_over_kx_gsl_matrix(options)
|
1207
1204
|
Dir.chdir(@directory) do
|
1208
1205
|
raise "Heat flux spectrum makes no sense for single modes" if @grid_option == "single"
|
@@ -1225,6 +1222,7 @@ module GSLMatrices
|
|
1225
1222
|
return gm
|
1226
1223
|
end
|
1227
1224
|
end
|
1225
|
+
|
1228
1226
|
def spectrum_over_ky_over_kx_gsl_matrix(options)
|
1229
1227
|
Dir.chdir(@directory) do
|
1230
1228
|
raise "Spectrum makes no sense for single modes" if @grid_option == "single"
|
@@ -1259,6 +1257,7 @@ module GSLMatrices
|
|
1259
1257
|
return gm
|
1260
1258
|
end
|
1261
1259
|
end
|
1260
|
+
|
1262
1261
|
def spectrum_over_ky_over_kpar_gsl_matrix(options)
|
1263
1262
|
Dir.chdir(@directory) do
|
1264
1263
|
|
@@ -1507,9 +1506,6 @@ def physical_kx_index(box_kx_index)
|
|
1507
1506
|
#end
|
1508
1507
|
end
|
1509
1508
|
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
1509
|
def gsl_complex(name, options={})
|
1514
1510
|
options = eval(options) if options.class == String
|
1515
1511
|
# p @directory
|
@@ -1557,7 +1553,5 @@ end
|
|
1557
1553
|
# end
|
1558
1554
|
# end
|
1559
1555
|
|
1560
|
-
|
1561
|
-
|
1562
1556
|
end
|
1563
1557
|
end
|