gs2crmod 0.12.9 → 0.12.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,171 +4,171 @@ class CodeRunner
4
4
  class Gs2
5
5
 
6
6
  # for backwards compatibility, and because I'm lazy
7
- # one day someone should get rid of this!
7
+ # one day someone should get rid of this!
8
8
  AxisKit = GraphKit::AxisKit
9
9
  DataKit = GraphKit::DataKit
10
10
 
11
11
  def auto_axiskits(name, options)
12
- hash = cache[:auto_axiskits] ||= {'t' => ['Time', ''],
12
+ hash = cache[:auto_axiskits] ||= {'t' => ['Time', ''],
13
13
  'phi2tot_over_time' => ['Phi^2 Total', ''],
14
14
  'apar2_over_time' => ['Apar^2 Total', ''],
15
- 'growth_rate_by_ky_over_time' => ['Growth Rate by ky', ''],
16
- 'growth_rate_by_kx_over_time' => ['Growth Rate by kx', ''],
17
- 'growth_rate_by_mode_over_time' => ["Growth Rate by mode", ''],
18
- # <MJL additions 2013-09-19>
19
- 'frequency_by_ky_over_time' => ['Real frequency by ky', ''],
20
- 'frequency_by_kx_over_time' => ['Real frequency by kx', ''],
21
- # </MJL>
22
- 'phi2_by_ky_over_time' => ['Phi^2 by ky', ''],
23
- 'phi2_by_kx_over_time' => ['Phi^2 by ky', ''],
24
15
  'es_heat_flux_by_ky_over_time' => ['Heat flux by ky', ''],
25
16
  'es_heat_flux_by_kx_over_time' => ['Heat flux by kx', ''],
26
- 'phi2_by_mode_over_time' => ["Phi^2 by mode", ''],
27
- 'tpar2_by_mode_over_time' => ["(delta T_parallel)^2 by mode", '%'],
28
- 'tperp2_by_mode_over_time' => ["(delta T_perp)^2 by mode", '%'],
29
- 'hflux_tot' => ['Total Heat Flux', ''],
30
17
  'es_heat_par' => ['Parallel electrostatic heat flux', ''],
31
18
  'es_heat_perp' => ['Perpendicular electrostatic heat flux', ''],
32
- 'ky' => ['ky', "1/rho_#{species_letter}"],
33
- 'kx' => ['kx', "1/rho_#{species_letter}"],
34
- 'x' => ['x', "rho_#{species_letter}", 1],
35
- 'kpar' => ['kpar', "2 pi/qR"],
19
+ 'es_heat_flux_over_kx' => ["Heat Flux at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", 'Q_gB', 1],
20
+ 'es_heat_flux_over_ky' => ["Heat Flux at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", 'Q_gB', 1],
21
+ 'es_heat_flux_over_ky_over_kx' => ["Heat flux at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", '', 2],
22
+ 'es_mom_flux_over_time' => ["#{species_type((options[:species_index] or 1)).capitalize} Momentum Flux", '', 1],
23
+ 'es_part_flux_over_time' => ["#{species_type((options[:species_index] or 1)).capitalize} Particle Flux", '', 1],
24
+ 'frequency_over_kx' => ['Frequency', "v_th#{species_letter}/a", 1],
25
+ 'frequency_over_ky' => ['Frequency', "v_th#{species_letter}/a", 1],
26
+ 'frequency_by_ky_over_time' => ['Real frequency by ky', ''],
27
+ 'frequency_by_kx_over_time' => ['Real frequency by kx', ''],
28
+ 'growth_rate_by_ky_over_time' => ['Growth Rate by ky', ''],
29
+ 'growth_rate_by_kx_over_time' => ['Growth Rate by kx', ''],
30
+ 'growth_rate_by_mode_over_time' => ["Growth Rate by mode", ''],
36
31
  'growth_rate_over_kx' => ['Growth Rate', "v_th#{species_letter}/a", 1],
37
32
  'growth_rate_over_ky' => ['Growth Rate', "v_th#{species_letter}/a", 1],
38
33
  'growth_rate_over_kx_slice' => ['Growth Rate', "v_th#{species_letter}/a", 1],
39
34
  'growth_rate_over_ky_slice' => ['Growth Rate', "v_th#{species_letter}/a", 1],
40
35
  'growth_rate_over_ky_over_kx' => ["Growth Rate", "v_th#{species_letter}/a", 2],
41
- 'frequency_over_ky' => ['Frequency', "v_th#{species_letter}/a", 1],
42
- 'transient_es_heat_flux_amplification_over_kx' => ['Transient Electrostatic Heat Amplification', "", 1],
43
- 'transient_es_heat_flux_amplification_over_ky' => ['Transient Electrostatic Heat Amplification', "", 1],
44
- 'transient_amplification_over_kx' => ['Transient Amplification', "", 1],
45
- 'transient_amplification_over_ky' => ['Transient Amplification', "", 1],
36
+ 'hflux_tot' => ['Total Heat Flux', ''],
37
+ 'kpar' => ['kpar', "2 pi/qR"],
38
+ 'ky' => ['ky', "1/rho_#{species_letter}"],
39
+ 'kx' => ['kx', "1/rho_#{species_letter}"],
40
+ 'phi2_by_ky_over_time' => ['Phi^2 by ky', ''],
41
+ 'phi2_by_kx_over_time' => ['Phi^2 by ky', ''],
42
+ 'phi2_by_mode_over_time' => ["Phi^2 by mode", ''],
43
+ 'tpar2_by_mode_over_time' => ["(delta T_parallel)^2 by mode", '%'],
44
+ 'tperp2_by_mode_over_time' => ["(delta T_perp)^2 by mode", '%'],
45
+ 'x' => ['x', "rho_#{species_letter}", 1],
46
46
  'spectrum_over_kx' => ["Spectrum at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", '', 1],
47
47
  'spectrum_over_kx_avg' => ["Spectrum Averaged Over Time", '', 1],
48
48
  'spectrum_over_ky' => ["Spectrum at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", '', 1],
49
49
  'spectrum_over_ky_avg' => ["Spectrum Averaged Over Time", '', 1],
50
- 'es_heat_flux_over_kx' => ["Heat Flux at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", 'Q_gB', 1],
51
- 'es_heat_flux_over_ky' => ["Heat Flux at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", 'Q_gB', 1],
52
- 'es_heat_flux_over_ky_over_kx' => ["Heat flux at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", '', 2],
53
50
  'spectrum_over_kpar' => ["Spectrum at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", '', 1],
54
51
  'spectrum_over_ky_over_kx' => ["Spectrum at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", '', 2],
55
52
  'spectrum_over_ky_over_kpar' => ["Spectrum at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", '', 2],
56
53
  #'phi0_over_x_over_y' => ["Phi at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", '', 2],
57
54
  'phi0_over_x_over_y' => ["Phi at theta = 0", '', 2],
58
- 'es_mom_flux_over_time' => ["#{species_type((options[:species_index] or 1)).capitalize} Momentum Flux", '', 1],
59
- 'es_part_flux_over_time' => ["#{species_type((options[:species_index] or 1)).capitalize} Particle Flux", '', 1],
55
+ 'transient_es_heat_flux_amplification_over_kx' => ['Transient Electrostatic Heat Amplification', "", 1],
56
+ 'transient_es_heat_flux_amplification_over_ky' => ['Transient Electrostatic Heat Amplification', "", 1],
57
+ 'transient_amplification_over_kx' => ['Transient Amplification', "", 1],
58
+ 'transient_amplification_over_ky' => ['Transient Amplification', "", 1],
60
59
  'zonal_spectrum' => ["Zonal spectrum at t = #{sprintf("%.3f" ,(options[:t] or list(:t)[options[:t_index]] or list(:t).values.max))}", '', 1],
61
60
  'zf_velocity_over_x' => ['Zonal Flow Velocity', "", 1],
62
61
  'mean_flow_velocity_over_x' => ['Mean Flow Velocity', "", 1]
63
62
  }
64
- return hash[name]
63
+ return hash[name]
65
64
  end
66
65
 
67
66
  def axiskit(name, options={})
68
- logf :axiskit
69
- if info = auto_axiskits(name, options)
70
- if info[2] and info[2] == 2
71
- axis = GraphKit::AxisKit.autocreate({data: gsl_matrix(name, options), title: info[0], units: info[1]})
72
- elsif !info[2] or info[2] == 1
73
- axis = GraphKit::AxisKit.autocreate({data: gsl_vector(name, options), title: info[0], units: info[1]})
74
- log 'successfully created axis'
75
- end
76
- return axis
77
- end
78
- case name
79
- when 'phi_along_field_line'
80
- title = options[:imrc].to_s.capitalize + " Phi"
81
- units = ""
82
- return GraphKit::AxisKit.autocreate(data: gsl_vector(name, options), title: title, units: units)
83
- when 'theta_along_field_line'
84
- title = options[:z] ? "z/l_B" : 'Theta'
85
- units = options[:z] ? '' : 'radians'
86
- return GraphKit::AxisKit.autocreate(data: gsl_vector(name, options), title: title, units: units)
87
- when 'es_heat_flux'
88
- type = species_type(options[:species_index]).capitalize
89
- units = ''
90
- return GraphKit::AxisKit.autocreate(data: gsl_vector('es_heat_flux_over_time', options), title: "#{type} Heat Flux", units: units)
91
- # when 'spectrum_by_ky'
92
- # return AxisKit.autocreate(data: gsl_vector('spectrum_by_ky', options), title: "Phi^2 at t = #{list(:t)[options[:t_index]]}", units: '')
93
- when 'es_heat_par'
67
+ logf :axiskit
68
+ if info = auto_axiskits(name, options)
69
+ if info[2] and info[2] == 2
70
+ axis = GraphKit::AxisKit.autocreate({data: gsl_matrix(name, options), title: info[0], units: info[1]})
71
+ elsif !info[2] or info[2] == 1
72
+ axis = GraphKit::AxisKit.autocreate({data: gsl_vector(name, options), title: info[0], units: info[1]})
73
+ log 'successfully created axis'
74
+ end
75
+ return axis
76
+ end
77
+ case name
78
+ when 'phi_along_field_line'
79
+ title = options[:imrc].to_s.capitalize + " Phi"
80
+ units = ""
81
+ return GraphKit::AxisKit.autocreate(data: gsl_vector(name, options), title: title, units: units)
82
+ when 'theta_along_field_line'
83
+ title = options[:z] ? "z/l_B" : 'Theta'
84
+ units = options[:z] ? '' : 'radians'
85
+ return GraphKit::AxisKit.autocreate(data: gsl_vector(name, options), title: title, units: units)
86
+ when 'es_heat_flux'
87
+ type = species_type(options[:species_index]).capitalize
88
+ units = ''
89
+ return GraphKit::AxisKit.autocreate(data: gsl_vector('es_heat_flux_over_time', options), title: "#{type} Heat Flux", units: units)
90
+ # when 'spectrum_by_ky'
91
+ # return AxisKit.autocreate(data: gsl_vector('spectrum_by_ky', options), title: "Phi^2 at t = #{list(:t)[options[:t_index]]}", units: '')
92
+ when 'es_heat_par'
94
93
  puts "heat par"
95
- type = species_type(options[:species_index]).capitalize
96
- units = ''
97
- return GraphKit::AxisKit.autocreate(data: gsl_vector('es_heat_par_over_time', options), title: "#{type} parallel es heat flux", units: units)
98
- # when 'spectrum_by_ky'
99
- # return AxisKit.autocreate(data: gsl_vector('spectrum_by_ky', options), title: "Phi^2 at t = #{list(:t)[options[:t_index]]}", units: '')
100
- end
101
- raise CRError.new("Unknown axis kit: #{name}")
94
+ type = species_type(options[:species_index]).capitalize
95
+ units = ''
96
+ return GraphKit::AxisKit.autocreate(data: gsl_vector('es_heat_par_over_time', options), title: "#{type} parallel es heat flux", units: units)
97
+ # when 'spectrum_by_ky'
98
+ # return AxisKit.autocreate(data: gsl_vector('spectrum_by_ky', options), title: "Phi^2 at t = #{list(:t)[options[:t_index]]}", units: '')
99
+ end
100
+ raise CRError.new("Unknown axis kit: #{name}")
102
101
  end
103
102
 
104
103
  def self.cache
105
- @cache ||= {}
106
- @cache
104
+ @cache ||= {}
105
+ @cache
107
106
  end
108
-
107
+
109
108
  def self.generate_graphs_rdoc_file
110
- File.open('graphs_rdoc.rb', 'w') do |file|
111
- graphs = self.instance_methods.find_all{|m| m.to_s =~ /_graphkit$/}.sort_by{|m| m.to_s}
112
- run = new(nil)
113
- file.puts "class #{self.to_s}::GraphKits\n"
114
- graphs.each do |graph|
115
- help = run.send(graph, command: :help)
116
- options = run.send(graph, command: :options)
117
- file.puts "# #{help}"
118
- if options and options.size > 0
119
- file.puts "# Options:"
120
- options.each do |op|
121
- file.puts "#\n# #{op}: #{GRAPHKIT_OPTIONS_HELP[op]}"
122
- end
123
- end
124
- file.puts "def #{graph}\nend"
125
- end
126
- file.puts "end"
127
- end
109
+ File.open('graphs_rdoc.rb', 'w') do |file|
110
+ graphs = self.instance_methods.find_all{|m| m.to_s =~ /_graphkit$/}.sort_by{|m| m.to_s}
111
+ run = new(nil)
112
+ file.puts "class #{self.to_s}::GraphKits\n"
113
+ graphs.each do |graph|
114
+ help = run.send(graph, command: :help)
115
+ options = run.send(graph, command: :options)
116
+ file.puts "# #{help}"
117
+ if options and options.size > 0
118
+ file.puts "# Options:"
119
+ options.each do |op|
120
+ file.puts "#\n# #{op}: #{GRAPHKIT_OPTIONS_HELP[op]}"
121
+ end
122
+ end
123
+ file.puts "def #{graph}\nend"
124
+ end
125
+ file.puts "end"
126
+ end
128
127
  end
128
+
129
129
  def self.help_graphs
130
- # @@runner ||= CodeRunner.fetch_runner(U: true,
131
- string = ""
132
- graphs = self.instance_methods.find_all{|m| m.to_s =~ /_graphkit$/}.sort_by{|m| m.to_s}
133
- run = new(nil)
134
- string << "-------------------------------------------\n Available Graphs For #{self.to_s}\n-------------------------------------------\n\n"
135
- graphs.each do |graph|
136
- help = run.send(graph, command: :help)
137
- options = run.send(graph, command: :options)
138
- string << "\n------------------------------------\n#{graph.to_s.sub(/_graphkit/, '')}\n------------------------------------\n\n#{help}\n"
139
- if options and options.size > 0
140
- string << "\n\tOptions:\n"
141
- options.each do |op|
142
- string << "\t\t#{op}: #{GRAPHKIT_OPTIONS_HELP[op]}\n"
143
- end
144
- end
145
-
146
- end
147
- string.paginate
130
+ # @@runner ||= CodeRunner.fetch_runner(U: true,
131
+ string = ""
132
+ graphs = self.instance_methods.find_all{|m| m.to_s =~ /_graphkit$/}.sort_by{|m| m.to_s}
133
+ run = new(nil)
134
+ string << "-------------------------------------------\n Available Graphs For #{self.to_s}\n-------------------------------------------\n\n"
135
+ graphs.each do |graph|
136
+ help = run.send(graph, command: :help)
137
+ options = run.send(graph, command: :options)
138
+ string << "\n------------------------------------\n#{graph.to_s.sub(/_graphkit/, '')}\n------------------------------------\n\n#{help}\n"
139
+ if options and options.size > 0
140
+ string << "\n\tOptions:\n"
141
+ options.each do |op|
142
+ string << "\t\t#{op}: #{GRAPHKIT_OPTIONS_HELP[op]}\n"
143
+ end
144
+ end
145
+
146
+ end
147
+ string.paginate
148
148
  end
149
149
 
150
150
  GRAPHKIT_OPTIONS_HELP = {
151
- t_index_window: "[begin, end], window of time indices to plot (e.g. t_index_window: [0,10])",
152
- t_index: "integer, index of time at which to plot (e.g. t_index: 20)",
153
- t: "float, value of time at which to plot (e.g. t: 2.45)",
154
- ky_index: "integer, index of ky at which to plot (e.g. ky_index: 20)",
155
- ky: "float, value of ky at which to plot (e.g. ky: 0.1)",
156
- kx_index: "integer, index of kx at which to plot (e.g. kx_index: 20)",
157
- kx: "float, value of kx at which to plot (e.g. kx: 0.1)",
158
- with: "Gnuplot Option (may not apply when using other packages), e.g. with: 'lp' or with 'pm3d palette'",
159
- rgbformulae: "Gnuplot Option (may not apply when using other packages), sets colour mapping. See gnuplot help set rgbformulae",
160
- limit: "Limit the range of quantity begin plotted - any values of the quantity outside the limits will be set to the limit: eg. limit: [0,80]",
161
- flip: 'Flip the y axis, e.g. flip: true',
162
- rev: 'Reverse the x axis, e.g. rev: true',
163
- z: 'Plot quantities vs z = theta/shat rather than theta. See Beer, Cowley Hammet 1996, eg. z: true',
164
- norm: 'Normalise the graph so that its maximum is 1, e.g. norm: true',
165
- mag: 'Plot the magnitude, e.g. mag: true',
166
- species_index: "Which GS2 species to plot the graph for (1-based).",
151
+ t_index_window: "[begin, end], window of time indices to plot (e.g. t_index_window: [0,10])",
152
+ t_index: "integer, index of time at which to plot (e.g. t_index: 20)",
153
+ t: "float, value of time at which to plot (e.g. t: 2.45)",
154
+ ky_index: "integer, index of ky at which to plot (e.g. ky_index: 20)",
155
+ ky: "float, value of ky at which to plot (e.g. ky: 0.1)",
156
+ kx_index: "integer, index of kx at which to plot (e.g. kx_index: 20)",
157
+ kx: "float, value of kx at which to plot (e.g. kx: 0.1)",
158
+ with: "Gnuplot Option (may not apply when using other packages), e.g. with: 'lp' or with 'pm3d palette'",
159
+ rgbformulae: "Gnuplot Option (may not apply when using other packages), sets colour mapping. See gnuplot help set rgbformulae",
160
+ limit: "Limit the range of quantity begin plotted - any values of the quantity outside the limits will be set to the limit: eg. limit: [0,80]",
161
+ flip: 'Flip the y axis, e.g. flip: true',
162
+ rev: 'Reverse the x axis, e.g. rev: true',
163
+ z: 'Plot quantities vs z = theta/shat rather than theta. See Beer, Cowley Hammet 1996, eg. z: true',
164
+ norm: 'Normalise the graph so that its maximum is 1, e.g. norm: true',
165
+ mag: 'Plot the magnitude, e.g. mag: true',
166
+ species_index: "Which GS2 species to plot the graph for (1-based).",
167
167
  strongest_non_zonal_mode: "Plot the graph requested for the mode with the highest value of phi^2. Overrides ky, kx, ky_index, kx_index. Can be set true or false; e.g. strongest_non_zonal_mode: true",
168
- no_zonal: "Don't plot the ky=0 part (boolean, e.g. no_zonal: true)",
169
- no_kpar0: "Don't plot the kpar=0 part (boolean, e.g. no_kpar0: true)",
170
- log: "Plot the log of a given quantity (exact meaning varies). boolean",
171
- Rmaj: "The major radius in metres. This has no effect on the shape of the graph: it merely multiplies every length",
168
+ no_zonal: "Don't plot the ky=0 part (boolean, e.g. no_zonal: true)",
169
+ no_kpar0: "Don't plot the kpar=0 part (boolean, e.g. no_kpar0: true)",
170
+ log: "Plot the log of a given quantity (exact meaning varies). boolean",
171
+ Rmaj: "The major radius in metres. This has no effect on the shape of the graph: it merely multiplies every length",
172
172
  n0: " The toroidal mode number of the longest y mode. In effect it is the number of periodic copies of the flux tube that will fit in the torus. Periodicity requires that n0 q is also an integer. If you specify :n0 where this is not the case, q will automatically be adjusted until it is",
173
173
  rho_star: " The ratio of the reference Lamour radius to the GS2 normalising length a. Cannot be specified at the same time as n0. If specified, both n0 and q will be adjusted to ensure periodicity",
174
174
  t_index: "The (1-based) time index",
@@ -181,926 +181,855 @@ GRAPHKIT_OPTIONS_HELP = {
181
181
  ymin: "The (0-based) index of the minimum value of y to include in the plot",
182
182
  thetamax: "The (0-based) index of the maximum value of theta to include in the plot",
183
183
  thetamin: "The (0-based) index of the minimum value of theta to include in the plot",
184
- theta_index: "integer, index of theta at which to plot (e.g. theta_index: 20)",
185
- kxfac: "float, overrides calculation of kxfac in zonal flow velocity function",
186
- add_mean_flow: "bool, Adds mean flow to zonal flow velocity",
184
+ theta_index: "integer, index of theta at which to plot (e.g. theta_index: 20)",
185
+ kxfac: "float, overrides calculation of kxfac in zonal flow velocity function",
186
+ add_mean_flow: "bool, Adds mean flow to zonal flow velocity",
187
187
  ncopies: " The number of periodic copies of the flux tube to include",
188
188
  torphi_values: "An array of two values of the toroidal angle. The graph will be plotted in between those two values with poloidal cross sections at either end",
189
189
  magnify: " The magnification factor of the small section. It can take any value greater than or equal to 1",
190
190
  }
191
-
191
+
192
192
  def graphkit(name, options={})
193
- logf :graphkit
194
- # If an array of t, kx or ky values is provided, plot one graph for each value and then sum the graphs together
195
- [:t, :kx, :ky, :X, :Y, :e, :l, :theta, :ri, :r].each do |var|
196
- #ep 'index', var
197
- if options[var].class == Symbol and options[var] == :all
198
- options[var] = list(var).values
199
- elsif options[var+:_index].class == Symbol and options[var+:_index] == :all
200
- #ep 'Symbol'
201
- options[var+:_index] = list(var).keys
202
- end
203
- if options[var].class == Array
204
- return options[var].map{|value| graphkit(name, options.dup.absorb({var => value}))}.sum
205
- elsif options[var+:_index].class == Array
206
- #ep 'Array'
207
- return options[var+:_index].map{|value| graphkit(name, options.dup.absorb({var+:_index => value}))}.sum
208
- end
209
- if options[var].class == Symbol and options[var] == :max
210
- options[var] = list(var).values.max
211
- elsif options[var+:_index].class == Symbol and options[var+:_index] == :max
212
- ep 'Symbol'
213
- options[var+:_index] = list(var).keys.max
214
- end
215
- end
216
- options[:t_index] ||= options[:frame_index] if options[:frame_index]
217
-
218
-
219
-
220
-
221
-
222
- # Smart graphkits are defined in the file read_netcdf
223
- if name =~ /^cdf_/
224
- return smart_graphkit(options + {graphkit_name: name})
225
- elsif name =~ /^nc_/
226
- return old_smart_graphkit(options + {graphkit_name: name})
227
- end
228
-
229
- # If a method from the new GraphKits module can generate this graphkit use it
230
- if method = self.class.instance_methods.find{|meth| (name + '_graphkit').to_sym == meth}
231
- options[:graphkit_name] = name
232
- return send(method, options)
233
- end
234
-
235
- raise "Graph #{name} not found"
236
-
193
+ logf :graphkit
194
+ # If an array of t, kx or ky values is provided, plot one graph for each value and then sum the graphs together
195
+ [:t, :kx, :ky, :X, :Y, :e, :l, :theta, :ri, :r].each do |var|
196
+ #ep 'index', var
197
+ if options[var].class == Symbol and options[var] == :all
198
+ options[var] = list(var).values
199
+ elsif options[var+:_index].class == Symbol and options[var+:_index] == :all
200
+ #ep 'Symbol'
201
+ options[var+:_index] = list(var).keys
202
+ end
203
+ if options[var].class == Array
204
+ return options[var].map{|value| graphkit(name, options.dup.absorb({var => value}))}.sum
205
+ elsif options[var+:_index].class == Array
206
+ #ep 'Array'
207
+ return options[var+:_index].map{|value| graphkit(name, options.dup.absorb({var+:_index => value}))}.sum
208
+ end
209
+ if options[var].class == Symbol and options[var] == :max
210
+ options[var] = list(var).values.max
211
+ elsif options[var+:_index].class == Symbol and options[var+:_index] == :max
212
+ ep 'Symbol'
213
+ options[var+:_index] = list(var).keys.max
214
+ end
215
+ end
216
+ options[:t_index] ||= options[:frame_index] if options[:frame_index]
217
+
218
+
219
+
220
+
221
+
222
+ # Smart graphkits are defined in the file read_netcdf
223
+ if name =~ /^cdf_/
224
+ return smart_graphkit(options + {graphkit_name: name})
225
+ elsif name =~ /^nc_/
226
+ return old_smart_graphkit(options + {graphkit_name: name})
227
+ end
228
+
229
+ # If a method from the new GraphKits module can generate this graphkit use it
230
+ if method = self.class.instance_methods.find{|meth| (name + '_graphkit').to_sym == meth}
231
+ options[:graphkit_name] = name
232
+ return send(method, options)
233
+ end
234
+
235
+ raise "Graph #{name} not found"
236
+
237
237
  end
238
238
 
239
239
  module GraphKits
240
-
241
-
242
- def apar2_by_kx_vs_time_graphkit(options={})
243
- options[:direction] = :kx
244
- apar2_by_kxy_or_mode_vs_time_graphkit(options)
245
- end
246
-
247
- def apar2_by_ky_vs_time_graphkit(options={})
248
- options[:direction] = :ky
249
- apar2_by_kxy_or_mode_vs_time_graphkit(options)
250
- end
251
-
252
- def apar2_by_kxy_or_mode_vs_time_graphkit(options={})
253
- case options[:command]
254
- when :help
255
- return "'apar2_by_ky_vs_time' or 'apar2_by_kx_vs_time' or 'apar2_by_mode_vs_time': Apar^2 over time for a given kx or ky, integrated over the other direction, or apar^2 vs time for a given kx and ky"
256
- when :options
257
- return [:ky, :ky_index, :kx, :kx_index]
258
- else
259
- kxy = options[:direction]
260
-
261
- # i.e. apar2_by_ky_vs_time or apar2_by_kx_vs_time or apar2_by_mode_vs_time
262
-
263
- nt_options = options.dup # 'no time' options
264
- nt_options.delete(:t_index) if nt_options[:t_index]
265
- nt_options.delete(:frame_index) if nt_options[:frame_index]
266
- phiax = axiskit("apar2_by_#{kxy}_over_time", nt_options)
267
- kit = GraphKit.autocreate({x: axiskit('t', options), y: phiax})
268
- kit.data[0].title = "Phi^2 total: #{kxy} = #{options[kxy]}"
269
- if options[:t_index]
270
- array_element = options[:t_index_window] ? options[:t_index] - options[:t_index_window][0] : options[:t_index] - 1
271
- # p phiax.data.size, array_element
272
- # p options[:t_index], options[:t_index_window]
273
- time = DataKit.autocreate({x: {data: GSL::Vector.alloc([list(:t)[options[:t_index]]])}, y: {data: GSL::Vector.alloc([phiax.data[array_element]]) } })
274
- time.pointsize = 3.0
275
- # p time
276
- # kit.data[0].axes[:x].data = -kit.data[0].axes[:x].data
277
- kit.data.push time
278
- if options[:with_moving_efn] and kxy==:ky
279
- tmax = kit.data[0].axes[:x].data[-1]
280
- # p 'tmax', tmax
281
-
282
- theta_max = @g_exb * tmax * options[:ky] * 2 * Math::PI / list(:kx)[2]
283
- kit.each_axiskit(:x) do |axiskit|
284
- # p axiskit
285
- axiskit.data = axiskit.data / tmax * theta_max - theta_max
286
- end
287
- end
288
- end
289
- if options[:norm]
290
- xrange, yrange = kit.plot_area_size
291
- kit.each_axiskit(:y) do |axiskit|
292
- axiskit.data /= yrange[1] / (options[:height] or 1.0)
293
- end
294
- end
295
- kit.log_axis = 'y'
296
- #kit.data[0].title = "gs2:#@run_name"
297
- kit.data[0].with = "l" #"linespoints"
298
- kit.file_name = options[:graphkit_name]
299
- kit
300
- end
301
- end
302
- def efnim_graphkit(options={})
303
- options[:imrc] = :im
304
- efn_graphkit(options)
305
- end
306
-
307
-
308
- def efnmag_graphkit(options={})
309
- options[:imrc] = :mag
310
- efn_graphkit(options)
311
- end
312
-
313
- def efn_graphkit(options={})
314
- case options[:command]
315
- when :help
316
- return "Plot the eigenfunction along the extended domain. Options mag, norm, z can be specified by using a short hand in the name of the graph, eg. efnmagnormz, efnmag, efnnorm etc. If the range is set to 0, it plots the whole eigenfunction. Otherwise it plot a small bit of it. Only specify kx or kx_index if magnetic shear is 0."
317
- when :options
318
- return [:mag, :norm, :z, :flip, :range, :kx_index, :ky_index, :kx, :ky, :strongest_non_zonal_mode]
319
- when :plot, nil
320
- #eputs "Starting efn, this can take a while..."
321
- options[:imrc] ||= :real
322
- ep options
323
- options.convert_to_index(self, :ky)
324
-
325
-
326
- kit = GraphKit.autocreate({x: axiskit('theta_along_field_line', options), y: axiskit('phi_along_field_line', options)})
327
- # ep kit
328
- kit.data[0].title = "gs2:efn#{options[:imrc]}:#@run_name"
329
- kit.title = "#{options[:mag] ? "Magnitude of" : ""} Eigenfunction for ky=#{list(:ky)[options[:ky_index]]}, g_exb=#{@g_exb.to_f.to_s}, shat=#{@shat.to_s}"
330
- kit.file_name = "efn_for_#@run_name"
331
- # kit.pointsize = 1.0
332
- kit.modify(options)
333
- kit.title += sprintf(" time = %3.1f", list(:t)[options[:t_index]]) if options[:t_index]
334
- kit.data[0].with = "linespoints"
335
- # kit.data[0].axes[:x].data *= -1 #if options[:rev]
336
- #(eputs 'reversing'; gets)
337
- #if (@s_hat_input||@shat).abs >= 1.0e-5
338
- #range = options[:range] == 0 ? nil : (options[:range] or options[:z] ? 1 / (@s_hat_input||@shat) : 2 * Math::PI / (@s_hat_input||@shat))
339
- #kit.xrange = [-range, range] if range
340
- #end
341
- return kit
342
- end
343
- end
344
-
345
- alias :eigenfunction_graphkit :efn_graphkit
346
-
347
- def es_heat_flux_vs_ky_vs_kx_graphkit(options={})
348
- case options[:command]
349
- when :help
350
- return "Graph of electrostatic contribution to heat flux at a given time vs kx and ky"
351
- when :options
352
- return [:with]
353
- else
354
- zaxis = axiskit('es_heat_flux_over_ky_over_kx', options)
355
- zaxis.data = zaxis.data.transpose
356
- kit = GraphKit.autocreate({y: axiskit('ky', options), x: axiskit('kx', options), z: zaxis})
357
- kit.title = "Heat flux"
358
- kit.data[0].with = (options[:with] or 'pm3d palette')
359
- kit.file_name = options[:graphkit_name]
360
- return kit
361
- end
362
- end
363
-
364
- def es_heat_flux_vs_kx_graphkit(options={})
365
- case options[:command]
366
- when :help
367
- return "Heat flux vs kx"
368
- when :options
369
- return [:species_index]
370
- else
371
- return es_heat_flux_vs_kxy_graphkit(options.absorb({direction: :kx}))
372
- end
373
- end
374
- def es_heat_flux_vs_ky_graphkit(options={})
375
- case options[:command]
376
- when :help
377
- return "Heat flux vs ky"
378
- when :options
379
- return [:species_index]
380
- else
381
- return es_heat_flux_vs_kxy_graphkit(options.absorb({direction: :ky}))
382
- end
383
- end
384
-
385
- def es_heat_flux_vs_kxy_graphkit(options={})
386
- case options[:command]
387
- when :help
388
- return "Heat flux vs options[:direction] (kx or ky)"
389
- when :options
390
- return [:ky_index, :species_index]
391
- else
392
- kxy = options[:direction]||options[:kxy]
393
- kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("es_heat_flux_over_#{kxy}", options)})
394
- kit.title = "Heat flux vs #{kxy} for species #{options[:species_index]}"
395
- kit.file_name = options[:graphkit_name] + options[:t_index].to_s
396
- kit.data[0].with = 'lp'
397
- kit.pointsize = 2.0
398
- return kit
399
- end
400
- end
401
-
402
-
403
- def es_heat_flux_vs_time_graphkit(options={})
404
- case options[:command]
405
- when :help
406
- return "Heat flux vs time for each species."
407
- when :options
408
- return [:t_index_window, :species_index]
409
- else
410
- kit = GraphKit.autocreate({x: axiskit('t', options), y: axiskit('es_heat_flux', options)})
411
- kit.data[0].title = "#{species_type(options[:species_index])} hflux: #@run_name"
412
- kit.data[0].with = "l" #"lines"
413
- kit.file_name = options[:graphkit_name]
414
- kit
415
- end
416
- end
417
-
418
- def es_heat_par_vs_time_graphkit(options={})
419
- case options[:command]
420
- when :help
421
- return "Graph of parallel electrostatic heat flux vs time."
422
- when :options
423
- return [:t_index_window, :species_index]
424
- else
425
- kit = GraphKit.autocreate({x: axiskit('t', options), y: axiskit('es_heat_par', options)})
426
- kit.data[0].title = "#{species_type(options[:species_index])} es_heat_par: #@run_name"
427
- kit.data[0].with = "l" #"lines"
428
- kit.file_name = options[:graphkit_name]
429
- # kit.log_axis = 'y'
430
- kit
431
- end
432
- end
433
-
434
- def es_heat_perp_vs_time_graphkit(options={})
435
- case options[:command]
436
- when :help
437
- return "Graph of perpendicular electrostatic heat flux vs time."
438
- when :options
439
- return [:t_index_window, :species_index]
440
- else
441
- kit = GraphKit.autocreate({x: axiskit('t', options), y: axiskit('es_heat_perp', options)})
442
- kit.data[0].title = "#{species_type(options[:species_index])} es_heat_perp: #@run_name"
443
- kit.data[0].with = "l" #"lines"
444
- kit.file_name = options[:graphkit_name]
445
- # kit.log_axis = 'y'
446
- kit
447
- end
448
- end
449
- def es_heat_all_vs_time_graphkit(options={})
450
- es_heat_par_vs_time_graphkit(options)
451
- es_heat_perp_vs_time_graphkit(options)
452
- end
453
- def es_mom_flux_vs_time_graphkit(options={})
454
- case options[:command]
455
- when :help
456
- return "Momentum flux vs time for each species."
457
- when :options
458
- return [:t_index_window, :species_index]
459
- else
460
- kit = GraphKit.autocreate({x: axiskit('t', options), y: axiskit('es_mom_flux_over_time', options)})
461
- kit.data[0].title = "#{species_type(options[:species_index])} momflux: #@run_name"
462
- kit.data[0].with = "l" #"lines"
463
- kit.file_name = options[:graphkit_name]
464
- # kit.log_axis = 'y'
465
- return kit
466
- end
467
- end
468
-
469
- def es_part_flux_vs_time_graphkit(options={})
470
- case options[:command]
471
- when :help
472
- return "Particle flux vs time for each species."
473
- when :options
474
- return [:t_index_window, :species_index]
475
- else
476
- kit = GraphKit.autocreate({x: axiskit('t', options), y: axiskit('es_part_flux_over_time', options)})
477
- kit.data[0].title = "#{species_type(options[:species_index])} partflux: #@run_name"
478
- kit.data[0].with = "l" #"lines"
479
- kit.file_name = options[:graphkit_name]
480
- return kit
481
- end
482
- end
483
-
484
- def transient_es_heat_flux_amplification_vs_kx_graphkit(options={})
485
- options[:kxy] = :kx
486
- transient_es_heat_flux_amplification_vs_kxy_graphkit(options)
487
- end
488
-
489
- def transient_es_heat_flux_amplification_vs_ky_graphkit(options={})
490
- options[:kxy] = :ky
491
- transient_es_heat_flux_amplification_vs_kxy_graphkit(options)
492
- end
493
-
494
- def transient_es_heat_flux_amplification_vs_kxy_graphkit(options={})
495
- case options[:command]
496
- when :help
497
- return "transient_es_heat_flux_amplification_vs_ky or transient_es_heat_flux_amplification_vs_kx. Growth rates vs either ky or kx for phi^2 integrated over the other direction. For growth rates at a specific kx AND ky, see /transient_es_heat_flux_amplification_vs_kx_vs_ky/. "
498
- when :options
499
- return []
500
- else
501
- #raise "Growth Rates are not available in non-linear mode" if @nonlinear_mode == "on"
502
- kxy = options[:kxy]
503
- kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("transient_es_heat_flux_amplification_over_#{kxy}", options)})
504
- kit.title = "Transient Amplification of the ES Heat flux for species #{options[:species_index]} by #{kxy}"
505
- kit.data[0].with = "lp"
506
- kit.data[0].title = @run_name
507
- kit.file_name = options[:graphkit_name]
508
- kit
509
- end
510
- end
511
-
512
- def transient_amplification_vs_kx_graphkit(options={})
513
- options[:kxy] = :kx
514
- transient_amplification_vs_kxy_graphkit(options)
515
- end
516
-
517
- def transient_amplification_vs_ky_graphkit(options={})
518
- options[:kxy] = :ky
519
- transient_amplification_vs_kxy_graphkit(options)
520
- end
521
-
522
- def transient_amplification_vs_kxy_graphkit(options={})
523
- case options[:command]
524
- when :help
525
- return "transient_amplification_vs_ky or transient_amplification_vs_kx. Growth rates vs either ky or kx for phi^2 integrated over the other direction. For growth rates at a specific kx AND ky, see /transient_amplification_vs_kx_vs_ky/. "
526
- when :options
527
- return []
528
- else
529
- #raise "Growth Rates are not available in non-linear mode" if @nonlinear_mode == "on"
530
- kxy = options[:kxy]
531
- kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("transient_amplification_over_#{kxy}", options)})
532
- kit.title = "Transient Amplification by #{kxy}"
533
- kit.data[0].with = "lp"
534
- kit.data[0].title = @run_name
535
- kit.file_name = options[:graphkit_name]
536
- kit
537
- end
538
- end
539
-
540
-
541
- def growth_rate_vs_kx_graphkit(options={})
542
- options[:kxy] = :kx
543
- growth_rate_vs_kxy_graphkit(options)
544
- end
545
-
546
- def growth_rate_vs_ky_graphkit(options={})
547
- options[:kxy] = :ky
548
- growth_rate_vs_kxy_graphkit(options)
549
- end
550
-
551
- def growth_rate_vs_kxy_graphkit(options={})
552
- case options[:command]
553
- when :help
554
- return "growth_rate_vs_ky or growth_rate_vs_kx. Growth rates vs either ky or kx for phi^2 integrated over the other direction. For growth rates at a specific kx AND ky, see /growth_rate_vs_kx_vs_ky/. "
555
- when :options
556
- return []
557
- else
558
- raise "Growth Rates are not available in non-linear mode" if @nonlinear_mode == "on"
559
- kxy = options[:kxy]
560
- kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("growth_rate_over_#{kxy}", options)})
561
- kit.title = "Growth Rates by #{kxy}"
562
- kit.data[0].with = "lp"
563
- kit.data[0].title = @run_name
564
- kit.file_name = options[:graphkit_name]
565
- kit
566
- end
567
- end
568
-
569
- def growth_rate_vs_kx_slice_graphkit(options={})
570
- case options[:command]
571
- when :help
572
- return "Growth rates vs kx at a fixed ky, not integrated over ky."
573
- when :options
574
- return [:ky, :ky_index]
575
- else
576
- options[:kxy] = :kx
577
- if options[:ky_index].nil?
578
- raise "You must specify ky or ky_index." if options[:ky].nil?
579
- options[:title] = "Growth rate vs kx at ky = "+options[:ky].to_s
580
- else
581
- options[:ky] = list(:ky)[options[:ky_index]]
582
- options[:title] = "Growth rate vs kx at ky_index = "+options[:ky_index].to_s
583
- end
584
- eputs "For run " + @id.to_s + ", using ky = " + options[:ky].to_s
585
- growth_rate_vs_kxy_slice_graphkit(options)
586
- end
587
- end
588
-
589
- def growth_rate_vs_ky_slice_graphkit(options={})
590
- case options[:command]
591
- when :help
592
- return "Growth rates vs ky at a fixed kx, not integrated over kx."
593
- when :options
594
- return [:kx, :kx_index]
595
- else
596
- options[:kxy] = :ky
597
- if options[:kx_index].nil?
598
- raise "You must specify kx or kx_index." if options[:kx].nil?
599
- options[:title] = "Growth rate vs ky at kx = "+options[:kx].to_s
600
- else
601
- options[:kx] = list(:kx)[options[:kx_index]]
602
- options[:title] = "Growth rate vs ky at kx_index = "+options[:kx_index].to_s
603
- end
604
- eputs "For run " + @id.to_s + ", using kx = " + options[:kx].to_s
605
- growth_rate_vs_kxy_slice_graphkit(options)
606
- end
607
- end
608
-
609
- def growth_rate_vs_kxy_slice_graphkit(options={})
610
- case options[:command]
611
- when :help
612
- when :options
613
- return []
614
- else
615
- raise "Growth Rates are not available in non-linear mode" if @nonlinear_mode == "on"
616
- raise "growth_rate_at_ky_at_kx was not calculated for this run, probably because the environment variable GS2_CALCULATE_ALL was not set when the run was analyzed. Try setting this variable and re-analyzing the run." if @growth_rate_at_ky_at_kx.nil?
617
- kxy = options[:kxy]
618
- kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("growth_rate_over_#{kxy}_slice", options)})
619
- kit.title = options[:title]
620
- kit.data[0].with = "lp"
621
- kit.data[0].title = @run_name
622
- kit.file_name = options[:graphkit_name]
623
- kit
624
- end
625
- end
626
-
627
- def growth_rate_vs_kx_vs_ky_graphkit(options={})
628
- case options[:command]
629
- when :help
630
- return "3D plot of growth rates vs ky and kx for phi^2"
631
- when :options
632
- return [:with]
633
- else
634
- zaxis = axiskit('growth_rate_over_ky_over_kx', options)
635
- zaxis.data = zaxis.data.transpose
636
- kit = GraphKit.autocreate({y: axiskit('ky', options), x: axiskit('kx', options), z: zaxis})
637
- kit.title = "Growth Rate by kx and ky"
638
- kit.data[0].with = (options[:with] or 'pm3d palette')
639
- kit.file_name = options[:graphkit_name]
640
- kit
641
- end
642
- end
643
-
644
- def frequency_vs_ky_graphkit(options={})
645
- case options[:command]
646
- when :help
647
- return "Frequencies vs ky. You need the parameter write_line set to \".true.\". "
648
- when :options
649
- return []
650
- else
651
- raise "Frequencies are not available in non-linear mode" if @nonlinear_mode == "on"
652
- kxy = options[:kxy]
653
- kit = GraphKit.autocreate({x: axiskit('ky', options), y: axiskit("frequency_over_ky", options)})
654
- kit.title = "Frequencies vs ky"
655
- kit.data[0].gp.with = "lp"
656
- kit.data[0].gp.title = @run_name
657
- kit.file_name = options[:graphkit_name]
658
- kit
659
- end
660
- end
661
- def hflux_tot_vs_time_graphkit(options={})
662
- case options[:command]
663
- when :help
664
- return "Graph of total heat flux vs time. No options"
665
- when :options
666
- return []
667
- else
668
- kit = GraphKit.autocreate({x: axiskit('t', options), y: axiskit('hflux_tot', options)})
669
- kit.data[0].title = "hflux tot:#@run_name"
670
- kit.data[0].with = "l" #"lines"
671
- kit.file_name = options[:graphkit_name]
672
- # kit.log_axis = 'y'
673
- kit
674
- end
675
- end
676
-
677
- def kpar_spectrum_graphkit(options={})
678
- case options[:command]
679
- when :help
680
- return "Graph of the k_parallel at a given kx and ky"
681
- when :options
682
- return [:kx, :ky, :strongest_non_zonal_mode]
683
- else
684
- kit = GraphKit.autocreate({x: axiskit('kpar', options), y: axiskit('spectrum_over_kpar', options)})
685
- kit.data[0].title = "Spectrum at t = #{list(:t).values.max}"
686
- kit.file_name = options[:graphkit_name]
687
- kit.data[0].with = 'lp'
688
- kit
689
- end
690
- end
691
-
692
- def kx_spectrum_graphkit(options={})
693
- options[:kxy] = :kx
694
- kxy_spectrum_graphkit(options)
695
- end
696
-
697
- #time averaged kx spectrum
698
- def kx_spectrum_avg_graphkit(options={})
699
- options[:kxy] = :kx
700
- kxy_spectrum_avg_graphkit(options)
701
- end
702
-
703
- def ky_spectrum_graphkit(options={})
704
- options[:kxy] = :ky
705
- kxy_spectrum_graphkit(options)
706
- end
707
-
708
- #time averaged ky spectrum
709
- def ky_spectrum_avg_graphkit(options={})
710
- options[:kxy] = :ky
711
- kxy_spectrum_avg_graphkit(options)
712
- end
713
-
714
- def kxy_spectrum_graphkit(options={})
715
- case options[:command]
716
- when :help
717
- return "ky_spectrum or kx_spectrum: Graph of phi^2 vs kx or ky"
718
- when :options
719
- return [:t, :t_index]
720
- else
721
- # ie ky_spectrum or kx_spectrum
722
- kxy = options[:kxy]
723
- kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("spectrum_over_#{kxy}", options)})
724
- kit.title = "#{kxy} Spectrum"
725
- kit.file_name = options[:graphkit_name] + options[:t_index].to_s
726
- kit.data[0].with = 'lp'
727
- kit.ylabel = "Phi^2 #{kxy}^2"
728
- kit.pointsize = 2.0
729
- kit
730
- end
731
- end
732
-
733
- #time averaged kx or ky spectrum
734
- def kxy_spectrum_avg_graphkit(options={})
735
- case options[:command]
736
- when :help
737
- return "ky_spectrum or kx_spectrum: Graph of phi^2 vs kx or ky averaged over time"
738
- when :options
739
- return [:t, :t_index]
740
- else
741
- # ie ky_spectrum or kx_spectrum
742
- kxy = options[:kxy]
743
- kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("spectrum_over_#{kxy}_avg", options)})
744
- kit.title = "#{kxy} Spectrum"
745
- kit.file_name = options[:graphkit_name] + options[:t_index].to_s + "_avg"
746
- kit.data[0].with = 'lp'
747
- kit.ylabel = "Phi^2 #{kxy}^2"
748
- kit.pointsize = 2.0
749
- kit
750
- end
751
- end
752
-
753
- def lagrangian_kx_graphkit(options={})
754
- case options[:command]
755
- when :help
756
- return "A graph of the evolution of a single Lagrangian kx vs Eulerian kx and ky. Principally for debugging purposes"
757
- when :options
758
- return []
759
- else
760
- kyax = axiskit('ky', options)
761
- kyk = list(:ky).keys
762
- kx_list = list(:kx)
763
- begin
764
- kx_data = kyk.map do |ky_index|
765
- options[:ky_index] = ky_index
766
- options[:kx_index] =1
767
- ekx_index = eulerian_kx_index(options)
768
- kx_list[ekx_index]
769
- end
770
- rescue #ArgumentError
771
- kyk.pop
772
- retry
773
- end
774
- lky = list(:ky)
775
- kyax.data = kyk.map{|k| lky[k]}
776
- kit = GraphKit.autocreate(x: {data: kx_data, title: 'Eulerian kx (i.e. location on the GS2 grid)'}, y: kyax )
777
- kit.data[0].title = 'Lagrangian kx=0'
778
- kit.xrange = [kx_list.values.min, 0]
779
- kit.yrange = [0, lky.values.max]
780
-
781
- kit.title = 'Evolution of a Single Lagrangian kx vs ky'
782
- kit.file_name = 'lagrangian_kx_graphkit'
783
- return kit
784
-
785
-
786
-
787
- end
788
- end
789
-
790
- def field_flux_tube_boundary_surface_graphkit(options={})
791
- case options[:command]
792
- when :help
793
- return "The field options[:field_name] as a function of cartesian coordinates, on one specified side of the flux tube (specified using the options :coordinate (:x, :y, :theta) and :side (:min, :max))"
794
- when :options
795
- return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :gs2_coordinate_factor, :xmax, :xmin, :ymax, :ymin, :thetamax, :thetamin, :ncopies, :side, :coordinate, :torphi_values]
796
- else
797
- field = options[:field] || field_real_space_gsl_tensor(options)
798
- if options[:ncopies]
799
- ops = options.dup
800
- ops.delete(:ncopies)
801
- return (options[:ncopies].times.map do |n|
802
- ops[:ncopy] = n
803
- field_flux_tube_boundary_surface_graphkit(ops)
804
- end).sum
805
- end
806
- side = options[:side]
807
- coord = options[:coordinate]
808
- shp = field.shape
809
- #raise " asdfal" unless shp
810
- opside = side == :max ? :min : :max
811
- ops = options.dup
812
- ops[coord+opside] = ops[coord+side] ||
813
- case side
814
- when :max
815
- case coord
816
- when :y
817
- shp[0]-1
818
- when :x
819
- shp[1]-1
820
- when :theta
821
- shp[2]-1
822
- end
823
-
824
-
825
- when :min
826
- 0
827
- end
828
- opscut = ops.dup
829
- opscut[:ymin] = ((opscut[:ymin]||0) - (options[:ymin]||0))
830
- opscut[:ymax] = ((opscut[:ymax]||shp[0]-1) - (options[:ymin]||0))
831
- #ep 'opscut', opscut, (opscut[:xmax]||shp[1]-1), shp
832
- opscut[:xmin] = ((opscut[:xmin]||0) - (options[:xmin]||0))
833
- opscut[:xmax] = ((opscut[:xmax]||shp[1]-1) - (options[:xmin]||0))
834
- #ep 'opscut', opscut
835
- #ep 'opscut', opscut
836
- opscut[:thetamin] = ((opscut[:thetamin]||0) - (options[:thetamin]||0))
837
- opscut[:thetamax] = ((opscut[:thetamax]||shp[2]-1) - (options[:thetamin]||0))
838
- #p opscut;#gets
839
- if options[:cyl]
840
- coords = cylindrical_coordinates_gsl_tensor(ops) #.transpose(0,1,2,3)
841
- else
842
- coords = cartesian_coordinates_gsl_tensor(ops)
843
- end
844
- #ep ['coords', coords.shape, field.shape]; gets
845
- newshape = coords.shape.slice(1..3)
846
- x = coords[0, false]; x.reshape!(*newshape)
847
- y = coords[1, false]; y.reshape!(*newshape)
848
- z = coords[2, false]; z.reshape!(*newshape)
849
- #ep shp , '...'
850
- range = [
851
- opscut[:ymin]||0..opscut[:ymax]||shp[0]-1,
852
- opscut[:xmin]||0..opscut[:xmax]||shp[1]-1,
853
- opscut[:thetamin]..opscut[:thetamax]
854
-
855
- #((ops[:thetamin]||0) - (options[:thetamin]||0))..((ops[:thetamax]||shp[2]-1) - (options[:thetamin]||0))
856
- ]
857
-
858
- #ep ['range', range, 'field.shape', field.shape]
859
- fieldside = field[*range ]
860
- #ep ['coords', x.shape, fieldside.shape]; gets
861
- kit = GraphKit.quick_create([x,y,z,fieldside])
862
-
863
- # Create a map of this surface onto a continuous surface between two poloidal planes if ops[:torfield_values] is specified
864
- if torphi_values = ops[:torphi_values]
865
- raise "Can't take a poloidal cut at constant y or theta" if coord == :y #or coord == :theta
866
- raise "Can't take a poloidal cut with a limited y range (Remove :ymin and :ymax from ops)" if options[:ymin] or options[:ymax]
867
-
868
- torphi_values = torphi_values.sort
869
- cyls = cylindrical_coordinates_gsl_tensor(ops.absorb(extra_points: true))
870
- torphi_const0 = constant_torphi_surface_gsl_tensor(ops.absorb(torphi: torphi_values[0]))
871
- #ep torphi_const0, ops
872
- #torphi_const1 = constant_torphi_surface_gsl_tensor(ops.absorb(torphi: torphi_values[1]))
873
- raise "torphi_should be of rank 1: #{torphi_const0.shape}" unless torphi_const0.shape.include? 1
874
-
875
- #Get the number of points in the y direction between the two poloidal planes
876
- deltorphi = cyls[2,-1,0,0] - cyls[2,0,0,0]
877
- i = i1 = istart = torphi_const0[0,0]
878
- displacement = torphi_values[0] - cyls[2,i,0,0] # which copy of the flux tube are we in?
879
- #ep 'displacement', displacement
880
- shpc = cyls.shape
881
- ny = shpc[1]-1 # remove extra point
882
- while cyls[2,i%ny,0,0] + displacement < torphi_values[1]
883
- #ep ['displacement', displacement, 'torphi', torphi = cyls[2,i%ny,0,0] + displacement, 'i', i]
884
- displacement=(cyls[2,i%ny+1,0,0]+displacement-cyls[2,0,0,0]) if (i+1)%ny == 0
885
- i+=1
886
- end
887
- ysize = i - i1
888
- #ep ['torphil', torphi = cyls[2,i%ny,0,0] + displacement, 'ysize', ysize]
889
- #exit
890
-
891
-
892
-
893
- #ysize = (torphi_const0[-1] - torphi_const1[0] ).abs + 1
894
- #case coord
895
- #when :x
896
- shpside = fieldside.shape
897
- fieldcut = GSL::Tensor.float(ysize, shpside[1], shpside[2])
898
- xcut = GSL::Tensor.float(ysize, shpside[1], shpside[2])
899
- ycut = GSL::Tensor.float(ysize, shpside[1], shpside[2])
900
- zcut = GSL::Tensor.float(ysize, shpside[1], shpside[2])
901
- #ep shpside
902
- shpcut = fieldcut.shape
903
- for k in 0...shpcut[2] # 1 of these 2 loops
904
- for j in 0...shpcut[1] # will have size 1
905
-
906
- istart = torphi_const0[j,k]
907
- displacement = torphi_values[0] - cyls[2,istart,j,k] # where in the torus does this copy of the flux tube start compared to where we want to be?
908
-
909
- #p torphi_const0[i,j], torphi_const1[i,j]
910
- for n in 0...shpcut[0] # index along our cut surface
911
- i = istart + n
912
- #icut = i%ysize
913
- #cyls = cylindrical_coordinates_gsl_tensor(ops.absorb(extra_points: true)) #.transpose(0,1,2,3)
914
- #ep ['displacement', displacement, n, i, ny, 'torphi', torphi = cyls[2,i%ny,j,k] +displacement]
915
- # We chop off the surface
916
- # between two y gridpoints
917
- # Hence we must interpolate
918
- # the field between those
919
- # gridpoints
920
- if n == 0
921
- torphi0 = torphi_values[0]
922
- s = Math.sin(torphi0)
923
- c = Math.cos(torphi0)
924
- d2 = cyls[2,(i+1)%ny,j,k] + displacement - torphi0
925
- d1 = torphi0 - (cyls[2,i%ny,j,k] + displacement)
926
- dfac = d1 / (d1+d2)
927
- elsif n == ysize-1
928
- torphi1 = torphi_values[1]
929
- s = Math.sin(torphi1)
930
- c = Math.cos(torphi1)
931
- d2 = cyls[2,(i+1)%ny,j,k] + displacement - torphi1
932
- d1 = torphi1 - (cyls[2,i%ny,j,k] + displacement)
933
- dfac = d1 / (d1+d2)
934
- else
935
- s = Math.sin(cyls[2,i%ny,j,k] + displacement)
936
- c = Math.cos(cyls[2,i%ny,j,k] + displacement)
937
- dfac = 0
938
- end
939
-
940
- #ep [(fieldside[i%ny,j,k] * (1-dfac) + fieldside[(i+1)%ny,j,k] * dfac).class, i,j,k, fieldside.shape, ny ]
941
-
942
- fieldcut[n,j,k] = fieldside[i%ny,j,k] * (1-dfac) + fieldside[((i+1)%ny),j,k] * dfac
943
-
944
- rad = cyls[0,i%ny,j,k]
945
- xcut[n,j,k] = rad * c
946
- ycut[n,j,k] = rad *s
947
- zcut[n,j,k] = cyls[1,i%ny,j,k]
948
- displacement=(cyls[2,i%ny+1,j,k]+displacement-cyls[2,0,j,k]) if (i+1)%ny == 0
949
- #displacement+=cyls[2,i,j,k] if (i+1)%ny == 0
950
- end
951
- #exit
952
- end
953
- end
954
-
955
- kit = GraphKit.quick_create([xcut,ycut,zcut,fieldcut])
956
- end
957
-
958
-
959
-
960
-
961
-
962
-
963
- kit.data[0].gp.with = "pm3d"
964
- return kit
965
- end
966
-
967
- end
968
- def density_real_space_standard_representation_graphkit(options={})
969
- case options[:command]
970
- when :help
971
- return "The density as a function of cartesian coordinates showing showing the standard way of representing the turbulence, with two poloidal cuts and the inner and outer radial surfaces. Multiple copies of the flux tube are used to fill the space."
972
- when :options
973
- return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :torphi_values, :species_index]
974
- else
975
- field_real_space_standard_representation_graphkit(options.absorb({field_name: :density}))
976
- end
977
- end
978
- def phi_real_space_standard_representation_graphkit(options={})
979
- case options[:command]
980
- when :help
981
- return "The potential as a function of cartesian coordinates showing showing the standard way of representing the turbulence, with two poloidal cuts and the inner and outer radial surfaces. Multiple copies of the flux tube are used to fill the space."
982
- when :options
983
- return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :torphi_values]
984
- else
985
- field_real_space_standard_representation_graphkit(options.absorb({field_name: :phi}))
986
- end
987
- end
988
- def field_real_space_standard_representation_graphkit(options={})
989
- case options[:command]
990
- when :help
991
- return "The field options[:field_name] as a function of cartesian coordinates showing showing the standard way of representing the turbulence, with two poloidal cuts and the inner and outer radial surfaces. Multiple copies of the flux tube are used to fill the space."
992
- when :options
993
- return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :torphi_values]
994
- else
995
- field = field_real_space_gsl_tensor(options)
996
- options[:field] = field
997
- poloidal_planes = options[:torphi_values]
998
- #ep poloidal_planes; gets
999
- raise "Please set options[:torphi_values] to an array of two values" unless poloidal_planes.kind_of? Array and poloidal_planes.size==2
1000
- options[:torphi] = poloidal_planes[0]
1001
- kit1 = field_real_space_poloidal_plane_graphkit(options)
1002
- options[:torphi] = poloidal_planes[1]
1003
- kit2 = field_real_space_poloidal_plane_graphkit(options)
1004
- options[:coordinate] = :x
1005
- options[:side] = :min
1006
- kit3 = field_flux_tube_boundary_surface_graphkit(options)
1007
- options[:side] = :max
1008
- kit4 = field_flux_tube_boundary_surface_graphkit(options)
1009
- #kit= kit1+kit2
1010
- #kit = kit3 +kit4
1011
- kit = kit1+kit2+kit3+kit4
1012
- if options[:thetamax] or options[:thetamin]
1013
- options[:coordinate] = :theta
1014
- options[:side] = :min
1015
- kit5 = field_flux_tube_boundary_surface_graphkit(options)
1016
- options[:side] = :max
1017
- kit6 = field_flux_tube_boundary_surface_graphkit(options)
1018
- kit += kit5+kit6
1019
- end
1020
- kit.gp.pm3d = "depthorder"
1021
- kit.xlabel = 'X (m)'
1022
- kit.ylabel = 'Y (m)'
1023
- kit.zlabel = "'Z (m)' rotate by 90"
1024
- kit.title = "3-D Potential"
1025
- return kit
1026
- end
1027
- end
1028
- def phi_real_space_poloidal_plane_graphkit(options={})
1029
- case options[:command]
1030
- when :help
1031
- return "The potential as a function of cartesian coordinates showing a cut at one toroidal angle, with multiple periodic copies of the flux tube used to fill the whole circle.."
1032
- when :options
1033
- return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :torphi]
1034
- else
1035
- return field_real_space_poloidal_plane_graphkit(options.absorb(field_name: :phi))
1036
- end
1037
- end
1038
- def density_real_space_poloidal_plane_graphkit(options={})
1039
- case options[:command]
1040
- when :help
1041
- return "The density as a function of cartesian coordinates showing a cut at one toroidal angle, with multiple periodic copies of the flux tube used to fill the whole circle.."
1042
- when :options
1043
- return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :torphi]
1044
- else
1045
- return field_real_space_poloidal_plane_graphkit(options.absorb({field_name: :density}))
1046
- end
1047
- end
1048
- def field_real_space_poloidal_plane_graphkit(options={})
1049
- case options[:command]
1050
- when :help
1051
- return "The potential as a function of cartesian coordinates showing a cut at one toroidal angle, with multiple periodic copies of the flux tube used to fill the whole circle.."
1052
- when :options
1053
- return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :torphi, :constant_torphi, :no_flux_tube_copies]
1054
- else
1055
- #if options[:ncopies]
1056
- #ops = options.dup
1057
- #ops.delete(:ncopies)
1058
- #return (options[:ncopies].times.map do |n|
1059
- #ops[:ncopy] = n
1060
- #field_real_space_surface_graphkit(ops)
1061
- #end).sum
1062
- #end
1063
- #zaxis = axiskit('field0_over_x_over_y', options)
1064
- #zaxis.data = zaxis.data.transpose
1065
- #shape = zaxis.data.shape
1066
- #carts = cartesian_coordinates_gsl_tensor(options)
1067
- #torphiout = 2.6
1068
- torphiout = options[:constant_torphi] || options[:torphi] #if constant_torphi is specified this is the toroidal angle at which data is printed
240
+
241
+ def apar2_by_kx_vs_time_graphkit(options={})
242
+ options[:direction] = :kx
243
+ apar2_by_kxy_or_mode_vs_time_graphkit(options)
244
+ end
245
+
246
+ def apar2_by_ky_vs_time_graphkit(options={})
247
+ options[:direction] = :ky
248
+ apar2_by_kxy_or_mode_vs_time_graphkit(options)
249
+ end
250
+
251
+ def apar2_by_kxy_or_mode_vs_time_graphkit(options={})
252
+ case options[:command]
253
+ when :help
254
+ return "'apar2_by_ky_vs_time' or 'apar2_by_kx_vs_time' or 'apar2_by_mode_vs_time': Apar^2 over time for a given kx or ky, integrated over the other direction, or apar^2 vs time for a given kx and ky"
255
+ when :options
256
+ return [:ky, :ky_index, :kx, :kx_index]
257
+ else
258
+ kxy = options[:direction]
259
+
260
+ # i.e. apar2_by_ky_vs_time or apar2_by_kx_vs_time or apar2_by_mode_vs_time
261
+
262
+ nt_options = options.dup # 'no time' options
263
+ nt_options.delete(:t_index) if nt_options[:t_index]
264
+ nt_options.delete(:frame_index) if nt_options[:frame_index]
265
+ phiax = axiskit("apar2_by_#{kxy}_over_time", nt_options)
266
+ kit = GraphKit.autocreate({x: axiskit('t', options), y: phiax})
267
+ kit.data[0].title = "Phi^2 total: #{kxy} = #{options[kxy]}"
268
+ if options[:t_index]
269
+ array_element = options[:t_index_window] ? options[:t_index] - options[:t_index_window][0] : options[:t_index] - 1
270
+ # p phiax.data.size, array_element
271
+ # p options[:t_index], options[:t_index_window]
272
+ time = DataKit.autocreate({x: {data: GSL::Vector.alloc([list(:t)[options[:t_index]]])}, y: {data: GSL::Vector.alloc([phiax.data[array_element]]) } })
273
+ time.pointsize = 3.0
274
+ # p time
275
+ # kit.data[0].axes[:x].data = -kit.data[0].axes[:x].data
276
+ kit.data.push time
277
+ if options[:with_moving_efn] and kxy==:ky
278
+ tmax = kit.data[0].axes[:x].data[-1]
279
+ # p 'tmax', tmax
280
+
281
+ theta_max = @g_exb * tmax * options[:ky] * 2 * Math::PI / list(:kx)[2]
282
+ kit.each_axiskit(:x) do |axiskit|
283
+ # p axiskit
284
+ axiskit.data = axiskit.data / tmax * theta_max - theta_max
285
+ end
286
+ end
287
+ end
288
+ if options[:norm]
289
+ xrange, yrange = kit.plot_area_size
290
+ kit.each_axiskit(:y) do |axiskit|
291
+ axiskit.data /= yrange[1] / (options[:height] or 1.0)
292
+ end
293
+ end
294
+ kit.log_axis = 'y'
295
+ #kit.data[0].title = "gs2:#@run_name"
296
+ kit.data[0].with = "l" #"linespoints"
297
+ kit.file_name = options[:graphkit_name]
298
+ kit
299
+ end
300
+ end
301
+
302
+ def efnim_graphkit(options={})
303
+ options[:imrc] = :im
304
+ efn_graphkit(options)
305
+ end
306
+
307
+ def efnmag_graphkit(options={})
308
+ options[:imrc] = :mag
309
+ efn_graphkit(options)
310
+ end
311
+
312
+ def efn_graphkit(options={})
313
+ case options[:command]
314
+ when :help
315
+ return "Plot the eigenfunction along the extended domain. Options mag, norm, z can be specified by using a short hand in the name of the graph, eg. efnmagnormz, efnmag, efnnorm etc. If the range is set to 0, it plots the whole eigenfunction. Otherwise it plot a small bit of it. Only specify kx or kx_index if magnetic shear is 0."
316
+ when :options
317
+ return [:mag, :norm, :z, :flip, :range, :kx_index, :ky_index, :kx, :ky, :strongest_non_zonal_mode]
318
+ when :plot, nil
319
+ #eputs "Starting efn, this can take a while..."
320
+ options[:imrc] ||= :real
321
+ ep options
322
+ options.convert_to_index(self, :ky)
323
+
324
+
325
+ kit = GraphKit.autocreate({x: axiskit('theta_along_field_line', options), y: axiskit('phi_along_field_line', options)})
326
+ # ep kit
327
+ kit.data[0].title = "gs2:efn#{options[:imrc]}:#@run_name"
328
+ kit.title = "#{options[:mag] ? "Magnitude of" : ""} Eigenfunction for ky=#{list(:ky)[options[:ky_index]]}, g_exb=#{@g_exb.to_f.to_s}, shat=#{@shat.to_s}"
329
+ kit.file_name = "efn_for_#@run_name"
330
+ # kit.pointsize = 1.0
331
+ kit.modify(options)
332
+ kit.title += sprintf(" time = %3.1f", list(:t)[options[:t_index]]) if options[:t_index]
333
+ kit.data[0].with = "linespoints"
334
+ # kit.data[0].axes[:x].data *= -1 #if options[:rev]
335
+ #(eputs 'reversing'; gets)
336
+ #if (@s_hat_input||@shat).abs >= 1.0e-5
337
+ #range = options[:range] == 0 ? nil : (options[:range] or options[:z] ? 1 / (@s_hat_input||@shat) : 2 * Math::PI / (@s_hat_input||@shat))
338
+ #kit.xrange = [-range, range] if range
339
+ #end
340
+ return kit
341
+ end
342
+ end
343
+ alias :eigenfunction_graphkit :efn_graphkit
344
+
345
+ def es_heat_flux_vs_ky_vs_kx_graphkit(options={})
346
+ case options[:command]
347
+ when :help
348
+ return "Graph of electrostatic contribution to heat flux at a given time vs kx and ky"
349
+ when :options
350
+ return [:with]
351
+ else
352
+ zaxis = axiskit('es_heat_flux_over_ky_over_kx', options)
353
+ zaxis.data = zaxis.data.transpose
354
+ kit = GraphKit.autocreate({y: axiskit('ky', options), x: axiskit('kx', options), z: zaxis})
355
+ kit.title = "Heat flux"
356
+ kit.data[0].with = (options[:with] or 'pm3d palette')
357
+ kit.file_name = options[:graphkit_name]
358
+ return kit
359
+ end
360
+ end
361
+
362
+ def es_heat_flux_vs_kx_graphkit(options={})
363
+ case options[:command]
364
+ when :help
365
+ return "Heat flux vs kx"
366
+ when :options
367
+ return [:species_index]
368
+ else
369
+ return es_heat_flux_vs_kxy_graphkit(options.absorb({direction: :kx}))
370
+ end
371
+ end
372
+
373
+ def es_heat_flux_vs_ky_graphkit(options={})
374
+ case options[:command]
375
+ when :help
376
+ return "Heat flux vs ky"
377
+ when :options
378
+ return [:species_index]
379
+ else
380
+ return es_heat_flux_vs_kxy_graphkit(options.absorb({direction: :ky}))
381
+ end
382
+ end
383
+
384
+ def es_heat_flux_vs_kxy_graphkit(options={})
385
+ case options[:command]
386
+ when :help
387
+ return "Heat flux vs options[:direction] (kx or ky)"
388
+ when :options
389
+ return [:ky_index, :species_index]
390
+ else
391
+ kxy = options[:direction]||options[:kxy]
392
+ kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("es_heat_flux_over_#{kxy}", options)})
393
+ kit.title = "Heat flux vs #{kxy} for species #{options[:species_index]}"
394
+ kit.file_name = options[:graphkit_name] + options[:t_index].to_s
395
+ kit.data[0].with = 'lp'
396
+ kit.pointsize = 2.0
397
+ return kit
398
+ end
399
+ end
400
+
401
+ def es_heat_flux_vs_time_graphkit(options={})
402
+ case options[:command]
403
+ when :help
404
+ return "Heat flux vs time for each species."
405
+ when :options
406
+ return [:t_index_window, :species_index]
407
+ else
408
+ kit = GraphKit.autocreate({x: axiskit('t', options), y: axiskit('es_heat_flux', options)})
409
+ kit.data[0].title = "#{species_type(options[:species_index])} hflux: #@run_name"
410
+ kit.data[0].with = "l" #"lines"
411
+ kit.file_name = options[:graphkit_name]
412
+ kit
413
+ end
414
+ end
415
+
416
+ def es_heat_par_vs_time_graphkit(options={})
417
+ case options[:command]
418
+ when :help
419
+ return "Graph of parallel electrostatic heat flux vs time."
420
+ when :options
421
+ return [:t_index_window, :species_index]
422
+ else
423
+ kit = GraphKit.autocreate({x: axiskit('t', options), y: axiskit('es_heat_par', options)})
424
+ kit.data[0].title = "#{species_type(options[:species_index])} es_heat_par: #@run_name"
425
+ kit.data[0].with = "l" #"lines"
426
+ kit.file_name = options[:graphkit_name]
427
+ kit
428
+ end
429
+ end
430
+
431
+ def es_heat_perp_vs_time_graphkit(options={})
432
+ case options[:command]
433
+ when :help
434
+ return "Graph of perpendicular electrostatic heat flux vs time."
435
+ when :options
436
+ return [:t_index_window, :species_index]
437
+ else
438
+ kit = GraphKit.autocreate({x: axiskit('t', options), y: axiskit('es_heat_perp', options)})
439
+ kit.data[0].title = "#{species_type(options[:species_index])} es_heat_perp: #@run_name"
440
+ kit.data[0].with = "l" #"lines"
441
+ kit.file_name = options[:graphkit_name]
442
+ kit
443
+ end
444
+ end
445
+
446
+ def es_heat_all_vs_time_graphkit(options={})
447
+ es_heat_par_vs_time_graphkit(options)
448
+ es_heat_perp_vs_time_graphkit(options)
449
+ end
450
+
451
+ def es_mom_flux_vs_time_graphkit(options={})
452
+ case options[:command]
453
+ when :help
454
+ return "Momentum flux vs time for each species."
455
+ when :options
456
+ return [:t_index_window, :species_index]
457
+ else
458
+ kit = GraphKit.autocreate({x: axiskit('t', options), y: axiskit('es_mom_flux_over_time', options)})
459
+ kit.data[0].title = "#{species_type(options[:species_index])} momflux: #@run_name"
460
+ kit.data[0].with = "l" #"lines"
461
+ kit.file_name = options[:graphkit_name]
462
+ return kit
463
+ end
464
+ end
465
+
466
+ def es_part_flux_vs_time_graphkit(options={})
467
+ case options[:command]
468
+ when :help
469
+ return "Particle flux vs time for each species."
470
+ when :options
471
+ return [:t_index_window, :species_index]
472
+ else
473
+ kit = GraphKit.autocreate({x: axiskit('t', options), y: axiskit('es_part_flux_over_time', options)})
474
+ kit.data[0].title = "#{species_type(options[:species_index])} partflux: #@run_name"
475
+ kit.data[0].with = "l" #"lines"
476
+ kit.file_name = options[:graphkit_name]
477
+ return kit
478
+ end
479
+ end
480
+
481
+ def growth_rate_vs_kx_graphkit(options={})
482
+ options[:kxy] = :kx
483
+ growth_rate_vs_kxy_graphkit(options)
484
+ end
485
+
486
+ def growth_rate_vs_ky_graphkit(options={})
487
+ options[:kxy] = :ky
488
+ growth_rate_vs_kxy_graphkit(options)
489
+ end
490
+
491
+ def growth_rate_vs_kxy_graphkit(options={})
492
+ case options[:command]
493
+ when :help
494
+ return "growth_rate_vs_ky or growth_rate_vs_kx. Growth rates vs either ky or kx for phi^2 integrated over the other direction. For growth rates at a specific kx AND ky, see /growth_rate_vs_kx_vs_ky/. "
495
+ when :options
496
+ return []
497
+ else
498
+ raise "Growth Rates are not available in non-linear mode" if @nonlinear_mode == "on"
499
+ kxy = options[:kxy]
500
+ kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("growth_rate_over_#{kxy}", options)})
501
+ kit.title = "Growth Rates by #{kxy}"
502
+ kit.data[0].with = "lp"
503
+ kit.data[0].title = @run_name
504
+ kit.file_name = options[:graphkit_name]
505
+ kit
506
+ end
507
+ end
508
+
509
+ def growth_rate_vs_kx_slice_graphkit(options={})
510
+ case options[:command]
511
+ when :help
512
+ return "Growth rates vs kx at a fixed ky, not integrated over ky."
513
+ when :options
514
+ return [:ky, :ky_index]
515
+ else
516
+ options[:kxy] = :kx
517
+ if options[:ky_index].nil?
518
+ raise "You must specify ky or ky_index." if options[:ky].nil?
519
+ options[:title] = "Growth rate vs kx at ky = "+options[:ky].to_s
520
+ else
521
+ options[:ky] = list(:ky)[options[:ky_index]]
522
+ options[:title] = "Growth rate vs kx at ky_index = "+options[:ky_index].to_s
523
+ end
524
+ eputs "For run " + @id.to_s + ", using ky = " + options[:ky].to_s
525
+ growth_rate_vs_kxy_slice_graphkit(options)
526
+ end
527
+ end
528
+
529
+ def growth_rate_vs_ky_slice_graphkit(options={})
530
+ case options[:command]
531
+ when :help
532
+ return "Growth rates vs ky at a fixed kx, not integrated over kx."
533
+ when :options
534
+ return [:kx, :kx_index]
535
+ else
536
+ options[:kxy] = :ky
537
+ if options[:kx_index].nil?
538
+ raise "You must specify kx or kx_index." if options[:kx].nil?
539
+ options[:title] = "Growth rate vs ky at kx = "+options[:kx].to_s
540
+ else
541
+ options[:kx] = list(:kx)[options[:kx_index]]
542
+ options[:title] = "Growth rate vs ky at kx_index = "+options[:kx_index].to_s
543
+ end
544
+ eputs "For run " + @id.to_s + ", using kx = " + options[:kx].to_s
545
+ growth_rate_vs_kxy_slice_graphkit(options)
546
+ end
547
+ end
548
+
549
+ def growth_rate_vs_kxy_slice_graphkit(options={})
550
+ case options[:command]
551
+ when :help
552
+ when :options
553
+ return []
554
+ else
555
+ raise "Growth Rates are not available in non-linear mode" if @nonlinear_mode == "on"
556
+ raise "growth_rate_at_ky_at_kx was not calculated for this run, probably because the environment variable GS2_CALCULATE_ALL was not set when the run was analyzed. Try setting this variable and re-analyzing the run." if @growth_rate_at_ky_at_kx.nil?
557
+ kxy = options[:kxy]
558
+ kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("growth_rate_over_#{kxy}_slice", options)})
559
+ kit.title = options[:title]
560
+ kit.data[0].with = "lp"
561
+ kit.data[0].title = @run_name
562
+ kit.file_name = options[:graphkit_name]
563
+ kit
564
+ end
565
+ end
566
+
567
+ def growth_rate_vs_kx_vs_ky_graphkit(options={})
568
+ case options[:command]
569
+ when :help
570
+ return "3D plot of growth rates vs ky and kx for phi^2"
571
+ when :options
572
+ return [:with]
573
+ else
574
+ zaxis = axiskit('growth_rate_over_ky_over_kx', options)
575
+ zaxis.data = zaxis.data.transpose
576
+ kit = GraphKit.autocreate({y: axiskit('ky', options), x: axiskit('kx', options), z: zaxis})
577
+ kit.title = "Growth Rate by kx and ky"
578
+ kit.data[0].with = (options[:with] or 'pm3d palette')
579
+ kit.file_name = options[:graphkit_name]
580
+ kit
581
+ end
582
+ end
583
+
584
+ def hflux_tot_vs_time_graphkit(options={})
585
+ case options[:command]
586
+ when :help
587
+ return "Graph of total heat flux vs time. No options"
588
+ when :options
589
+ return []
590
+ else
591
+ kit = GraphKit.autocreate({x: axiskit('t', options), y: axiskit('hflux_tot', options)})
592
+ kit.data[0].title = "hflux tot:#@run_name"
593
+ kit.data[0].with = "l" #"lines"
594
+ kit.file_name = options[:graphkit_name]
595
+ # kit.log_axis = 'y'
596
+ kit
597
+ end
598
+ end
599
+
600
+ def kpar_spectrum_graphkit(options={})
601
+ case options[:command]
602
+ when :help
603
+ return "Graph of the k_parallel at a given kx and ky"
604
+ when :options
605
+ return [:kx, :ky, :strongest_non_zonal_mode]
606
+ else
607
+ kit = GraphKit.autocreate({x: axiskit('kpar', options), y: axiskit('spectrum_over_kpar', options)})
608
+ kit.data[0].title = "Spectrum at t = #{list(:t).values.max}"
609
+ kit.file_name = options[:graphkit_name]
610
+ kit.data[0].with = 'lp'
611
+ kit
612
+ end
613
+ end
614
+
615
+ def kx_spectrum_graphkit(options={})
616
+ options[:kxy] = :kx
617
+ kxy_spectrum_graphkit(options)
618
+ end
619
+
620
+ def kx_spectrum_avg_graphkit(options={})
621
+ #time averaged kx spectrum
622
+ options[:kxy] = :kx
623
+ kxy_spectrum_avg_graphkit(options)
624
+ end
625
+
626
+ def ky_spectrum_graphkit(options={})
627
+ options[:kxy] = :ky
628
+ kxy_spectrum_graphkit(options)
629
+ end
630
+
631
+ def ky_spectrum_avg_graphkit(options={})
632
+ #time averaged ky spectrum
633
+ options[:kxy] = :ky
634
+ kxy_spectrum_avg_graphkit(options)
635
+ end
636
+
637
+ def kxy_spectrum_graphkit(options={})
638
+ case options[:command]
639
+ when :help
640
+ return "ky_spectrum or kx_spectrum: Graph of phi^2 vs kx or ky"
641
+ when :options
642
+ return [:t, :t_index]
643
+ else
644
+ # ie ky_spectrum or kx_spectrum
645
+ kxy = options[:kxy]
646
+ kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("spectrum_over_#{kxy}", options)})
647
+ kit.title = "#{kxy} Spectrum"
648
+ kit.file_name = options[:graphkit_name] + options[:t_index].to_s
649
+ kit.data[0].with = 'lp'
650
+ kit.ylabel = "Phi^2 #{kxy}^2"
651
+ kit.pointsize = 2.0
652
+ kit
653
+ end
654
+ end
655
+
656
+ def kxy_spectrum_avg_graphkit(options={})
657
+ #time averaged kx or ky spectrum
658
+ case options[:command]
659
+ when :help
660
+ return "ky_spectrum or kx_spectrum: Graph of phi^2 vs kx or ky averaged over time"
661
+ when :options
662
+ return [:t, :t_index]
663
+ else
664
+ # ie ky_spectrum or kx_spectrum
665
+ kxy = options[:kxy]
666
+ kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("spectrum_over_#{kxy}_avg", options)})
667
+ kit.title = "#{kxy} Spectrum"
668
+ kit.file_name = options[:graphkit_name] + options[:t_index].to_s + "_avg"
669
+ kit.data[0].with = 'lp'
670
+ kit.ylabel = "Phi^2 #{kxy}^2"
671
+ kit.pointsize = 2.0
672
+ kit
673
+ end
674
+ end
675
+
676
+ def lagrangian_kx_graphkit(options={})
677
+ case options[:command]
678
+ when :help
679
+ return "A graph of the evolution of a single Lagrangian kx vs Eulerian kx and ky. Principally for debugging purposes"
680
+ when :options
681
+ return []
682
+ else
683
+ kyax = axiskit('ky', options)
684
+ kyk = list(:ky).keys
685
+ kx_list = list(:kx)
686
+ begin
687
+ kx_data = kyk.map do |ky_index|
688
+ options[:ky_index] = ky_index
689
+ options[:kx_index] =1
690
+ ekx_index = eulerian_kx_index(options)
691
+ kx_list[ekx_index]
692
+ end
693
+ rescue #ArgumentError
694
+ kyk.pop
695
+ retry
696
+ end
697
+ lky = list(:ky)
698
+ kyax.data = kyk.map{|k| lky[k]}
699
+ kit = GraphKit.autocreate(x: {data: kx_data, title: 'Eulerian kx (i.e. location on the GS2 grid)'}, y: kyax )
700
+ kit.data[0].title = 'Lagrangian kx=0'
701
+ kit.xrange = [kx_list.values.min, 0]
702
+ kit.yrange = [0, lky.values.max]
703
+
704
+ kit.title = 'Evolution of a Single Lagrangian kx vs ky'
705
+ kit.file_name = 'lagrangian_kx_graphkit'
706
+ return kit
707
+
708
+
709
+
710
+ end
711
+ end
712
+
713
+ def field_flux_tube_boundary_surface_graphkit(options={})
714
+ case options[:command]
715
+ when :help
716
+ return "The field options[:field_name] as a function of cartesian coordinates, on one specified side of the flux tube (specified using the options :coordinate (:x, :y, :theta) and :side (:min, :max))"
717
+ when :options
718
+ return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :gs2_coordinate_factor, :xmax, :xmin, :ymax, :ymin, :thetamax, :thetamin, :ncopies, :side, :coordinate, :torphi_values]
719
+ else
720
+ field = options[:field] || field_real_space_gsl_tensor(options)
721
+ if options[:ncopies]
722
+ ops = options.dup
723
+ ops.delete(:ncopies)
724
+ return (options[:ncopies].times.map do |n|
725
+ ops[:ncopy] = n
726
+ field_flux_tube_boundary_surface_graphkit(ops)
727
+ end).sum
728
+ end
729
+ side = options[:side]
730
+ coord = options[:coordinate]
731
+ shp = field.shape
732
+ #raise " asdfal" unless shp
733
+ opside = side == :max ? :min : :max
734
+ ops = options.dup
735
+ ops[coord+opside] = ops[coord+side] ||
736
+ case side
737
+ when :max
738
+ case coord
739
+ when :y
740
+ shp[0]-1
741
+ when :x
742
+ shp[1]-1
743
+ when :theta
744
+ shp[2]-1
745
+ end
746
+
747
+
748
+ when :min
749
+ 0
750
+ end
751
+ opscut = ops.dup
752
+ opscut[:ymin] = ((opscut[:ymin]||0) - (options[:ymin]||0))
753
+ opscut[:ymax] = ((opscut[:ymax]||shp[0]-1) - (options[:ymin]||0))
754
+ #ep 'opscut', opscut, (opscut[:xmax]||shp[1]-1), shp
755
+ opscut[:xmin] = ((opscut[:xmin]||0) - (options[:xmin]||0))
756
+ opscut[:xmax] = ((opscut[:xmax]||shp[1]-1) - (options[:xmin]||0))
757
+ #ep 'opscut', opscut
758
+ #ep 'opscut', opscut
759
+ opscut[:thetamin] = ((opscut[:thetamin]||0) - (options[:thetamin]||0))
760
+ opscut[:thetamax] = ((opscut[:thetamax]||shp[2]-1) - (options[:thetamin]||0))
761
+ #p opscut;#gets
762
+ if options[:cyl]
763
+ coords = cylindrical_coordinates_gsl_tensor(ops) #.transpose(0,1,2,3)
764
+ else
765
+ coords = cartesian_coordinates_gsl_tensor(ops)
766
+ end
767
+ #ep ['coords', coords.shape, field.shape]; gets
768
+ newshape = coords.shape.slice(1..3)
769
+ x = coords[0, false]; x.reshape!(*newshape)
770
+ y = coords[1, false]; y.reshape!(*newshape)
771
+ z = coords[2, false]; z.reshape!(*newshape)
772
+ #ep shp , '...'
773
+ range = [
774
+ opscut[:ymin]||0..opscut[:ymax]||shp[0]-1,
775
+ opscut[:xmin]||0..opscut[:xmax]||shp[1]-1,
776
+ opscut[:thetamin]..opscut[:thetamax]
777
+
778
+ #((ops[:thetamin]||0) - (options[:thetamin]||0))..((ops[:thetamax]||shp[2]-1) - (options[:thetamin]||0))
779
+ ]
780
+
781
+ #ep ['range', range, 'field.shape', field.shape]
782
+ fieldside = field[*range ]
783
+ #ep ['coords', x.shape, fieldside.shape]; gets
784
+ kit = GraphKit.quick_create([x,y,z,fieldside])
785
+
786
+ # Create a map of this surface onto a continuous surface between two poloidal planes if ops[:torfield_values] is specified
787
+ if torphi_values = ops[:torphi_values]
788
+ raise "Can't take a poloidal cut at constant y or theta" if coord == :y #or coord == :theta
789
+ raise "Can't take a poloidal cut with a limited y range (Remove :ymin and :ymax from ops)" if options[:ymin] or options[:ymax]
790
+
791
+ torphi_values = torphi_values.sort
792
+ cyls = cylindrical_coordinates_gsl_tensor(ops.absorb(extra_points: true))
793
+ torphi_const0 = constant_torphi_surface_gsl_tensor(ops.absorb(torphi: torphi_values[0]))
794
+ #ep torphi_const0, ops
795
+ #torphi_const1 = constant_torphi_surface_gsl_tensor(ops.absorb(torphi: torphi_values[1]))
796
+ raise "torphi_should be of rank 1: #{torphi_const0.shape}" unless torphi_const0.shape.include? 1
797
+
798
+ #Get the number of points in the y direction between the two poloidal planes
799
+ deltorphi = cyls[2,-1,0,0] - cyls[2,0,0,0]
800
+ i = i1 = istart = torphi_const0[0,0]
801
+ displacement = torphi_values[0] - cyls[2,i,0,0] # which copy of the flux tube are we in?
802
+ #ep 'displacement', displacement
803
+ shpc = cyls.shape
804
+ ny = shpc[1]-1 # remove extra point
805
+ while cyls[2,i%ny,0,0] + displacement < torphi_values[1]
806
+ #ep ['displacement', displacement, 'torphi', torphi = cyls[2,i%ny,0,0] + displacement, 'i', i]
807
+ displacement=(cyls[2,i%ny+1,0,0]+displacement-cyls[2,0,0,0]) if (i+1)%ny == 0
808
+ i+=1
809
+ end
810
+ ysize = i - i1
811
+ #ep ['torphil', torphi = cyls[2,i%ny,0,0] + displacement, 'ysize', ysize]
812
+ #exit
813
+
814
+
815
+
816
+ #ysize = (torphi_const0[-1] - torphi_const1[0] ).abs + 1
817
+ #case coord
818
+ #when :x
819
+ shpside = fieldside.shape
820
+ fieldcut = GSL::Tensor.float(ysize, shpside[1], shpside[2])
821
+ xcut = GSL::Tensor.float(ysize, shpside[1], shpside[2])
822
+ ycut = GSL::Tensor.float(ysize, shpside[1], shpside[2])
823
+ zcut = GSL::Tensor.float(ysize, shpside[1], shpside[2])
824
+ #ep shpside
825
+ shpcut = fieldcut.shape
826
+ for k in 0...shpcut[2] # 1 of these 2 loops
827
+ for j in 0...shpcut[1] # will have size 1
828
+
829
+ istart = torphi_const0[j,k]
830
+ displacement = torphi_values[0] - cyls[2,istart,j,k] # where in the torus does this copy of the flux tube start compared to where we want to be?
831
+
832
+ #p torphi_const0[i,j], torphi_const1[i,j]
833
+ for n in 0...shpcut[0] # index along our cut surface
834
+ i = istart + n
835
+ #icut = i%ysize
836
+ #cyls = cylindrical_coordinates_gsl_tensor(ops.absorb(extra_points: true)) #.transpose(0,1,2,3)
837
+ #ep ['displacement', displacement, n, i, ny, 'torphi', torphi = cyls[2,i%ny,j,k] +displacement]
838
+ # We chop off the surface
839
+ # between two y gridpoints
840
+ # Hence we must interpolate
841
+ # the field between those
842
+ # gridpoints
843
+ if n == 0
844
+ torphi0 = torphi_values[0]
845
+ s = Math.sin(torphi0)
846
+ c = Math.cos(torphi0)
847
+ d2 = cyls[2,(i+1)%ny,j,k] + displacement - torphi0
848
+ d1 = torphi0 - (cyls[2,i%ny,j,k] + displacement)
849
+ dfac = d1 / (d1+d2)
850
+ elsif n == ysize-1
851
+ torphi1 = torphi_values[1]
852
+ s = Math.sin(torphi1)
853
+ c = Math.cos(torphi1)
854
+ d2 = cyls[2,(i+1)%ny,j,k] + displacement - torphi1
855
+ d1 = torphi1 - (cyls[2,i%ny,j,k] + displacement)
856
+ dfac = d1 / (d1+d2)
857
+ else
858
+ s = Math.sin(cyls[2,i%ny,j,k] + displacement)
859
+ c = Math.cos(cyls[2,i%ny,j,k] + displacement)
860
+ dfac = 0
861
+ end
862
+
863
+ #ep [(fieldside[i%ny,j,k] * (1-dfac) + fieldside[(i+1)%ny,j,k] * dfac).class, i,j,k, fieldside.shape, ny ]
864
+
865
+ fieldcut[n,j,k] = fieldside[i%ny,j,k] * (1-dfac) + fieldside[((i+1)%ny),j,k] * dfac
866
+
867
+ rad = cyls[0,i%ny,j,k]
868
+ xcut[n,j,k] = rad * c
869
+ ycut[n,j,k] = rad *s
870
+ zcut[n,j,k] = cyls[1,i%ny,j,k]
871
+ displacement=(cyls[2,i%ny+1,j,k]+displacement-cyls[2,0,j,k]) if (i+1)%ny == 0
872
+ #displacement+=cyls[2,i,j,k] if (i+1)%ny == 0
873
+ end
874
+ #exit
875
+ end
876
+ end
877
+
878
+ kit = GraphKit.quick_create([xcut,ycut,zcut,fieldcut])
879
+ end
880
+
881
+
882
+
883
+
884
+
885
+
886
+ kit.data[0].gp.with = "pm3d"
887
+ return kit
888
+ end
889
+
890
+ end
891
+
892
+ def density_real_space_standard_representation_graphkit(options={})
893
+ case options[:command]
894
+ when :help
895
+ return "The density as a function of cartesian coordinates showing showing the standard way of representing the turbulence, with two poloidal cuts and the inner and outer radial surfaces. Multiple copies of the flux tube are used to fill the space."
896
+ when :options
897
+ return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :torphi_values, :species_index]
898
+ else
899
+ field_real_space_standard_representation_graphkit(options.absorb({field_name: :density}))
900
+ end
901
+ end
902
+
903
+ def phi_real_space_standard_representation_graphkit(options={})
904
+ case options[:command]
905
+ when :help
906
+ return "The potential as a function of cartesian coordinates showing showing the standard way of representing the turbulence, with two poloidal cuts and the inner and outer radial surfaces. Multiple copies of the flux tube are used to fill the space."
907
+ when :options
908
+ return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :torphi_values]
909
+ else
910
+ field_real_space_standard_representation_graphkit(options.absorb({field_name: :phi}))
911
+ end
912
+ end
913
+
914
+ def field_real_space_standard_representation_graphkit(options={})
915
+ case options[:command]
916
+ when :help
917
+ return "The field options[:field_name] as a function of cartesian coordinates showing showing the standard way of representing the turbulence, with two poloidal cuts and the inner and outer radial surfaces. Multiple copies of the flux tube are used to fill the space."
918
+ when :options
919
+ return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :torphi_values]
920
+ else
921
+ field = field_real_space_gsl_tensor(options)
922
+ options[:field] = field
923
+ poloidal_planes = options[:torphi_values]
924
+ #ep poloidal_planes; gets
925
+ raise "Please set options[:torphi_values] to an array of two values" unless poloidal_planes.kind_of? Array and poloidal_planes.size==2
926
+ options[:torphi] = poloidal_planes[0]
927
+ kit1 = field_real_space_poloidal_plane_graphkit(options)
928
+ options[:torphi] = poloidal_planes[1]
929
+ kit2 = field_real_space_poloidal_plane_graphkit(options)
930
+ options[:coordinate] = :x
931
+ options[:side] = :min
932
+ kit3 = field_flux_tube_boundary_surface_graphkit(options)
933
+ options[:side] = :max
934
+ kit4 = field_flux_tube_boundary_surface_graphkit(options)
935
+ #kit= kit1+kit2
936
+ #kit = kit3 +kit4
937
+ kit = kit1+kit2+kit3+kit4
938
+ if options[:thetamax] or options[:thetamin]
939
+ options[:coordinate] = :theta
940
+ options[:side] = :min
941
+ kit5 = field_flux_tube_boundary_surface_graphkit(options)
942
+ options[:side] = :max
943
+ kit6 = field_flux_tube_boundary_surface_graphkit(options)
944
+ kit += kit5+kit6
945
+ end
946
+ kit.gp.pm3d = "depthorder"
947
+ kit.xlabel = 'X (m)'
948
+ kit.ylabel = 'Y (m)'
949
+ kit.zlabel = "'Z (m)' rotate by 90"
950
+ kit.title = "3-D Potential"
951
+ return kit
952
+ end
953
+ end
954
+
955
+ def phi_real_space_poloidal_plane_graphkit(options={})
956
+ case options[:command]
957
+ when :help
958
+ return "The potential as a function of cartesian coordinates showing a cut at one toroidal angle, with multiple periodic copies of the flux tube used to fill the whole circle.."
959
+ when :options
960
+ return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :torphi]
961
+ else
962
+ return field_real_space_poloidal_plane_graphkit(options.absorb(field_name: :phi))
963
+ end
964
+ end
965
+
966
+ def density_real_space_poloidal_plane_graphkit(options={})
967
+ case options[:command]
968
+ when :help
969
+ return "The density as a function of cartesian coordinates showing a cut at one toroidal angle, with multiple periodic copies of the flux tube used to fill the whole circle.."
970
+ when :options
971
+ return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :torphi]
972
+ else
973
+ return field_real_space_poloidal_plane_graphkit(options.absorb({field_name: :density}))
974
+ end
975
+ end
976
+
977
+ def field_real_space_poloidal_plane_graphkit(options={})
978
+ case options[:command]
979
+ when :help
980
+ return "The potential as a function of cartesian coordinates showing a cut at one toroidal angle, with multiple periodic copies of the flux tube used to fill the whole circle.."
981
+ when :options
982
+ return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :torphi, :constant_torphi, :no_flux_tube_copies]
983
+ else
984
+ #if options[:ncopies]
985
+ #ops = options.dup
986
+ #ops.delete(:ncopies)
987
+ #return (options[:ncopies].times.map do |n|
988
+ #ops[:ncopy] = n
989
+ #field_real_space_surface_graphkit(ops)
990
+ #end).sum
991
+ #end
992
+ #zaxis = axiskit('field0_over_x_over_y', options)
993
+ #zaxis.data = zaxis.data.transpose
994
+ #shape = zaxis.data.shape
995
+ #carts = cartesian_coordinates_gsl_tensor(options)
996
+ #torphiout = 2.6
997
+ torphiout = options[:constant_torphi] || options[:torphi] #if constant_torphi is specified this is the toroidal angle at which data is printed
1069
998
  torphiactual = options[:torphi] #This is the actual tor_phi used in the calculation
1070
- raise "Please specify a toroidal angle (options[:torphi])" unless torphiout
1071
- field = options[:field] || field_real_space_gsl_tensor(options)
1072
- torphi_const = constant_torphi_surface_gsl_tensor(options)
999
+ raise "Please specify a toroidal angle (options[:torphi])" unless torphiout
1000
+ field = options[:field] || field_real_space_gsl_tensor(options)
1001
+ torphi_const = constant_torphi_surface_gsl_tensor(options)
1073
1002
  cyls = cylindrical_coordinates_gsl_tensor(options.absorb({extra_points: true}))
1074
- #p torphi_const[0,true].to_a;
1075
- #p 'sh', cyls.shape[1], '','','','';
1076
- #exit
1077
- #carts = cartesian_coordinates_gsl_tensor(options)
1078
- shp = field.shape
1079
- shpc = cyls.shape
1080
- #ep 'shapes', shp, cyls.shape
1081
- new_field = GSL::Tensor.alloc(shp[1], shp[2])
1082
- new_X = GSL::Tensor.alloc(shp[1], shp[2])
1083
- new_Y = GSL::Tensor.alloc(shp[1], shp[2])
1084
- new_Z = GSL::Tensor.alloc(shp[1], shp[2])
1085
- #y = gsl_vector('y', options)
1086
- #y = y.connect([2*y[-1] - y[-2]].to_gslv).dup
1087
- #c = Math.cos(torphiout)
1088
- #s = Math.sin(torphiout)
1089
- #theta_vec = gsl_vector('theta', options)
1090
- #x_vec = gsl_vector('x', options)
1091
- #y_vec = gsl_vector('y', options)
1092
- #field.iterate do |i,j,k|
1093
- #lastbracketed = nil
1094
- #lastj = -1
1095
- #field.iterate_row_maj do |i,j,k|
1096
- for k in 0...shp[2] #theta loop
1097
- for j in 0...shp[1] #xloop
1098
- #raise "Missed #{[j,k].inspect}, #{lastj}" unless lastj == j-1
1099
- #ep [i,j,k], cyls.shape
1100
- i = torphi_const[j,k]
1101
- torphi1 = cyls[2,i,j,k]
1102
- torphi2 = cyls[2,i+1,j,k]
1103
- deltorphi = cyls[2,shpc[1]-1,j,k] - cyls[2,0,j,k]
1003
+ #p torphi_const[0,true].to_a;
1004
+ #p 'sh', cyls.shape[1], '','','','';
1005
+ #exit
1006
+ #carts = cartesian_coordinates_gsl_tensor(options)
1007
+ shp = field.shape
1008
+ shpc = cyls.shape
1009
+ #ep 'shapes', shp, cyls.shape
1010
+ new_field = GSL::Tensor.alloc(shp[1], shp[2])
1011
+ new_X = GSL::Tensor.alloc(shp[1], shp[2])
1012
+ new_Y = GSL::Tensor.alloc(shp[1], shp[2])
1013
+ new_Z = GSL::Tensor.alloc(shp[1], shp[2])
1014
+ #y = gsl_vector('y', options)
1015
+ #y = y.connect([2*y[-1] - y[-2]].to_gslv).dup
1016
+ #c = Math.cos(torphiout)
1017
+ #s = Math.sin(torphiout)
1018
+ #theta_vec = gsl_vector('theta', options)
1019
+ #x_vec = gsl_vector('x', options)
1020
+ #y_vec = gsl_vector('y', options)
1021
+ #field.iterate do |i,j,k|
1022
+ #lastbracketed = nil
1023
+ #lastj = -1
1024
+ #field.iterate_row_maj do |i,j,k|
1025
+ for k in 0...shp[2] #theta loop
1026
+ for j in 0...shp[1] #xloop
1027
+ #raise "Missed #{[j,k].inspect}, #{lastj}" unless lastj == j-1
1028
+ #ep [i,j,k], cyls.shape
1029
+ i = torphi_const[j,k]
1030
+ torphi1 = cyls[2,i,j,k]
1031
+ torphi2 = cyls[2,i+1,j,k]
1032
+ deltorphi = cyls[2,shpc[1]-1,j,k] - cyls[2,0,j,k]
1104
1033
 
1105
1034
  #This options tests whether the point is inside or outside a single
1106
1035
  #flux tube and defines a factor which will zero all other points.
@@ -1115,1342 +1044,1403 @@ module GraphKits
1115
1044
  field_fac = 1.0
1116
1045
  end
1117
1046
 
1118
- #raise "Periodicity not satisfied: #{(2*Math::PI/deltorphi+1.0e-8)%1.0}, #{(2*Math::PI/deltorphi+1.0e-5)}" unless ((2*Math::PI/deltorphi)+1.0e-8)%1.0 < 1.0e-5
1119
- m1 = (torphi1 )%deltorphi
1120
- m2 = (torphi2 )%deltorphi
1121
- m3 = (torphiactual)%deltorphi
1122
- #bracketed = ((m1-m3).abs < 1.0e-4) || (
1123
- #(m2-m3.abs) > 1.0e-4 &&
1124
- #(m2 - m3) *
1125
- #(m1 - m3) *
1126
- #(m2 - m1) *
1127
- #(torphi2 - torphi1) < 0)
1128
- ##p 'n0', (2*Math::PI/deltorphi).round
1129
- #bracketed2 = (2*Math::PI/deltorphi + 1).round.times.inject(false) do |b,n|
1130
- #epsn = 1.0e-4
1131
- #eps2 = 1.0e-4
1132
- #upp = torphiout + deltorphi * n
1133
- #lwr = torphiout - deltorphi * n
1134
- ##measure = ((torphi1 < upp or (torphi1 - upp).abs < epsn) and upp+epsn < torphi2) or ((torphi1 < lwr or (torphi1-lwr).abs < eps) and lwr + eps < torphi2)
1135
- #a1 = a2 = a3 = b1 = b2 = b3 = 'q'
1136
- ##measure = ((
1137
- ###a1=((torphi1-upp).abs < (torphi2-upp).abs) and
1138
- ##(a1=((torphi2-upp).abs > 1.0e-7)) and
1139
- ##(a2=((torphi1 < upp or (torphi1 - upp).abs < epsn))) and
1140
- ##(a3=(upp < torphi2))
1141
- ##) or (
1142
- ###b1=((torphi1-lwr).abs < (torphi2-lwr).abs) and
1143
- ##(b1=((torphi2-lwr).abs > 1.0e7)) and
1144
- ##(b2=(torphi1 < lwr or (torphi1-lwr).abs < epsn)) and
1145
- ##(b3 = (lwr < torphi2))
1146
- ##))
1147
- #a1=((torphi2-upp).abs > eps2)
1148
- #a2=((torphi1 < upp or (torphi1 - upp).abs < epsn))
1149
- #a3=(upp < torphi2)
1150
- #b1=(torphi2-lwr).abs > eps2
1151
- #b2=(torphi1 < lwr or (torphi1-lwr).abs < epsn)
1152
- #b3 = (lwr < torphi2)
1153
- #measure = ((a1 and a2 and a3) or (b1 and b2 and b3))
1154
- ##ep 'measure', measure, [torphi1, torphi2, upp, lwr , n, deltorphi, a1, a2, a3, b1, b2, b3, (torphi2-lwr).abs, (torphi2-lwr).abs > eps2] if measure #; gets if [j,k] == [5,8] # if measure
1155
- #b or measure
1156
- #end
1157
- ##bracketed = bracketed2
1158
- #raise "Measures don't agree #{bracketed}, #{bracketed2}" unless bracketed2 == bracketed
1047
+ #raise "Periodicity not satisfied: #{(2*Math::PI/deltorphi+1.0e-8)%1.0}, #{(2*Math::PI/deltorphi+1.0e-5)}" unless ((2*Math::PI/deltorphi)+1.0e-8)%1.0 < 1.0e-5
1048
+ m1 = (torphi1 )%deltorphi
1049
+ m2 = (torphi2 )%deltorphi
1050
+ m3 = (torphiactual)%deltorphi
1051
+ #bracketed = ((m1-m3).abs < 1.0e-4) || (
1052
+ #(m2-m3.abs) > 1.0e-4 &&
1053
+ #(m2 - m3) *
1054
+ #(m1 - m3) *
1055
+ #(m2 - m1) *
1056
+ #(torphi2 - torphi1) < 0)
1057
+ ##p 'n0', (2*Math::PI/deltorphi).round
1058
+ #bracketed2 = (2*Math::PI/deltorphi + 1).round.times.inject(false) do |b,n|
1059
+ #epsn = 1.0e-4
1060
+ #eps2 = 1.0e-4
1061
+ #upp = torphiout + deltorphi * n
1062
+ #lwr = torphiout - deltorphi * n
1063
+ ##measure = ((torphi1 < upp or (torphi1 - upp).abs < epsn) and upp+epsn < torphi2) or ((torphi1 < lwr or (torphi1-lwr).abs < eps) and lwr + eps < torphi2)
1064
+ #a1 = a2 = a3 = b1 = b2 = b3 = 'q'
1065
+ ##measure = ((
1066
+ ###a1=((torphi1-upp).abs < (torphi2-upp).abs) and
1067
+ ##(a1=((torphi2-upp).abs > 1.0e-7)) and
1068
+ ##(a2=((torphi1 < upp or (torphi1 - upp).abs < epsn))) and
1069
+ ##(a3=(upp < torphi2))
1070
+ ##) or (
1071
+ ###b1=((torphi1-lwr).abs < (torphi2-lwr).abs) and
1072
+ ##(b1=((torphi2-lwr).abs > 1.0e7)) and
1073
+ ##(b2=(torphi1 < lwr or (torphi1-lwr).abs < epsn)) and
1074
+ ##(b3 = (lwr < torphi2))
1075
+ ##))
1076
+ #a1=((torphi2-upp).abs > eps2)
1077
+ #a2=((torphi1 < upp or (torphi1 - upp).abs < epsn))
1078
+ #a3=(upp < torphi2)
1079
+ #b1=(torphi2-lwr).abs > eps2
1080
+ #b2=(torphi1 < lwr or (torphi1-lwr).abs < epsn)
1081
+ #b3 = (lwr < torphi2)
1082
+ #measure = ((a1 and a2 and a3) or (b1 and b2 and b3))
1083
+ ##ep 'measure', measure, [torphi1, torphi2, upp, lwr , n, deltorphi, a1, a2, a3, b1, b2, b3, (torphi2-lwr).abs, (torphi2-lwr).abs > eps2] if measure #; gets if [j,k] == [5,8] # if measure
1084
+ #b or measure
1085
+ #end
1086
+ ##bracketed = bracketed2
1087
+ #raise "Measures don't agree #{bracketed}, #{bracketed2}" unless bracketed2 == bracketed
1088
+ #
1089
+ #
1090
+ ##d2 = torphi2 - torphiout
1091
+ ##d1 = torphiout - torphi1
1092
+ #if bracketed
1093
+ #y1 =
1094
+ d2 = m2 - m3
1095
+ d1 = m3 - m1
1096
+ if torphi2 > torphi1
1097
+ d1+=deltorphi if d1 < 0
1098
+ else
1099
+ d2-=deltorphi if d2 > 0
1100
+ end
1101
+ dfac = d1 / (d1+d2)
1102
+
1103
+ #n = 0
1104
+ #loop do
1105
+
1106
+ #ep [torphi1, torphi2, cyls[2,shpc[1]-1,j,k] , cyls[2,0,j,k], deltorphi, m1, m2, m3]
1107
+ #ep (mod2 - mod3)/(mod1 - mod3) < 0,"********"
1108
+ #raise "Doubled up" if lastbracketed == [j,k]
1109
+ #raise "Missed: #{i},#{j}, #{lastbracketed.inspect} " unless lastbracketed == [j-1,k] or lastbracketed == [shp[1]-1, k-1] if lastbracketed
1110
+ #ep bracketed,"********"
1111
+ #ep ['bracketed', i, j, k]
1112
+ #ep ['field', field[i,j,k]]
1113
+ #new_phi[j,k] = theta_vec[k]
1114
+ new_field[j,k] = (field[i,j,k] * (1-dfac) + field[(i+1)%shp[0],j,k] * dfac) * field_fac
1115
+ #raise "Mismatched radii" unless
1116
+ #new_X[j,k] = cyls[0,i,j,k] * Math.cos(cyls[2,i,j,k])
1117
+ #new_X[j,k] = x_vec[j]
1118
+ new_X[j,k] = cyls[0,i,j,k] * Math.cos(torphiout)
1119
+ #new_Y[j,k] = cyls[0,i,j,k] * Math.sin(cyls[2,i,j,k])
1120
+ #new_Y[j,k] = y_vec[i]
1121
+ new_Y[j,k] = cyls[0,i,j,k] * Math.sin(torphiout)
1122
+ #new_Z[j,k] = theta_vec[k]
1123
+ new_Z[j,k] = cyls[1,i,j,k]
1124
+ #lastbracketed = [j,k]
1125
+ #lastj = j
1126
+ #end
1127
+ end # xloop
1128
+ end # theta loop
1129
+ #exit
1130
+ kit = GraphKit.quick_create([new_X, new_Y, new_Z, new_field])
1131
+ kit.xlabel = 'X'
1132
+ kit.ylabel = 'Y'
1133
+ kit.data[0].gp.with = "pm3d"
1134
+ return kit
1135
+
1136
+
1137
+
1138
+
1139
+
1140
+
1141
+
1142
+
1143
+ #end
1144
+
1145
+ sides = [:max, :min]
1146
+ kits = []
1147
+ #[].each_with_index do |coord,i|
1148
+ #sides.each_with_index do |side,j|
1149
+ [[:y, :min, 0], [:y, :max, Math::PI]].each do |coord, side, toroidalphi|
1150
+ #[0].each do |toroidalphi|
1151
+ #raise unless i.kind_of? Integer
1152
+ #return kit if coord + side == :xmax
1153
+ options[:field] = field
1154
+ options[:side] = side
1155
+ options[:coordinate] = coord
1156
+ options[:toroidal_projection] = coord == :x ? nil : toroidalphi
1157
+ next if coord == :x and toroidalphi == Math::PI
1158
+ kit = field_flux_tube_boundary_surface_graphkit(options)
1159
+ kits.push kit
1160
+ end
1161
+ #end
1162
+ #end
1163
+ k = kits.sum
1164
+ #k = kits[5] + kits[4] + kits[3] + kits[2] + kits[1] + kits[0]
1165
+ #k = kits[5] + kits[4] + kits[1] + kits[0]
1166
+ k.gp.pm3d = "depthorder"
1167
+ #k.compress_datakits = true
1168
+ return k
1169
+
1170
+ end
1171
+ end
1172
+
1173
+ # def phi_flux_tube_poloidal_cut_graphkit(options={})
1174
+ # #####case options[:command]
1175
+ # #####when :help
1176
+ # ######return "The potential as a function of cartesian coordinates, cut at two toroidal angles."
1177
+ # #####when :options
1178
+ # ######return [:rgbformulae, :limit, :t_index]
1179
+ # #####end
1180
+ # poloidal_planes = options[:torphi_values]
1181
+ # #ep poloidal_planes; gets
1182
+ # raise "Please set options[:torphi_values] to an array of two values" unless poloidal_planes.kind_of? Array and poloidal_planes.size==2
1183
+ # field = options[:phi] || phi_real_space_gsl_tensor(options)
1184
+ # options[:torphi] = poloidal_planes[0]
1185
+ # torphi_const1 = constant_torphi_surface_gsl_tensor(options.dup.absorb(no_copies: true))
1186
+ # options[:torphi] = poloidal_planes[1]
1187
+ # torphi_const2 = constant_torphi_surface_gsl_tensor(options.dup.absorb(no_copies: true))
1188
+ # x1 = SparseTensor.new(2) # First poloidal face
1189
+ # y1 = SparseTensor.new(2)
1190
+ # z1 = SparseTensor.new(2)
1191
+ # field1 = SparseTensor.new(2)
1192
+ #
1193
+ # x2 = SparseTensor.new(2) # Second poloidal
1194
+ # y2 = SparseTensor.new(2) # face
1195
+ # z2 = SparseTensor.new(2)
1196
+ # field2 = SparseTensor.new(2)
1197
+ #
1198
+ # xmaxx = SparseTensor.new(2) # Connecting
1199
+ # ymaxx = SparseTensor.new(2) # surface of the
1200
+ # zmaxx = SparseTensor.new(2) # flux tube
1201
+ # fieldmaxx = SparseTensor.new(2) # max x
1202
+ # xminx = SparseTensor.new(2) # Connecting
1203
+ # yminx = SparseTensor.new(2) # surface of the
1204
+ # zminx = SparseTensor.new(2) # flux tube
1205
+ # fieldminx = SparseTensor.new(2)
1206
+ # xmaxth = SparseTensor.new(2) # Connecting
1207
+ # ymaxth = SparseTensor.new(2) # surface of the
1208
+ # zmaxth = SparseTensor.new(2) # flux tube
1209
+ # fieldmaxth = SparseTensor.new(2)
1210
+ # xminth = SparseTensor.new(2) # Connecting
1211
+ # yminth = SparseTensor.new(2) # surface of the
1212
+ # zminth = SparseTensor.new(2) # flux tube
1213
+ # fieldminth = SparseTensor.new(2)
1214
+ #
1215
+ # xsurf = [xmaxx, xminx, xmaxth, xminth]
1216
+ # ysurf = [ymaxx, yminx, ymaxth, yminth]
1217
+ # zsurf = [zmaxx, zminx, zmaxth, zminth]
1218
+ # fieldsurf = [fieldmaxx, fieldminx, fieldmaxth, fieldminth]
1219
+ #
1220
+ # cyls = cylindrical_coordinates_gsl_tensor(options)
1221
+ # shp = cyls.shape
1222
+ # ysize = shp[1]
1223
+ #
1224
+ # # Find out how far each cut
1225
+ # # poloidal face of the flux
1226
+ # # tube extends in theta and x
1227
+ # k1min = GSL::Tensor.int(shp[2])
1228
+ # k1max = GSL::Tensor.int(shp[2])
1229
+ # k2min = GSL::Tensor.int(shp[2])
1230
+ # k2max = GSL::Tensor.int(shp[2])
1231
+ # k1min[true] = shp[3]; k1max[true] = 0
1232
+ # k2min[true] = shp[3]; k2max[true] = 0
1233
+ # j1min = GSL::Tensor.int(shp[3])
1234
+ # j1max = GSL::Tensor.int(shp[3])
1235
+ # j2min = GSL::Tensor.int(shp[3])
1236
+ # j2max = GSL::Tensor.int(shp[3])
1237
+ # j1min[true] = shp[2]; j1max[true] = 0
1238
+ # j2min[true] = shp[2]; j2max[true] = 0
1239
+ # #ep j1max;gets
1240
+ # for j in 0...shp[2]
1241
+ # for k in 0...shp[3]
1242
+ # i1 = torphi_const1[j,k]
1243
+ # i2 = torphi_const2[j,k]
1244
+ # i1 = 0 if i1==-1
1245
+ # i2 = 0 if i2==-1
1246
+ # i1 = ysize-1 if i1==ysize
1247
+ # i2 = ysize-1 if i2==ysize
1248
+ # if i1%ysize==i1
1249
+ # k1min[j] = [k, k1min[j]].min
1250
+ # k1max[j] = [k, k1max[j]].max
1251
+ # j1min[k] = [j, j1min[k]].min
1252
+ # j1max[k] = [j, j1max[k]].max
1253
+ # end
1254
+ # if i2%ysize==i2
1255
+ # k2min[j] = [k, k2min[j]].min
1256
+ # k2max[j] = [k, k2max[j]].max
1257
+ # j2min[k] = [j, j2min[k]].min
1258
+ # j2max[k] = [j, j2max[k]].max
1259
+ # end
1260
+ # end
1261
+ # end
1262
+ # lineorder = SparseTensor.new(2)
1263
+ # surfaces = SparseTensor.new(2)
1264
+ # #Now we generate the order of the line
1265
+ # #scans between one cross section and
1266
+ # #the other (the lines have to be in order
1267
+ # # around the cross section)
1268
+ # # We also specify which surface(s) the
1269
+ # # line lies on
1270
+ # o = 0
1271
+ # #min x surface
1272
+ # j=0
1273
+ # for k in ([k1min[0],k2min[0]].min)..([k1max[0], k2max[0]].max)
1274
+ # lineorder[j,k] = o
1275
+ # surfaces[j,k]||=[]
1276
+ # surfaces[j,k].push 1
1277
+ # o+=1
1278
+ # end
1279
+ # # max theta surface
1280
+ # for j in 0...shp[2]
1281
+ # lineorder[j,[k1max[j],k2max[j]].max]=o
1282
+ # surfaces[j,[k1max[j],k2max[j]].max]||=[]
1283
+ # surfaces[j,[k1max[j],k2max[j]].max].push 2
1284
+ # o+=1
1285
+ # end
1286
+ # j = shp[2]-1
1287
+ # # max x surface
1288
+ # ep ([k1max[j], k2max[j]].max)..([k1min[j],k2min[j]].min)
1289
+ # for k in (-[k1max[j], k2max[j]].max)...(-[k1min[j],k2min[j]].min)
1290
+ # #ep 'k', k
1291
+ # lineorder[j,-k] = o
1292
+ # surfaces[j,-k]||=[]
1293
+ # surfaces[j,-k].push 0
1294
+ # o+=1
1295
+ # end
1296
+ # # max theta surface
1297
+ # for j in -(shp[2]-1)..0
1298
+ # lineorder[-j,[k1min[j],k2min[j]].min]=o
1299
+ # surfaces[-j,[k1min[j],k2min[j]].min]||=[]
1300
+ # surfaces[-j,[k1min[j],k2min[j]].min].push 3
1301
+ # o+=1
1302
+ # end
1303
+ # ep lineorder, surfaces;gets
1159
1304
  #
1305
+ # #ep j1max.to_a;gets
1306
+ # for j in 0...shp[2]
1307
+ # for k in 0...shp[3]
1308
+ # i10 = i1 = torphi_const1[j,k]
1309
+ # i20 = i2 = torphi_const2[j,k]
1310
+ # ep ['i1', i1, 'i2', i2]
1160
1311
  #
1161
- ##d2 = torphi2 - torphiout
1162
- ##d1 = torphiout - torphi1
1163
- #if bracketed
1164
- #y1 =
1165
- d2 = m2 - m3
1166
- d1 = m3 - m1
1167
- if torphi2 > torphi1
1168
- d1+=deltorphi if d1 < 0
1169
- else
1170
- d2-=deltorphi if d2 > 0
1171
- end
1172
- dfac = d1 / (d1+d2)
1173
-
1174
- #n = 0
1175
- #loop do
1176
-
1177
- #ep [torphi1, torphi2, cyls[2,shpc[1]-1,j,k] , cyls[2,0,j,k], deltorphi, m1, m2, m3]
1178
- #ep (mod2 - mod3)/(mod1 - mod3) < 0,"********"
1179
- #raise "Doubled up" if lastbracketed == [j,k]
1180
- #raise "Missed: #{i},#{j}, #{lastbracketed.inspect} " unless lastbracketed == [j-1,k] or lastbracketed == [shp[1]-1, k-1] if lastbracketed
1181
- #ep bracketed,"********"
1182
- #ep ['bracketed', i, j, k]
1183
- #ep ['field', field[i,j,k]]
1184
- #new_phi[j,k] = theta_vec[k]
1185
- new_field[j,k] = (field[i,j,k] * (1-dfac) + field[(i+1)%shp[0],j,k] * dfac) * field_fac
1186
- #raise "Mismatched radii" unless
1187
- #new_X[j,k] = cyls[0,i,j,k] * Math.cos(cyls[2,i,j,k])
1188
- #new_X[j,k] = x_vec[j]
1189
- new_X[j,k] = cyls[0,i,j,k] * Math.cos(torphiout)
1190
- #new_Y[j,k] = cyls[0,i,j,k] * Math.sin(cyls[2,i,j,k])
1191
- #new_Y[j,k] = y_vec[i]
1192
- new_Y[j,k] = cyls[0,i,j,k] * Math.sin(torphiout)
1193
- #new_Z[j,k] = theta_vec[k]
1194
- new_Z[j,k] = cyls[1,i,j,k]
1195
- #lastbracketed = [j,k]
1196
- #lastj = j
1197
- #end
1198
- end # xloop
1199
- end # theta loop
1200
- #exit
1201
- kit = GraphKit.quick_create([new_X, new_Y, new_Z, new_field])
1202
- kit.xlabel = 'X'
1203
- kit.ylabel = 'Y'
1204
- kit.data[0].gp.with = "pm3d"
1205
- return kit
1206
-
1207
-
1208
-
1209
-
1210
-
1211
-
1212
-
1213
-
1214
- #end
1215
-
1216
- sides = [:max, :min]
1217
- kits = []
1218
- #[].each_with_index do |coord,i|
1219
- #sides.each_with_index do |side,j|
1220
- [[:y, :min, 0], [:y, :max, Math::PI]].each do |coord, side, toroidalphi|
1221
- #[0].each do |toroidalphi|
1222
- #raise unless i.kind_of? Integer
1223
- #return kit if coord + side == :xmax
1224
- options[:field] = field
1225
- options[:side] = side
1226
- options[:coordinate] = coord
1227
- options[:toroidal_projection] = coord == :x ? nil : toroidalphi
1228
- next if coord == :x and toroidalphi == Math::PI
1229
- kit = field_flux_tube_boundary_surface_graphkit(options)
1230
- kits.push kit
1231
- end
1232
- #end
1233
- #end
1234
- k = kits.sum
1235
- #k = kits[5] + kits[4] + kits[3] + kits[2] + kits[1] + kits[0]
1236
- #k = kits[5] + kits[4] + kits[1] + kits[0]
1237
- k.gp.pm3d = "depthorder"
1238
- #k.compress_datakits = true
1239
- return k
1240
-
1241
- end
1242
- end
1243
- #def phi_flux_tube_poloidal_cut_graphkit(options={})
1244
- ######case options[:command]
1245
- ######when :help
1246
- ######return "The potential as a function of cartesian coordinates, cut at two toroidal angles."
1247
- ######when :options
1248
- ######return [:rgbformulae, :limit, :t_index]
1249
- ######end
1250
- #poloidal_planes = options[:torphi_values]
1251
- ##ep poloidal_planes; gets
1252
- #raise "Please set options[:torphi_values] to an array of two values" unless poloidal_planes.kind_of? Array and poloidal_planes.size==2
1253
- #field = options[:phi] || phi_real_space_gsl_tensor(options)
1254
- #options[:torphi] = poloidal_planes[0]
1255
- #torphi_const1 = constant_torphi_surface_gsl_tensor(options.dup.absorb(no_copies: true))
1256
- #options[:torphi] = poloidal_planes[1]
1257
- #torphi_const2 = constant_torphi_surface_gsl_tensor(options.dup.absorb(no_copies: true))
1258
- #x1 = SparseTensor.new(2) # First poloidal face
1259
- #y1 = SparseTensor.new(2)
1260
- #z1 = SparseTensor.new(2)
1261
- #field1 = SparseTensor.new(2)
1262
-
1263
- #x2 = SparseTensor.new(2) # Second poloidal
1264
- #y2 = SparseTensor.new(2) # face
1265
- #z2 = SparseTensor.new(2)
1266
- #field2 = SparseTensor.new(2)
1267
-
1268
- #xmaxx = SparseTensor.new(2) # Connecting
1269
- #ymaxx = SparseTensor.new(2) # surface of the
1270
- #zmaxx = SparseTensor.new(2) # flux tube
1271
- #fieldmaxx = SparseTensor.new(2) # max x
1272
- #xminx = SparseTensor.new(2) # Connecting
1273
- #yminx = SparseTensor.new(2) # surface of the
1274
- #zminx = SparseTensor.new(2) # flux tube
1275
- #fieldminx = SparseTensor.new(2)
1276
- #xmaxth = SparseTensor.new(2) # Connecting
1277
- #ymaxth = SparseTensor.new(2) # surface of the
1278
- #zmaxth = SparseTensor.new(2) # flux tube
1279
- #fieldmaxth = SparseTensor.new(2)
1280
- #xminth = SparseTensor.new(2) # Connecting
1281
- #yminth = SparseTensor.new(2) # surface of the
1282
- #zminth = SparseTensor.new(2) # flux tube
1283
- #fieldminth = SparseTensor.new(2)
1284
-
1285
- #xsurf = [xmaxx, xminx, xmaxth, xminth]
1286
- #ysurf = [ymaxx, yminx, ymaxth, yminth]
1287
- #zsurf = [zmaxx, zminx, zmaxth, zminth]
1288
- #fieldsurf = [fieldmaxx, fieldminx, fieldmaxth, fieldminth]
1289
-
1290
- #cyls = cylindrical_coordinates_gsl_tensor(options)
1291
- #shp = cyls.shape
1292
- #ysize = shp[1]
1293
-
1294
- ## Find out how far each cut
1295
- ## poloidal face of the flux
1296
- ## tube extends in theta and x
1297
- #k1min = GSL::Tensor.int(shp[2])
1298
- #k1max = GSL::Tensor.int(shp[2])
1299
- #k2min = GSL::Tensor.int(shp[2])
1300
- #k2max = GSL::Tensor.int(shp[2])
1301
- #k1min[true] = shp[3]; k1max[true] = 0
1302
- #k2min[true] = shp[3]; k2max[true] = 0
1303
- #j1min = GSL::Tensor.int(shp[3])
1304
- #j1max = GSL::Tensor.int(shp[3])
1305
- #j2min = GSL::Tensor.int(shp[3])
1306
- #j2max = GSL::Tensor.int(shp[3])
1307
- #j1min[true] = shp[2]; j1max[true] = 0
1308
- #j2min[true] = shp[2]; j2max[true] = 0
1309
- ##ep j1max;gets
1310
- #for j in 0...shp[2]
1311
- #for k in 0...shp[3]
1312
- #i1 = torphi_const1[j,k]
1313
- #i2 = torphi_const2[j,k]
1314
- #i1 = 0 if i1==-1
1315
- #i2 = 0 if i2==-1
1316
- #i1 = ysize-1 if i1==ysize
1317
- #i2 = ysize-1 if i2==ysize
1318
- #if i1%ysize==i1
1319
- #k1min[j] = [k, k1min[j]].min
1320
- #k1max[j] = [k, k1max[j]].max
1321
- #j1min[k] = [j, j1min[k]].min
1322
- #j1max[k] = [j, j1max[k]].max
1323
- #end
1324
- #if i2%ysize==i2
1325
- #k2min[j] = [k, k2min[j]].min
1326
- #k2max[j] = [k, k2max[j]].max
1327
- #j2min[k] = [j, j2min[k]].min
1328
- #j2max[k] = [j, j2max[k]].max
1329
- #end
1330
- #end
1331
- #end
1332
- #lineorder = SparseTensor.new(2)
1333
- #surfaces = SparseTensor.new(2)
1334
- ##Now we generate the order of the line
1335
- ##scans between one cross section and
1336
- ##the other (the lines have to be in order
1337
- ## around the cross section)
1338
- ## We also specify which surface(s) the
1339
- ## line lies on
1340
- #o = 0
1341
- ##min x surface
1342
- #j=0
1343
- #for k in ([k1min[0],k2min[0]].min)..([k1max[0], k2max[0]].max)
1344
- #lineorder[j,k] = o
1345
- #surfaces[j,k]||=[]
1346
- #surfaces[j,k].push 1
1347
- #o+=1
1348
- #end
1349
- ## max theta surface
1350
- #for j in 0...shp[2]
1351
- #lineorder[j,[k1max[j],k2max[j]].max]=o
1352
- #surfaces[j,[k1max[j],k2max[j]].max]||=[]
1353
- #surfaces[j,[k1max[j],k2max[j]].max].push 2
1354
- #o+=1
1355
- #end
1356
- #j = shp[2]-1
1357
- ## max x surface
1358
- #ep ([k1max[j], k2max[j]].max)..([k1min[j],k2min[j]].min)
1359
- #for k in (-[k1max[j], k2max[j]].max)...(-[k1min[j],k2min[j]].min)
1360
- #ep 'k', k
1361
- #lineorder[j,-k] = o
1362
- #surfaces[j,-k]||=[]
1363
- #surfaces[j,-k].push 0
1364
- #o+=1
1365
- #end
1366
- ## max theta surface
1367
- #for j in -(shp[2]-1)..0
1368
- #lineorder[-j,[k1min[j],k2min[j]].min]=o
1369
- #surfaces[-j,[k1min[j],k2min[j]].min]||=[]
1370
- #surfaces[-j,[k1min[j],k2min[j]].min].push 3
1371
- #o+=1
1372
- #end
1373
- #ep lineorder, surfaces;gets
1374
-
1375
- ##ep j1max.to_a;gets
1376
- #for j in 0...shp[2]
1377
- #for k in 0...shp[3]
1378
- #i10 = i1 = torphi_const1[j,k]
1379
- #i20 = i2 = torphi_const2[j,k]
1380
- #ep ['i1', i1, 'i2', i2]
1381
-
1382
- ## Include extra points just outside
1383
- ## if necessary
1384
- #i10 = 0 if i1==-1 #
1385
- #i20 = 0 if i2==-1
1386
- #i10 = ysize - 1 if i1 == ysize
1387
- #i20 = ysize - 1 if i2 == ysize
1388
- ##if i1%ysize==i1 || i1==-1
1389
- #if i10%ysize==i10
1390
- ## First assign all the points on the first cut poloidal face
1391
- #r = cyls[0,i10,j,k]
1392
- #z = cyls[1,i10,j,k]
1393
- #tphi = poloidal_planes[0]
1394
- ##tphi = cyls[2,i1,j,k]
1395
- ##ep ['tphi', tphi, 'i1', i1, cyls[2,i1,j,k]%(2*Math::PI), cyls[2,(i1+1)%ysize,j,k]%(2*Math::PI)]
1396
- #s = Math.sin(tphi)
1397
- #c = Math.cos(tphi)
1398
- #x1p = x1[j,k] = r*c# X (not gs2 x!)
1399
- #y1p = y1[j,k] = r*s# Y (not gs2 y!)
1400
- #z1p = z1[j,k] = z# Z
1401
- ##ep [2,(i1+1)%ysize,j,k, cyls.shape]
1402
- ## I think this bit will be wrong
1403
- ## when i1 = -1 or ysize - 1
1404
- ## but it won't be a big error
1405
- ## --- need to fix
1406
- ##d2 = cyls[2,(i1+1)%ysize,j,k] - tphi
1407
- ##d1 = tphi - cyls[2,i1,j,k]
1408
- ##dfac = d1 / (d1+d2)
1409
- ##f1p = field1[j,k] = field[i1,j,k] * (1-dfac) + field[i1%ysize,j,k] * dfac
1410
- #f1p = (field1[j,k] = field[i1%ysize,j,k] + field[(i1+1)%ysize,j,k])/2.0
1411
- #end
1412
- #if i20%ysize==i20
1413
- #r = cyls[0,i20,j,k]
1414
- #z = cyls[1,i20,j,k]
1415
- #tphi = poloidal_planes[1]
1416
- #s = Math.sin(tphi)
1417
- #c = Math.cos(tphi)
1418
- #x2[j,k] = r*c# X (not gs2 x!)
1419
- #y2[j,k] = r*s# Y (not gs2 y!)
1420
- #z2[j,k] = z# Z
1421
- ##ep [2,(i2+1)%ysize,j,k, cyls.shape]
1422
- ##d2 = cyls[2,(i2+1)%ysize,j,k] - tphi
1423
- ##d1 = tphi - cyls[2,i2,j,k]
1424
- ##dfac = d1 / (d1+d2)
1425
- #field2[j,k] = (field[i2%ysize,j,k] + field[(i2+1)%ysize,j,k])/2.0
1426
- ##field2[j,k] = field[i2,j,k] * (1-dfac) + field[i2%ysize,j,k] * dfac
1427
- #end
1428
- #end
1429
- #end
1430
- #for j in 0...shp[2]
1431
- #for k in 0...shp[3]
1432
- #i10 = i1 = torphi_const1[j,k]
1433
- #i20 = i2 = torphi_const2[j,k]
1434
- ##ep ['i1', i1, 'i2', i2]
1435
-
1436
- ## Include extra points just outside
1437
- ## if necessary
1438
- #i10 = 0 if i1==-1 #
1439
- #i20 = 0 if i2==-1
1440
- #i10 = ysize - 1 if i1 == ysize
1441
- #i20 = ysize - 1 if i2 == ysize
1442
- #if lineorder[j,k]
1443
- #n=0
1444
- #sign21 = ((i2-i1)/(i2-i1).abs).round
1445
- ## Go from y on the first surface to
1446
- ## y on the next surface
1447
- #ep ['jk',j,k, (i10+n*sign21)*sign21 < i20*sign21]
1448
- #while (i10+n*sign21)*sign21 < i20*sign21
1449
- #ka = k
1450
- #ia10 = i10
1451
- #ia20 = i20
1452
- #while (ia10+n*sign21)%ysize != ia10+n*sign21
1453
- #ep [j,k,ka, 'ia10', ia10, ia10+n*sign21, lineorder[j,k], surfaces[j,k], 'n', n, 'ni', ia10 + n * sign21, 'ysize', ysize, 'max', k1max[j], k2max[j], 'min', k1min[j], k2min[j] ]
1454
- ## We have left the flux surface...
1455
- ## increase/decrease theta to get back in
1456
- #if k > k1max[j] or k > k2max[j] # thetamax
1457
- #ka-=1
1458
- #elsif k < k1min[j] or k < k2min[j] # thetamin
1459
- #ka+=1
1460
- #else
1461
- #raise "Got lost!"
1462
- #end
1463
- #ia10 = torphi_const1[j,ka]
1464
- #ia10 = 0 if ia10==1
1465
- #ia10 = ysize - 1 if ia10 == ysize
1466
- #ia20 = torphi_const2[j,ka]
1467
- #ia20 = 0 if ia20==1
1468
- #ia20 = ysize - 1 if ia20 == ysize
1469
- #end
1470
- #ni = n*sign21+ia10
1471
- ## First end
1472
- #if ni==ia10
1473
- #xs = x1[j,ka]
1474
- #ys = y1[j,ka]
1475
- #zs = z1[j,ka]
1476
- #fs = field1[j,ka]
1477
- ## Second ed
1478
- #elsif ni*sign21 == ia20*sign21 - 1
1479
- #xs = x2[j,ka]
1480
- #ys = y2[j,ka]
1481
- #zs = z2[j,ka]
1482
- #fs = field2[j,ka]
1483
- ## Connecting line
1484
- #else
1485
- #tphi = cyls[2,ni,j,ka]
1486
- #s = Math.sin(tphi)
1487
- #c = Math.cos(tphi)
1488
- #r = cyls[0,ni,j,ka]
1489
- #xs = r*c
1490
- #ys = r*s
1491
- #zs = cyls[1,ni,j,ka]
1492
- #fs = field[ni,j,ka]
1493
- #end
1494
-
1495
-
1496
- #surfaces[j,k].each do |m|
1497
- #o = lineorder[j,k]
1498
- #xsurf[m][o,n] = xs
1499
- #ysurf[m][o,n] = ys
1500
- #zsurf[m][o,n] = zs
1501
- #fieldsurf[m][o,n] = fs
1502
- #end
1503
-
1504
- #n+=1
1505
- #end
1506
- #end
1507
-
1508
-
1509
- #next
1510
-
1511
- ## Fill in from the first poloidal plane to the second poloidal plane or the edge of the box, which ever is closer
1512
- #if [j1min[k], j1max[k]].include? j or (false and [k1min[j],k1max[j]].include? k)
1513
- #m = (j==j1min[k] ? 1 : 0)
1514
-
1515
- #xsurf[m][j,k,0] = r*c# X (not gs2 x!)
1516
- #ysurf[m][j,k,0] = r*s# Y (not gs2 y!)
1517
- #zsurf[m][j,k,0] = z# Z
1518
- #fieldsurf[m][j,k,0] = field[i1,j,k]
1519
- #sign21 = ((i2-i1)/(i2-i1).abs).round
1520
- ##ep sign21; gets
1521
- #n=1
1522
- ##while (i1+n*sign21)%ysize==i1+n*sign21 and (i1+n*sign21)*sign21 < i2*sign21
1523
- #while (i10+n*sign21)%ysize==i10+n*sign21 and (i10+n*sign21)*sign21 < i20*sign21
1524
- #ni = n*sign21+i10
1525
- ##ep [[2,ni,j,k], cyls.shape]
1526
- #tphi = cyls[2,ni,j,k]
1527
- #s = Math.sin(tphi)
1528
- #c = Math.cos(tphi)
1529
- #r = cyls[0,ni,j,k]
1530
- #z = cyls[1,ni,j,k]
1531
- #xsurf[m][j,k,n] = r*c# X (not gs2 x!)
1532
- #ysurf[m][j,k,n] = r*s# Y (not gs2 y!)
1533
- #zsurf[m][j,k,n] = z# Z
1534
- #fieldsurf[m][j,k,n] = field[ni,j,k]
1535
- #n+=1
1536
- #end
1537
- #end
1538
- ##end
1539
- ##if i2%ysize==i2 || i2==-1
1540
- #if i20%ysize==i20
1541
- #r = cyls[0,i2,j,k]
1542
- #z = cyls[1,i2,j,k]
1543
- #tphi = poloidal_planes[1]
1544
- #s = Math.sin(tphi)
1545
- #c = Math.cos(tphi)
1546
- #x2[j,k] = r*c# X (not gs2 x!)
1547
- #y2[j,k] = r*s# Y (not gs2 y!)
1548
- #z2[j,k] = z# Z
1549
- ##ep [2,(i2+1)%ysize,j,k, cyls.shape]
1550
- #d2 = cyls[2,(i2+1)%ysize,j,k] - tphi
1551
- #d1 = tphi - cyls[2,i2,j,k]
1552
- #dfac = d1 / (d1+d2)
1553
- #field2[j,k] = field[i2,j,k] * (1-dfac) + field[i2%ysize,j,k] * dfac
1554
- #end
1555
- #next
1556
- ##if (i1%ysize==i1 || i1==-1) and ( [0,shp[2]-1].include? j or (false and [k1min[j],k1max[j]].include? k))
1557
- #if i10%ysize==i10 and ( [j1min[k], j1max[k]].include? j or (false and [k1min[j],k1max[j]].include? k))
1558
- #m = (j==j1min[k] ? 1 : 0)
1559
- #xsurf[m][j,k,n] = x2[j,k]
1560
- #ysurf[m][j,k,n] = y2[j,k]
1561
- #zsurf[m][j,k,n] = z2[j,k]
1562
- #fieldsurf[m][j,k,n] = field2[j,k]
1563
- #elsif false
1564
- #if [0,shp[2]-1].include? j or [k2min[j],k2max[j]].include? k
1565
- #sign12 = ((i1-i2)/(i1-i2).abs).round
1566
- #xouter[j,k,0] = x2[j,k]
1567
- #youter[j,k,0] = y2[j,k]
1568
- #zouter[j,k,0] = z2[j,k]
1569
- #fieldouter[j,k,0] = field2[j,k]
1570
- ##ep sign12; gets
1571
-
1572
- ## Fill in from the first poloidal plane to the second poloidal plane or the edge of the box, which ever is closer
1573
- #n=1
1574
- #while (i2+n*sign12)%ysize==i2+n*sign12 and (i2+n*sign12)*sign12 < i1*sign12
1575
- #ni = n*sign12+i2
1576
- ##ep [[1,ni,j,k], cyls.shape]
1577
- #tphi = cyls[2,ni,j,k]
1578
- #s = Math.sin(tphi)
1579
- #c = Math.cos(tphi)
1580
- #r = cyls[0,ni,j,k]
1581
- #z = cyls[1,ni,j,k]
1582
- #xouter[j,k,n] = r*c# X (not gs2 x!)
1583
- #youter[j,k,n] = r*s# Y (not gs2 y!)
1584
- #zouter[j,k,n] = z# Z
1585
- #fieldouter[j,k,n] = field[ni,j,k]
1586
- #n+=1
1587
- #end
1588
- #end
1589
-
1590
- ##end
1591
- #end
1592
- #end
1593
- #end
1594
- #ep xsurf[3]
1595
- #ep xsurf[2]
1596
- #kit1 = GraphKit.quick_create([x1,y1,z1,field1])
1597
- #kit2 = GraphKit.quick_create([x2,y2,z2,field2])
1598
- #kits = 4.times.map{|i| GraphKit.quick_create([xsurf[i],ysurf[i],zsurf[i],fieldsurf[i]])}
1599
- #return kit1 + kit2 + kits.sum
1600
- #end
1601
-
1602
-
1603
-
1604
-
1605
-
1606
- def phi_magnifying_glass_graphkit(options={})
1607
- case options[:command]
1608
- when :help
1609
- return "The potential as a function of cartesian coordinates, plus a close up section."
1610
- when :options
1611
- return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :magnify]
1612
- end
1613
-
1614
- ops = options.dup
1615
- ops.delete(:thetamin)
1616
- ops.delete(:thetamax)
1617
- flux_tube = phi_real_space_surface_graphkit(ops)
1618
- options[:thetamin] #= options[:theta_magnify]
1619
- options[:thetamax] #= options[:theta_magnify] + 4
1620
- #options[:torphi_values] = [:options
1621
- #correct_3d_options(options)
1622
- #factors = geometric_factors_gsl_tensor(options)
1623
- #xfac = 1.0 / options[:rho_star_actual]
1624
- #yfac = options[:rhoc_actual] / options[:q_actual] / options[:rho_star_actual]
1625
- #y = gsl_vector('y', options)
1626
- #x = gsl_vector('x', options)
1627
- #kmin = 0 #options[:thetamin]
1628
- #kmax = -1 #options[:thetamax]
1629
-
1630
- #ep 'factors.shape', factors.shape
1631
- #torphi1 = y[-1]/yfac - factors[2,kmin] - x[-1]/xfac * factors[5,kmin]
1632
- #torphi2 = factors[2,kmax]
1633
- cyls = cylindrical_coordinates_gsl_tensor(options)
1634
- #torphi1 = cyls[2,0,true,0].max
1635
- torphi1 = cyls[2,0,true,-1].max
1636
- torphi2 = cyls[2,-1,true,-1].min
1637
- torphi3 = cyls[2,0,true,-1].max
1638
- torphi4 = cyls[2,-1,true,0].min
1639
- delta = 0.5
1640
- if torphi1 > torphi3
1641
- tv = [torphi1, [torphi1 + delta, torphi4].min]
1642
- else
1643
- tv = [torphi3, [torphi3 + delta, torphi2].min]
1644
- end
1645
-
1646
- ep 'torphiVaues', options[:torphi_values] = tv;
1647
-
1648
-
1649
- #ep options; gets
1650
- section = phi_real_space_standard_representation_graphkit(options)
1651
- #dR1 = (section.data.map{|dk|
1652
- #(dk.x.data.max**2 + dk.y.data.max**2)**0.5
1653
- #}.max +
1654
- #section.data.map{|dk|
1655
- #(dk.x.data.min**2 + dk.y.data.min**2)**0.5
1656
- #}.min)/2
1657
- #z1max = section.data.map{|dk| dk.z.data.max}.max
1658
- #z1min = section.data.map{|dk| dk.z.data.min}.min )/2
1659
-
1660
- magnify = options[:magnify]
1661
-
1662
- #p section; gets
1663
- blacked_out = section.dup
1664
- fmin = section.data.map{|dk| dk.f.data.min}.min
1665
- if magnify > 2
1666
- blacked_out.data.each{|dk|
1667
- dk.x.data *= 1.05
1668
- dk.y.data *= 1.05
1669
- dk.z.data *= 1.05
1670
- dk.f.data.fill!(fmin)
1671
- #dk.gp.with = 'p lc rgb "#000000" ps 3.0 '
1672
- }
1673
- end
1674
- section.data.each do |dk|
1675
- magnify = options[:magnify]
1676
- #ep dk.x.data.shape
1677
- dk.x.data *= magnify
1678
- dk.y.data *= magnify
1679
- dk.z.data *= magnify
1680
- end
1681
- dR = (section.data.map{|dk|
1682
- (dk.x.data.max**2 + dk.y.data.max**2)**0.5
1683
- }.max +
1684
- section.data.map{|dk|
1685
- (dk.x.data.min**2 + dk.y.data.min**2)**0.5
1686
- }.min)/2
1687
-
1688
- #xmag = (section.data.map{|dk| dk.x.data.max}.max +
1689
- #section.data.map{|dk| dk.x.data.min}.min)/2
1690
- #ymag = (section.data.map{|dk| dk.y.data.max}.max +
1691
- #section.data.map{|dk| dk.y.data.min}.min)/2
1692
-
1693
- #ep 'dR', dR; gets
1694
- #dy = (section.data.map{|dk| dk.y.data.max}.max +
1695
- #section.data.map{|dk| dk.y.data.min}.min)/2
1696
- dz = (section.data.map{|dk| dk.z.data.max}.max +
1697
- section.data.map{|dk| dk.z.data.min}.min )/2
1698
- section.data.each do |dk|
1699
- #dk.x.data -= options[:Rgeo]*(magnify* (1.0-Math.exp(-(magnify-1)**2)))*c/1.2
1700
- #dk.x.data -= (options[:Rgeo]-options[:rhoc_actual])*([magnify-2, 0].max)*c* (1.0-Math.exp(-(magnify-1)**2))
1701
- ep 'rhoc', options[:rhoc_actual]
1702
- #dR = options[:Rgeo]*(0.75*magnify - magnify * (1.0 - options[:rhoc_actual]/options[:Rgeo]))* (1.0-Math.exp(-(magnify-1)**2))
1703
- c = Math.cos(tv[0])
1704
- s = Math.sin(tv[0])
1705
- #dR = options[:Rgeo]*(1.5 - magnify * (1.0 - options[:rhoc_actual]))* (1.0-Math.exp(-(magnify-1)**2))
1706
-
1707
- rout = 2.0
1708
- dk.x.data -= (dR - options[:Rgeo] * rout) * c* (1.0-Math.exp(-(magnify-1)**2))
1709
- #ep dk.x.data.shape; gets
1710
- #dk.y.data -= (options[:Rgeo]-options[:rhoc_actual])*([magnify-2, 0].max)*s* (1.0-Math.exp(-(magnify-1)**2))
1711
- dk.y.data -= (dR - options[:Rgeo] * rout) * s* (1.0-Math.exp(-(magnify-1)**2))
1712
- dk.z.data-=dz* (1.0-Math.exp(-(magnify-1)**2))
1713
- end
1714
- #return section
1715
- kit = flux_tube + section
1716
- kit.data.each{|dk| dk.gp.with = "pm3d"}
1717
- kit += blacked_out
1718
- kit.data.each{|dk| dk.gp.with = "pm3d"}
1719
- kit.xlabel = 'X'
1720
- ep phideg = tv[0]/Math::PI * 180
1721
- kit.gp.view = [",#{(180-phideg)%360},2.0", "equal xyz"]
1722
- kit.gp.hidden3d = ""
1723
- kit.gp.pm3d = "depthorder"
1724
- kit.xlabel = 'X (m)'
1725
- kit.ylabel = 'Y (m)'
1726
- kit.zlabel = "'Z (m)' rotate by 90"
1727
- kit.title = "3-D Potential"
1728
-
1729
- kit
1730
- end
1731
-
1732
-
1733
- def density_real_space_surface_graphkit(options={})
1734
- case options[:command]
1735
- when :help
1736
- return "The density as a function of cartesian coordinates, plotted on the six outer surfaces of constant x, y and theta."
1737
- when :options
1738
- return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :gs2_coordinate_factor, :xmax, :xmin, :ymax, :ymin, :thetamax, :thetamin, :ncopies]
1739
- else
1740
- return field_real_space_surface_graphkit(options.absorb({field_name: :density}))
1741
- end
1742
- end
1743
- def phi_real_space_surface_graphkit(options={})
1744
- case options[:command]
1745
- when :help
1746
- return "The potential as a function of cartesian coordinates, plotted on the six outer surfaces of constant x, y and theta."
1747
- when :options
1748
- return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :gs2_coordinate_factor, :xmax, :xmin, :ymax, :ymin, :thetamax, :thetamin, :ncopies]
1749
- else
1750
- return field_real_space_surface_graphkit(options.absorb({field_name: :phi}))
1751
- end
1752
- end
1753
-
1754
- def field_real_space_surface_graphkit(options={})
1755
- case options[:command]
1756
- when :help
1757
- return "The field options[:field_name] as a function of cartesian coordinates, plotted on the six outer surfaces of constant x, y and theta."
1758
- when :options
1759
- return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :gs2_coordinate_factor, :xmax, :xmin, :ymax, :ymin, :thetamax, :thetamin, :ncopies]
1760
- else
1761
- if options[:ncopies]
1762
- ops = options.dup
1763
- ops.delete(:ncopies)
1764
- return (options[:ncopies].times.map do |n|
1765
- ops[:ncopy] = n
1766
- field_real_space_surface_graphkit(ops)
1767
- end).sum
1768
- end
1769
- #zaxis = axiskit('field0_over_x_over_y', options)
1770
- #zaxis.data = zaxis.data.transpose
1771
- #shape = zaxis.data.shape
1772
- #carts = cartesian_coordinates_gsl_tensor(options)
1773
- field = options[:field] || field_real_space_gsl_tensor(options)
1774
- sides = [:max, :min]
1775
- kits = []
1776
- [:y, :x, :theta].each_with_index do |coord,i|
1777
- sides.each_with_index do |side,j|
1778
- raise unless i.kind_of? Integer
1779
- #return kit if coord + side == :xmax
1780
- options[:field] = field
1781
- options[:side] = side
1782
- options[:coordinate] = coord
1783
- kit = field_flux_tube_boundary_surface_graphkit(options)
1784
- kits.push kit
1785
- end
1786
- end
1787
- k = kits.reverse.sum
1788
- #k = kits[5] + kits[4] + kits[3] + kits[2] + kits[1] + kits[0]
1789
- #k = kits[5] + kits[4] + kits[1] + kits[0]
1790
- k.gp.pm3d = "depthorder"
1791
- kit = k
1792
- kit.data.each{|dk| dk.title = "notitle"}
1793
- #k.compress_datakits = true
1794
- if options[:gs2_coordinate_factor] and options[:gs2_coordinate_factor] == 1.0
1795
- kit.xlabel = 'x (rho_i)'
1796
- kit.ylabel = 'y (rho_i)'
1797
- kit.zlabel = "'theta' rotate by 90"
1798
- else
1799
- kit.xlabel = 'X (m)'
1800
- kit.ylabel = 'Y (m)'
1801
- kit.zlabel = "'Z (m)' rotate by 90"
1802
- end
1803
- kit.title = "3-D Potential"
1804
- return k
1805
-
1806
- end
1807
- end
1808
- def density_real_space_graphkit(options={})
1809
- case options[:command]
1810
- when :help
1811
- return "The potential as a function of cartesian coordinates"
1812
- when :options
1813
- return [:rgbformulae, :limit, :t_index]
1814
- else
1815
- kit = field_real_space_graphkit(options.absorb({field_name: :density}))
1816
- kit.title = 'Density'
1817
- kit
1818
- end
1819
- end
1820
- def phi_real_space_graphkit(options={})
1821
- case options[:command]
1822
- when :help
1823
- return "The potential as a function of cartesian coordinates"
1824
- when :options
1825
- return [:rgbformulae, :limit, :t_index]
1826
- else
1827
- return field_real_space_graphkit(options.absorb({field_name: :phi}))
1828
- end
1829
- end
1830
- def field_real_space_graphkit(options={})
1831
- case options[:command]
1832
- when :help
1833
- return "The field options[:field_name] as a function of cartesian coordinates"
1834
- when :options
1835
- return [:rgbformulae, :limit, :t_index]
1836
- else
1837
- if options[:ncopies]
1838
- ops = options.dup
1839
- ops.delete(:ncopies)
1840
- return (options[:ncopies].times.map do |n|
1841
- ops[:ncopy] = n
1842
- field_real_space_graphkit(ops)
1843
- end).sum
1844
- end
1845
- #zaxis = axiskit('field0_over_x_over_y', options)
1846
- #zaxis.data = zaxis.data.transpose
1847
- #shape = zaxis.data.shape
1848
- #carts = cartesian_coordinates_gsl_tensor(options)
1849
- field = field_real_space_gsl_tensor(options)
1850
- if options[:cyl]
1851
- carts = cylindrical_coordinates_gsl_tensor(options) #.transpose(0,1,2,3)
1852
- else
1853
- carts = cartesian_coordinates_gsl_tensor(options)
1854
- end
1855
-
1856
- newshape = carts.shape.slice(1..3)
1857
-
1858
- x = carts[0, false]; x.reshape!(*newshape)
1859
- y = carts[1, false]; y.reshape!(*newshape)
1860
- z = carts[2, false]; z.reshape!(*newshape)
1861
-
1862
- unless options[:cyl]
1863
- #x = x.transpose(2,1,0)
1864
- #y = y.transpose(2,1,0)
1865
- #z = z.transpose(2,1,0)
1866
- #field = field.transpose(2,1,0)
1867
- end
1868
-
1869
-
1870
- kit = GraphKit.autocreate({
1871
- x: GraphKit::AxisKit.autocreate({data: x, title: "X", units: "m"}),
1872
- y: GraphKit::AxisKit.autocreate({data: y, title: "Y", units: "m"}),
1873
- z: GraphKit::AxisKit.autocreate({data: z, title: "Z", units: "m"}),
1874
- f: GraphKit::AxisKit.autocreate({data: field, title: "Phi"})
1875
- })
1876
- # kit.xrange = [0,shape[0]]
1877
- # kit.yrange = [0,shape[1]]
1878
- kit.cbrange = options[:limit] if options[:limit]
1879
- kit.title = "Phi"
1880
- #kit.palette = "rgbformulae #{(options[:rgbformulae] or "-3,3,0")}"
1881
- #kit.view = "map"
1882
- kit.data[0].with = "pm3d"
1883
- #kit.gp.pm3d = "interpolate 2,2"
1884
- #kit.title = "Phi at the outboard midplane"
1885
- # kit.data[0].with = (options[:with] or 'pm3d palette')
1886
- kit.file_name = options[:graphkit_name]
1887
- kit
1888
- end
1889
- end
1890
- def phi_gs2_space_graphkit(options={})
1891
- case options[:command]
1892
- when :help
1893
- return "The potential as a function of y, x and theta"
1894
- when :options
1895
- return [:rgbformulae, :limit, :t_index]
1896
- else
1897
- #zaxis = axiskit('phi0_over_x_over_y', options)
1898
- #zaxis.data = zaxis.data.transpose
1899
- #shape = zaxis.data.shape
1900
- kit = GraphKit.autocreate({
1901
- x: GraphKit::AxisKit.autocreate({data: gsl_vector('y',options), title: "y", units: "rho_#{species_letter}"}),
1902
- y: AxisKit.autocreate({data: gsl_vector('x',options), title: "x", units: "rho_#{species_letter}"}),
1903
- z: GraphKit::AxisKit.autocreate({data: gsl_vector('theta',options), title: "theta"}),
1904
- f: GraphKit::AxisKit.autocreate({data: phi_real_space_gsl_tensor(options), title: "Phi"})
1905
- })
1906
- # kit.xrange = [0,shape[0]]
1907
- # kit.yrange = [0,shape[1]]
1908
- kit.cbrange = options[:limit] if options[:limit]
1909
- kit.title = "Phi"
1910
- #kit.palette = "rgbformulae #{(options[:rgbformulae] or "-3,3,0")}"
1911
- #kit.view = "map"
1912
- kit.data[0].with = "pm3d"
1913
- #kit.title = "Phi at the outboard midplane"
1914
- # kit.data[0].with = (options[:with] or 'pm3d palette')
1915
- kit.file_name = options[:graphkit_name]
1916
- kit
1917
- end
1918
- end
1919
- def phi0_vs_x_vs_y_graphkit(options={})
1920
- case options[:command]
1921
- when :help
1922
- return "The potential at the outboard midplane"
1923
- when :options
1924
- return [:rgbformulae, :limit, :xres, :x_resolution, :yres, :y_resolution, :no_zonal, :t_index]
1925
- else
1926
- zaxis = axiskit('phi0_over_x_over_y', options)
1927
- zaxis.data = zaxis.data.transpose
1928
- shape = zaxis.data.shape
1929
- kit = GraphKit.autocreate({x: GraphKit::AxisKit.autocreate({data: (GSL::Vector.alloc((0...shape[0]).to_a)/shape[0] - 0.5) * 2*Math::PI * (@x0 or @y0 * @jtwist / 2 / Math::PI / @shat), title: "x", units: "rho_#{species_letter}"}), y: AxisKit.autocreate({data: (GSL::Vector.alloc((0...shape[1]).to_a)/shape[1] - 0.5) * 2*Math::PI * @y0, title: "y", units: "rho_#{species_letter}"}), z: zaxis})
1930
- kit.zrange = options[:limit] if options[:limit]
1931
- kit.title = "Spectrum"
1932
- kit.palette = "rgbformulae #{(options[:rgbformulae] or "-3,3,0")}"
1933
- kit.gp.view = "map"
1934
- kit.gp.style = "data pm3d"
1312
+ # # Include extra points just outside
1313
+ # # if necessary
1314
+ # i10 = 0 if i1==-1 #
1315
+ # i20 = 0 if i2==-1
1316
+ # i10 = ysize - 1 if i1 == ysize
1317
+ # i20 = ysize - 1 if i2 == ysize
1318
+ # #if i1%ysize==i1 || i1==-1
1319
+ # if i10%ysize==i10
1320
+ # # First assign all the points on the first cut poloidal face
1321
+ # r = cyls[0,i10,j,k]
1322
+ # z = cyls[1,i10,j,k]
1323
+ # tphi = poloidal_planes[0]
1324
+ # #tphi = cyls[2,i1,j,k]
1325
+ # #ep ['tphi', tphi, 'i1', i1, cyls[2,i1,j,k]%(2*Math::PI), cyls[2,(i1+1)%ysize,j,k]%(2*Math::PI)]
1326
+ # s = Math.sin(tphi)
1327
+ # c = Math.cos(tphi)
1328
+ # x1p = x1[j,k] = r*c# X (not gs2 x!)
1329
+ # y1p = y1[j,k] = r*s# Y (not gs2 y!)
1330
+ # z1p = z1[j,k] = z# Z
1331
+ # #ep [2,(i1+1)%ysize,j,k, cyls.shape]
1332
+ # # I think this bit will be wrong
1333
+ # # when i1 = -1 or ysize - 1
1334
+ # # but it won't be a big error
1335
+ # # --- need to fix
1336
+ # #d2 = cyls[2,(i1+1)%ysize,j,k] - tphi
1337
+ # #d1 = tphi - cyls[2,i1,j,k]
1338
+ # #dfac = d1 / (d1+d2)
1339
+ # #f1p = field1[j,k] = field[i1,j,k] * (1-dfac) + field[i1%ysize,j,k] * dfac
1340
+ # f1p = (field1[j,k] = field[i1%ysize,j,k] + field[(i1+1)%ysize,j,k])/2.0
1341
+ # end
1342
+ # if i20%ysize==i20
1343
+ # r = cyls[0,i20,j,k]
1344
+ # z = cyls[1,i20,j,k]
1345
+ # tphi = poloidal_planes[1]
1346
+ # s = Math.sin(tphi)
1347
+ # c = Math.cos(tphi)
1348
+ # x2[j,k] = r*c# X (not gs2 x!)
1349
+ # y2[j,k] = r*s# Y (not gs2 y!)
1350
+ # z2[j,k] = z# Z
1351
+ # #ep [2,(i2+1)%ysize,j,k, cyls.shape]
1352
+ # #d2 = cyls[2,(i2+1)%ysize,j,k] - tphi
1353
+ # #d1 = tphi - cyls[2,i2,j,k]
1354
+ # #dfac = d1 / (d1+d2)
1355
+ # field2[j,k] = (field[i2%ysize,j,k] + field[(i2+1)%ysize,j,k])/2.0
1356
+ # #field2[j,k] = field[i2,j,k] * (1-dfac) + field[i2%ysize,j,k] * dfac
1357
+ # end
1358
+ # end
1359
+ # end
1360
+ # for j in 0...shp[2]
1361
+ # for k in 0...shp[3]
1362
+ # i10 = i1 = torphi_const1[j,k]
1363
+ # i20 = i2 = torphi_const2[j,k]
1364
+ # #ep ['i1', i1, 'i2', i2]
1365
+ #
1366
+ # # Include extra points just outside
1367
+ # # if necessary
1368
+ # i10 = 0 if i1==-1 #
1369
+ # i20 = 0 if i2==-1
1370
+ # i10 = ysize - 1 if i1 == ysize
1371
+ # i20 = ysize - 1 if i2 == ysize
1372
+ # if lineorder[j,k]
1373
+ # n=0
1374
+ # sign21 = ((i2-i1)/(i2-i1).abs).round
1375
+ # # Go from y on the first surface to
1376
+ # # y on the next surface
1377
+ # ep ['jk',j,k, (i10+n*sign21)*sign21 < i20*sign21]
1378
+ # while (i10+n*sign21)*sign21 < i20*sign21
1379
+ # ka = k
1380
+ # ia10 = i10
1381
+ # ia20 = i20
1382
+ # while (ia10+n*sign21)%ysize != ia10+n*sign21
1383
+ # ep [j,k,ka, 'ia10', ia10, ia10+n*sign21, lineorder[j,k], surfaces[j,k], 'n', n, 'ni', ia10 + n * sign21, 'ysize', ysize, 'max', k1max[j], k2max[j], 'min', k1min[j], k2min[j] ]
1384
+ # # We have left the flux surface...
1385
+ # # increase/decrease theta to get back in
1386
+ # if k > k1max[j] or k > k2max[j] # thetamax
1387
+ # #ka-=1
1388
+ # elsif k < k1min[j] or k < k2min[j] # thetamin
1389
+ # #ka+=1
1390
+ # else
1391
+ # #raise "Got lost!"
1392
+ # end
1393
+ # ia10 = torphi_const1[j,ka]
1394
+ # ia10 = 0 if ia10==1
1395
+ # ia10 = ysize - 1 if ia10 == ysize
1396
+ # ia20 = torphi_const2[j,ka]
1397
+ # ia20 = 0 if ia20==1
1398
+ # ia20 = ysize - 1 if ia20 == ysize
1399
+ # end
1400
+ # ni = n*sign21+ia10
1401
+ # # First end
1402
+ # if ni==ia10
1403
+ # xs = x1[j,ka]
1404
+ # ys = y1[j,ka]
1405
+ # zs = z1[j,ka]
1406
+ # fs = field1[j,ka]
1407
+ # # Second ed
1408
+ # elsif ni*sign21 == ia20*sign21 - 1
1409
+ # xs = x2[j,ka]
1410
+ # ys = y2[j,ka]
1411
+ # zs = z2[j,ka]
1412
+ # fs = field2[j,ka]
1413
+ # # Connecting line
1414
+ # else
1415
+ # tphi = cyls[2,ni,j,ka]
1416
+ # s = Math.sin(tphi)
1417
+ # c = Math.cos(tphi)
1418
+ # r = cyls[0,ni,j,ka]
1419
+ # xs = r*c
1420
+ # ys = r*s
1421
+ # zs = cyls[1,ni,j,ka]
1422
+ # fs = field[ni,j,ka]
1423
+ # end
1424
+ #
1425
+ # surfaces[j,k].each do |m|
1426
+ # o = lineorder[j,k]
1427
+ # xsurf[m][o,n] = xs
1428
+ # ysurf[m][o,n] = ys
1429
+ # zsurf[m][o,n] = zs
1430
+ # fieldsurf[m][o,n] = fs
1431
+ # end
1432
+ #
1433
+ # n+=1
1434
+ # end
1435
+ # end
1436
+ # next
1437
+ #
1438
+ # # Fill in from the first poloidal plane to the second poloidal plane or the edge of the box, which ever is closer
1439
+ # if [j1min[k], j1max[k]].include? j or (false and [k1min[j],k1max[j]].include? k)
1440
+ # m = (j==j1min[k] ? 1 : 0)
1441
+ #
1442
+ # xsurf[m][j,k,0] = r*c# X (not gs2 x!)
1443
+ # ysurf[m][j,k,0] = r*s# Y (not gs2 y!)
1444
+ # zsurf[m][j,k,0] = z# Z
1445
+ # fieldsurf[m][j,k,0] = field[i1,j,k]
1446
+ # sign21 = ((i2-i1)/(i2-i1).abs).round
1447
+ # #ep sign21; gets
1448
+ # n=1
1449
+ # #while (i1+n*sign21)%ysize==i1+n*sign21 and (i1+n*sign21)*sign21 < i2*sign21
1450
+ # while (i10+n*sign21)%ysize==i10+n*sign21 and (i10+n*sign21)*sign21 < i20*sign21
1451
+ # ni = n*sign21+i10
1452
+ # #ep [[2,ni,j,k], cyls.shape]
1453
+ # tphi = cyls[2,ni,j,k]
1454
+ # s = Math.sin(tphi)
1455
+ # c = Math.cos(tphi)
1456
+ # r = cyls[0,ni,j,k]
1457
+ # z = cyls[1,ni,j,k]
1458
+ # xsurf[m][j,k,n] = r*c# X (not gs2 x!)
1459
+ # ysurf[m][j,k,n] = r*s# Y (not gs2 y!)
1460
+ # zsurf[m][j,k,n] = z# Z
1461
+ # fieldsurf[m][j,k,n] = field[ni,j,k]
1462
+ # n+=1
1463
+ # end
1464
+ # end
1465
+ # #end
1466
+ # #if i2%ysize==i2 || i2==-1
1467
+ # if i20%ysize==i20
1468
+ # r = cyls[0,i2,j,k]
1469
+ # z = cyls[1,i2,j,k]
1470
+ # tphi = poloidal_planes[1]
1471
+ # s = Math.sin(tphi)
1472
+ # c = Math.cos(tphi)
1473
+ # x2[j,k] = r*c# X (not gs2 x!)
1474
+ # y2[j,k] = r*s# Y (not gs2 y!)
1475
+ # z2[j,k] = z# Z
1476
+ # #ep [2,(i2+1)%ysize,j,k, cyls.shape]
1477
+ # d2 = cyls[2,(i2+1)%ysize,j,k] - tphi
1478
+ # d1 = tphi - cyls[2,i2,j,k]
1479
+ # dfac = d1 / (d1+d2)
1480
+ # field2[j,k] = field[i2,j,k] * (1-dfac) + field[i2%ysize,j,k] * dfac
1481
+ # end
1482
+ # next
1483
+ # #if (i1%ysize==i1 || i1==-1) and ( [0,shp[2]-1].include? j or (false and [k1min[j],k1max[j]].include? k))
1484
+ # if i10%ysize==i10 and ( [j1min[k], j1max[k]].include? j or (false and [k1min[j],k1max[j]].include? k))
1485
+ # m = (j==j1min[k] ? 1 : 0)
1486
+ # xsurf[m][j,k,n] = x2[j,k]
1487
+ # ysurf[m][j,k,n] = y2[j,k]
1488
+ # zsurf[m][j,k,n] = z2[j,k]
1489
+ # fieldsurf[m][j,k,n] = field2[j,k]
1490
+ # elsif false
1491
+ # if [0,shp[2]-1].include? j or [k2min[j],k2max[j]].include? k
1492
+ # sign12 = ((i1-i2)/(i1-i2).abs).round
1493
+ # xouter[j,k,0] = x2[j,k]
1494
+ # youter[j,k,0] = y2[j,k]
1495
+ # zouter[j,k,0] = z2[j,k]
1496
+ # fieldouter[j,k,0] = field2[j,k]
1497
+ # #ep sign12; gets
1498
+ #
1499
+ # # Fill in from the first poloidal plane to the second poloidal plane or the edge of the box, which ever is closer
1500
+ # n=1
1501
+ # while (i2+n*sign12)%ysize==i2+n*sign12 and (i2+n*sign12)*sign12 < i1*sign12
1502
+ # ni = n*sign12+i2
1503
+ # #ep [[1,ni,j,k], cyls.shape]
1504
+ # tphi = cyls[2,ni,j,k]
1505
+ # s = Math.sin(tphi)
1506
+ # c = Math.cos(tphi)
1507
+ # r = cyls[0,ni,j,k]
1508
+ # z = cyls[1,ni,j,k]
1509
+ # xouter[j,k,n] = r*c# X (not gs2 x!)
1510
+ # youter[j,k,n] = r*s# Y (not gs2 y!)
1511
+ # zouter[j,k,n] = z# Z
1512
+ # fieldouter[j,k,n] = field[ni,j,k]
1513
+ # n+=1
1514
+ # end
1515
+ # end
1516
+ # end
1517
+ # end
1518
+ # end
1519
+ # end
1520
+ # ep xsurf[3]
1521
+ # ep xsurf[2]
1522
+ # kit1 = GraphKit.quick_create([x1,y1,z1,field1])
1523
+ # kit2 = GraphKit.quick_create([x2,y2,z2,field2])
1524
+ # kits = 4.times.map{|i| GraphKit.quick_create([xsurf[i],ysurf[i],zsurf[i],fieldsurf[i]])}
1525
+ # return kit1 + kit2 + kits.sum
1526
+ # end
1527
+
1528
+ def phi_magnifying_glass_graphkit(options={})
1529
+ case options[:command]
1530
+ when :help
1531
+ return "The potential as a function of cartesian coordinates, plus a close up section."
1532
+ when :options
1533
+ return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :xmax, :xmin, :thetamax, :thetamin, :magnify]
1534
+ end
1535
+
1536
+ ops = options.dup
1537
+ ops.delete(:thetamin)
1538
+ ops.delete(:thetamax)
1539
+ flux_tube = phi_real_space_surface_graphkit(ops)
1540
+ options[:thetamin] #= options[:theta_magnify]
1541
+ options[:thetamax] #= options[:theta_magnify] + 4
1542
+ #options[:torphi_values] = [:options
1543
+ #correct_3d_options(options)
1544
+ #factors = geometric_factors_gsl_tensor(options)
1545
+ #xfac = 1.0 / options[:rho_star_actual]
1546
+ #yfac = options[:rhoc_actual] / options[:q_actual] / options[:rho_star_actual]
1547
+ #y = gsl_vector('y', options)
1548
+ #x = gsl_vector('x', options)
1549
+ #kmin = 0 #options[:thetamin]
1550
+ #kmax = -1 #options[:thetamax]
1551
+
1552
+ #ep 'factors.shape', factors.shape
1553
+ #torphi1 = y[-1]/yfac - factors[2,kmin] - x[-1]/xfac * factors[5,kmin]
1554
+ #torphi2 = factors[2,kmax]
1555
+ cyls = cylindrical_coordinates_gsl_tensor(options)
1556
+ #torphi1 = cyls[2,0,true,0].max
1557
+ torphi1 = cyls[2,0,true,-1].max
1558
+ torphi2 = cyls[2,-1,true,-1].min
1559
+ torphi3 = cyls[2,0,true,-1].max
1560
+ torphi4 = cyls[2,-1,true,0].min
1561
+ delta = 0.5
1562
+ if torphi1 > torphi3
1563
+ tv = [torphi1, [torphi1 + delta, torphi4].min]
1564
+ else
1565
+ tv = [torphi3, [torphi3 + delta, torphi2].min]
1566
+ end
1567
+
1568
+ ep 'torphiVaues', options[:torphi_values] = tv;
1569
+
1570
+
1571
+ #ep options; gets
1572
+ section = phi_real_space_standard_representation_graphkit(options)
1573
+ #dR1 = (section.data.map{|dk|
1574
+ #(dk.x.data.max**2 + dk.y.data.max**2)**0.5
1575
+ #}.max +
1576
+ #section.data.map{|dk|
1577
+ #(dk.x.data.min**2 + dk.y.data.min**2)**0.5
1578
+ #}.min)/2
1579
+ #z1max = section.data.map{|dk| dk.z.data.max}.max
1580
+ #z1min = section.data.map{|dk| dk.z.data.min}.min )/2
1581
+
1582
+ magnify = options[:magnify]
1583
+
1584
+ #p section; gets
1585
+ blacked_out = section.dup
1586
+ fmin = section.data.map{|dk| dk.f.data.min}.min
1587
+ if magnify > 2
1588
+ blacked_out.data.each{|dk|
1589
+ dk.x.data *= 1.05
1590
+ dk.y.data *= 1.05
1591
+ dk.z.data *= 1.05
1592
+ dk.f.data.fill!(fmin)
1593
+ #dk.gp.with = 'p lc rgb "#000000" ps 3.0 '
1594
+ }
1595
+ end
1596
+ section.data.each do |dk|
1597
+ magnify = options[:magnify]
1598
+ #ep dk.x.data.shape
1599
+ dk.x.data *= magnify
1600
+ dk.y.data *= magnify
1601
+ dk.z.data *= magnify
1602
+ end
1603
+ dR = (section.data.map{|dk|
1604
+ (dk.x.data.max**2 + dk.y.data.max**2)**0.5
1605
+ }.max +
1606
+ section.data.map{|dk|
1607
+ (dk.x.data.min**2 + dk.y.data.min**2)**0.5
1608
+ }.min)/2
1609
+
1610
+ #xmag = (section.data.map{|dk| dk.x.data.max}.max +
1611
+ #section.data.map{|dk| dk.x.data.min}.min)/2
1612
+ #ymag = (section.data.map{|dk| dk.y.data.max}.max +
1613
+ #section.data.map{|dk| dk.y.data.min}.min)/2
1614
+
1615
+ #ep 'dR', dR; gets
1616
+ #dy = (section.data.map{|dk| dk.y.data.max}.max +
1617
+ #section.data.map{|dk| dk.y.data.min}.min)/2
1618
+ dz = (section.data.map{|dk| dk.z.data.max}.max +
1619
+ section.data.map{|dk| dk.z.data.min}.min )/2
1620
+ section.data.each do |dk|
1621
+ #dk.x.data -= options[:Rgeo]*(magnify* (1.0-Math.exp(-(magnify-1)**2)))*c/1.2
1622
+ #dk.x.data -= (options[:Rgeo]-options[:rhoc_actual])*([magnify-2, 0].max)*c* (1.0-Math.exp(-(magnify-1)**2))
1623
+ ep 'rhoc', options[:rhoc_actual]
1624
+ #dR = options[:Rgeo]*(0.75*magnify - magnify * (1.0 - options[:rhoc_actual]/options[:Rgeo]))* (1.0-Math.exp(-(magnify-1)**2))
1625
+ c = Math.cos(tv[0])
1626
+ s = Math.sin(tv[0])
1627
+ #dR = options[:Rgeo]*(1.5 - magnify * (1.0 - options[:rhoc_actual]))* (1.0-Math.exp(-(magnify-1)**2))
1628
+
1629
+ rout = 2.0
1630
+ dk.x.data -= (dR - options[:Rgeo] * rout) * c* (1.0-Math.exp(-(magnify-1)**2))
1631
+ #ep dk.x.data.shape; gets
1632
+ #dk.y.data -= (options[:Rgeo]-options[:rhoc_actual])*([magnify-2, 0].max)*s* (1.0-Math.exp(-(magnify-1)**2))
1633
+ dk.y.data -= (dR - options[:Rgeo] * rout) * s* (1.0-Math.exp(-(magnify-1)**2))
1634
+ dk.z.data-=dz* (1.0-Math.exp(-(magnify-1)**2))
1635
+ end
1636
+ #return section
1637
+ kit = flux_tube + section
1638
+ kit.data.each{|dk| dk.gp.with = "pm3d"}
1639
+ kit += blacked_out
1640
+ kit.data.each{|dk| dk.gp.with = "pm3d"}
1641
+ kit.xlabel = 'X'
1642
+ ep phideg = tv[0]/Math::PI * 180
1643
+ kit.gp.view = [",#{(180-phideg)%360},2.0", "equal xyz"]
1644
+ kit.gp.hidden3d = ""
1645
+ kit.gp.pm3d = "depthorder"
1646
+ kit.xlabel = 'X (m)'
1647
+ kit.ylabel = 'Y (m)'
1648
+ kit.zlabel = "'Z (m)' rotate by 90"
1649
+ kit.title = "3-D Potential"
1650
+
1651
+ kit
1652
+ end
1653
+
1654
+ def density_real_space_surface_graphkit(options={})
1655
+ case options[:command]
1656
+ when :help
1657
+ return "The density as a function of cartesian coordinates, plotted on the six outer surfaces of constant x, y and theta."
1658
+ when :options
1659
+ return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :gs2_coordinate_factor, :xmax, :xmin, :ymax, :ymin, :thetamax, :thetamin, :ncopies]
1660
+ else
1661
+ return field_real_space_surface_graphkit(options.absorb({field_name: :density}))
1662
+ end
1663
+ end
1664
+
1665
+ def phi_real_space_surface_graphkit(options={})
1666
+ case options[:command]
1667
+ when :help
1668
+ return "The potential as a function of cartesian coordinates, plotted on the six outer surfaces of constant x, y and theta."
1669
+ when :options
1670
+ return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :gs2_coordinate_factor, :xmax, :xmin, :ymax, :ymin, :thetamax, :thetamin, :ncopies]
1671
+ else
1672
+ return field_real_space_surface_graphkit(options.absorb({field_name: :phi}))
1673
+ end
1674
+ end
1675
+
1676
+ def field_real_space_surface_graphkit(options={})
1677
+ case options[:command]
1678
+ when :help
1679
+ return "The field options[:field_name] as a function of cartesian coordinates, plotted on the six outer surfaces of constant x, y and theta."
1680
+ when :options
1681
+ return [:Rgeo, :n0, :rho_star, :t_index, :nakx, :naky, :gs2_coordinate_factor, :xmax, :xmin, :ymax, :ymin, :thetamax, :thetamin, :ncopies]
1682
+ else
1683
+ if options[:ncopies]
1684
+ ops = options.dup
1685
+ ops.delete(:ncopies)
1686
+ return (options[:ncopies].times.map do |n|
1687
+ ops[:ncopy] = n
1688
+ field_real_space_surface_graphkit(ops)
1689
+ end).sum
1690
+ end
1691
+ #zaxis = axiskit('field0_over_x_over_y', options)
1692
+ #zaxis.data = zaxis.data.transpose
1693
+ #shape = zaxis.data.shape
1694
+ #carts = cartesian_coordinates_gsl_tensor(options)
1695
+ field = options[:field] || field_real_space_gsl_tensor(options)
1696
+ sides = [:max, :min]
1697
+ kits = []
1698
+ [:y, :x, :theta].each_with_index do |coord,i|
1699
+ sides.each_with_index do |side,j|
1700
+ raise unless i.kind_of? Integer
1701
+ #return kit if coord + side == :xmax
1702
+ options[:field] = field
1703
+ options[:side] = side
1704
+ options[:coordinate] = coord
1705
+ kit = field_flux_tube_boundary_surface_graphkit(options)
1706
+ kits.push kit
1707
+ end
1708
+ end
1709
+ k = kits.reverse.sum
1710
+ #k = kits[5] + kits[4] + kits[3] + kits[2] + kits[1] + kits[0]
1711
+ #k = kits[5] + kits[4] + kits[1] + kits[0]
1712
+ k.gp.pm3d = "depthorder"
1713
+ kit = k
1714
+ kit.data.each{|dk| dk.title = "notitle"}
1715
+ #k.compress_datakits = true
1716
+ if options[:gs2_coordinate_factor] and options[:gs2_coordinate_factor] == 1.0
1717
+ kit.xlabel = 'x (rho_i)'
1718
+ kit.ylabel = 'y (rho_i)'
1719
+ kit.zlabel = "'theta' rotate by 90"
1720
+ else
1721
+ kit.xlabel = 'X (m)'
1722
+ kit.ylabel = 'Y (m)'
1723
+ kit.zlabel = "'Z (m)' rotate by 90"
1724
+ end
1725
+ kit.title = "3-D Potential"
1726
+ return k
1727
+
1728
+ end
1729
+ end
1730
+
1731
+ def density_real_space_graphkit(options={})
1732
+ case options[:command]
1733
+ when :help
1734
+ return "The potential as a function of cartesian coordinates"
1735
+ when :options
1736
+ return [:rgbformulae, :limit, :t_index]
1737
+ else
1738
+ kit = field_real_space_graphkit(options.absorb({field_name: :density}))
1739
+ kit.title = 'Density'
1740
+ kit
1741
+ end
1742
+ end
1743
+
1744
+ def phi_real_space_graphkit(options={})
1745
+ case options[:command]
1746
+ when :help
1747
+ return "The potential as a function of cartesian coordinates"
1748
+ when :options
1749
+ return [:rgbformulae, :limit, :t_index]
1750
+ else
1751
+ return field_real_space_graphkit(options.absorb({field_name: :phi}))
1752
+ end
1753
+ end
1754
+
1755
+ def field_real_space_graphkit(options={})
1756
+ case options[:command]
1757
+ when :help
1758
+ return "The field options[:field_name] as a function of cartesian coordinates"
1759
+ when :options
1760
+ return [:rgbformulae, :limit, :t_index]
1761
+ else
1762
+ if options[:ncopies]
1763
+ ops = options.dup
1764
+ ops.delete(:ncopies)
1765
+ return (options[:ncopies].times.map do |n|
1766
+ ops[:ncopy] = n
1767
+ field_real_space_graphkit(ops)
1768
+ end).sum
1769
+ end
1770
+ #zaxis = axiskit('field0_over_x_over_y', options)
1771
+ #zaxis.data = zaxis.data.transpose
1772
+ #shape = zaxis.data.shape
1773
+ #carts = cartesian_coordinates_gsl_tensor(options)
1774
+ field = field_real_space_gsl_tensor(options)
1775
+ if options[:cyl]
1776
+ carts = cylindrical_coordinates_gsl_tensor(options) #.transpose(0,1,2,3)
1777
+ else
1778
+ carts = cartesian_coordinates_gsl_tensor(options)
1779
+ end
1780
+
1781
+ newshape = carts.shape.slice(1..3)
1782
+
1783
+ x = carts[0, false]; x.reshape!(*newshape)
1784
+ y = carts[1, false]; y.reshape!(*newshape)
1785
+ z = carts[2, false]; z.reshape!(*newshape)
1786
+
1787
+ unless options[:cyl]
1788
+ #x = x.transpose(2,1,0)
1789
+ #y = y.transpose(2,1,0)
1790
+ #z = z.transpose(2,1,0)
1791
+ #field = field.transpose(2,1,0)
1792
+ end
1793
+
1794
+
1795
+ kit = GraphKit.autocreate({
1796
+ x: GraphKit::AxisKit.autocreate({data: x, title: "X", units: "m"}),
1797
+ y: GraphKit::AxisKit.autocreate({data: y, title: "Y", units: "m"}),
1798
+ z: GraphKit::AxisKit.autocreate({data: z, title: "Z", units: "m"}),
1799
+ f: GraphKit::AxisKit.autocreate({data: field, title: "Phi"})
1800
+ })
1801
+ # kit.xrange = [0,shape[0]]
1802
+ # kit.yrange = [0,shape[1]]
1803
+ kit.cbrange = options[:limit] if options[:limit]
1804
+ kit.title = "Phi"
1805
+ #kit.palette = "rgbformulae #{(options[:rgbformulae] or "-3,3,0")}"
1806
+ #kit.view = "map"
1807
+ kit.data[0].with = "pm3d"
1808
+ #kit.gp.pm3d = "interpolate 2,2"
1809
+ #kit.title = "Phi at the outboard midplane"
1810
+ # kit.data[0].with = (options[:with] or 'pm3d palette')
1811
+ kit.file_name = options[:graphkit_name]
1812
+ kit
1813
+ end
1814
+ end
1815
+
1816
+ def phi_gs2_space_graphkit(options={})
1817
+ case options[:command]
1818
+ when :help
1819
+ return "The potential as a function of y, x and theta"
1820
+ when :options
1821
+ return [:rgbformulae, :limit, :t_index]
1822
+ else
1823
+ #zaxis = axiskit('phi0_over_x_over_y', options)
1824
+ #zaxis.data = zaxis.data.transpose
1825
+ #shape = zaxis.data.shape
1826
+ kit = GraphKit.autocreate({
1827
+ x: GraphKit::AxisKit.autocreate({data: gsl_vector('y',options), title: "y", units: "rho_#{species_letter}"}),
1828
+ y: AxisKit.autocreate({data: gsl_vector('x',options), title: "x", units: "rho_#{species_letter}"}),
1829
+ z: GraphKit::AxisKit.autocreate({data: gsl_vector('theta',options), title: "theta"}),
1830
+ f: GraphKit::AxisKit.autocreate({data: phi_real_space_gsl_tensor(options), title: "Phi"})
1831
+ })
1832
+ # kit.xrange = [0,shape[0]]
1833
+ # kit.yrange = [0,shape[1]]
1834
+ kit.cbrange = options[:limit] if options[:limit]
1835
+ kit.title = "Phi"
1836
+ #kit.palette = "rgbformulae #{(options[:rgbformulae] or "-3,3,0")}"
1837
+ #kit.view = "map"
1838
+ kit.data[0].with = "pm3d"
1839
+ #kit.title = "Phi at the outboard midplane"
1840
+ # kit.data[0].with = (options[:with] or 'pm3d palette')
1841
+ kit.file_name = options[:graphkit_name]
1842
+ kit
1843
+ end
1844
+ end
1845
+
1846
+ def phi0_vs_x_vs_y_graphkit(options={})
1847
+ case options[:command]
1848
+ when :help
1849
+ return "The potential at the outboard midplane"
1850
+ when :options
1851
+ return [:rgbformulae, :limit, :xres, :x_resolution, :yres, :y_resolution, :no_zonal, :t_index]
1852
+ else
1853
+ zaxis = axiskit('phi0_over_x_over_y', options)
1854
+ zaxis.data = zaxis.data.transpose
1855
+ shape = zaxis.data.shape
1856
+ kit = GraphKit.autocreate({x: GraphKit::AxisKit.autocreate({data: (GSL::Vector.alloc((0...shape[0]).to_a)/shape[0] - 0.5) * 2*Math::PI * (@x0 or @y0 * @jtwist / 2 / Math::PI / @shat), title: "x", units: "rho_#{species_letter}"}), y: AxisKit.autocreate({data: (GSL::Vector.alloc((0...shape[1]).to_a)/shape[1] - 0.5) * 2*Math::PI * @y0, title: "y", units: "rho_#{species_letter}"}), z: zaxis})
1857
+ kit.zrange = options[:limit] if options[:limit]
1858
+ kit.title = "Spectrum"
1859
+ kit.palette = "rgbformulae #{(options[:rgbformulae] or "-3,3,0")}"
1860
+ kit.gp.view = "map"
1861
+ kit.gp.style = "data pm3d"
1935
1862
  kit.gp.size = "ratio #{@y0 / (@x0 or @y0 * @jtwist / 2 / Math::PI / @shat)}"
1936
- kit.title = "Phi at theta = 0, t = #{sprintf("%.3f" ,list(:t)[options[:t_index]])}"
1937
- # kit.data[0].with = (options[:with] or 'pm3d palette')
1938
- kit.file_name = options[:graphkit_name]
1939
- kit
1940
- end
1941
- end
1942
-
1943
- def growth_rate_by_mode_vs_time_graphkit(options={})
1944
- options[:direction] = :mode
1945
- growth_rate_by_kxy_or_mode_vs_time_graphkit(options)
1946
- end
1947
-
1948
- def growth_rate_by_kx_vs_time_graphkit(options={})
1949
- options[:direction] = :kx
1950
- growth_rate_by_kxy_or_mode_vs_time_graphkit(options)
1951
- end
1952
-
1953
- def growth_rate_by_ky_vs_time_graphkit(options={})
1954
- options[:direction] = :ky
1955
- growth_rate_by_kxy_or_mode_vs_time_graphkit(options)
1956
- end
1957
-
1958
- def growth_rate_by_kxy_or_mode_vs_time_graphkit(options={})
1959
- case options[:command]
1960
- when :help
1961
- return "'growth_rate_by_ky_vs_time' or 'growth_rate_by_kx_vs_time': Growth rate vs time for a given kx or ky, integrated over the other direction"
1962
- when :options
1963
- return [:ky, :ky_index, :kx, :kx_index]
1964
- else
1965
- kxy = options[:direction]
1966
- phiax = axiskit("growth_rate_by_#{kxy}_over_time", options)
1863
+ kit.title = "Phi at theta = 0, t = #{sprintf("%.3f" ,list(:t)[options[:t_index]])}"
1864
+ # kit.data[0].with = (options[:with] or 'pm3d palette')
1865
+ kit.file_name = options[:graphkit_name]
1866
+ kit
1867
+ end
1868
+ end
1869
+
1870
+ def growth_rate_by_mode_vs_time_graphkit(options={})
1871
+ options[:direction] = :mode
1872
+ growth_rate_by_kxy_or_mode_vs_time_graphkit(options)
1873
+ end
1874
+
1875
+ def growth_rate_by_kx_vs_time_graphkit(options={})
1876
+ options[:direction] = :kx
1877
+ growth_rate_by_kxy_or_mode_vs_time_graphkit(options)
1878
+ end
1879
+
1880
+ def growth_rate_by_ky_vs_time_graphkit(options={})
1881
+ options[:direction] = :ky
1882
+ growth_rate_by_kxy_or_mode_vs_time_graphkit(options)
1883
+ end
1884
+
1885
+ def growth_rate_by_kxy_or_mode_vs_time_graphkit(options={})
1886
+ case options[:command]
1887
+ when :help
1888
+ return "'growth_rate_by_ky_vs_time' or 'growth_rate_by_kx_vs_time': Growth rate vs time for a given kx or ky, integrated over the other direction"
1889
+ when :options
1890
+ return [:ky, :ky_index, :kx, :kx_index]
1891
+ else
1892
+ kxy = options[:direction]
1893
+ phiax = axiskit("growth_rate_by_#{kxy}_over_time", options)
1967
1894
  x = axiskit('t', options)
1968
- x.data = x.data.subvector(0, x.data.size-1)
1969
- kit = GraphKit.autocreate({x: x , y: phiax})
1970
- #kit.data[0].title = "Growth Rate: #{kxy} = #{options[kxy]}"
1971
- #kit.data[0].title = "gs2:#@run_name"
1895
+ x.data = x.data.subvector(0, x.data.size-1)
1896
+ kit = GraphKit.autocreate({x: x , y: phiax})
1897
+ #kit.data[0].title = "Growth Rate: #{kxy} = #{options[kxy]}"
1898
+ #kit.data[0].title = "gs2:#@run_name"
1972
1899
  # <MJL additions on 2013-09-19>
1973
- kxy_index = kxy + :_index
1974
- kit.data[0].title = "gs2:#@run_name, #{kxy}_index = #{options[kxy_index]}"
1900
+ kxy_index = kxy + :_index
1901
+ kit.data[0].title = "gs2:#@run_name, #{kxy}_index = #{options[kxy_index]}"
1975
1902
  # </MJL>
1976
- kit.data[0].with = "l" #"linespoints"
1977
- kit.file_name = options[:graphkit_name]
1978
- kit
1979
- end
1980
- end
1981
-
1982
- # <MJL additions on 2013-09-19>
1983
- def frequency_by_kx_vs_time_graphkit(options={})
1984
- options[:direction] = :kx
1985
- frequency_by_kxy_or_mode_vs_time_graphkit(options)
1986
- end
1987
-
1988
- def frequency_by_ky_vs_time_graphkit(options={})
1989
- options[:direction] = :ky
1990
- frequency_by_kxy_or_mode_vs_time_graphkit(options)
1991
- end
1992
-
1993
- def frequency_by_kxy_or_mode_vs_time_graphkit(options={})
1994
- case options[:command]
1995
- when :help
1996
- return "'frequency_by_ky_vs_time' or 'frequency_by_kx_vs_time': Real part of the frequency vs time for a given kx or ky, integrated over the other direction"
1997
- when :options
1998
- return [:ky, :ky_index, :kx, :kx_index]
1999
- else
2000
- raise "Frequencies are not available in non-linear mode" if @nonlinear_mode == "on"
2001
- kxy = options[:direction]
2002
- x_data = axiskit('t', options)
2003
- y_data = axiskit("frequency_by_#{kxy}_over_time", options)
2004
- kit = GraphKit.autocreate({x: x_data , y: y_data})
2005
- kxy_index = kxy + :_index
2006
- kit.data[0].title = "gs2:#@run_name, #{kxy}_index = #{options[kxy_index]}"
2007
- kit.data[0].with = "l" #"linespoints"
2008
- kit.file_name = options[:graphkit_name]
2009
- kit
1903
+ kit.data[0].with = "l" #"linespoints"
1904
+ kit.file_name = options[:graphkit_name]
1905
+ kit
2010
1906
  end
1907
+ end
1908
+
1909
+ def frequency_by_kx_vs_time_graphkit(options={})
1910
+ options[:direction] = :kx
1911
+ frequency_by_kxy_or_mode_vs_time_graphkit(options)
1912
+ end
1913
+
1914
+ def frequency_by_ky_vs_time_graphkit(options={})
1915
+ options[:direction] = :ky
1916
+ frequency_by_kxy_or_mode_vs_time_graphkit(options)
1917
+ end
1918
+
1919
+ def frequency_by_kxy_or_mode_vs_time_graphkit(options={})
1920
+ case options[:command]
1921
+ when :help
1922
+ return "'frequency_by_ky_vs_time' or 'frequency_by_kx_vs_time': Real part of the frequency vs time for a given kx or ky, integrated over the other direction"
1923
+ when :options
1924
+ return [:ky, :ky_index, :kx, :kx_index]
1925
+ else
1926
+ raise "Frequencies are not available in non-linear mode" if @nonlinear_mode == "on"
1927
+ kxy = options[:direction]
1928
+ x_data = axiskit('t', options)
1929
+ y_data = axiskit("frequency_by_#{kxy}_over_time", options)
1930
+ kit = GraphKit.autocreate({x: x_data , y: y_data})
1931
+ kxy_index = kxy + :_index
1932
+ kit.data[0].title = "gs2:#@run_name, #{kxy}_index = #{options[kxy_index]}"
1933
+ kit.data[0].with = "l" #"linespoints"
1934
+ kit.file_name = options[:graphkit_name]
1935
+ kit
2011
1936
  end
2012
- # </MJL>
1937
+ end
1938
+
1939
+ def es_heat_flux_by_mode_vs_time_graphkit(options={})
1940
+ options[:direction] = :mode
1941
+ es_heat_flux_by_kxy_or_mode_vs_time_graphkit(options)
1942
+ end
2013
1943
 
2014
- def es_heat_flux_by_mode_vs_time_graphkit(options={})
2015
- options[:direction] = :mode
2016
- es_heat_flux_by_kxy_or_mode_vs_time_graphkit(options)
2017
- end
2018
-
2019
- def es_heat_flux_by_kx_vs_time_graphkit(options={})
2020
- options[:direction] = :kx
2021
- es_heat_flux_by_kxy_or_mode_vs_time_graphkit(options)
2022
- end
2023
-
2024
- def es_heat_flux_by_ky_vs_time_graphkit(options={})
2025
- options[:direction] = :ky
2026
- es_heat_flux_by_kxy_or_mode_vs_time_graphkit(options)
2027
- end
2028
-
2029
- def es_heat_flux_by_kxy_or_mode_vs_time_graphkit(options={})
2030
- case options[:command]
2031
- when :help
2032
- return "'es_heat_flux_by_ky_vs_time' or 'es_heat_flux_by_kx_vs_time': Electrostatic Heat Flux vs Time for a given kx or ky, integrated over the other direction"
2033
- when :options
2034
- return [:ky, :ky_index, :kx, :kx_index, :species_index]
2035
- else
2036
- kxy = options[:direction]
2037
- nt_options = options.dup # 'no time' options
2038
- #nt_options.delete(:t_index) if nt_options[:t_index]
2039
- #nt_options.delete(:frame_index) if nt_options[:frame_index]
2040
- phiax = axiskit("es_heat_flux_by_#{kxy}_over_time", nt_options)
2041
- kit = GraphKit.autocreate({x: axiskit('t', options), y: phiax})
2042
- kit.data[0].title = "ES Heat Flux: #@run_name #{kxy} = #{options[kxy]}"
2043
- kit.log_axis = 'y'
2044
- #kit.data[0].title = "gs2:#@run_name"
2045
- kit.data[0].with = "l" #"linespoints"
2046
- kit.file_name = options[:graphkit_name]
2047
- kit
2048
- end
2049
- end
2050
- def phi2_by_mode_vs_time_graphkit(options={})
2051
- options[:direction] = :mode
2052
- phi2_by_kxy_or_mode_vs_time_graphkit(options)
2053
- end
2054
-
2055
- def phi2_by_kx_vs_time_graphkit(options={})
2056
- options[:direction] = :kx
2057
- phi2_by_kxy_or_mode_vs_time_graphkit(options)
2058
- end
2059
-
2060
- def phi2_by_ky_vs_time_graphkit(options={})
2061
- options[:direction] = :ky
2062
- phi2_by_kxy_or_mode_vs_time_graphkit(options)
2063
- end
2064
-
2065
- def phi2_by_kxy_or_mode_vs_time_graphkit(options={})
2066
- case options[:command]
2067
- when :help
2068
- return "'phi2_by_ky_vs_time' or 'phi2_by_kx_vs_time': Phi^2 over time for a given kx or ky, integrated over the other direction"
2069
- when :options
2070
- return [:ky, :ky_index, :kx, :kx_index]
2071
- else
2072
- kxy = options[:direction]
2073
-
2074
- # i.e. phi2_by_ky_vs_time or phi2_by_kx_vs_time or phi2_by_mode_vs_time
2075
-
2076
- nt_options = options.dup # 'no time' options
2077
- nt_options.delete(:t_index) if nt_options[:t_index]
2078
- nt_options.delete(:frame_index) if nt_options[:frame_index]
2079
- phiax = axiskit("phi2_by_#{kxy}_over_time", nt_options)
2080
- kit = GraphKit.autocreate({x: axiskit('t', options), y: phiax})
2081
- kit.data[0].title = "Phi^2 total: #{kxy} = #{options[kxy]}"
2082
- if options[:t_index]
2083
- array_element = options[:t_index_window] ? options[:t_index] - options[:t_index_window][0] : options[:t_index] - 1
2084
- # p phiax.data.size, array_element
2085
- # p options[:t_index], options[:t_index_window]
2086
- time = DataKit.autocreate({x: {data: GSL::Vector.alloc([list(:t)[options[:t_index]]])}, y: {data: GSL::Vector.alloc([phiax.data[array_element]]) } })
2087
- time.pointsize = 3.0
2088
- # p time
2089
- # kit.data[0].axes[:x].data = -kit.data[0].axes[:x].data
2090
- kit.data.push time
2091
- if options[:with_moving_efn] and kxy==:ky
2092
- tmax = kit.data[0].axes[:x].data[-1]
2093
- # p 'tmax', tmax
2094
-
2095
- theta_max = @g_exb * tmax * options[:ky] * 2 * Math::PI / list(:kx)[2]
2096
- kit.each_axiskit(:x) do |axiskit|
2097
- # p axiskit
2098
- axiskit.data = axiskit.data / tmax * theta_max - theta_max
2099
- end
2100
- end
2101
- end
2102
- if options[:norm]
2103
- xrange, yrange = kit.plot_area_size
2104
- kit.each_axiskit(:y) do |axiskit|
2105
- axiskit.data /= yrange[1] / (options[:height] or 1.0)
2106
- end
2107
- end
2108
- kit.log_axis = 'y'
2109
- #kit.data[0].title = "gs2:#@run_name"
2110
- kit.data[0].with = "l" #"linespoints"
2111
- kit.file_name = options[:graphkit_name]
2112
- kit
2113
- end
2114
- end
2115
-
2116
- def tpar2_by_mode_vs_time_graphkit(options={})
2117
- case options[:command]
2118
- when :help
2119
- return "'tpar2_by_ky_vs_time' or 'tpar2_by_kx_vs_time': tpar^2 over time for a given kx or ky, integrated over the other direction"
2120
- when :options
2121
- return [:ky, :ky_index, :kx, :kx_index]
2122
- else
2123
- kxy = :mode
2124
-
2125
- # i.e. tpar2_by_ky_vs_time or tpar2_by_kx_vs_time or tpar2_by_mode_vs_time
2126
-
2127
- nt_options = options.dup # 'no time' options
2128
- nt_options.delete(:t_index) if nt_options[:t_index]
2129
- nt_options.delete(:frame_index) if nt_options[:frame_index]
2130
- tparax = axiskit("tpar2_by_#{kxy}_over_time", nt_options)
2131
- kit = GraphKit.autocreate({x: axiskit('t', options), y: tparax})
2132
- kit.data[0].title = "Tpar^2 total: #{kxy} = #{options[kxy]}"
2133
- if options[:t_index]
2134
- array_element = options[:t_index_window] ? options[:t_index] - options[:t_index_window][0] : options[:t_index] - 1
2135
- # p tparax.data.size, array_element
2136
- # p options[:t_index], options[:t_index_window]
2137
- time = DataKit.autocreate({x: {data: GSL::Vector.alloc([list(:t)[options[:t_index]]])}, y: {data: GSL::Vector.alloc([tparax.data[array_element]]) } })
2138
- time.pointsize = 3.0
2139
- # p time
2140
- # kit.data[0].axes[:x].data = -kit.data[0].axes[:x].data
2141
- kit.data.push time
2142
- end
2143
- if options[:norm]
2144
- xrange, yrange = kit.plot_area_size
2145
- kit.each_axiskit(:y) do |axiskit|
2146
- axiskit.data /= yrange[1] / (options[:height] or 1.0)
2147
- end
2148
- end
2149
- kit.log_axis = 'y'
2150
- #kit.data[0].title = "gs2:#@run_name"
2151
- kit.data[0].with = "l" #"linespoints"
2152
- kit.file_name = options[:graphkit_name]
2153
- kit
2154
- end
2155
- end
2156
-
2157
- def tperp2_by_mode_vs_time_graphkit(options={})
2158
- case options[:command]
2159
- when :help
2160
- return "'tperp2_by_ky_vs_time' or 'tperp2_by_kx_vs_time': tperp^2 over time for a given kx or ky, integrated over the other direction"
2161
- when :options
2162
- return [:ky, :ky_index, :kx, :kx_index]
2163
- else
2164
- kxy = :mode
2165
-
2166
- # i.e. tperp2_by_ky_vs_time or tperp2_by_kx_vs_time or tperp2_by_mode_vs_time
2167
-
2168
- nt_options = options.dup # 'no time' options
2169
- nt_options.delete(:t_index) if nt_options[:t_index]
2170
- nt_options.delete(:frame_index) if nt_options[:frame_index]
2171
- tperpax = axiskit("tperp2_by_#{kxy}_over_time", nt_options)
2172
- kit = GraphKit.autocreate({x: axiskit('t', options), y: tperpax})
2173
- kit.data[0].title = "Tperp^2 total: #{kxy} = #{options[kxy]}"
2174
- if options[:t_index]
2175
- array_element = options[:t_index_window] ? options[:t_index] - options[:t_index_window][0] : options[:t_index] - 1
2176
- # p tparax.data.size, array_element
2177
- # p options[:t_index], options[:t_index_window]
2178
- time = DataKit.autocreate({x: {data: GSL::Vector.alloc([list(:t)[options[:t_index]]])}, y: {data: GSL::Vector.alloc([tperpax.data[array_element]]) } })
2179
- time.pointsize = 3.0
2180
- # p time
2181
- # kit.data[0].axes[:x].data = -kit.data[0].axes[:x].data
2182
- kit.data.push time
2183
- end
2184
- if options[:norm]
2185
- xrange, yrange = kit.plot_area_size
2186
- kit.each_axiskit(:y) do |axiskit|
2187
- axiskit.data /= yrange[1] / (options[:height] or 1.0)
2188
- end
2189
- end
2190
- kit.log_axis = 'y'
2191
- #kit.data[0].title = "gs2:#@run_name"
2192
- kit.data[0].with = "l" #"linespoints"
2193
- kit.file_name = options[:graphkit_name]
2194
- kit
2195
- end
2196
- end
1944
+ def es_heat_flux_by_kx_vs_time_graphkit(options={})
1945
+ options[:direction] = :kx
1946
+ es_heat_flux_by_kxy_or_mode_vs_time_graphkit(options)
1947
+ end
1948
+
1949
+ def es_heat_flux_by_ky_vs_time_graphkit(options={})
1950
+ options[:direction] = :ky
1951
+ es_heat_flux_by_kxy_or_mode_vs_time_graphkit(options)
1952
+ end
1953
+
1954
+ def es_heat_flux_by_kxy_or_mode_vs_time_graphkit(options={})
1955
+ case options[:command]
1956
+ when :help
1957
+ return "'es_heat_flux_by_ky_vs_time' or 'es_heat_flux_by_kx_vs_time': Electrostatic Heat Flux vs Time for a given kx or ky, integrated over the other direction"
1958
+ when :options
1959
+ return [:ky, :ky_index, :kx, :kx_index, :species_index]
1960
+ else
1961
+ kxy = options[:direction]
1962
+ nt_options = options.dup # 'no time' options
1963
+ #nt_options.delete(:t_index) if nt_options[:t_index]
1964
+ #nt_options.delete(:frame_index) if nt_options[:frame_index]
1965
+ phiax = axiskit("es_heat_flux_by_#{kxy}_over_time", nt_options)
1966
+ kit = GraphKit.autocreate({x: axiskit('t', options), y: phiax})
1967
+ kit.data[0].title = "ES Heat Flux: #@run_name #{kxy} = #{options[kxy]}"
1968
+ kit.log_axis = 'y'
1969
+ #kit.data[0].title = "gs2:#@run_name"
1970
+ kit.data[0].with = "l" #"linespoints"
1971
+ kit.file_name = options[:graphkit_name]
1972
+ kit
1973
+ end
1974
+ end
1975
+
1976
+ def phi2_by_mode_vs_time_graphkit(options={})
1977
+ options[:direction] = :mode
1978
+ phi2_by_kxy_or_mode_vs_time_graphkit(options)
1979
+ end
1980
+
1981
+ def phi2_by_kx_vs_time_graphkit(options={})
1982
+ options[:direction] = :kx
1983
+ phi2_by_kxy_or_mode_vs_time_graphkit(options)
1984
+ end
1985
+
1986
+ def phi2_by_ky_vs_time_graphkit(options={})
1987
+ options[:direction] = :ky
1988
+ phi2_by_kxy_or_mode_vs_time_graphkit(options)
1989
+ end
1990
+
1991
+ def phi2_by_kxy_or_mode_vs_time_graphkit(options={})
1992
+ case options[:command]
1993
+ when :help
1994
+ return "'phi2_by_ky_vs_time' or 'phi2_by_kx_vs_time': Phi^2 over time for a given kx or ky, integrated over the other direction"
1995
+ when :options
1996
+ return [:ky, :ky_index, :kx, :kx_index]
1997
+ else
1998
+ kxy = options[:direction]
1999
+
2000
+ # i.e. phi2_by_ky_vs_time or phi2_by_kx_vs_time or phi2_by_mode_vs_time
2001
+
2002
+ nt_options = options.dup # 'no time' options
2003
+ nt_options.delete(:t_index) if nt_options[:t_index]
2004
+ nt_options.delete(:frame_index) if nt_options[:frame_index]
2005
+ phiax = axiskit("phi2_by_#{kxy}_over_time", nt_options)
2006
+ kit = GraphKit.autocreate({x: axiskit('t', options), y: phiax})
2007
+ kit.data[0].title = "Phi^2 total: #{kxy} = #{options[kxy]}"
2008
+ if options[:t_index]
2009
+ array_element = options[:t_index_window] ? options[:t_index] - options[:t_index_window][0] : options[:t_index] - 1
2010
+ # p phiax.data.size, array_element
2011
+ # p options[:t_index], options[:t_index_window]
2012
+ time = DataKit.autocreate({x: {data: GSL::Vector.alloc([list(:t)[options[:t_index]]])}, y: {data: GSL::Vector.alloc([phiax.data[array_element]]) } })
2013
+ time.pointsize = 3.0
2014
+ # p time
2015
+ # kit.data[0].axes[:x].data = -kit.data[0].axes[:x].data
2016
+ kit.data.push time
2017
+ if options[:with_moving_efn] and kxy==:ky
2018
+ tmax = kit.data[0].axes[:x].data[-1]
2019
+ # p 'tmax', tmax
2020
+
2021
+ theta_max = @g_exb * tmax * options[:ky] * 2 * Math::PI / list(:kx)[2]
2022
+ kit.each_axiskit(:x) do |axiskit|
2023
+ # p axiskit
2024
+ axiskit.data = axiskit.data / tmax * theta_max - theta_max
2025
+ end
2026
+ end
2027
+ end
2028
+ if options[:norm]
2029
+ xrange, yrange = kit.plot_area_size
2030
+ kit.each_axiskit(:y) do |axiskit|
2031
+ axiskit.data /= yrange[1] / (options[:height] or 1.0)
2032
+ end
2033
+ end
2034
+ kit.log_axis = 'y'
2035
+ #kit.data[0].title = "gs2:#@run_name"
2036
+ kit.data[0].with = "l" #"linespoints"
2037
+ kit.file_name = options[:graphkit_name]
2038
+ kit
2039
+ end
2040
+ end
2041
+
2042
+ def tpar2_by_mode_vs_time_graphkit(options={})
2043
+ case options[:command]
2044
+ when :help
2045
+ return "'tpar2_by_ky_vs_time' or 'tpar2_by_kx_vs_time': tpar^2 over time for a given kx or ky, integrated over the other direction"
2046
+ when :options
2047
+ return [:ky, :ky_index, :kx, :kx_index]
2048
+ else
2049
+ kxy = :mode
2050
+
2051
+ # i.e. tpar2_by_ky_vs_time or tpar2_by_kx_vs_time or tpar2_by_mode_vs_time
2052
+
2053
+ nt_options = options.dup # 'no time' options
2054
+ nt_options.delete(:t_index) if nt_options[:t_index]
2055
+ nt_options.delete(:frame_index) if nt_options[:frame_index]
2056
+ tparax = axiskit("tpar2_by_#{kxy}_over_time", nt_options)
2057
+ kit = GraphKit.autocreate({x: axiskit('t', options), y: tparax})
2058
+ kit.data[0].title = "Tpar^2 total: #{kxy} = #{options[kxy]}"
2059
+ if options[:t_index]
2060
+ array_element = options[:t_index_window] ? options[:t_index] - options[:t_index_window][0] : options[:t_index] - 1
2061
+ # p tparax.data.size, array_element
2062
+ # p options[:t_index], options[:t_index_window]
2063
+ time = DataKit.autocreate({x: {data: GSL::Vector.alloc([list(:t)[options[:t_index]]])}, y: {data: GSL::Vector.alloc([tparax.data[array_element]]) } })
2064
+ time.pointsize = 3.0
2065
+ # p time
2066
+ # kit.data[0].axes[:x].data = -kit.data[0].axes[:x].data
2067
+ kit.data.push time
2068
+ end
2069
+ if options[:norm]
2070
+ xrange, yrange = kit.plot_area_size
2071
+ kit.each_axiskit(:y) do |axiskit|
2072
+ axiskit.data /= yrange[1] / (options[:height] or 1.0)
2073
+ end
2074
+ end
2075
+ kit.log_axis = 'y'
2076
+ #kit.data[0].title = "gs2:#@run_name"
2077
+ kit.data[0].with = "l" #"linespoints"
2078
+ kit.file_name = options[:graphkit_name]
2079
+ kit
2080
+ end
2081
+ end
2082
+
2083
+ def tperp2_by_mode_vs_time_graphkit(options={})
2084
+ case options[:command]
2085
+ when :help
2086
+ return "'tperp2_by_ky_vs_time' or 'tperp2_by_kx_vs_time': tperp^2 over time for a given kx or ky, integrated over the other direction"
2087
+ when :options
2088
+ return [:ky, :ky_index, :kx, :kx_index]
2089
+ else
2090
+ kxy = :mode
2091
+
2092
+ # i.e. tperp2_by_ky_vs_time or tperp2_by_kx_vs_time or tperp2_by_mode_vs_time
2093
+
2094
+ nt_options = options.dup # 'no time' options
2095
+ nt_options.delete(:t_index) if nt_options[:t_index]
2096
+ nt_options.delete(:frame_index) if nt_options[:frame_index]
2097
+ tperpax = axiskit("tperp2_by_#{kxy}_over_time", nt_options)
2098
+ kit = GraphKit.autocreate({x: axiskit('t', options), y: tperpax})
2099
+ kit.data[0].title = "Tperp^2 total: #{kxy} = #{options[kxy]}"
2100
+ if options[:t_index]
2101
+ array_element = options[:t_index_window] ? options[:t_index] - options[:t_index_window][0] : options[:t_index] - 1
2102
+ # p tparax.data.size, array_element
2103
+ # p options[:t_index], options[:t_index_window]
2104
+ time = DataKit.autocreate({x: {data: GSL::Vector.alloc([list(:t)[options[:t_index]]])}, y: {data: GSL::Vector.alloc([tperpax.data[array_element]]) } })
2105
+ time.pointsize = 3.0
2106
+ # p time
2107
+ # kit.data[0].axes[:x].data = -kit.data[0].axes[:x].data
2108
+ kit.data.push time
2109
+ end
2110
+ if options[:norm]
2111
+ xrange, yrange = kit.plot_area_size
2112
+ kit.each_axiskit(:y) do |axiskit|
2113
+ axiskit.data /= yrange[1] / (options[:height] or 1.0)
2114
+ end
2115
+ end
2116
+ kit.log_axis = 'y'
2117
+ #kit.data[0].title = "gs2:#@run_name"
2118
+ kit.data[0].with = "l" #"linespoints"
2119
+ kit.file_name = options[:graphkit_name]
2120
+ kit
2121
+ end
2122
+ end
2123
+
2124
+ def transient_es_heat_flux_amplification_vs_kx_graphkit(options={})
2125
+ options[:kxy] = :kx
2126
+ transient_es_heat_flux_amplification_vs_kxy_graphkit(options)
2127
+ end
2128
+
2129
+ def transient_es_heat_flux_amplification_vs_ky_graphkit(options={})
2130
+ options[:kxy] = :ky
2131
+ transient_es_heat_flux_amplification_vs_kxy_graphkit(options)
2132
+ end
2133
+
2134
+ def transient_es_heat_flux_amplification_vs_kxy_graphkit(options={})
2135
+ case options[:command]
2136
+ when :help
2137
+ return "transient_es_heat_flux_amplification_vs_ky or transient_es_heat_flux_amplification_vs_kx. Growth rates vs either ky or kx for phi^2 integrated over the other direction. For growth rates at a specific kx AND ky, see /transient_es_heat_flux_amplification_vs_kx_vs_ky/. "
2138
+ when :options
2139
+ return []
2140
+ else
2141
+ #raise "Growth Rates are not available in non-linear mode" if @nonlinear_mode == "on"
2142
+ kxy = options[:kxy]
2143
+ kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("transient_es_heat_flux_amplification_over_#{kxy}", options)})
2144
+ kit.title = "Transient Amplification of the ES Heat flux for species #{options[:species_index]} by #{kxy}"
2145
+ kit.data[0].with = "lp"
2146
+ kit.data[0].title = @run_name
2147
+ kit.file_name = options[:graphkit_name]
2148
+ kit
2149
+ end
2150
+ end
2151
+
2152
+ def transient_amplification_vs_kx_graphkit(options={})
2153
+ options[:kxy] = :kx
2154
+ transient_amplification_vs_kxy_graphkit(options)
2155
+ end
2156
+
2157
+ def transient_amplification_vs_ky_graphkit(options={})
2158
+ options[:kxy] = :ky
2159
+ transient_amplification_vs_kxy_graphkit(options)
2160
+ end
2161
+
2162
+ def transient_amplification_vs_kxy_graphkit(options={})
2163
+ case options[:command]
2164
+ when :help
2165
+ return "transient_amplification_vs_ky or transient_amplification_vs_kx. Growth rates vs either ky or kx for phi^2 integrated over the other direction. For growth rates at a specific kx AND ky, see /transient_amplification_vs_kx_vs_ky/. "
2166
+ when :options
2167
+ return []
2168
+ else
2169
+ #raise "Growth Rates are not available in non-linear mode" if @nonlinear_mode == "on"
2170
+ kxy = options[:kxy]
2171
+ kit = GraphKit.autocreate({x: axiskit(kxy.to_s, options), y: axiskit("transient_amplification_over_#{kxy}", options)})
2172
+ kit.title = "Transient Amplification by #{kxy}"
2173
+ kit.data[0].with = "lp"
2174
+ kit.data[0].title = @run_name
2175
+ kit.file_name = options[:graphkit_name]
2176
+ kit
2177
+ end
2178
+ end
2179
+
2197
2180
  def apar2_vs_time_graphkit(options={})
2198
- case options[:command]
2199
- when :help
2200
- return "Graph of apar^2 vs time integrated over all space. No options"
2201
- when :options
2202
- return []
2203
- else
2204
- kit = GraphKit.autocreate({x: axiskit('t'), y: axiskit('apar2_over_time', options)})
2205
- kit.data[0].with = "l" #"linespoints"
2206
- kit.data[0].title = "Apar^2 total:#@run_name"
2207
- kit.file_name = options[:graphkit_name]
2208
- kit.log_axis = 'y'
2209
- kit
2210
- end
2211
- end
2212
- def phi2tot_vs_time_graphkit(options={})
2213
- case options[:command]
2214
- when :help
2215
- return "Graph of phi^2 vs time integrated over all space. No options"
2216
- when :options
2217
- return []
2218
- else
2219
- kit = GraphKit.autocreate({x: axiskit('t'), y: axiskit('phi2tot_over_time', options)})
2220
- kit.data[0].with = "l" #"linespoints"
2221
- kit.data[0].title = "Phi^2 total:#@run_name"
2222
- kit.file_name = options[:graphkit_name]
2223
- kit.log_axis = 'y'
2224
- kit
2225
- end
2226
- end
2227
- def spectrum_graphkit(options={})
2228
- case options[:command]
2229
- when :help
2230
- return "Graph of phi^2 at a given time vs kx and ky"
2231
- when :options
2232
- return [:with]
2233
- else
2234
- # p @name_match
2235
- #options[:times_kx4] = true if @name_match[:kxsq]
2236
- zaxis = axiskit('spectrum_over_ky_over_kx', options)
2237
- zaxis.data = zaxis.data.transpose
2238
- kit = GraphKit.autocreate({y: axiskit('ky', options), x: axiskit('kx', options), z: zaxis})
2239
- kit.title = "#{options[:log] ? "Log ": ""}Spectrum (phi^2#{options[:times_kx2] ? " * kx^2" : ""}#{options[:times_kx4] ? " * kx^4" : ""})"
2240
- kit.data[0].with = (options[:with] or 'pm3d palette')
2241
- kit.file_name = options[:graphkit_name]
2242
- kit
2243
- end
2244
- end
2245
- def spectrum_vs_kpar_vs_ky_graphkit(options={})
2246
- case options[:command]
2247
- when :help
2248
- return "Graph of phi^2 * ky^2 at a given time vs kpar and ky"
2249
- when :options
2250
- return [:with, :log, :no_zonal, :no_kpar0]
2251
- else
2252
- # p @name_match
2253
- #options[:times_kx4] = true if @name_match[:kxsq]
2254
- zaxis = axiskit('spectrum_over_ky_over_kpar', options)
2255
- zaxis.data = zaxis.data.transpose
2256
- kit = GraphKit.autocreate({y: axiskit('ky', options), x: axiskit('kpar', options.modify({ky_index: 1, kx_index: 1})), z: zaxis})
2257
- kit.title = "#{options[:log] ? "Log ": ""}Spectrum (phi^2 ky^2)"
2258
- kit.data[0].with = (options[:with] or 'pm3d palette')
2259
- kit.gp.view = "map" if options[:map]
2260
- kit.file_name = options[:graphkit_name]
2261
- kit
2262
- end
2263
- end
2264
- def g2_by_energy_by_all_k_graphkit(options={})
2265
- case options[:command]
2266
- when :help
2267
- return "Plots g**2 vs Hankel mode for fixed wavenumber and Hankel mode. JTP"
2268
- when :options
2269
- return []
2270
- else
2271
- #raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vpg"
2272
- raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vpx#{'%02d'%options[:kx_index]}y#{'%02d'%options[:ky_index]}z#{'%02d'%options[:kz_index]}g"
2273
- g2 = []
2274
- x_axis = []
2181
+ case options[:command]
2182
+ when :help
2183
+ return "Graph of apar^2 vs time integrated over all space. No options"
2184
+ when :options
2185
+ return []
2186
+ else
2187
+ kit = GraphKit.autocreate({x: axiskit('t'), y: axiskit('apar2_over_time', options)})
2188
+ kit.data[0].with = "l" #"linespoints"
2189
+ kit.data[0].title = "Apar^2 total:#@run_name"
2190
+ kit.file_name = options[:graphkit_name]
2191
+ kit.log_axis = 'y'
2192
+ kit
2193
+ end
2194
+ end
2195
+
2196
+ def phi2tot_vs_time_graphkit(options={})
2197
+ case options[:command]
2198
+ when :help
2199
+ return "Graph of phi^2 vs time integrated over all space. No options"
2200
+ when :options
2201
+ return []
2202
+ else
2203
+ kit = GraphKit.autocreate({x: axiskit('t'), y: axiskit('phi2tot_over_time', options)})
2204
+ kit.data[0].with = "l" #"linespoints"
2205
+ kit.data[0].title = "Phi^2 total:#@run_name"
2206
+ kit.file_name = options[:graphkit_name]
2207
+ kit.log_axis = 'y'
2208
+ kit
2209
+ end
2210
+ end
2211
+
2212
+ def spectrum_graphkit(options={})
2213
+ case options[:command]
2214
+ when :help
2215
+ return "Graph of phi^2 at a given time vs kx and ky"
2216
+ when :options
2217
+ return [:with]
2218
+ else
2219
+ zaxis = axiskit('spectrum_over_ky_over_kx', options)
2220
+ zaxis.data = zaxis.data.transpose
2221
+ kit = GraphKit.autocreate({y: axiskit('ky', options), x: axiskit('kx', options), z: zaxis})
2222
+ kit.title = "#{options[:log] ? "Log ": ""}Spectrum (phi^2#{options[:times_kx2] ? " * kx^2" : ""}#{options[:times_kx4] ? " * kx^4" : ""})"
2223
+ kit.data[0].with = (options[:with] or 'pm3d palette')
2224
+ kit.file_name = options[:graphkit_name]
2225
+ kit
2226
+ end
2227
+ end
2228
+
2229
+ def spectrum_vs_kpar_vs_ky_graphkit(options={})
2230
+ case options[:command]
2231
+ when :help
2232
+ return "Graph of phi^2 * ky^2 at a given time vs kpar and ky"
2233
+ when :options
2234
+ return [:with, :log, :no_zonal, :no_kpar0]
2235
+ else
2236
+ # p @name_match
2237
+ #options[:times_kx4] = true if @name_match[:kxsq]
2238
+ zaxis = axiskit('spectrum_over_ky_over_kpar', options)
2239
+ zaxis.data = zaxis.data.transpose
2240
+ kit = GraphKit.autocreate({y: axiskit('ky', options), x: axiskit('kpar', options.modify({ky_index: 1, kx_index: 1})), z: zaxis})
2241
+ kit.title = "#{options[:log] ? "Log ": ""}Spectrum (phi^2 ky^2)"
2242
+ kit.data[0].with = (options[:with] or 'pm3d palette')
2243
+ kit.gp.view = "map" if options[:map]
2244
+ kit.file_name = options[:graphkit_name]
2245
+ kit
2246
+ end
2247
+ end
2248
+
2249
+ def g2_by_energy_by_all_k_graphkit(options={})
2250
+ case options[:command]
2251
+ when :help
2252
+ return "Plots g**2 vs Hankel mode for fixed wavenumber and Hankel mode. JTP"
2253
+ when :options
2254
+ return []
2255
+ else
2256
+ #raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vpg"
2257
+ raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vpx#{'%02d'%options[:kx_index]}y#{'%02d'%options[:ky_index]}z#{'%02d'%options[:kz_index]}g"
2258
+ g2 = []
2259
+ x_axis = []
2275
2260
  File.open("#@directory/#@run_name.vpx#{'%02d'%options[:kx_index]}y#{'%02d'%options[:ky_index]}z#{'%02d'%options[:kz_index]}g","r").each_line do | line |
2276
2261
  #File.open("#@directory/#@run_name.vpg","r").each_line do | line |
2277
- line_array = line.split(/\s+/).map{|v| v.to_f}
2278
- if( options[:il_index] == line_array[5] )
2279
- g2.push line_array[1]**2+line_array[2]**2
2280
- x_axis.push line_array[4]
2281
- end
2282
- end
2283
-
2284
- return GraphKit.quick_create([x_axis,g2])
2285
- end
2286
- end
2287
- def g2_by_energy_by_kx_by_ky_graphkit(options={})
2288
- case options[:command]
2289
- when :help
2290
- return "Plots g**2 vs Hankel mode for fixed wavenumber and Hankel mode. JTP"
2291
- when :options
2292
- return []
2293
- else
2294
- raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vpg"
2295
- g2 = []
2296
- x_axis = []
2262
+ line_array = line.split(/\s+/).map{|v| v.to_f}
2263
+ if( options[:il_index] == line_array[5] )
2264
+ g2.push line_array[1]**2+line_array[2]**2
2265
+ x_axis.push line_array[4]
2266
+ end
2267
+ end
2268
+
2269
+ return GraphKit.quick_create([x_axis,g2])
2270
+ end
2271
+ end
2272
+
2273
+ def g2_by_energy_by_kx_by_ky_graphkit(options={})
2274
+ case options[:command]
2275
+ when :help
2276
+ return "Plots g**2 vs Hankel mode for fixed wavenumber and Hankel mode. JTP"
2277
+ when :options
2278
+ return []
2279
+ else
2280
+ raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vpg"
2281
+ g2 = []
2282
+ x_axis = []
2297
2283
  File.open("#@directory/#@run_name.vpx#{'%02d'%options[:kx_index]}y#{'%02d'%options[:ky_index]}g","r").each_line do | line |
2298
2284
  #File.open("#@directory/#@run_name.vpg","r").each_line do | line |
2299
- line_array = line.split(/\s+/).map{|v| v.to_f}
2300
- if( options[:il_index] == line_array[5] )
2301
- g2.push line_array[1]**2+line_array[2]**2
2302
- x_axis.push line_array[4]
2303
- end
2304
- end
2305
-
2306
- return GraphKit.quick_create([x_axis,g2])
2307
- end
2308
- end
2309
- def g2_by_energy_graphkit(options={})
2310
- case options[:command]
2311
- when :help
2312
- return "Plots g**2 vs Hankel mode for fixed wavenumber and Hankel mode. JTP"
2313
- when :options
2314
- return []
2315
- else
2316
- raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vpg"
2317
- g2 = []
2318
- x_axis = []
2285
+ line_array = line.split(/\s+/).map{|v| v.to_f}
2286
+ if( options[:il_index] == line_array[5] )
2287
+ g2.push line_array[1]**2+line_array[2]**2
2288
+ x_axis.push line_array[4]
2289
+ end
2290
+ end
2291
+
2292
+ return GraphKit.quick_create([x_axis,g2])
2293
+ end
2294
+ end
2295
+
2296
+ def g2_by_energy_graphkit(options={})
2297
+ case options[:command]
2298
+ when :help
2299
+ return "Plots g**2 vs Hankel mode for fixed wavenumber and Hankel mode. JTP"
2300
+ when :options
2301
+ return []
2302
+ else
2303
+ raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vpg"
2304
+ g2 = []
2305
+ x_axis = []
2319
2306
  #File.open("#@directory/#@run_name.vpx#{options[:kx_index]}y#{options[:ky_index]}g","r").each_line do | line |
2320
2307
  File.open("#@directory/#@run_name.vpg","r").each_line do | line |
2321
- line_array = line.split(/\s+/).map{|v| v.to_f}
2322
- if( options[:il_index] == line_array[5] )
2323
- g2.push line_array[1]**2+line_array[2]**2
2324
- x_axis.push line_array[4]
2325
- end
2326
- end
2327
-
2328
- return GraphKit.quick_create([x_axis,g2])
2329
- end
2330
- end
2331
- def g2_by_lambda_by_all_k_graphkit(options={})
2332
- case options[:command]
2333
- when :help
2334
- return "Plots g**2 vs Hermite mode for fixed wavenumber and Hankel mode. JTP"
2335
- when :options
2336
- return []
2337
- else
2338
- #raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vpg"
2339
- g2 = []
2340
- x_axis = []
2308
+ line_array = line.split(/\s+/).map{|v| v.to_f}
2309
+ if( options[:il_index] == line_array[5] )
2310
+ g2.push line_array[1]**2+line_array[2]**2
2311
+ x_axis.push line_array[4]
2312
+ end
2313
+ end
2314
+
2315
+ return GraphKit.quick_create([x_axis,g2])
2316
+ end
2317
+ end
2318
+
2319
+ def g2_by_lambda_by_all_k_graphkit(options={})
2320
+ case options[:command]
2321
+ when :help
2322
+ return "Plots g**2 vs Hermite mode for fixed wavenumber and Hankel mode. JTP"
2323
+ when :options
2324
+ return []
2325
+ else
2326
+ #raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vpg"
2327
+ g2 = []
2328
+ x_axis = []
2341
2329
  #File.open("#@directory/#@run_name.vpx#{options[:kx_index]}y#{options[:ky_index]}g","r").each_line do | line |
2342
2330
  #File.open("#@directory/#@run_name.vpg","r").each_line do | line |
2343
2331
  File.open("#@directory/#@run_name.vpx#{'%02d'%options[:kx_index]}y#{'%02d'%options[:ky_index]}z#{'%02d'%options[:kz_index]}g","r").each_line do | line |
2344
- line_array = line.split(/\s+/).map{|v| v.to_f}
2345
- if( options[:e_index] == line_array[4] )
2346
- g2.push line_array[1]**2+line_array[2]**2
2347
- x_axis.push line_array[5]
2348
- end
2349
- end
2350
-
2351
- return GraphKit.quick_create([x_axis,g2])
2352
- end
2353
- end
2354
- def g2_by_lambda_graphkit(options={})
2355
- case options[:command]
2356
- when :help
2357
- return "Plots g**2 vs Hermite mode for fixed wavenumber and Hankel mode. JTP"
2358
- when :options
2359
- return []
2360
- else
2361
- raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vpg"
2362
- g2 = []
2363
- x_axis = []
2332
+ line_array = line.split(/\s+/).map{|v| v.to_f}
2333
+ if( options[:e_index] == line_array[4] )
2334
+ g2.push line_array[1]**2+line_array[2]**2
2335
+ x_axis.push line_array[5]
2336
+ end
2337
+ end
2338
+
2339
+ return GraphKit.quick_create([x_axis,g2])
2340
+ end
2341
+ end
2342
+
2343
+ def g2_by_lambda_graphkit(options={})
2344
+ case options[:command]
2345
+ when :help
2346
+ return "Plots g**2 vs Hermite mode for fixed wavenumber and Hankel mode. JTP"
2347
+ when :options
2348
+ return []
2349
+ else
2350
+ raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.vpg"
2351
+ g2 = []
2352
+ x_axis = []
2364
2353
  #File.open("#@directory/#@run_name.vpx#{options[:kx_index]}y#{options[:ky_index]}g","r").each_line do | line |
2365
2354
  File.open("#@directory/#@run_name.vpg","r").each_line do | line |
2366
- line_array = line.split(/\s+/).map{|v| v.to_f}
2367
- if( options[:e_index] == line_array[4] )
2368
- g2.push line_array[1]**2+line_array[2]**2
2369
- x_axis.push line_array[5]
2370
- end
2371
- end
2372
-
2373
- return GraphKit.quick_create([x_axis,g2])
2374
- end
2375
- end
2376
-
2377
- def vspace_diagnostics_graphkit(options={})
2378
- case options[:command]
2379
- when :help
2380
- return "Plots vspace diagnostics. All lines shouldn't stray much above 0.1 - otherwise large amounts of the distribution function is in the higher k velocity space and velocity space is probably unresolved. (NB This graph is here temporarily (ha ha) until I add the vspace diagnostics to the NetCDF file (or the apocalypse, whichever is sooner) EGH)"
2381
- when :options
2382
- return []
2383
- else
2384
- raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.lpc" or FileTest.exist? "#@directory/#@run_name.vres"
2385
- lpc = GSL::Vector.filescan("#@directory/#@run_name.lpc") rescue [[0], [0], [0]]
2386
- vres = GSL::Vector.filescan("#@directory/#@run_name.vres") rescue [[0], [0], [0]]
2387
- xaxis = AxisKit.autocreate({data: lpc[0], title: "Time"})
2388
- data = [[lpc[0], lpc[1], "Pitch Angle Harmonics (lpc)"], [lpc[0], lpc[2], "Energy Harmonics (lpc)"], [vres[0], vres[1], "Pitch Angle Harmonics (vres)"], [vres[0], vres[2], "Energy Harmonics (vres)"]]
2389
- kits = data.inject([]) do |arr, (x, vector, title)|
2390
- arr + [GraphKit.autocreate({x: AxisKit.autocreate({data: x, title: "Time"}), y: AxisKit.autocreate({data: vector, title: title})})]
2391
- end
2392
- kit = kits.sum
2393
- # exit
2394
- kit.title = "Velocity Space Diagnostics"
2395
- kit.ylabel = "Fraction of Dist Func Contained"
2396
- kit.file_name = options[:graphkit_name]
2397
- # kit.log_axis = 'y'
2398
- kit
2399
- end
2400
- end
2401
- def zonal_spectrum_graphkit(options={})
2402
- case options[:command]
2403
- when :help
2404
- return "zonal_spectrum: Graph of kx^4 phi^2 vs kx for ky=0"
2405
- when :options
2406
- return [:t, :t_index]
2407
- else
2408
- options[:times_kx2] = true
2409
- kit = GraphKit.autocreate({x: axiskit('kx', options), y: axiskit("zonal_spectrum", options)})
2410
- kit.title = "Zonal Spectrum"
2411
- kit.file_name = options[:graphkit_name] + options[:t_index].to_s
2412
- kit.data[0].with = 'lp'
2413
- kit.pointsize = 2.0
2414
- kit
2415
- end
2416
- end
2417
-
2418
- def zf_velocity_vs_x_graphkit(options={})
2419
- case options[:command]
2420
- when :help
2421
- return "zonal_flow_velocity_vs_x: Graph of the zonal flow velocity kxfac*IFT(i k_x phi). kxfac = (qinp/rhoc)*grho(rhoc)."
2422
- when :options
2423
- return [:t, :t_index, :theta_index, :kxfac, :add_mean_flow]
2424
- else
2355
+ line_array = line.split(/\s+/).map{|v| v.to_f}
2356
+ if( options[:e_index] == line_array[4] )
2357
+ g2.push line_array[1]**2+line_array[2]**2
2358
+ x_axis.push line_array[5]
2359
+ end
2360
+ end
2361
+
2362
+ return GraphKit.quick_create([x_axis,g2])
2363
+ end
2364
+ end
2365
+
2366
+ def vspace_diagnostics_graphkit(options={})
2367
+ case options[:command]
2368
+ when :help
2369
+ return "Plots vspace diagnostics. All lines shouldn't stray much above 0.1 - otherwise large amounts of the distribution function is in the higher k velocity space and velocity space is probably unresolved. (NB This graph is here temporarily (ha ha) until I add the vspace diagnostics to the NetCDF file (or the apocalypse, whichever is sooner) EGH)"
2370
+ when :options
2371
+ return []
2372
+ else
2373
+ raise "Velocity space diagnostics not found" unless FileTest.exist? "#@directory/#@run_name.lpc" or FileTest.exist? "#@directory/#@run_name.vres"
2374
+ lpc = GSL::Vector.filescan("#@directory/#@run_name.lpc") rescue [[0], [0], [0]]
2375
+ vres = GSL::Vector.filescan("#@directory/#@run_name.vres") rescue [[0], [0], [0]]
2376
+ xaxis = AxisKit.autocreate({data: lpc[0], title: "Time"})
2377
+ data = [[lpc[0], lpc[1], "Pitch Angle Harmonics (lpc)"], [lpc[0], lpc[2], "Energy Harmonics (lpc)"], [vres[0], vres[1], "Pitch Angle Harmonics (vres)"], [vres[0], vres[2], "Energy Harmonics (vres)"]]
2378
+ kits = data.inject([]) do |arr, (x, vector, title)|
2379
+ arr + [GraphKit.autocreate({x: AxisKit.autocreate({data: x, title: "Time"}), y: AxisKit.autocreate({data: vector, title: title})})]
2380
+ end
2381
+ kit = kits.sum
2382
+ # exit
2383
+ kit.title = "Velocity Space Diagnostics"
2384
+ kit.ylabel = "Fraction of Dist Func Contained"
2385
+ kit.file_name = options[:graphkit_name]
2386
+ # kit.log_axis = 'y'
2387
+ kit
2388
+ end
2389
+ end
2390
+
2391
+ def zonal_spectrum_graphkit(options={})
2392
+ case options[:command]
2393
+ when :help
2394
+ return "zonal_spectrum: Graph of kx^4 phi^2 vs kx for ky=0"
2395
+ when :options
2396
+ return [:t, :t_index]
2397
+ else
2398
+ options[:times_kx2] = true
2399
+ kit = GraphKit.autocreate({x: axiskit('kx', options), y: axiskit("zonal_spectrum", options)})
2400
+ kit.title = "Zonal Spectrum"
2401
+ kit.file_name = options[:graphkit_name] + options[:t_index].to_s
2402
+ kit.data[0].with = 'lp'
2403
+ kit.pointsize = 2.0
2404
+ kit
2405
+ end
2406
+ end
2407
+
2408
+ def zf_velocity_vs_x_graphkit(options={})
2409
+ case options[:command]
2410
+ when :help
2411
+ return "zonal_flow_velocity_vs_x: Graph of the zonal flow velocity kxfac*IFT(i k_x phi). kxfac = (qinp/rhoc)*grho(rhoc)."
2412
+ when :options
2413
+ return [:t, :t_index, :theta_index, :kxfac, :add_mean_flow]
2414
+ else
2425
2415
  options[:ky_index]=0
2426
- kit = GraphKit.autocreate({x: axiskit('x', options), y: axiskit("zf_velocity_over_x", options)})
2416
+ kit = GraphKit.autocreate({x: axiskit('x', options), y: axiskit("zf_velocity_over_x", options)})
2427
2417
  if options[:add_mean_flow]
2428
2418
  kit.data[0].y.data += mean_flow_velocity_over_x_gsl_vector(options)
2429
2419
  end
2430
- kit.title = "Zonal Flow Velocity versus x"
2431
- kit.file_name = options[:graphkit_name] + options[:t_index].to_s
2432
- kit.data[0].with = 'lp'
2433
- kit.pointsize = 2.0
2434
- kit
2435
- end
2436
- end
2437
-
2438
- def mean_flow_velocity_vs_x_graphkit(options={})
2439
- case options[:command]
2440
- when :help
2441
- return "mean_flow_velocity_vs_x: Graph of the mean flow velocity (x - x(centre))*g_exb"
2442
- when :options
2443
- return [:t, :t_index, :theta_index]
2444
- else
2420
+ kit.title = "Zonal Flow Velocity versus x"
2421
+ kit.file_name = options[:graphkit_name] + options[:t_index].to_s
2422
+ kit.data[0].with = 'lp'
2423
+ kit.pointsize = 2.0
2424
+ kit
2425
+ end
2426
+ end
2427
+
2428
+ def mean_flow_velocity_vs_x_graphkit(options={})
2429
+ case options[:command]
2430
+ when :help
2431
+ return "mean_flow_velocity_vs_x: Graph of the mean flow velocity (x - x(centre))*g_exb"
2432
+ when :options
2433
+ return [:t, :t_index, :theta_index]
2434
+ else
2445
2435
  options[:ky_index]=0
2446
- kit = GraphKit.autocreate({x: axiskit('x', options), y: axiskit("mean_flow_velocity_over_x", options)})
2447
- kit.title = "Mean Flow Velocity versus x"
2448
- kit.file_name = options[:graphkit_name] + options[:t_index].to_s
2449
- kit.data[0].with = 'lp'
2450
- kit.pointsize = 2.0
2451
- kit
2452
- end
2453
- end
2436
+ kit = GraphKit.autocreate({x: axiskit('x', options), y: axiskit("mean_flow_velocity_over_x", options)})
2437
+ kit.title = "Mean Flow Velocity versus x"
2438
+ kit.file_name = options[:graphkit_name] + options[:t_index].to_s
2439
+ kit.data[0].with = 'lp'
2440
+ kit.pointsize = 2.0
2441
+ kit
2442
+ end
2443
+ end
2454
2444
 
2455
2445
  end
2456
2446