gs2crmod 0.11.20 → 0.11.21

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.20
1
+ 0.11.21
data/ext/gs2crmod_ext.c CHANGED
@@ -1,4 +1,8 @@
1
1
  #include "gs2crmod_ext.h"
2
+ #include <math.h>
3
+ #include <string.h>
4
+ #include <gsl/gsl_spline.h>
5
+ #include <gsl/gsl_spline.h>
2
6
 
3
7
  VALUE gs2crmod_tensor_complexes_field_gsl_tensor_complex_2(VALUE self, VALUE options)
4
8
  {
@@ -345,6 +349,408 @@ VALUE gs2crmod_tensor_field_gsl_tensor(VALUE self, VALUE options)
345
349
  return field_real_space;
346
350
  }
347
351
 
352
+ inline int arr_index(int ix, int iy, int ith, int it, int *c_shape, int t_size)
353
+ {
354
+ return ix*c_shape[0]*c_shape[2]*t_size + iy*c_shape[0]*t_size + ith*t_size + it;
355
+ }
356
+
357
+ //Calculates normalized correlation function of 2 time series and stores result
358
+ void correlate_norm(double *A, double *B, double *C, int t_size)
359
+ {
360
+ //printf("%lf, %lf, %d\n", A[0], B[0], size);
361
+
362
+ int i, j, jmax;
363
+ double temp_sum, norm_a=0., norm_b=0.;
364
+
365
+ //printf("%lf, %lf, %lf, %d\n", A[0], B[0], C[0], t_size);
366
+
367
+ //Sum over appropriate terms to get vector of correlations as function of time delay
368
+ //Split into two loops instead of trying to be too smart with the indices.
369
+ for(i=0; i<=t_size; i++){
370
+ temp_sum=0;
371
+ for(j=0; j<=i; j++)
372
+ {
373
+ temp_sum += A[j] * B[t_size - i - 1 + j];
374
+ }
375
+ C[i] = temp_sum;
376
+ }
377
+ //Second half
378
+ for(i=t_size+1; i<2*t_size-1; i++){
379
+ jmax = 2*t_size - 2 - i;
380
+ temp_sum=0;
381
+ for(j=0; j<=2*t_size-2-i; j++){
382
+ temp_sum += A[t_size - jmax - 1 + j] * B[j];
383
+ }
384
+ C[i] = temp_sum;
385
+ }
386
+
387
+ // for(i=0; i<t_size; i++)
388
+ // printf("%lf, ", A[i]);
389
+ // printf("\n\n");
390
+ // for(i=0; i<2*t_size-1; i++)
391
+ // printf("%lf, ", C[i]);
392
+ // printf("\n\ntemp_sum=%lf, Cmax=%lf\n", temp_sum, C[50]);
393
+
394
+ //Normalize each array with its zero time delay correlation value
395
+ for(i=0; i<t_size; i++){
396
+ norm_a += A[i]*A[i];
397
+ norm_b += B[i]*B[i];
398
+ }
399
+ //Final answer written to C array
400
+ for(i=0; i<2*t_size-1; i++)
401
+ C[i] = C[i]/sqrt(norm_a * norm_b);
402
+ }
403
+
404
+ VALUE gs2crmod_tensor_field_correlation_gsl_tensor(VALUE self, VALUE options)
405
+ {
406
+ VALUE field_graphkit, shape, datakit, datakit_array;
407
+ VALUE x_narray, y_narray, z_narray, field_narray;
408
+ VALUE t_gsl_vector;
409
+ //Write some as floats to avoid flooring to wrong (lower) number later
410
+ float *lx_bin, *ly_bin, *lz_bin, *lt_bin;
411
+ float lxmin, lxmax, lymin, lymax, lzmin, lzmax, ltmin, ltmax, lx, ly, lz, *lt;
412
+ double *x, *y, *z, *t, *field, *coarray, *corr_norm, amin;
413
+ int *c_shape, tot_size, ith, ix, iy, it, t_size, first=1;
414
+ int index, i, i2, i3, i4, tot_bins, *count;
415
+ long int i1;
416
+
417
+ printf("Starting correlation analysis\n");
418
+
419
+ /*Find time steps*/
420
+ /*self.gsl_vector('t')*/
421
+ //t_gsl_vector = RFCALL_11("gsl_vector", rb_str_new2("t"));
422
+ t_gsl_vector = rb_funcall(self, rb_intern("gsl_vector"), 2, rb_str_new2("t"), options);
423
+ t_size = NUM2INT(RFCALL_10_ON(t_gsl_vector, "size"));
424
+ t = ALLOC_N(double, t_size);
425
+ for(it=0; it<t_size; it++)
426
+ {
427
+ t[it] = NUM2DBL(CR_TELMT_R1(t_gsl_vector, it));
428
+ }
429
+
430
+ //Read from options
431
+ if(RTEST(CR_HKS(options, "amin")))
432
+ amin = NUM2DBL(CR_HKS(options, "amin"));
433
+ else
434
+ amin = 1.0;
435
+
436
+ VALUE nbins_array=CR_HKS(options, "nbins_array");
437
+ int *nbins;
438
+ if(RTEST(nbins_array) && RTEST(rb_obj_is_kind_of(nbins_array, RGET_CLASS_TOP("Array")))){
439
+ CR_INT_ARY_R2C_STACK(nbins_array, nbins);
440
+ }
441
+ else
442
+ rb_raise(RGET_CLASS_TOP("TypeError"), "Please specify nbins_array as a 4D array");
443
+
444
+ //correlation_type = options[:correlation_type]
445
+ //Test which correlation type is to be calculated using ruby string comparison in a proc
446
+ VALUE test_proc = rb_eval_string("Proc.new {|options| case options[:correlation_type]; when 'perp'; 0; when 'par'; 1; when 'time'; 2; when 'full'; 3 ;else; raise 'Please specify correlation_type as a string (perp/par/time/full)'; end}");
447
+ int corr_type = FIX2INT(RFCALL_11_ON(test_proc, "call", options));
448
+
449
+ for(it=0; it<t_size; it++)
450
+ {
451
+ /*options[:t_index] = it+1*/
452
+ /*options.send("[]=", :t_index, it+1)*/
453
+
454
+ //rb_funcall(options, rb_intern("[]="), ID2SYM(rb_intern("t_index")), Qnil);
455
+ CR_HKS_SET(options, "t_index", INT2FIX(it));
456
+
457
+ field_graphkit = RFCALL_11("field_real_space_graphkit", options);
458
+
459
+ /*shape = rb_funcall(field_graphkit, rb_intern("shape"), 0);*/
460
+ datakit_array = RFCALL_10_ON(field_graphkit, "data");
461
+ datakit = CR_ELEMENT_ACCESS(datakit_array, INT2FIX(0));
462
+
463
+ /*Access data: datakit.x.data.narray*/
464
+ x_narray = RFCALL_10_ON(RFCALL_10_ON(RFCALL_10_ON(datakit, "x"), "data"), "narray");
465
+ y_narray = RFCALL_10_ON(RFCALL_10_ON(RFCALL_10_ON(datakit, "y"), "data"), "narray");
466
+ z_narray = RFCALL_10_ON(RFCALL_10_ON(RFCALL_10_ON(datakit, "z"), "data"), "narray");
467
+ field_narray = RFCALL_10_ON(RFCALL_10_ON(RFCALL_10_ON(datakit, "f"), "data"), "narray");
468
+
469
+ shape = RFCALL_10_ON(x_narray, "shape");
470
+ CR_INT_ARY_R2C_STACK(shape, c_shape);
471
+
472
+ if(first)
473
+ {
474
+ tot_size = c_shape[0]*c_shape[1]*c_shape[2]*t_size;
475
+ x = ALLOC_N(double, tot_size);
476
+ y = ALLOC_N(double, tot_size);
477
+ z = ALLOC_N(double, tot_size);
478
+ field = ALLOC_N(double, tot_size);
479
+ first=0;
480
+ }
481
+
482
+
483
+ /*Copy NArrays to C arrays*/
484
+ for(ith=0; ith<c_shape[0]; ith++)
485
+ for(ix=0; ix<c_shape[1]; ix++)
486
+ for(iy=0; iy<c_shape[2]; iy++)
487
+ {
488
+ index = arr_index(ix,iy,ith,it,c_shape,t_size);
489
+ x[index] = NUM2DBL(CR_TELMT_R3(x_narray, ith, ix, iy));
490
+ y[index] = NUM2DBL(CR_TELMT_R3(y_narray, ith, ix, iy));
491
+ z[index] = NUM2DBL(CR_TELMT_R3(z_narray, ith, ix, iy));
492
+ field[index] = NUM2DBL(CR_TELMT_R3(field_narray, ith, ix, iy));
493
+ }
494
+ }
495
+
496
+
497
+
498
+ /******************************
499
+ * GSL Interpolation of field *
500
+ * in time *
501
+ *****************************/
502
+ //Read t interp from options (default is 100)
503
+ int nt_reg;
504
+ if(RTEST(CR_HKS(options, "nt_reg")))
505
+ nt_reg = NUM2INT(CR_HKS(options, "nt_reg"));
506
+ else
507
+ nt_reg = 100;
508
+ int idx, ti;
509
+ double *x_reg, *y_reg, *z_reg, *t_reg, *field_reg, delta_t_reg, *y1;
510
+ tot_size = c_shape[0]*c_shape[1]*c_shape[2]*nt_reg;
511
+ //printf("Start interpolation, %d, %d, %d, %d, %d\n", c_shape[0], c_shape[1], c_shape[2], nt_reg, tot_size);
512
+ delta_t_reg = (t[t_size-1]-t[0])/(nt_reg-1);
513
+
514
+ y1 = ALLOC_N(double, t_size);
515
+ x_reg = ALLOC_N(double, tot_size);
516
+ y_reg = ALLOC_N(double, tot_size);
517
+ z_reg = ALLOC_N(double, tot_size);
518
+ t_reg = ALLOC_N(double, nt_reg);
519
+ field_reg = ALLOC_N(double, tot_size);
520
+
521
+ for(i1=0; i1<c_shape[0]*c_shape[1]*c_shape[2]*t_size; i1+=t_size)
522
+ {
523
+ //printf("%d, %d\n", i1, c_shape[0]*c_shape[1]*c_shape[2]*t_size);
524
+ for (i2 = 0; i2 < t_size; i2++)
525
+ {
526
+ y1[i2] = field[i1+i2];
527
+ //printf ("%d, %lf %lf\n", i2, t[i2], y1[i2]);
528
+ }
529
+
530
+ gsl_interp_accel *acc
531
+ = gsl_interp_accel_alloc ();
532
+ gsl_spline *spline
533
+ = gsl_spline_alloc (gsl_interp_cspline, t_size);
534
+
535
+ gsl_spline_init (spline, t, y1, t_size);
536
+
537
+ //printf("Interpolated:\n");
538
+ for (ti = 0; ti < nt_reg; ti++)
539
+ {
540
+ t_reg[ti] = t[0]+ti*delta_t_reg;
541
+ idx = floor((i1)/t_size)*nt_reg;
542
+ x_reg[idx+ti] = x[i1];
543
+ y_reg[idx+ti] = y[i1];
544
+ z_reg[idx+ti] = z[i1];
545
+ field_reg[idx+ti] = gsl_spline_eval (spline, t_reg[ti], acc);
546
+ }
547
+ gsl_spline_free (spline);
548
+ gsl_interp_accel_free (acc);
549
+
550
+ }
551
+
552
+ //Can now free the original pointers
553
+ free(x); x=0;
554
+ free(y); y=0;
555
+ free(z); z=0;
556
+ free(t); t=0;
557
+
558
+ /*printf("interpolated:\n");
559
+ for(i1=0; i1<c_shape[1]; i1++){
560
+ index = arr_index(i1,0,0,0,c_shape,nt_reg);
561
+ printf("%lf, ", x_reg[index]);
562
+ }*/
563
+
564
+ /**********************************************************************
565
+ * First need to know max and min lengths and times in each dimension *
566
+ * in order to define bins. These need to be specified before the loop*
567
+ * since the binning will be done at each step since there is too much*
568
+ * info to store. *
569
+ * ********************************************************************/
570
+ double lx_pos_min=20;
571
+ i3=0;
572
+ lxmin=0; lymin=0; lzmin=0;
573
+ for(i1=0; i1<tot_size; i1+=nt_reg){
574
+ //printf("%lf, %lf, %lf\n", x_reg[i1], y_reg[i1], z_reg[i1]);
575
+ for(i2=0; i2<tot_size; i2+=nt_reg)
576
+ {
577
+ lx = x_reg[i2] - x_reg[i1];
578
+ ly = y_reg[i2] - y_reg[i1];
579
+ lz = z_reg[i2] - z_reg[i1];
580
+
581
+ if(lx < lxmin)
582
+ lxmin = lx;
583
+ if(ly < lymin)
584
+ lymin = ly;
585
+ if(lz < lzmin)
586
+ lzmin = lz;
587
+ }
588
+ }
589
+ lxmax = -lxmin;
590
+ lymax = -lymin;
591
+ lzmax = -lzmin;
592
+ ltmin = t_reg[0] - t_reg[nt_reg-1];
593
+ ltmax = -ltmin;
594
+ //printf("\nMin/Max = %lf, %lf\n", lxmin, lxmax);
595
+ //printf("Min/Max = %lf, %lf\n", lymin, lymax);
596
+ //printf("Min/Max = %lf, %lf\n", lzmin, lzmax);
597
+
598
+ //printf("Bins\n");
599
+ //Initialize the bin arrays
600
+ tot_bins = nbins[0]*nbins[1]*nbins[2]*nbins[3];
601
+ lx_bin = ALLOC_N(double, nbins[0]);
602
+ ly_bin = ALLOC_N(double, nbins[1]);
603
+ lz_bin = ALLOC_N(double, nbins[2]);
604
+ lt_bin = ALLOC_N(double, nbins[3]);
605
+
606
+ for(i1=0; i1<nbins[0]; i1++){
607
+ lx_bin[i1] = lxmin + i1*(lxmax-lxmin)/(nbins[0]-1);
608
+ //printf("lx_bin = %f\n ", lx_bin[i1]);
609
+ }
610
+ for(i1=0; i1<nbins[1]; i1++){
611
+ ly_bin[i1] = lymin + i1*(lymax-lymin)/(nbins[1]-1);
612
+ //printf("ly_bin = %f\n", ly_bin[i1]);
613
+ }
614
+ for(i1=0; i1<nbins[2]; i1++){
615
+ lz_bin[i1] = lzmin + i1*(lzmax-lzmin)/(nbins[2]-1);
616
+ //printf("lz_bin = %f\n", lz_bin[i1]);
617
+ }
618
+ for(i1=0; i1<nbins[3]; i1++)
619
+ lt_bin[i1] = ltmin + i1*(ltmax-ltmin)/(nbins[3]-1);
620
+
621
+ //Now define and initialize the coarray and count arrays
622
+ coarray = ALLOC_N(double, tot_bins);
623
+ count = ALLOC_N(int, tot_bins);
624
+ corr_norm = ALLOC_N(double, (2*nt_reg-1)); //store correlate result before adding to coarray
625
+ lt = ALLOC_N(double, (2*nt_reg-1)); //Can calculate lt before loops
626
+
627
+ for(i1=0; i1<tot_bins; i1++){
628
+ coarray[i1] = 0.;
629
+ count[i1] = 0;
630
+ }
631
+ /******************************************************
632
+ * Start looping and calculating correlation function *
633
+ ******************************************************/
634
+ //Can predefine the time separations
635
+ for(i1=0; i1<2*nt_reg-1; i1++){
636
+ if(i1<nt_reg)
637
+ lt[i1] = t_reg[i1] - t_reg[nt_reg-1];
638
+ else if(i1>nt_reg-1)
639
+ lt[i1] = t_reg[i1-nt_reg] - t_reg[0] + delta_t_reg;
640
+ }
641
+
642
+ /* Now test which correlation function is to be calculated since full 4D correlation
643
+ * is usually intractable. The type was read in at begininning and corr_type corresponds to:
644
+ *
645
+ * 0 : perpendicular only (lz = 0)
646
+ * 1 : parallel only (lx = ly = 0)
647
+ * 2 : time only (lx = lz = 0)
648
+ * 3 : full correlation (may take very long) (all separations != 0)
649
+ */
650
+ float eps1 = 1e-5, eps2 = 1e5; //define very small and very large numbers to test against
651
+ float lx_test, ly_test, lz_test;
652
+ switch (corr_type){
653
+ case 0: //perp
654
+ lx_test = eps2;
655
+ ly_test = eps2;
656
+ lz_test = eps1;
657
+ break;
658
+ case 1: //par
659
+ lx_test = eps1;
660
+ ly_test = eps1;
661
+ lz_test = eps2;
662
+ break;
663
+ case 2: //time
664
+ lx_test = eps1;
665
+ ly_test = eps2;
666
+ lz_test = eps1;
667
+ break;
668
+ case 3: //full
669
+ lx_test = eps2;
670
+ ly_test = eps2;
671
+ lz_test = eps2;
672
+ break;
673
+ }
674
+
675
+ //Start main loop for correlation function calculation
676
+ for(i1=0; i1<tot_size; i1+=nt_reg){
677
+ for(i2=i1; i2<tot_size; i2+=nt_reg)
678
+ {
679
+ //Calculate spatial and temporal separation
680
+ lx = x_reg[i2] - x_reg[i1];
681
+ ly = y_reg[i2] - y_reg[i1];
682
+ lz = z_reg[i2] - z_reg[i1];
683
+
684
+ if(lx<lx_test && ly<ly_test && lz<lz_test){
685
+ //Calculate correlation function:
686
+ //corr = correlate(field[i1], field[i2], answer, no of t pts)
687
+ correlate_norm(&field_reg[i1], &field_reg[i2], &corr_norm[0], nt_reg);
688
+
689
+ //Calculate appropriate bin (subtracting min ensures +ve idx)
690
+ ix = floor((lx - lxmin) / (lx_bin[1] - lx_bin[0]));
691
+ iy = floor((ly - lymin) / (ly_bin[1] - ly_bin[0]));
692
+ ith = floor((lz - lzmin) / (lz_bin[1] - lz_bin[0]));
693
+ //printf("(%lf, %lf, %lf, %lf)\n", lz, lzmin, lz_bin[1], lz_bin[0]);
694
+ //printf("indices: (%d, %d, %d)\n", ix, iy, ith);
695
+
696
+ //Loop over time calculate time bin and put into coarray
697
+ for(i3=0; i3<2*nt_reg-1; i3++){
698
+ it = floor((lt[i3] - ltmin) / (lt_bin[1] - lt_bin[0]));
699
+ coarray[ix*nbins[1]*nbins[2]*nbins[3] + iy*nbins[2]*nbins[3] + ith*nbins[3] + it] += corr_norm[i3];
700
+ count[ix*nbins[1]*nbins[2]*nbins[3] + iy*nbins[2]*nbins[3] + ith*nbins[3] + it] += 1;
701
+ }
702
+
703
+ /**************************
704
+ * Repeat for negative *
705
+ * lx, ly, lz, to avoid *
706
+ * recalculating corr_norm*
707
+ **************************/
708
+
709
+ lx = -lx; ly = -ly; lz = -lz;
710
+
711
+ //Calculate appropriate bin (subtracting min ensures +ve idx)
712
+ ix = floor((lx - lxmin) / (lx_bin[1] - lx_bin[0]));
713
+ iy = floor((ly - lymin) / (ly_bin[1] - ly_bin[0]));
714
+ ith = floor((lz - lzmin) / (lz_bin[1] - lz_bin[0]));
715
+ //printf("- = {%d, %d, %d}\n", ix, iy, ith);
716
+
717
+ //Loop over time calculate time bin and put into coarray
718
+ for(i3=0; i3<2*nt_reg-1; i3++){
719
+ it = floor((-lt[i3] - ltmin) / (lt_bin[1] - lt_bin[0]));
720
+ coarray[ix*nbins[1]*nbins[2]*nbins[3] + iy*nbins[2]*nbins[3] + ith*nbins[3] + it] += corr_norm[i3];
721
+ count[ix*nbins[1]*nbins[2]*nbins[3] + iy*nbins[2]*nbins[3] + ith*nbins[3] + it] += 1;
722
+ }
723
+ }
724
+ }
725
+ }
726
+ //End main loop
727
+
728
+ //Finally have to normalize coarray with count when count != 0
729
+ //printf("Normalization: \n");
730
+ for(i1=0; i1<tot_bins; i1++){
731
+ if(count[i1]>0){
732
+ coarray[i1] = coarray[i1]/count[i1];
733
+ }
734
+ }
735
+ //printf("Finish normalization: \n");
736
+
737
+ //Retun output to CR
738
+ VALUE cgsl_tensor, output_tensor;
739
+ cgsl_tensor = RGET_CLASS(cgsl, "Tensor");
740
+ //output_tensor = GSL::Tensor.alloc(nbins, ...)
741
+ output_tensor = rb_funcall(cgsl_tensor, rb_intern("alloc"), 4, INT2FIX(nbins[0]), INT2FIX(nbins[1]), INT2FIX(nbins[2]), INT2FIX(nbins[3]));
742
+
743
+ for(i1=0; i1<nbins[0]; i1++)
744
+ for(i2=0; i2<nbins[1]; i2++)
745
+ for(i3=0; i3<nbins[2]; i3++)
746
+ for(i4=0; i4<nbins[3]; i4++){
747
+ CR_TELMT_R4_SET(output_tensor, i1, i2, i3, i4, rb_float_new(coarray[i1*nbins[1]*nbins[2]*nbins[3] + i2*nbins[2]*nbins[3] + i3*nbins[3] + i4]));
748
+ }
749
+
750
+ printf("Finished correlation analysis\n");
751
+ return output_tensor;
752
+ }
753
+
348
754
  void Init_gs2crmod_ext()
349
755
  {
350
756
  /*printf("HERE!!!");*/
@@ -368,6 +774,7 @@ void Init_gs2crmod_ext()
368
774
 
369
775
  rb_define_method(ccode_runner_gs2_gsl_tensor_complexes, "field_gsl_tensor_complex_2", gs2crmod_tensor_complexes_field_gsl_tensor_complex_2, 1);
370
776
  rb_define_method(ccode_runner_gs2_gsl_tensors, "field_real_space_gsl_tensor", gs2crmod_tensor_field_gsl_tensor, 1);
777
+ rb_define_method(ccode_runner_gs2_gsl_tensors, "field_correlation_gsl_tensor", gs2crmod_tensor_field_correlation_gsl_tensor, 1);
371
778
 
372
779
  /*rb_define_method(ccode_runner_ext, "hello_world", code_runner_ext_hello_world, 0);*/
373
780
  }
data/gs2crmod.gemspec CHANGED
@@ -2,15 +2,12 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: gs2crmod 0.11.20 ruby lib
6
- # stub: ext/extconf.rb
7
5
 
8
6
  Gem::Specification.new do |s|
9
7
  s.name = "gs2crmod"
10
- s.version = "0.11.20"
8
+ s.version = "0.11.21"
11
9
 
12
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
13
- s.require_paths = ["lib"]
14
11
  s.authors = ["Edmund Highcock", "Ferdinand van Wyk"]
15
12
  s.date = "2014-03-04"
16
13
  s.description = "GS2 is a gyrokinetic flux tube initial value turbulence code which can be used for fusion or astrophysical plasmas. CodeRunner is a framework for the automated running and analysis of large simulations. This module allows GS2 (and its sister code AstroGK) to harness the power of the CodeRunner framework."
@@ -85,12 +82,13 @@ Gem::Specification.new do |s|
85
82
  ]
86
83
  s.homepage = "http://gs2crmod.sourceforge.net"
87
84
  s.licenses = ["GSLv3"]
85
+ s.require_paths = ["lib"]
88
86
  s.required_ruby_version = Gem::Requirement.new(">= 1.9.1")
89
- s.rubygems_version = "2.2.1"
87
+ s.rubygems_version = "1.8.11"
90
88
  s.summary = "Module to allow CodeRunner to run and analyse the GS2 and AstroGK codes."
91
89
 
92
90
  if s.respond_to? :specification_version then
93
- s.specification_version = 4
91
+ s.specification_version = 3
94
92
 
95
93
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
96
94
  s.add_runtime_dependency(%q<coderunner>, [">= 0.14.10"])
@@ -7,13 +7,18 @@
7
7
  #define RFCALL_10_ON(obj, name) (rb_funcall(obj, rb_intern(name), 0))
8
8
  #define RFCALL_11(name, arg1) (rb_funcall(self, rb_intern(name), 1, arg1))
9
9
  #define RFCALL_11_ON(obj, name, arg1) (rb_funcall(obj, rb_intern(name), 1, arg1))
10
+ #define RFCALL_12(name, arg1, arg2) (rb_funcall(self, rb_intern(name), 2, arg1, arg2))
11
+ #define RFCALL_12_ON(obj, name, arg1, arg2) (rb_funcall(obj, rb_intern(name), 2, arg1, arg2))
10
12
  #define CR_ELEMENT_ACCESS(recvr, key) ( \
11
13
  RFCALL_11_ON(recvr, "[]", key) \
12
14
  )
13
15
  #define CR_HKS(hash, cstr) (CR_ELEMENT_ACCESS(hash, ID2SYM(rb_intern(cstr))))
16
+ #define CR_HKS_SET(hash, cstr, value)(rb_funcall(hash, rb_intern("[]="), 2, ID2SYM(rb_intern(cstr)), value))
14
17
  #define CR_RANGE_INC(start, end) (rb_funcall(RGET_CLASS_TOP("Range"), rb_intern("new"), 2, INT2FIX(start), INT2FIX(end)))
15
18
  #define CR_RANGE_EXC(start, end) (rb_funcall(RGET_CLASS_TOP("Range"), rb_intern("new"), 3, INT2FIX(start), INT2FIX(end), Qtrue))
16
19
 
20
+ #define CR_SYM(cstr)(ID2SYM(rb_intern(cstr)))
21
+
17
22
  /*Allocates an integer array on the heap
18
23
  with values of array. int_ptr should be
19
24
  an unallocated int*. array should not
@@ -30,6 +35,14 @@
30
35
  FIX2INT(RARRAY_PTR(array)[cr_internal_xaa11]);\
31
36
  }
32
37
 
38
+ /* Get element of a rank 1,2 or 3 tensor respectively */
39
+ #define CR_TELMT_R1(tensor, i)(rb_funcall(tensor, rb_intern("[]"), 1, INT2FIX(i)))
40
+ #define CR_TELMT_R2(tensor, i, j)(rb_funcall(tensor, rb_intern("[]"), 2, INT2FIX(i), INT2FIX(j)))
41
+ #define CR_TELMT_R3(tensor, i, j, k)(rb_funcall(tensor, rb_intern("[]"), 3, INT2FIX(i), INT2FIX(j), INT2FIX(k)))
42
+
43
+ // Set the value of a 4D tensor
44
+ #define CR_TELMT_R4_SET(tensor, i, j, k, l, value)(rb_funcall(tensor, rb_intern("[]="), 5, INT2FIX(i), INT2FIX(j), INT2FIX(k), INT2FIX(l), value))
45
+
33
46
 
34
47
  /*Allocates an integer array on the heap
35
48
  with values of array. int_ptr should be
data/lib/gs2crmod/gs2.rb CHANGED
@@ -1159,6 +1159,90 @@ end
1159
1159
  end
1160
1160
  end
1161
1161
 
1162
+ #This function will handle running the correlation analysis and writing the results to a NetCDF file.
1163
+ #Cases need to be handled differently since perp, par and full are just subsets of the full correlation function
1164
+ #but the time correlation calculation needs to deal with each radial location separately. Time correlation
1165
+ #uses the zonal flows in the toroidal direction to calculate the correlation time.
1166
+ #
1167
+ #This function takes in the same options as field_real_space_standard_representation, along with the following
1168
+ #new options dealing with interpolation and binning:
1169
+ #
1170
+ # correlation_type: determines which subset of correlation function should be calculated (perp/par/full/time)
1171
+ # nbins_array: array giving number of bins to use in the binning procedure. Index order (x, y, z ,t)
1172
+ # nt_reg: Most of the time you have many more time points than you need for spatial correlations. This sets
1173
+ # number of new interpolation points in time.
1174
+ #
1175
+ # Using this function: Since this can only be single threaded, this can be a very expensive calculation when
1176
+ # trying to do the full correlation function, so this is not recommended for highly resolved nonlinear runs. This is
1177
+ # why the perp/par/full splitting is implemented, allowing one dimension to be taken out essentially.
1178
+ def correlation_analysis(options={})
1179
+
1180
+ #Sanity checks:
1181
+ #Cannot only have one bin since require difference between bins for index calculation
1182
+ if options[:nbins_array].include?1
1183
+ raise('Cannot have only one bin in nbins_array. Minuimum is two.')
1184
+ end
1185
+ #Thetamin shouldn't be equal to thetamax to avoid possibili
1186
+ #
1187
+
1188
+ case options[:correlation_type]
1189
+ when 'perp', 'par', 'full'
1190
+ gsl_tensor = field_correlation_gsl_tensor(options)
1191
+ shape = gsl_tensor.shape
1192
+
1193
+ #Set up dimensions
1194
+ file = NumRu::NetCDF.create(@run_name + "_correlation_analysis_#{options[:correlation_type]}.nc")
1195
+ ydim = file.def_dim('x',shape[0])
1196
+ xdim = file.def_dim('y',shape[1])
1197
+ zdim = file.def_dim('z',shape[2])
1198
+ tdim = file.def_dim('t',shape[3])
1199
+ correlation_var = file.def_var("correlation", 'sfloat', [xdim, ydim, zdim, tdim])
1200
+ file.enddef
1201
+ #Write out array
1202
+ correlation_var.put(NArray.to_na(gsl_tensor.to_a))
1203
+ file.close
1204
+ when 'time'
1205
+ nakx_actual = NumRu::NetCDF.open(@run_name + ".out.nc").var('kx').get
1206
+ kx_len = nakx_actual.length
1207
+ if options[:nakx] == nil
1208
+ radial_pts = kx_len
1209
+ elsif options[:nakx] <= kx_len
1210
+ radial_pts = options[:nakx]
1211
+ else
1212
+ raise('nakx exceeds the total number of kx\'s in simulation')
1213
+ end
1214
+
1215
+ #Check whether t_index_window is specified, if not, set to entire t range
1216
+ if options[:t_index_window] == nil
1217
+ options[:t_index_window] = [1, -1]
1218
+ end
1219
+
1220
+
1221
+ #Now loop through the radial locations and calculate the correlation function in y and t.
1222
+ for x in 0...radial_pts
1223
+ options[:xmin] = x
1224
+ options[:xmax] = x
1225
+ gsl_tensor = field_correlation_gsl_tensor(options)
1226
+ shape = gsl_tensor.shape
1227
+
1228
+ if x == 0 #Write dimensions to NetCDF file
1229
+ file = NumRu::NetCDF.create(@run_name + "_correlation_analysis_#{options[:correlation_type]}.nc")
1230
+ ydim = file.def_dim('x',shape[0])
1231
+ xdim = file.def_dim('y',shape[1])
1232
+ zdim = file.def_dim('z',shape[2])
1233
+ tdim = file.def_dim('t',shape[3])
1234
+ end
1235
+ file.redef
1236
+ correlation_var = file.def_var("correlation_x_#{x}", 'sfloat', [xdim, ydim, zdim, tdim])
1237
+ file.enddef
1238
+ #Write out array
1239
+ correlation_var.put(NArray.to_na(gsl_tensor.to_a))
1240
+ end
1241
+ file.close #only close after loop over radial points
1242
+ else
1243
+ raise 'Please specify correlation_type as perp/par/time/full'
1244
+ end
1245
+ end
1162
1246
  end # class GS2
1163
1247
  # For backwards compatibility
1164
1248
 
@@ -171,7 +171,7 @@ class CodeRunner::Gs2
171
171
  case options[:field_name].to_s
172
172
  when /density/
173
173
  options.convert_to_index(self, :species)
174
- ep 'options', options
174
+ #ep 'options', options
175
175
  options[:species_index] - 1
176
176
  else
177
177
  nil
@@ -179,7 +179,7 @@ class CodeRunner::Gs2
179
179
  end
180
180
  def field_gsl_tensor(options)
181
181
  species_element = field_species_element(options)
182
- ep 'species_element', species_element
182
+ #ep 'species_element', species_element
183
183
  if options[:t_index]
184
184
  #ep options; gets
185
185
  #raise CRFatal.new("write_phi_over_time is not enabled so this function won't work") unless @write_phi_over_time
@@ -59,6 +59,12 @@ class TestAnalysis < Test::Unit::TestCase
59
59
  assert_equal(6.6036e-01, @run.frequency_at_ky_at_kx[0.5][2.5133])
60
60
  #p @run.gsl_vector('kx'); STDIN.gets
61
61
  assert_equal(6.6036e-01, @run.frequency_at_ky_at_kx[0.5][@run.gsl_vector('kx')[3]])
62
+
63
+ #Correlation analysis testing
64
+ CodeRunner.run_command('correlation_analysis(correlation_type:"full", field_name:"density", gs2_coordinate_factor:1.0, species_index: 1, nbins_array:[4,4,4,25], nt_reg:25, Rgeo:3, n0:1)', {j:1, Y:tfolder})
65
+ corr_file = NumRu::NetCDF.open("#{tfolder}/v/id_1/v_write_moments_.true._write_line_.true._id_1_correlation_analysis_full.nc")
66
+ corr_function = corr_file.var('correlation').get
67
+ assert_equal([4,4,4,25], corr_function.shape)
62
68
  end
63
69
  def test_interpolation
64
70
  assert_equal(5, @run.gsl_vector('kx').size)
metadata CHANGED
@@ -1,7 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gs2crmod
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.20
4
+ version: 0.11.21
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Edmund Highcock
@@ -13,102 +14,81 @@ date: 2014-03-04 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: coderunner
16
- requirement: !ruby/object:Gem::Requirement
17
+ requirement: &23277780 !ruby/object:Gem::Requirement
18
+ none: false
17
19
  requirements:
18
- - - ">="
20
+ - - ! '>='
19
21
  - !ruby/object:Gem::Version
20
22
  version: 0.14.10
21
23
  type: :runtime
22
24
  prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- version: 0.14.10
25
+ version_requirements: *23277780
28
26
  - !ruby/object:Gem::Dependency
29
27
  name: rubyhacks
30
- requirement: !ruby/object:Gem::Requirement
28
+ requirement: &23277220 !ruby/object:Gem::Requirement
29
+ none: false
31
30
  requirements:
32
- - - ">="
31
+ - - ! '>='
33
32
  - !ruby/object:Gem::Version
34
33
  version: 0.1.2
35
34
  type: :runtime
36
35
  prerelease: false
37
- version_requirements: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- version: 0.1.2
36
+ version_requirements: *23277220
42
37
  - !ruby/object:Gem::Dependency
43
38
  name: ruby-netcdf-updated
44
- requirement: !ruby/object:Gem::Requirement
39
+ requirement: &23273380 !ruby/object:Gem::Requirement
40
+ none: false
45
41
  requirements:
46
- - - ">="
42
+ - - ! '>='
47
43
  - !ruby/object:Gem::Version
48
44
  version: 0.6.6.1
49
45
  type: :runtime
50
46
  prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: 0.6.6.1
47
+ version_requirements: *23273380
56
48
  - !ruby/object:Gem::Dependency
57
49
  name: shoulda
58
- requirement: !ruby/object:Gem::Requirement
50
+ requirement: &23443080 !ruby/object:Gem::Requirement
51
+ none: false
59
52
  requirements:
60
- - - ">="
53
+ - - ! '>='
61
54
  - !ruby/object:Gem::Version
62
55
  version: '0'
63
56
  type: :development
64
57
  prerelease: false
65
- version_requirements: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- version: '0'
58
+ version_requirements: *23443080
70
59
  - !ruby/object:Gem::Dependency
71
60
  name: rdoc
72
- requirement: !ruby/object:Gem::Requirement
61
+ requirement: &23442460 !ruby/object:Gem::Requirement
62
+ none: false
73
63
  requirements:
74
- - - "~>"
64
+ - - ~>
75
65
  - !ruby/object:Gem::Version
76
66
  version: '3.12'
77
67
  type: :development
78
68
  prerelease: false
79
- version_requirements: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - "~>"
82
- - !ruby/object:Gem::Version
83
- version: '3.12'
69
+ version_requirements: *23442460
84
70
  - !ruby/object:Gem::Dependency
85
71
  name: bundler
86
- requirement: !ruby/object:Gem::Requirement
72
+ requirement: &23441920 !ruby/object:Gem::Requirement
73
+ none: false
87
74
  requirements:
88
- - - ">"
75
+ - - ! '>'
89
76
  - !ruby/object:Gem::Version
90
77
  version: 1.0.0
91
78
  type: :development
92
79
  prerelease: false
93
- version_requirements: !ruby/object:Gem::Requirement
94
- requirements:
95
- - - ">"
96
- - !ruby/object:Gem::Version
97
- version: 1.0.0
80
+ version_requirements: *23441920
98
81
  - !ruby/object:Gem::Dependency
99
82
  name: jeweler
100
- requirement: !ruby/object:Gem::Requirement
83
+ requirement: &23441400 !ruby/object:Gem::Requirement
84
+ none: false
101
85
  requirements:
102
- - - ">="
86
+ - - ! '>='
103
87
  - !ruby/object:Gem::Version
104
88
  version: 1.8.4
105
89
  type: :development
106
90
  prerelease: false
107
- version_requirements: !ruby/object:Gem::Requirement
108
- requirements:
109
- - - ">="
110
- - !ruby/object:Gem::Version
111
- version: 1.8.4
91
+ version_requirements: *23441400
112
92
  description: GS2 is a gyrokinetic flux tube initial value turbulence code which can
113
93
  be used for fusion or astrophysical plasmas. CodeRunner is a framework for the automated
114
94
  running and analysis of large simulations. This module allows GS2 (and its sister
@@ -122,7 +102,7 @@ extra_rdoc_files:
122
102
  - README.md
123
103
  - README.rdoc
124
104
  files:
125
- - ".document"
105
+ - .document
126
106
  - Gemfile
127
107
  - LICENSE.txt
128
108
  - README.md
@@ -185,25 +165,26 @@ files:
185
165
  homepage: http://gs2crmod.sourceforge.net
186
166
  licenses:
187
167
  - GSLv3
188
- metadata: {}
189
168
  post_install_message:
190
169
  rdoc_options: []
191
170
  require_paths:
192
171
  - lib
193
172
  required_ruby_version: !ruby/object:Gem::Requirement
173
+ none: false
194
174
  requirements:
195
- - - ">="
175
+ - - ! '>='
196
176
  - !ruby/object:Gem::Version
197
177
  version: 1.9.1
198
178
  required_rubygems_version: !ruby/object:Gem::Requirement
179
+ none: false
199
180
  requirements:
200
- - - ">="
181
+ - - ! '>='
201
182
  - !ruby/object:Gem::Version
202
183
  version: '0'
203
184
  requirements: []
204
185
  rubyforge_project:
205
- rubygems_version: 2.2.1
186
+ rubygems_version: 1.8.11
206
187
  signing_key:
207
- specification_version: 4
188
+ specification_version: 3
208
189
  summary: Module to allow CodeRunner to run and analyse the GS2 and AstroGK codes.
209
190
  test_files: []
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 6573d709227e4e6a3ef38b5e91a2a798051bbe94
4
- data.tar.gz: 34e87dca9ffb31bb3700be59cf829adb3c8a0bf7
5
- SHA512:
6
- metadata.gz: b059c57412e1c7cf3dfd78d4c2d2cf8dfc588ce9d4336b39608861351210605501656b1c512997e99afdf4771d582858ccd2e051322cee777bcc4f28f198e405
7
- data.tar.gz: 2df0e3c66ed093b41fc620775a7b8b01622fe3d7188ee5a7e7b1622ef94c7c73038e68bcd175af0f7ec727b6f3ceb57025ae6f4e7740fda93ebb6cb5a2bfe9bb