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 +1 -1
- data/ext/gs2crmod_ext.c +407 -0
- data/gs2crmod.gemspec +4 -6
- data/include/gs2crmod_ext.h +13 -0
- data/lib/gs2crmod/gs2.rb +84 -0
- data/lib/gs2crmod/gsl_data_3d.rb +2 -2
- data/test/test_gs2crmod.rb +6 -0
- metadata +37 -56
- checksums.yaml +0 -7
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.11.
|
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.
|
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 = "
|
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 =
|
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"])
|
data/include/gs2crmod_ext.h
CHANGED
@@ -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
|
|
data/lib/gs2crmod/gsl_data_3d.rb
CHANGED
@@ -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
|
data/test/test_gs2crmod.rb
CHANGED
@@ -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.
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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
|
-
-
|
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:
|
186
|
+
rubygems_version: 1.8.11
|
206
187
|
signing_key:
|
207
|
-
specification_version:
|
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
|