gs2crmod 0.11.78 → 0.11.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/gs2crmod/gs2.rb CHANGED
@@ -1181,246 +1181,10 @@ end
1181
1181
  end
1182
1182
  end
1183
1183
 
1184
- #This function will handle running the correlation analysis and writing the results to a NetCDF file.
1185
- #Cases need to be handled differently since perp, par and full are just subsets of the full correlation function
1186
- #but the time correlation calculation needs to deal with each radial location separately. Time correlation
1187
- #uses the zonal flows in the toroidal direction to calculate the correlation time.
1188
- #
1189
- #This function takes in the same options as field_real_space_standard_representation, along with the following
1190
- #new options dealing with interpolation and binning:
1191
- #
1192
- # correlation_type: determines which subset of correlation function should be calculated (perp/par/full/time)
1193
- # nbins_array: array giving number of bins to use in the binning procedure. Index order (x, y, z ,t)
1194
- # nt_reg: Most of the time you have many more time points than you need for spatial correlations. This sets
1195
- # number of new interpolation points in time.
1196
- #
1197
- # Using this function: Since this can only be single threaded, this can be a very expensive calculation when
1198
- # trying to do the full correlation function, so this is not recommended for highly resolved nonlinear runs. This is
1199
- # why the perp/par/full splitting is implemented, allowing one dimension to be taken out essentially.
1200
- def correlation_analysis(options={})
1201
-
1202
- #Sanity checks:
1203
- #Cannot only have one bin since require difference between bins for index calculation
1204
- if options[:nbins_array].include?1
1205
- raise('Cannot have only one bin in nbins_array. Minuimum is two.')
1206
- end
1207
- #Thetamin shouldn't be equal to thetamax to avoid possibili
1208
- #
1209
-
1210
- case options[:correlation_type]
1211
- when 'perp', 'par', 'full'
1212
- gsl_tensor = field_correlation_gsl_tensor(options)
1213
- shape = gsl_tensor.shape
1214
-
1215
- #Set up dimensions
1216
- file = NumRu::NetCDF.create(@run_name + "_correlation_analysis_#{options[:correlation_type]}.nc")
1217
- ydim = file.def_dim('x',shape[0])
1218
- xdim = file.def_dim('y',shape[1])
1219
- zdim = file.def_dim('z',shape[2])
1220
- tdim = file.def_dim('t',shape[3])
1221
- correlation_var = file.def_var("correlation", 'sfloat', [xdim, ydim, zdim, tdim])
1222
- file.enddef
1223
- #Write out array
1224
- correlation_var.put(NArray.to_na(gsl_tensor.to_a))
1225
- file.close
1226
- when 'time'
1227
- nakx_actual = NumRu::NetCDF.open(@run_name + ".out.nc").var('kx').get
1228
- kx_len = nakx_actual.length
1229
- if options[:nakx] == nil
1230
- radial_pts = kx_len
1231
- elsif options[:nakx] <= kx_len
1232
- radial_pts = options[:nakx]
1233
- else
1234
- raise('nakx exceeds the total number of kx\'s in simulation')
1235
- end
1236
-
1237
- #Check whether t_index_window is specified, if not, set to entire t range
1238
- if options[:t_index_window] == nil
1239
- options[:t_index_window] = [1, -1]
1240
- end
1241
-
1242
-
1243
- #Now loop through the radial locations and calculate the correlation function in y and t.
1244
- for x in 0...radial_pts
1245
- options[:xmin] = x
1246
- options[:xmax] = x
1247
- gsl_tensor = field_correlation_gsl_tensor(options)
1248
- shape = gsl_tensor.shape
1249
-
1250
- if x == 0 #Write dimensions to NetCDF file
1251
- file = NumRu::NetCDF.create(@run_name + "_correlation_analysis_#{options[:correlation_type]}.nc")
1252
- ydim = file.def_dim('x',shape[0])
1253
- xdim = file.def_dim('y',shape[1])
1254
- zdim = file.def_dim('z',shape[2])
1255
- tdim = file.def_dim('t',shape[3])
1256
- end
1257
- file.redef
1258
- correlation_var = file.def_var("correlation_x_#{x}", 'sfloat', [xdim, ydim, zdim, tdim])
1259
- file.enddef
1260
- #Write out array
1261
- correlation_var.put(NArray.to_na(gsl_tensor.to_a))
1262
- end
1263
- file.close #only close after loop over radial points
1264
- else
1265
- raise 'Please specify correlation_type as perp/par/time/full'
1266
- end
1267
- end
1268
-
1269
1184
  def input_file_extension
1270
1185
  '.in'
1271
1186
  end
1272
1187
 
1273
- #This function will interpolate and output either phi or density at the outboard midplane
1274
- #on a 40x40 grid appropriate to analyse as experimental data. It called as a run_command
1275
- #e.g. rc 'bes_output(options)', j:<run number>. It will call field_real_space_poloidal_plane_graphkit
1276
- #for every time step, interpolate at outboard midplane, and write fields and grids out to NetCDF file.
1277
- #
1278
- #Options: Same as field_real_space_poloidal_plane, field name must also be specified for generality. New options:
1279
- #
1280
- # no_flux_tube_copies: ensures only one flux tube is printed out with zeroes everywhere else.
1281
- # amin: Minor radius (to which R,Z are normalized) so that grid is in right units
1282
- # output_box_size: Array of sizes of output box (in units of amin) either side of middle of fluxtube at outboard midplane
1283
- # in R direction and either side of outboard midplane in Z direction.
1284
- # output_box_points: Array of number of points in output box (R,Z). Default will be 50x50.
1285
- #
1286
- #The interpolation routine used will only interpolate correctly inside the fluxtube and produce garbage outside. Regular points are checked
1287
- #for being inside or outside the fluxtube and values of the field outside the fluxtube are set to zero.
1288
- def bes_output(options={})
1289
- #******************
1290
- # Read in options *
1291
- #******************
1292
- #In order to interpolate on constant grids, ensure constant_torphi is set to some value (default 0.0)
1293
- if options[:constant_torphi] == nil
1294
- p 'constant_torphi not set! Setting it to 0.0.'
1295
- options[:constant_torphi] = 0.0
1296
- end
1297
- #Check whether t_index_window is specified, if not, set to entire t range
1298
- if options[:t_index_window] == nil
1299
- t_index_beg = 1
1300
- t_index_end = gsl_vector(:t).length
1301
- else
1302
- t_index_beg = options[:t_index_window][0]
1303
- t_index_end = options[:t_index_window][1]
1304
- end
1305
- if options[:amin]
1306
- amin = options[:amin]
1307
- end
1308
- if options[:v_ref] # velocity of reference species
1309
- v_ref = options[:v_ref]
1310
- end
1311
- if options[:omega] # angular velocity of plasma
1312
- omega = options[:omega]
1313
- end
1314
- if options[:omega] and (options[:v_ref] == nil or options[:amin] == nil)
1315
- raise 'Need to specify amin AND v_ref options when specifying omega to move to LAB frame!'
1316
- end
1317
- if options[:output_box_size] and options[:output_box_size].kind_of?Array
1318
- _r_box_size = options[:output_box_size][0] # EGH These variables are marked as unused... are they used anywhere?
1319
- _z_box_size = options[:output_box_size][1]
1320
- #else
1321
- # raise 'Option output_box_size must be specified (in units of amin) and must be an Array.'
1322
- end
1323
- if options[:output_box_points] and options[:output_box_points].kind_of?Array
1324
- r_box_pts = options[:output_box_points][0]
1325
- z_box_pts = options[:output_box_points][1]
1326
- else
1327
- r_box_pts = 50
1328
- z_box_pts = 50
1329
- end
1330
-
1331
- #Call at first time step to set up arrays and grids
1332
- options[:t_index] = t_index_beg
1333
- kit = field_real_space_poloidal_plane_graphkit(options)
1334
- x = kit.data[0].x.data
1335
- _y = kit.data[0].y.data
1336
- z = kit.data[0].z.data
1337
-
1338
- #Set up NetCDf file
1339
- file = NumRu::NetCDF.create(@run_name + "_bes_output.nc")
1340
- xdim = file.def_dim('y', x.shape[0])
1341
- zdim = file.def_dim('z', z.shape[1])
1342
- tdim = file.def_dim('t', 0) #zero means unlimited
1343
- x_var = file.def_var("x", 'sfloat', [xdim, zdim])
1344
- z_var = file.def_var("z", 'sfloat', [xdim, zdim])
1345
- t_var = file.def_var("t", 'sfloat', [tdim])
1346
- field_var = file.def_var("field", 'sfloat', [xdim, zdim, tdim])
1347
- file.enddef
1348
- #Write dimensions to file
1349
- x_var.put(NArray.to_na(x.to_a))
1350
- z_var.put(NArray.to_na(z.to_a))
1351
-
1352
- #Loop over time, load field as function of space at each time index, write to file
1353
- for i in t_index_beg...t_index_end #inclusive of end
1354
- Terminal.erewind(1) #go back one line in terminal
1355
- eputs sprintf("Writing time index = %d of %d#{Terminal::CLEAR_LINE}", i, t_index_end-t_index_beg+1) #clear line and print time index
1356
- options[:t_index] = i
1357
- #Need to test whether omega is specified to change torphi at each time step. If not, do nothing since torphi must be
1358
- #set to a value to call the graphkit below
1359
- if options[:omega]
1360
- options[:torphi] = omega * (gsl_vector(:t)[i] - gsl_vector(:t)[0]) * (amin/v_ref)
1361
- end
1362
- kit = field_real_space_poloidal_plane_graphkit(options)
1363
- t_var.put(gsl_vector(:t)[i], 'index'=>[i-t_index_beg]) #Write time to unlimited time NetCDF variable
1364
- field_var.put(NArray.to_na((kit.data[0].f.data).to_a), 'start'=>[0,0,i-t_index_beg], 'end'=>[-1,-1,i-t_index_beg])
1365
- end
1366
- file.close
1367
-
1368
- #Ignore this until interpolation issue is sorted
1369
- =begin
1370
- #**************************
1371
- # Set up new regular grid *
1372
- #**************************
1373
- th_grid_size = x.shape[1]
1374
- flux_tube_midpt = x[0, (th_grid_size-1)/2] + (x[-1, (th_grid_size-1)/2] - x[1, (th_grid_size-1)/2])/2
1375
- x_vec_reg = GSL::Vector.linspace(flux_tube_midpt - r_box_size, flux_tube_midpt + r_box_size, r_box_pts)
1376
- z_vec_reg = GSL::Vector.linspace(-z_box_size, z_box_size, z_box_pts)
1377
- x_reg = GSL::Matrix.alloc(r_box_pts, z_box_pts)
1378
- z_reg = GSL::Matrix.alloc(r_box_pts, z_box_pts)
1379
- field_reg = GSL::Matrix.alloc(r_box_pts, z_box_pts)
1380
- for i in 0...r_box_pts
1381
- for j in 0...z_box_pts
1382
- x_reg[i,j] = x_vec_reg[i]
1383
- z_reg[i,j] = z_vec_reg[j]
1384
- end
1385
- end
1386
-
1387
- #************************************************
1388
- # Find the field at every point on regular grid *
1389
- #************************************************
1390
- #To evaluate field on a regular grid given the field on an irregular grid, need to interpolate. The rubygem
1391
- #gsl_extras contains an interpolation routine called ScatterInterp which does exactly this based on a
1392
- #'Radial Basis Function' method.
1393
-
1394
- #Have R, Z, and field on an irregular grid in the form of matrices. ScatterInterp only takes in GSL vectors
1395
- #so simply convert these matrices to vectors (of size row*col) since the order of the pts don't matter.
1396
- x_vec = GSL::Vector.alloc(x.shape[0]*x.shape[1])
1397
- z_vec = GSL::Vector.alloc(x.shape[0]*x.shape[1])
1398
- field_vec = GSL::Vector.alloc(x.shape[0]*x.shape[1])
1399
- for i in 0...x.shape[0]
1400
- for j in 0...x.shape[1]
1401
- x_vec[x.shape[1]*i + j] = x[i,j]
1402
- z_vec[x.shape[1]*i + j] = z[i,j]
1403
- field_vec[x.shape[1]*i + j] = field[i,j]
1404
- end
1405
- end
1406
-
1407
- #Now pass these vectors to ScatterInterp. This creates an object with instance method 'eval' which can be given an x,z coord
1408
- #at which to evaluate the interpolated function.
1409
- p 'Interpolating'
1410
- interp = GSL::ScatterInterp.alloc(:linear, [x_vec, z_vec, field_vec], false, r0=0.1)
1411
- p 'Finished interpolating'
1412
- for i in 0...x_vec_reg.size
1413
- for j in 0...z_vec_reg.size
1414
- field_reg[i,j] = interp.eval(x_vec_reg[i], z_vec_reg[j])
1415
- end
1416
- end
1417
-
1418
- kit = GraphKit.quick_create([x_vec_reg, z_vec_reg, field_reg])
1419
- #kit2 = GraphKit.quick_create([x_vec, z_vec, field_vec])
1420
- =end
1421
-
1422
- end
1423
-
1424
1188
  #This section defines a selection of graphs which are written to a latex file when the CR function write_report is called. To add your own, simply copy one a similar looking graph and modify it to your needs.
1425
1189
  # The requirements to use the latex report writing is further specified in CodeRunner.
1426
1190
  def latex_graphs