gs2crmod 0.11.20 → 0.11.21

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/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