From 5e48668823b5e7613da65795d3201b8b48604fb9 Mon Sep 17 00:00:00 2001
From: Antoine Cyril David Hoffmann <ahoffman@spcpc606.epfl.ch>
Date: Tue, 5 Apr 2022 17:27:10 +0200
Subject: [PATCH] first commit of z parallel version, still buggy

---
 Makefile                                      |  16 +-
 matlab/compile_results.m                      |  74 ++-
 matlab/compute/compute_fluxtube_growth_rate.m |  72 +++
 matlab/compute/ifourier_GENE.m                |  57 ++-
 .../compute/rotate_c_plane_nxnky_to_nkxny.m   |  52 ++
 matlab/load/load_gene_data.m                  |  72 +++
 matlab/load/read_namelist.m                   | 219 +++++++++
 matlab/plot/gene_transport_spectrum.m         |   6 +-
 matlab/plot/plot_fluxes.m                     |   5 +
 matlab/plot/plot_metric.m                     |  26 +
 .../plot_radial_transport_and_spacetime.m     |  72 ++-
 matlab/plot/show_geometry.m                   |  10 +-
 matlab/plot/spectrum_1D.m                     | 146 +++---
 matlab/process_field.m                        |  40 ++
 src/advance_field.F90                         |   4 +-
 src/array_mod.F90                             |  24 +-
 src/auxval.F90                                |   1 -
 src/basic_mod.F90                             |   9 +-
 src/calculus_mod.F90                          | 190 +++++---
 src/closure_mod.F90                           | 132 ++++--
 src/collision_mod.F90                         |  13 +-
 src/diagnose.F90                              |  75 ++-
 src/diagnostics_par_mod.F90                   |   4 +-
 src/geometry_mod.F90                          |  43 +-
 src/ghosts_mod.F90                            | 162 ++++++-
 src/grid_mod.F90                              | 210 +++++----
 src/inital.F90                                |  90 ++--
 src/memory.F90                                |  76 +--
 ...ents_eq_rhs.F90 => moments_eq_rhs_mod.F90} | 162 +++----
 src/{compute_Sapj.F90 => nonlinear_mod.F90}   |  39 +-
 src/numerics_mod.F90                          |  12 +-
 src/poisson.F90                               |  28 +-
 src/ppinit.F90                                |  17 +-
 src/prec_const_mod.F90                        |   1 +
 src/processing_mod.F90                        | 444 +++++++++++++-----
 src/srcinfo.h                                 |   4 +-
 src/srcinfo/srcinfo.h                         |   4 +-
 src/stepon.F90                                |  42 +-
 src/utility_mod.F90                           |   8 +-
 wk/analysis_3D.m                              |  87 ++--
 wk/analysis_header.m                          | 164 +------
 wk/analysis_header_2DZP.m                     | 171 +++++++
 wk/benchmark_HeLaZ_gene_transport_zpinch.m    |   6 +-
 wk/gene_analysis_3D.m                         |  84 ++++
 wk/tmp.txt                                    |   0
 45 files changed, 2259 insertions(+), 914 deletions(-)
 create mode 100644 matlab/compute/compute_fluxtube_growth_rate.m
 create mode 100644 matlab/compute/rotate_c_plane_nxnky_to_nkxny.m
 create mode 100644 matlab/load/load_gene_data.m
 create mode 100644 matlab/load/read_namelist.m
 create mode 100644 matlab/plot/plot_fluxes.m
 create mode 100644 matlab/plot/plot_metric.m
 rename src/{moments_eq_rhs.F90 => moments_eq_rhs_mod.F90} (61%)
 rename src/{compute_Sapj.F90 => nonlinear_mod.F90} (96%)
 create mode 100644 wk/analysis_header_2DZP.m
 create mode 100644 wk/gene_analysis_3D.m
 delete mode 100644 wk/tmp.txt

diff --git a/Makefile b/Makefile
index 8901e87b..8066b0e2 100644
--- a/Makefile
+++ b/Makefile
@@ -55,10 +55,10 @@ $(OBJDIR)/diagnose.o : src/srcinfo.h
 
 FOBJ=$(OBJDIR)/advance_field.o $(OBJDIR)/array_mod.o $(OBJDIR)/auxval.o $(OBJDIR)/basic_mod.o \
 $(OBJDIR)/coeff_mod.o $(OBJDIR)/closure_mod.o $(OBJDIR)/collision_mod.o \
-$(OBJDIR)/compute_Sapj.o $(OBJDIR)/control.o $(OBJDIR)/fourier_mod.o \
+$(OBJDIR)/nonlinear_mod.o $(OBJDIR)/control.o $(OBJDIR)/fourier_mod.o \
 $(OBJDIR)/diagnose.o $(OBJDIR)/diagnostics_par_mod.o $(OBJDIR)/endrun.o $(OBJDIR)/fields_mod.o \
 $(OBJDIR)/inital.o $(OBJDIR)/initial_par_mod.o $(OBJDIR)/geometry_mod.o \
-$(OBJDIR)/main.o $(OBJDIR)/memory.o $(OBJDIR)/model_mod.o $(OBJDIR)/moments_eq_rhs.o \
+$(OBJDIR)/main.o $(OBJDIR)/memory.o $(OBJDIR)/model_mod.o $(OBJDIR)/moments_eq_rhs_mod.o \
 $(OBJDIR)/numerics_mod.o $(OBJDIR)/poisson.o $(OBJDIR)/ppexit.o $(OBJDIR)/ppinit.o $(OBJDIR)/prec_const_mod.o \
 $(OBJDIR)/processing_mod.o $(OBJDIR)/readinputs.o $(OBJDIR)/ghosts_mod.o $(OBJDIR)/grid_mod.o \
 $(OBJDIR)/restarts_mod.o $(OBJDIR)/stepon.o $(OBJDIR)/tesend.o $(OBJDIR)/time_integration_mod.o \
@@ -94,8 +94,8 @@ $(OBJDIR)/utility_mod.o
  $(OBJDIR)/collision_mod.o : src/collision_mod.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/time_integration_mod.o $(OBJDIR)/utility_mod.o
 	 	$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/collision_mod.F90 -o $@
 
- $(OBJDIR)/compute_Sapj.o : src/compute_Sapj.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/fourier_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/time_integration_mod.o
-		$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/compute_Sapj.F90 -o $@
+ $(OBJDIR)/nonlinear_mod.o : src/nonlinear_mod.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/fourier_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/time_integration_mod.o
+		$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/nonlinear_mod.F90 -o $@
 
  $(OBJDIR)/control.o : src/control.F90 $(OBJDIR)/auxval.o $(OBJDIR)/geometry_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/ppexit.o $(OBJDIR)/ppinit.o $(OBJDIR)/readinputs.o $(OBJDIR)/tesend.o
 	$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/control.F90 -o $@
@@ -139,13 +139,13 @@ $(OBJDIR)/utility_mod.o
  $(OBJDIR)/model_mod.o : src/model_mod.F90 $(OBJDIR)/prec_const_mod.o
 	$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/model_mod.F90 -o $@
 
- $(OBJDIR)/moments_eq_rhs.o : src/moments_eq_rhs.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/calculus_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/time_integration_mod.o
-	$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/moments_eq_rhs.F90 -o $@
+ $(OBJDIR)/moments_eq_rhs_mod.o : src/moments_eq_rhs_mod.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/calculus_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/time_integration_mod.o
+	$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/moments_eq_rhs_mod.F90 -o $@
 
  $(OBJDIR)/numerics_mod.o : src/numerics_mod.F90 $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/coeff_mod.o $(OBJDIR)/utility_mod.o
 	$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/numerics_mod.F90 -o $@
 
- $(OBJDIR)/poisson.o : src/poisson.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/array_mod.o $(OBJDIR)/time_integration_mod.o $(OBJDIR)/basic_mod.o
+ $(OBJDIR)/poisson.o : src/poisson.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/ghosts_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/array_mod.o $(OBJDIR)/time_integration_mod.o $(OBJDIR)/basic_mod.o
 	$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/poisson.F90 -o $@
 
  $(OBJDIR)/ppexit.o : src/ppexit.F90 $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/coeff_mod.o
@@ -166,7 +166,7 @@ $(OBJDIR)/utility_mod.o
  $(OBJDIR)/restarts_mod.o : src/restarts_mod.F90  $(OBJDIR)/diagnostics_par_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/time_integration_mod.o
 	$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/restarts_mod.F90 -o $@
 
- $(OBJDIR)/stepon.o : src/stepon.F90 $(OBJDIR)/initial_par_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/advance_field.o $(OBJDIR)/basic_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/array_mod.o $(OBJDIR)/numerics_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/ghosts_mod.o $(OBJDIR)/moments_eq_rhs.o $(OBJDIR)/poisson.o $(OBJDIR)/time_integration_mod.o $(OBJDIR)/utility_mod.o $(OBJDIR)/model_mod.o
+ $(OBJDIR)/stepon.o : src/stepon.F90 $(OBJDIR)/initial_par_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/advance_field.o $(OBJDIR)/basic_mod.o $(OBJDIR)/nonlinear_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/array_mod.o $(OBJDIR)/numerics_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/ghosts_mod.o $(OBJDIR)/moments_eq_rhs_mod.o $(OBJDIR)/poisson.o $(OBJDIR)/time_integration_mod.o $(OBJDIR)/utility_mod.o $(OBJDIR)/model_mod.o
 	$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/stepon.F90 -o $@
 
  $(OBJDIR)/tesend.o : src/tesend.F90 $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o
diff --git a/matlab/compile_results.m b/matlab/compile_results.m
index b511eb92..03aa07db 100644
--- a/matlab/compile_results.m
+++ b/matlab/compile_results.m
@@ -19,6 +19,16 @@ PGAMMA_  = [];
 PHI_     = [];
 DENS_E_  = [];
 DENS_I_  = [];
+UPAR_E_  = [];
+UPAR_I_  = [];
+UPER_E_  = [];
+UPER_I_  = [];
+TPAR_E_  = [];
+TPAR_I_  = [];
+TPER_E_  = [];
+TPER_I_  = [];
+TEMP_E_  = [];
+TEMP_I_  = [];
 TEMP_E_  = [];
 TEMP_I_  = [];
 Ts0D_    = [];
@@ -39,15 +49,14 @@ while(CONTINUE)
         DT_SIM    = h5readatt(filename,'/data/input','dt');
         [Pe, Je, Pi, Ji, kx, ky, z] = load_grid_data(filename);
         W_GAMMA   = strcmp(h5readatt(filename,'/data/input','write_gamma'),'y');
-        W_HF      = 0;%strcmp(h5readatt(filename,'/data/input','write_hf'   ),'y');
+        W_HF      = strcmp(h5readatt(filename,'/data/input','write_hf'   ),'y');
         W_PHI     = strcmp(h5readatt(filename,'/data/input','write_phi'  ),'y');
         W_NA00    = strcmp(h5readatt(filename,'/data/input','write_Na00' ),'y');
         W_NAPJ    = strcmp(h5readatt(filename,'/data/input','write_Napj' ),'y');
-        W_SAPJ    = 0;%strcmp(h5readatt(filename,'/data/input','write_Sapj' ),'y');
+        W_SAPJ    = strcmp(h5readatt(filename,'/data/input','write_Sapj' ),'y');
         W_DENS    = strcmp(h5readatt(filename,'/data/input','write_dens' ),'y');
         W_TEMP    = strcmp(h5readatt(filename,'/data/input','write_temp' ),'y');
         KIN_E     = strcmp(h5readatt(filename,'/data/input',     'KIN_E' ),'y');
-%         KIN_E     = 1;
         
         % Check polynomials degrees
         Pe_new= numel(Pe); Je_new= numel(Je);
@@ -127,11 +136,31 @@ while(CONTINUE)
         [DENS_I, Ts3D, ~] = load_3D_data(filename, 'dens_i');
             DENS_I_ = cat(4,DENS_I_,DENS_I); clear DENS_I
         end
+        if 0
+            if KIN_E
+        [UPAR_E, Ts3D, ~] = load_3D_data(filename, 'upar_e');
+            UPAR_E_ = cat(4,UPAR_E_,UPAR_E); clear UPAR_E
+        [UPER_E, Ts3D, ~] = load_3D_data(filename, 'uper_e');
+%             UPER_E_ = cat(4,UPER_E_,UPER_E); clear UPER_E
+            end
+        [UPAR_I, Ts3D, ~] = load_3D_data(filename, 'upar_i');
+            UPAR_I_ = cat(4,UPAR_I_,UPAR_I); clear UPAR_I
+        [UPER_I, Ts3D, ~] = load_3D_data(filename, 'uper_i');
+            UPER_I_ = cat(4,UPER_I_,UPER_I); clear UPER_I
+        end
         if W_TEMP
             if KIN_E 
+%         [TPAR_E, Ts3D, ~] = load_3D_data(filename, 'Tpar_e');
+%             TPAR_E_ = cat(4,TPAR_E_,TPAR_E); clear TPAR_E
+%         [TPER_E, Ts3D, ~] = load_3D_data(filename, 'Tper_e');
+%             TPER_E_ = cat(4,TPER_E_,TPER_E); clear TPER_E
         [TEMP_E, Ts3D, ~] = load_3D_data(filename, 'temp_e');
                 TEMP_E_ = cat(4,TEMP_E_,TEMP_E); clear TEMP_E
             end
+%         [TPAR_I, Ts3D, ~] = load_3D_data(filename, 'Tpar_i');
+%             TPAR_I_ = cat(4,TPAR_I_,TPAR_I); clear TPAR_I
+%         [TPER_I, Ts3D, ~] = load_3D_data(filename, 'Tper_i');
+%             TPER_I_ = cat(4,TPER_I_,TPER_I); clear TPER_I
         [TEMP_I, Ts3D, ~] = load_3D_data(filename, 'temp_i');
             TEMP_I_ = cat(4,TEMP_I_,TEMP_I); clear TEMP_I
         end
@@ -178,19 +207,38 @@ while(CONTINUE)
 end
 
 %% Build grids
-Nkx = numel(kx); Nky = numel(ky);
+
+Nkx = numel(kx); 
+if Nkx > 1
+    dkx = kx(2); 
+    Lx = 2*pi/dkx;   
+else
+    dkx = 0;
+    Lx  = 0;   
+end
+[~,ikx0] = min(abs(kx)); 
+Nx = 2*Nkx-1;  
+x  = linspace(-Lx/2,Lx/2,Nx+1); x = x(1:end-1);
+
+Nky = numel(ky);
+if Nky > 1
+    dky = ky(2);
+    Ly = 2*pi/dky;
+else
+    dky = 0;
+    Ly  = 0;
+end    
+[~,iky0] = min(abs(ky));
+Ny = Nky;      
+y  = linspace(-Ly/2,Ly/2,Ny+1); y = y(1:end-1);
+
+Nz = numel(z);
+
 [KY,KX] = meshgrid(ky,kx);
-Lkx = max(kx)-min(kx); Lky = max(ky)-min(ky);
-dkx = Lkx/(Nkx-1); dky = Lky/(Nky-1);
 KPERP2 = KY.^2+KX.^2;
-[~,ikx0] = min(abs(kx)); [~,iky0] = min(abs(ky));
-
-Nx = 2*(Nkx-1);  Ny = Nky;      Nz = numel(z);
-Lx = 2*pi/dkx;   Ly = 2*pi/dky;
-dx = Lx/Nx;      dy = Ly/Ny; dz = 2*pi/Nz;
-x = dx*(-Nx/2:(Nx/2-1)); Lx = max(x)-min(x);
-y = dy*(-Ny/2:(Ny/2-1)); Ly = max(y)-min(y);
 %% Add everything in output structure
+% scaling
+DATA.scale = -(1/Nx/Ny)^2;
 % Fields
 DATA.GGAMMA_RI = GGAMMA_; DATA.PGAMMA_RI = PGAMMA_; DATA.HFLUX_X = HFLUX_;
 DATA.Nipj = Nipj_; DATA.Ni00 = Ni00_; DATA.DENS_I = DENS_I_; DATA.TEMP_I = TEMP_I_;
diff --git a/matlab/compute/compute_fluxtube_growth_rate.m b/matlab/compute/compute_fluxtube_growth_rate.m
new file mode 100644
index 00000000..60fb9437
--- /dev/null
+++ b/matlab/compute/compute_fluxtube_growth_rate.m
@@ -0,0 +1,72 @@
+function [ linear_gr ] = compute_fluxtube_growth_rate(DATA, TRANGE, PLOT)
+
+% Remove AA part
+if DATA.Nx > 1
+    ikxnz = abs(DATA.PHI(:,1,1,1)) > 0;
+else
+    ikxnz = abs(DATA.PHI(:,1,1,1)) > -1;
+end
+ikynz = abs(DATA.PHI(1,:,1,1)) > 0;
+
+phi = DATA.PHI(ikxnz,ikynz,:,:);
+t   = DATA.Ts3D;
+
+[~,its] = min(abs(t-TRANGE(1)));
+[~,ite] = min(abs(t-TRANGE(end)));
+
+w_ky = zeros(sum(ikynz),ite-its);
+ce   = zeros(sum(ikynz),ite-its);
+
+is = 1;
+for it = its+1:ite
+    phi_n   = phi(:,:,:,it); 
+    phi_nm1 = phi(:,:,:,it-1);
+    dt      = t(it)-t(it-1);
+    ZS      = sum(sum(phi_nm1,1),3);
+   
+    wl         = log(phi_n./phi_nm1)/dt;
+    w_ky(:,is) = sum(sum(wl.*phi_nm1,1),3)./ZS;
+    
+    for iky = 1:numel(w_ky(:,is))
+        ce(iky,is)   = abs(sum(sum(abs(w_ky(iky,is)-wl(:,iky,:)).^2.*phi_nm1(:,iky,:),1),3)./ZS(:,iky,:));
+    end
+    is = is + 1;
+end
+[kys, Is] = sort(DATA.ky(ikynz));
+
+linear_gr.trange = t(its:ite);
+linear_gr.g_ky   = real(w_ky(Is,:));
+linear_gr.w_ky   = imag(w_ky(Is,:));
+linear_gr.ce     = abs(ce);
+linear_gr.ky     = kys;
+if PLOT >0
+       figure
+       plot(linear_gr.ky,linear_gr.g_ky(:,end),'DisplayName','$Re(\omega_{k_y})$'); hold on;
+       plot(linear_gr.ky,linear_gr.w_ky(:,end),'DisplayName','$Im(\omega_{k_y})$'); hold on;
+       plot(linear_gr.ky,linear_gr.ce  (:,end),'DisplayName','$\epsilon$'); hold on;
+       xlim([min(linear_gr.ky) max(linear_gr.ky)]);
+       xlabel('$k_y$');
+       legend('show');
+       if PLOT > 1
+           [YY,XX] = meshgrid(kys,t(its+1:ite));
+           figure
+              subplot(311)
+%            imagesc(t(its:ite),kys,real(w_ky)); set(gca,'YDir','normal'); 
+           pclr = pcolor(XX',YY',real(w_ky));    set(pclr, 'edgecolor','none'); 
+           xlabel('$t$'); ylabel('$k_y$');
+           title('Re($\omega$)')
+           
+              subplot(312)
+           pclr = pcolor(XX',YY',imag(w_ky));    set(pclr, 'edgecolor','none'); 
+           xlabel('$t$'); ylabel('$k_y$');
+           title('Im($\omega$)')
+           
+              subplot(313)
+           pclr = pcolor(XX',YY',abs(w_ky));    set(pclr, 'edgecolor','none'); 
+           xlabel('$t$'); ylabel('$k_y$');
+           title('|$\omega$|')
+       end
+
+end
+
+end
\ No newline at end of file
diff --git a/matlab/compute/ifourier_GENE.m b/matlab/compute/ifourier_GENE.m
index 15a94dab..f5d98f75 100644
--- a/matlab/compute/ifourier_GENE.m
+++ b/matlab/compute/ifourier_GENE.m
@@ -1,26 +1,47 @@
-function [ field_r ] = ifourier_GENE( field_c, dims )
+function [ field_r ] = ifourier_GENE( field_c )
 %IFOURIER_FIELD_GENE method of ifourier used in GENE post processing
 %   This fourier transform back from the half complex plane to a full real
 %   space, in 2 or 3D (dim). Compied from computeFXYZ of GENE for
 %   comparison purpose.
-sz = size(field_c);
-nkx = sz(1);
-field_r = zeros(dims);
 
-if numel(dims) == 2 %2D
-    nx = dims(1); ny = dims(2);
-    %note, we need one extra point which we set to zero for the ifft 
-    spectrumKxKyZ                  = zeros(nx,ny);
-    spectrumKxKyZ(1:nkx,:)         = field_c;
-    spectrumKxKyZ((nkx):(nx),1)    = conj(field_c(nkx:-1:2));       
-    spectrumKxKyZ((nkx):(nx),2:ny) = conj(field_c(nkx:-1:2,ny:-1:2));
-    
-%     spectrumKxYZ = ny*ifft(spectrumKxKyZ,[],2);
-%     field_r      = nx*ifft(spectrumKxYZ,[],1,'symmetric');
-    
-    spectrumKxYZ = ifft(spectrumKxKyZ,[],2);
-    field_r      = ifft(spectrumKxYZ,[],1,'symmetric');
-end
+%% Original
+% [nx,nky,nz]=size(field_c);
+% %extend to whole ky by imposing reality condition
+% ny=2*nky-1;
+% 
+% if ny~=1
+%     %note, we need one extra point which we set to zero for the ifft 
+%     spectrumKxKyZ=zeros(nx,ny,nz);
+%     spectrumKxKyZ(:,1:nky,:)=field_c(:,:,:);
+%     spectrumKxKyZ(1,(nky+1):(ny),:)=conj(field_c(1,nky:-1:2,:));
+%     spectrumKxKyZ(2:nx,(nky+1):(ny),:)=conj(field_c(nx:-1:2,nky:-1:2,:));
+% else
+%     %pad with zeros to interpolate on fine scale
+%     ny=20;
+%     spectrumKxKyZ=zeros(nx,ny,nz);
+%     spectrumKxKyZ(:,2,:)=field_c(:,:,:);
+% end   
+% 
+% %inverse fft, symmetric as we are using real data
+% spectrumXKyZ=nx*ifft(spectrumKxKyZ,[],1);
+% field_r=ny*ifft(spectrumXKyZ,[],2,'symmetric');
+% clear spectrumKxKyZ 
+
+%% Adapted for HeLaZ representation
+[nkx,ny,nz]=size(field_c);
+%extend to whole ky by imposing reality condition
+nx=2*nkx-1;
+
+%note, we need one extra point which we set to zero for the ifft 
+spectrumKxKyZ=zeros(nx,ny,nz);
+spectrumKxKyZ(1:nkx,:,:)=field_c(:,:,:);
+spectrumKxKyZ((nkx+1):(nx),1,:)=conj(field_c(nkx:-1:2,1,:));
+spectrumKxKyZ((nkx+1):(nx),2:ny,:)=conj(field_c(nkx:-1:2,ny:-1:2,:));
 
+%inverse fft, symmetric as we are using real data
+spectrumXKyZ=nx*ifft(spectrumKxKyZ,[],1);
+field_r=ny*ifft(spectrumXKyZ,[],2,'symmetric');
+clear spectrumKxKyZ 
+ 
 end
 
diff --git a/matlab/compute/rotate_c_plane_nxnky_to_nkxny.m b/matlab/compute/rotate_c_plane_nxnky_to_nkxny.m
new file mode 100644
index 00000000..0bcdb1e6
--- /dev/null
+++ b/matlab/compute/rotate_c_plane_nxnky_to_nkxny.m
@@ -0,0 +1,52 @@
+function [ data ] = rotate_c_plane_nxnky_to_nkxny( data )
+%to go from nx nky Gene representation to nkx ny HeLaZ one
+
+kx_full  = data.kx;
+
+ky_full  = [data.ky; -data.ky(end-1:-1:2)];
+
+dens = data.DENS_I; temp = data.TEMP_I; phi = data.PHI;
+
+dims = size(dens); nz = dims(3); nt = dims(4);
+
+nkx = numel(data.kx); 
+nky = numel(data.ky); 
+nx  = nkx;
+ny  = 2*numel(data.ky)-1;
+
+%note, we need one extra point which we set to zero for the ifft 
+dens_full                        = zeros(nx,ny,nz,nt);
+dens_full(:,1:nky,:,:)           = dens(:,:,:,:);
+dens_full(1,(nky+1):(ny),:,:)    = conj(dens(1,nky:-1:2,:,:));       
+dens_full(2:nx,(nky+1):(ny),:,:) = conj(dens(nx:-1:2,nky:-1:2,:,:)); 
+dens_full = cat(2,dens(1:data.Nkx,:,:,:),conj(dens(1:data.Nkx,end-1:-1:2,:,:)));
+
+temp_full                        = zeros(nx,ny,nz,nt);
+temp_full(:,1:nky,:,:)           = temp(:,:,:,:);
+temp_full(1,(nky+1):(ny),:,:)    = conj(temp(1,nky:-1:2,:,:));       
+temp_full(2:nx,(nky+1):(ny),:,:) = conj(temp(nx:-1:2,nky:-1:2,:,:)); 
+temp_full = cat(2,temp(1:data.Nkx,:,:,:),conj(temp(1:data.Nkx,end-1:-1:2,:,:)));
+
+phi_full                        = zeros(nx,ny,nz,nt);
+phi_full(:,1:nky,:,:)           = phi(:,:,:,:);
+phi_full(1,(nky+1):(ny),:,:)    = conj(phi(1,nky:-1:2,:,:));       
+phi_full(2:nx,(nky+1):(ny),:,:) = conj(phi(nx:-1:2,nky:-1:2,:,:));
+phi_full  = cat(2, phi(1:data.Nkx,:,:,:),conj( phi(1:data.Nkx,end-1:-1:2,:,:)));
+
+data.DENS_I = dens_full(1:data.Nkx/2+1,:,:,:);
+data.TEMP_I = temp_full(1:data.Nkx/2+1,:,:,:);
+data.PHI    = phi_full (1:data.Nkx/2+1,:,:,:);
+data.kx     = kx_full(1:data.Nkx/2+1);
+data.ky     = ky_full;
+data.Nkx    = numel(data.kx);
+data.Nky    = numel(data.ky);
+data.Nx     = nx+1;
+data.Ny     = ny-1;
+
+dkx = data.kx(2); dky = data.ky(2);
+Lx = 2*pi/dkx;   Ly = 2*pi/dky;
+x = linspace(-Lx/2,Lx/2,data.Nx+1); x = x(1:end-1);
+y = linspace(-Ly/2,Ly/2,data.Ny+1); y = y(1:end-1);
+data.x = x; data.y = y; data.Lx = Lx; data.Ly = Ly;
+end
+
diff --git a/matlab/load/load_gene_data.m b/matlab/load/load_gene_data.m
new file mode 100644
index 00000000..2fdb98a4
--- /dev/null
+++ b/matlab/load/load_gene_data.m
@@ -0,0 +1,72 @@
+function [ DATA ] = load_gene_data( folder )
+%to load gene data as for HeLaZ results
+namelist      = read_namelist([folder,'parameters.dat']);
+DATA.namelist = namelist;
+%% Grid
+file = 'coord.dat.h5';
+DATA.vp  = h5read([folder,file],'/coord/vp');
+DATA.Nvp = numel(DATA.vp);
+
+DATA.mu  = h5read([folder,file],'/coord/mu');
+DATA.Nmu = numel(DATA.mu);
+
+DATA.kx  = h5read([folder,file],'/coord/kx');
+DATA.Nkx = numel(DATA.kx);
+DATA.Nx  = DATA.Nkx;
+
+DATA.ky  = h5read([folder,file],'/coord/ky');
+DATA.Nky = numel(DATA.ky);
+DATA.Ny  = DATA.Nky*2-1;
+
+DATA.z   = h5read([folder,file],'/coord/z');
+DATA.Nz  = numel(DATA.z);
+
+dkx = DATA.kx(2); dky = DATA.ky(2);
+Lx = 2*pi/dkx;   Ly = 2*pi/dky;
+x = linspace(-Lx/2,Lx/2,DATA.Nx+1); x = x(1:end-1);
+y = linspace(-Ly/2,Ly/2,DATA.Ny+1); y = y(1:end-1);
+DATA.x = x; DATA.y = y; DATA.Lx = Lx; DATA.Ly = Ly;
+%% Transport
+file           = 'nrg.dat.h5';
+DATA.Ts0D      = h5read([folder,file],'/nrgions/time');
+DATA.PGAMMA_RI = h5read([folder,file],'/nrgions/Gamma_es');
+DATA.HFLUX_X   = h5read([folder,file],'/nrgions/Q_es');
+
+%% fields and moments
+file = 'mom_ions.dat.h5';
+DATA.Ts3D = h5read([folder,file],'/mom_ions/time');
+DATA.DENS_I = zeros(DATA.Nkx,DATA.Nky,DATA.Nz,numel(DATA.Ts3D));
+DATA.TPER_I = zeros(DATA.Nkx,DATA.Nky,DATA.Nz,numel(DATA.Ts3D));
+DATA.TPAR_I = zeros(DATA.Nkx,DATA.Nky,DATA.Nz,numel(DATA.Ts3D));
+DATA.PHI    = zeros(DATA.Nkx,DATA.Nky,DATA.Nz,numel(DATA.Ts3D));
+
+for jt = 1:numel(DATA.Ts3D)
+    t = DATA.Ts3D(jt);
+    [~, it] = min(abs(DATA.Ts3D-t));
+
+    tmp = h5read([folder,file],['/mom_ions/dens/',sprintf('%10.10d',it-1)]);
+    DATA.DENS_I(:,:,:,it) = tmp.real + 1i*tmp.imaginary;
+
+    tmp = h5read([folder,file],['/mom_ions/T_par/',sprintf('%10.10d',it-1)]);
+    DATA.TPAR_I(:,:,:,it) = tmp.real + 1i*tmp.imaginary;
+ 
+    tmp = h5read([folder,file],['/mom_ions/T_perp/',sprintf('%10.10d',it-1)]);
+    DATA.TPER_I(:,:,:,it) = tmp.real + 1i*tmp.imaginary;
+    
+    tmp = h5read([folder,'field.dat.h5'],['/field/phi/',sprintf('%10.10d',it-1)]);
+    DATA.PHI(:,:,:,it) = tmp.real + 1i*tmp.imaginary;
+
+end
+
+DATA.TEMP_I = (DATA.TPAR_I + 2*DATA.TPER_I)/3.0 - DATA.DENS_I;
+DATA.scale = 1;
+DATA.PARAMS = ['GENE'];
+DATA.param_title = 'GENE';
+DATA.localdir = folder;
+%% Geometry
+CMD = ['tail -n ',num2str(namelist.box.nz0),' ',folder,namelist.geometry.magn_geometry{1},'.dat > tmp.txt'];
+system(CMD);
+DATA.geo_arrays = load('tmp.txt');
+system('rm tmp.txt');
+end
+
diff --git a/matlab/load/read_namelist.m b/matlab/load/read_namelist.m
new file mode 100644
index 00000000..74f64c69
--- /dev/null
+++ b/matlab/load/read_namelist.m
@@ -0,0 +1,219 @@
+
+function S = read_namelist(filename)
+%   S = READ_NAMELIST(FILENAME) returns the struct S containg namelists and
+%   variables in the file FILENAME organised in hierachical way:
+%
+%                  |--VAR1
+%                  |--VAR2
+%     |-- NMLST_A--|...
+%     |            |--VARNa
+%     |
+%     |            |--VAR1
+%     |-- NMLST_B--|--VAR2
+%     |            |...
+% S --|     ...    |--VARNb
+%     |
+%     |            |--VAR1
+%     |-- NMLST_M--|--VAR2
+%                  |...
+%                  |--VARNm
+% 
+%   Note:  The function can read multidimensioal variables as well. The  
+%   function assumes that there is no more than one namelist section per 
+%   line. At this time there is no syntax checking functionality so the 
+%   function will crash in case of errors.
+%    
+%   Example:
+%       NMLST = read_namelist('OPTIONS.nam');
+%       NMLST.NAM_FRAC.XUNIF_NATURE = 0.1;
+%       write_namelist(NMlST, 'MOD_OPTIONS.nam');
+%
+%   Written by:     Darien Pardinas Diaz (darien.pardinas-diaz@monash.edu)
+%   Version:        1.0
+%   Date:           16 Dec 2011
+S = struct();
+% Open and read the text file containing the namelists
+fid = fopen(filename,'r');
+c = 0;
+lines = cell(1);
+% Read all the text lines in namelist file
+while ~feof(fid)
+    line = fgetl(fid);
+    % Remove comments if any on the line
+    idx = find(line == '!');
+    if ~isempty(idx),
+        line = line(1:idx(1)-1);
+    end
+    if ~isempty(line),
+        c = c + 1;
+        lines{c} = line;
+    end
+end
+fclose(fid);
+i = 0;
+while i < c;    
+    % Find a record
+    i = i + 1; 
+    line = lines{i};
+    idx = find(line == '&');
+    if ~isempty(idx), % i.e. a namelist start
+        line = line(idx(1) + 1:end);
+        % find next space
+        idx = find(line == ' ');
+        if ~isempty(idx),
+            namelst = line(1:idx(1) - 1);
+            line = line(idx(1) + 1:end);
+        else
+            namelst = line;
+            line = [];
+        end
+        nmlst_bdy = [];
+        idx = strfind(line,'/');
+        % Get the variable specification section
+        while isempty(idx) && i < c,
+            nmlst_bdy = [nmlst_bdy ' ' line]; 
+            i = i + 1;
+            line = lines{i};
+            idx = strfind(line,'/');
+        end
+        if ~isempty(idx) && idx(1) > 1,
+            nmlst_bdy = [nmlst_bdy ' ' line];
+        end
+        % Parse current namelist (set of variables)
+        switch namelst
+            case 'info'
+            otherwise
+            S.(namelst) = parse_namelist(nmlst_bdy);        
+        end
+    end
+end
+function S = parse_namelist(strng)
+% Internal function to parse the body text of a namelist section.
+% Limitations: the following patterns are prohibited inside the literal
+% strings: '.t.' '.f.' '.true.' '.false.' '(:)'
+% Get all .true., .t. and .false., .f. to T and F
+strng = regexprep(strng,'\.true\.' ,'T','ignorecase'); 
+strng = regexprep(strng,'\.false\.','F','ignorecase');
+strng = regexprep(strng,'\.t\.','T','ignorecase'); 
+strng = regexprep(strng,'\.f\.','F','ignorecase');
+% Make evaluable the (:) expression in MATLAB if any
+strng = regexprep(strng, '\(:\)', '(1,:)');
+[strng, islit] = parse_literal_strings([strng ' ']);
+% Find the position of all the '='
+eq_idx = find(strng == '=');
+nvars = length(eq_idx);
+arg_start = eq_idx + 1;
+arg_end   = zeros(size(eq_idx));
+vars = cell(nvars,1);
+S = struct;
+% Loop through every variable
+for k = 1:nvars,
+    i = eq_idx(k) - 1;
+    % Move to the left and discard blank spaces
+    while strng(i) == ' ', i = i - 1; end
+    % Now we are over the variable name or closing parentesis
+    j = i;
+    if strng(i) == ')',
+        while strng(i) ~= '(', i = i - 1; end
+        i = i - 1;
+        % Move to the left and discard any possible blank spaces
+        while strng(i) == ' ', i = i - 1; end
+    end
+    
+    % Now we are over the last character of the variable name
+    while strng(i) ~= ' ', i = i - 1; end    
+    
+    if k > 1, arg_end(k - 1) = i; end    
+    vars{k} = ['S.' strng(i + 1: j)];
+end
+if numel(arg_end) > 0
+arg_end(end) = length(strng);
+end
+% This variables are used in the eval function to evaluate True/False, 
+% so don't remove it!
+T = '.true.';
+F = '.false.';
+% Loop through every variable guess varible type
+for k = 1:nvars,    
+    arg = strng(arg_start(k):arg_end(k));
+    arglit = islit(arg_start(k):arg_end(k))';
+    % Remove commas in non literal string...
+    commas = ~arglit & arg == ',';
+    if any(commas)
+        arg(commas) = ' ';
+    end
+    
+    if any(arglit),
+        % We are parsing a variable that is literal string
+        arg = ['{' arg '};'];
+    elseif ~isempty(find( arg == 'T' | arg == 'F', 1)),
+        % We are parsing a boolean variable
+        arg = ['{' arg '};'];
+    else
+        % We are parsing a numerical array
+        arg = ['[' arg '];'];
+    end
+    % Eval the modified syntax in Matlab
+    eval([vars{k} ' = ' arg]);
+end
+function [strng, is_lit] = parse_literal_strings(strng)
+% Parse the literal declarations of strings and change to Matlab syntax
+len = length(strng);
+add_squote = []; % Positions to add a scape single quote on syntax
+rem_dquote = []; % Positions to remove a double quote scape on syntax
+i = 1;
+while i < len,
+    if strng(i) == '''',  % Opening string with single quote...
+        i = i + 1;
+        while i < len && strng(i) ~= '''' || strcmp(strng(i:i+1),'''''') , 
+            i = i + 1; 
+            if strcmp(strng(i-1:i),''''''),
+                i = i + 1;
+            end
+        end   
+    end
+    if strng(i) == '"',  % Opening string with double quote...
+        strng(i) = ''''; % Change to single quote
+        i = i + 1;
+        while strng(i) ~= '"' || strcmp(strng(i:i+1),'""') && i < len,
+            % Check for a possible sigle quote here
+            if strng(i) == '''',
+                add_squote = [add_squote i];
+            end            
+            i = i + 1; 
+            if strcmp(strng(i-1:i),'""'),
+                rem_dquote = [rem_dquote i-1];
+                i = i + 1;
+            end
+        end
+        strng(i) = ''''; % Change to single quote
+    end    
+    i = i + 1;
+end
+for i = 1:length(add_squote);
+    strng = [strng(1:add_squote(i)) strng(add_squote(i):end)];
+end
+for i = 1:length(rem_dquote);
+    strng = [strng(1:rem_dquote(i)-1) strng(rem_squote(i)+1:end)];
+end
+% Now everything should be in Matlab string syntax
+% Classify syntax as literal or regular expression
+i = 1;
+len = length(strng);
+is_lit = zeros(len,1);
+while i < len,
+    if strng(i) == '''',  % Opening string with single quote...
+        is_lit(i) = 1;
+        i = i + 1;
+        while i < len && strng(i) ~= '''' || strcmp(strng(i:i+1),''''''), 
+            is_lit(i) = 1;
+            i = i + 1; 
+            if strcmp(strng(i-1:i),''''''),
+                is_lit(i) = 1;
+                i = i + 1;
+            end
+        end
+        is_lit(i) = 1;    
+    end
+    i = i + 1;
+end
diff --git a/matlab/plot/gene_transport_spectrum.m b/matlab/plot/gene_transport_spectrum.m
index 66563af5..e6244070 100644
--- a/matlab/plot/gene_transport_spectrum.m
+++ b/matlab/plot/gene_transport_spectrum.m
@@ -1,9 +1,9 @@
 % folder = '/misc/gene_results/NL_Zpinch_Kn_1.8_eta_0.25_nuSG_5e-2_mu_1e-2_SGDK_36x20/';
 % folder = '/misc/gene_results/HP_fig_2c_mu_5e-2/';
-folder = '/misc/gene_results/HP_fig_2b_mu_5e-2/';
+% folder = '/misc/gene_results/HP_fig_2b_mu_5e-2/';
 % folder = '/misc/gene_results/HP_fig_2c_gyroLES/';
 % folder = '/misc/gene_results/NL_Zpinch_Kn_1.8_eta_0.25_nuSG_5e-2_mu_1e-2_SGDK_128x32x48x32/';
-
+folder = '/misc/gene_results/shearless_cyclone/output/';
 file = 'coord.dat.h5';
 vp = h5read([folder,file],'/coord/vp');
 mu = h5read([folder,file],'/coord/mu');
@@ -17,7 +17,7 @@ file = 'field.dat.h5';
 time  = h5read([folder,file],'/field/time');
 
 KDIM = 'ky';
-TIMES = 2500:100:3500;
+TIMES = time;
 switch KDIM
     case 'kx'
         sdim  = 2;
diff --git a/matlab/plot/plot_fluxes.m b/matlab/plot/plot_fluxes.m
new file mode 100644
index 00000000..02905b11
--- /dev/null
+++ b/matlab/plot/plot_fluxes.m
@@ -0,0 +1,5 @@
+figure
+subplot(211)
+plot(data.Ts0D,data.PGAMMA_RI');
+subplot(212)
+plot(data.Ts0D,-data.HFLUX_X);
\ No newline at end of file
diff --git a/matlab/plot/plot_metric.m b/matlab/plot/plot_metric.m
new file mode 100644
index 00000000..b4b9e080
--- /dev/null
+++ b/matlab/plot/plot_metric.m
@@ -0,0 +1,26 @@
+function [ fig ] = plot_metric( data )
+
+names = {'$g^{xx}$','$g^{xy}$','$g^{xz}$','$g^{yy}$','$g^{yz}$','$g^{zz}$',...
+         '$B_0$','$\partial_x B_0$','$\partial_y B_0$','$\partial_z B_0$',...
+         '$J$','$R$','$\phi$','$Z$','$\partial_R x$','$\partial_Z x$'};
+data.geo_arrays = load([data.localdir,'geometry.dat']);
+fig = figure;
+subplot(311)
+    for i = 1:6
+    plot(data.z, data.geo_arrays(:,i),'DisplayName',names{i}); hold on;
+    end
+    xlim([min(data.z),max(data.z)]); legend('show'); title('MoNoLiT geometry');
+    
+subplot(312)
+    for i = 7:10
+    plot(data.z, data.geo_arrays(:,i),'DisplayName',names{i}); hold on;
+    end
+    xlim([min(data.z),max(data.z)]); legend('show');
+
+subplot(313)
+    for i = 11:16
+    plot(data.z, data.geo_arrays(:,i),'DisplayName',names{i}); hold on;
+    end
+    xlim([min(data.z),max(data.z)]); legend('show');
+end
+
diff --git a/matlab/plot/plot_radial_transport_and_spacetime.m b/matlab/plot/plot_radial_transport_and_spacetime.m
index 9a3234df..be4680f6 100644
--- a/matlab/plot/plot_radial_transport_and_spacetime.m
+++ b/matlab/plot/plot_radial_transport_and_spacetime.m
@@ -1,14 +1,17 @@
-function [FIGURE] = plot_radial_transport_and_spacetime(DATA, TAVG_0, TAVG_1,stfname,Nmvm)
+function [FIGURE] = plot_radial_transport_and_spacetime(DATA, TAVG_0, TAVG_1,stfname,Nmvm, COMPZ)
     %Compute steady radial transport
     tend = TAVG_1; tstart = TAVG_0;
     [~,its0D] = min(abs(DATA.Ts0D-tstart));
     [~,ite0D]   = min(abs(DATA.Ts0D-tend));
-    SCALE = (1/DATA.Nx/DATA.Ny)^2;
-    gamma_infty_avg = mean(DATA.PGAMMA_RI(its0D:ite0D))*SCALE;
-    gamma_infty_std = std (DATA.PGAMMA_RI(its0D:ite0D))*SCALE;
+    SCALE = DATA.scale;%(1/DATA.Nx/DATA.Ny)^2;
+    Gx_infty_avg = mean(DATA.PGAMMA_RI(its0D:ite0D))*SCALE;
+    Gx_infty_std = std (DATA.PGAMMA_RI(its0D:ite0D))*SCALE;
+    Qx_infty_avg = mean(DATA.HFLUX_X(its0D:ite0D))*SCALE;
+    Qx_infty_std = std (DATA.HFLUX_X(its0D:ite0D))*SCALE;
     [~,ikzf] = max(squeeze(mean(abs(squeeze(DATA.PHI(:,1,1,:))),2)));
     Ns3D = numel(DATA.Ts3D);
     [KY, KX] = meshgrid(DATA.ky, DATA.kx);
+    z = DATA.z;
     
     %% computations
 
@@ -16,12 +19,22 @@ function [FIGURE] = plot_radial_transport_and_spacetime(DATA, TAVG_0, TAVG_1,stf
     Gx = zeros(DATA.Nx,DATA.Ny,numel(DATA.Ts3D));
     for it = 1:numel(DATA.Ts3D)
         for iz = 1:DATA.Nz
-            Gx(:,:,it)  = Gx(:,:,it) + ifourier_GENE(-1i*KY.*(DATA.PHI(:,:,iz,it)),[DATA.Nx,DATA.Ny])...
-                          .*ifourier_GENE(DATA.DENS_I(:,:,iz,it),[DATA.Nx,DATA.Ny]);
+            Gx(:,:,it)  = Gx(:,:,it) + ifourier_GENE(-1i*KY.*(DATA.PHI(:,:,iz,it)))...
+                          .*ifourier_GENE(DATA.DENS_I(:,:,iz,it));
         end
         Gx(:,:,it)  = Gx(:,:,it)/DATA.Nz;
     end
-    Gamma_t_mtlb = squeeze(mean(mean(Gx,1),2)); 
+    Gx_t_mtlb = squeeze(mean(mean(Gx,1),2)); 
+    % Compute Heat flux from ifft matlab
+    Qx = zeros(DATA.Nx,DATA.Ny,numel(DATA.Ts3D));
+    for it = 1:numel(DATA.Ts3D)
+        for iz = 1:DATA.Nz
+            Qx(:,:,it)  = Qx(:,:,it) + ifourier_GENE(-1i*KY.*(DATA.PHI(:,:,iz,it)))...
+                          .*ifourier_GENE(DATA.TEMP_I(:,:,iz,it));
+        end
+        Qx(:,:,it)  = Qx(:,:,it)/DATA.Nz;
+    end
+    Qx_t_mtlb = squeeze(mean(mean(Qx,1),2)); 
     % zonal vs nonzonal energies for phi(t)
 
     E_Zmode_SK       = zeros(1,Ns3D);
@@ -35,16 +48,25 @@ function [FIGURE] = plot_radial_transport_and_spacetime(DATA, TAVG_0, TAVG_1,stf
 
 %% Figure    
 mvm = @(x) movmean(x,Nmvm);
-    FIGURE.fig = figure; FIGURE.FIGNAME = ['ZF_transport_drphi','_',DATA.PARAMS]; set(gcf, 'Position',  [100, 100, 1200, 600])
+    FIGURE.fig = figure; FIGURE.FIGNAME = ['ZF_transport_drphi','_',DATA.PARAMS]; set(gcf, 'Position',  [100, 100, 1000, 600])
     subplot(311)
-%     yyaxis left
+    yyaxis left
         plot(mvm(DATA.Ts0D),mvm(DATA.PGAMMA_RI*SCALE),'DisplayName','$\langle n_i \partial_y\phi \rangle_y$'); hold on;
-        plot(mvm(DATA.Ts3D),mvm(Gamma_t_mtlb),'DisplayName','matlab comp.'); hold on;
-        plot(DATA.Ts0D(its0D:ite0D),ones(ite0D-its0D+1,1)*gamma_infty_avg, '-k',...
-            'DisplayName',['$\Gamma^{\infty} = $',num2str(gamma_infty_avg),'$\pm$',num2str(gamma_infty_std)]);
-        grid on; set(gca,'xticklabel',[]); ylabel('$\Gamma_x$')
-        ylim([0,5*abs(gamma_infty_avg)]); xlim([DATA.Ts0D(1),DATA.Ts0D(end)]);
-        title([DATA.param_title,', $\Gamma^{\infty} = $',num2str(gamma_infty_avg),'$\pm$',num2str(gamma_infty_std)]);
+        plot(mvm(DATA.Ts3D),mvm(Gx_t_mtlb),'DisplayName','matlab comp.'); hold on;
+        plot(DATA.Ts0D(its0D:ite0D),ones(ite0D-its0D+1,1)*Gx_infty_avg, '-k',...
+            'DisplayName',['$\Gamma^{\infty} = $',num2str(Gx_infty_avg),'$\pm$',num2str(Gx_infty_std)]);
+        ylabel('$\Gamma_x$')
+        ylim([0,5*abs(Gx_infty_avg)]); xlim([DATA.Ts0D(1),DATA.Ts0D(end)]);
+    yyaxis right
+        plot(mvm(DATA.Ts0D),mvm(DATA.HFLUX_X*SCALE),'DisplayName','$\langle n_i \partial_y\phi \rangle_y$'); hold on;
+        plot(mvm(DATA.Ts3D),mvm(Qx_t_mtlb),'DisplayName','matlab comp.'); hold on;
+        plot(DATA.Ts0D(its0D:ite0D),ones(ite0D-its0D+1,1)*Qx_infty_avg, '-k',...
+            'DisplayName',['$Q_x^{\infty} = $',num2str(Qx_infty_avg),'$\pm$',num2str(Qx_infty_std)]);
+        ylabel('$Q_x$')  
+        ylim([0,5*abs(Qx_infty_avg)]); xlim([DATA.Ts0D(1),DATA.Ts0D(end)]);
+    grid on; set(gca,'xticklabel',[]); 
+    title({DATA.param_title,...
+        ['$\Gamma^{\infty} = $',num2str(Gx_infty_avg),'$, Q^{\infty} = $',num2str(Qx_infty_avg)]});
     %% radial shear radial profile
         % computation
     Ns3D = numel(DATA.Ts3D);
@@ -53,29 +75,39 @@ mvm = @(x) movmean(x,Nmvm);
     kycut = max(DATA.ky);
     kxcut = max(DATA.kx);
     LP = (abs(KY)<kycut).*(abs(KX)<kxcut); %Low pass filter
+    switch COMPZ
+        case 'avg'
+            compz = @(f) mean(f,3);
+            nameL = '$\langle$ ';
+            nameR = ' $\rangle_{z}$';
+        otherwise
+            compz = @(f) f(:,:,COMPZ);
+            nameL = '';
+            nameR = [' $(z=',num2str(z(COMPZ)),')$'];
+    end
     switch stfname
         case 'phi'
                 phi            = zeros(DATA.Nx,DATA.Ny,1,Ns3D);
                 for it = 1:numel(DATA.Ts3D)
-                    phi(:,:,1,it)  = ifourier_GENE(DATA.PHI(:,:,1,it),[DATA.Nx,DATA.Ny]);
+                    phi(:,:,1,it)  = ifourier_GENE(compz(DATA.PHI(:,:,:,it)));
                 end
                 f2plot = phi; fname = '$\phi$';
         case 'v_y'
                 dxphi            = zeros(DATA.Nx,DATA.Ny,1,Ns3D);
                 for it = 1:numel(DATA.Ts3D)
-                    dxphi(:,:,1,it)  = ifourier_GENE(-1i*KX.*(DATA.PHI(:,:,1,it)).*LP,[DATA.Nx,DATA.Ny]);
+                    dxphi(:,:,1,it)  = ifourier_GENE(-1i*KX.*compz(DATA.PHI(:,:,:,it)).*LP);
                 end
                 f2plot = dxphi; fname = '$\langle \partial_x\phi\rangle_y$';
         case 'v_x'
                 dyphi            = zeros(DATA.Nx,DATA.Ny,1,Ns3D);
                 for it = 1:numel(DATA.Ts3D)
-                    dyphi(:,:,1,it)  = ifourier_GENE(1i*KY.*(DATA.PHI(:,:,1,it)).*LP,[DATA.Nx,DATA.Ny]);
+                    dyphi(:,:,1,it)  = ifourier_GENE(1i*KY.*compz(DATA.PHI(:,:,:,it)).*LP);
                 end
                 f2plot = dyphi; fname = '$\langle \partial_y\phi\rangle_y$';
         case 'szf'
             dx2phi           = zeros(DATA.Nx,DATA.Ny,1,Ns3D);
             for it = 1:numel(DATA.Ts3D)
-                dx2phi(:,:,1,it) = ifourier_GENE(-KX.^2.*(DATA.PHI(:,:,1,it)).*LP,[DATA.Nx,DATA.Ny]);
+                dx2phi(:,:,1,it) = ifourier_GENE(-KX.^2.*compz(DATA.PHI(:,:,:,it)).*LP);
             end
             f2plot = dx2phi; fname = '$\langle \partial_x^2\phi\rangle_y$';
     end
@@ -84,7 +116,7 @@ mvm = @(x) movmean(x,Nmvm);
         [TY,TX] = meshgrid(DATA.x,DATA.Ts3D);
         pclr = pcolor(TX,TY,squeeze(plt(f2plot))'); 
         set(pclr, 'edgecolor','none'); 
-        legend(fname) %colorbar;
+        legend([nameL,fname,nameR]) %colorbar;
         caxis(clim*[-1 1]);
         cmap = bluewhitered(256);
         colormap(cmap)
diff --git a/matlab/plot/show_geometry.m b/matlab/plot/show_geometry.m
index 3794d8c8..926eef86 100644
--- a/matlab/plot/show_geometry.m
+++ b/matlab/plot/show_geometry.m
@@ -64,11 +64,13 @@ FIGURE.fig = figure; FIGURE.FIGNAME = ['geometry','_',DATA.PARAMS]; set(gcf, 'Po
 for it_ = 1:numel(OPTIONS.TIME)
 subplot(1,numel(OPTIONS.TIME),it_)
     %plot magnetic geometry
+    if OPTIONS.PLT_MTOPO
     magnetic_topo=surf(x_tor, y_tor, z_tor); hold on;alpha 1.0;%light('Position',[-1 1 1],'Style','local')
-    set(magnetic_topo,'edgecolor',[1 1 1]*0.8,'facecolor','none')
+    set(magnetic_topo,'edgecolor',[1 1 1]*0.7,'facecolor','none')
+    end
     %plot field line
     theta  = linspace(-Nturns*pi, Nturns*pi, 512)   ; % Poloidal angle
-    plot3(Xfl(theta),Yfl(theta),Zfl(theta))
+    plot3(Xfl(theta),Yfl(theta),Zfl(theta)); hold on;
     %plot vector basis
     theta  = DATA.z   ; % Poloidal angle
     plot3(Xfl(theta),Yfl(theta),Zfl(theta),'ok'); hold on;
@@ -100,9 +102,9 @@ subplot(1,numel(OPTIONS.TIME),it_)
         ylim([-0.1 0.1]);
         zlim([-0.2 0.2]);
     end
-    end
+end
     %%
-    % axis equal
+    axis equal
     view([1,-2,1])
 
 end
diff --git a/matlab/plot/spectrum_1D.m b/matlab/plot/spectrum_1D.m
index d57f6755..dea4c3f2 100644
--- a/matlab/plot/spectrum_1D.m
+++ b/matlab/plot/spectrum_1D.m
@@ -1,8 +1,10 @@
 function [ FIGURE ] = spectrum_1D( data, options )
 
 options.PLAN      = 'kxky';
-options.COMP      = 1;
+options.COMP      = 'avg';
+options.INTERP    = 0;
 options.POLARPLOT = 0;
+options.AXISEQUAL = 1;
 toplot = process_field(data,options);
 t = data.Ts3D; frames = toplot.FRAMES;
 
@@ -23,6 +25,7 @@ switch options.NAME
     yname = '$\sum_{k_y}|n_e|$'; fieldname = 'elec. dens.';
 end
 
+PLOT2D = 0;
 switch options.COMPXY
     case 'avg'
         compx = @(x) mean(x,1);
@@ -34,12 +37,14 @@ switch options.COMPXY
         compx = @(x) max(x,1);
         compy = @(x) max(x,2);
     otherwise
-        compx =  @(x) x(data.kx==0,:);
-        compy =  @(x) x(:,data.ky==0);
+        compx =  @(x) x(:,:);
+        compy =  @(x) x(:,:);
+        PLOT2D= 1;
 end
 
-set(gcf, 'Position',  [20 50 5000 2000])
-subplot(1,2,1)
+if ~PLOT2D
+    set(gcf, 'Position',  [20 50 5000 2000])
+    subplot(1,2,1)
 
     k     = data.kx;
     xname = '$k_x$';
@@ -48,82 +53,89 @@ subplot(1,2,1)
     shiftx = @(x) x;%(1:nmax);
     shifty = @(x) x;%(1:nmax);
     switch options.COMPT
-        case 'avg'
-            it0 = toplot.FRAMES(1); it1 = toplot.FRAMES(end);
-            Gk    = compy(abs(mean(toplot.FIELD(:,:,it0:it1),3)));
-            Gk    = squeeze(Gk);
-            if options.NORM
-                Gk    = Gk./max(abs(Gk));
-            end
-            X = shiftx(k);
-            if options.OK
-                Y = shifty(Gk)./X;
-            else
-                Y = shifty(Gk);
-            end
-            plot(X,Y,'DisplayName','t-averaged')  
-        otherwise
-        for it = 1:numel(toplot.FRAMES)
-            Gk    = compy(abs(toplot.FIELD(:,:,toplot.FRAMES(it))));
-            Gk    = squeeze(Gk);
-            if options.NORM
-                Gk    = Gk./max(abs(Gk));
-            end
-            X = shiftx(k);
-            if options.OK
-                Y = shifty(Gk)./X;
-            else
-                Y = shifty(Gk);
-            end
-            plot(X,Y,'DisplayName',['$t=',num2str(t(frames(it))),'$'],...
-                'Color',colors(it,:)); hold on;
+    case 'avg'
+        it0 = toplot.FRAMES(1); it1 = toplot.FRAMES(end);
+        Gk    = compy(abs(mean(toplot.FIELD(:,:,it0:it1),3)));
+        Gk    = squeeze(Gk);
+        if options.NORM
+            Gk    = Gk./max(max(abs(Gk)));
+        end
+        X = shiftx(k);
+        if options.OK
+            Y = shifty(Gk)./X;
+        else
+            Y = shifty(Gk);
+        end
+        plot(X,Y,'DisplayName','t-averaged')  
+    otherwise
+    for it = 1:numel(toplot.FRAMES)
+        Gk    = compy(abs(toplot.FIELD(:,:,toplot.FRAMES(it))));
+        Gk    = squeeze(Gk);
+        if options.NORM
+            Gk    = Gk./max(max(abs(Gk)));
         end
+        X = shiftx(k);
+        if options.OK
+            Y = shifty(Gk)./X;
+        else
+            Y = shifty(Gk);
+        end
+        plot(X,Y,'DisplayName',['$t=',num2str(t(frames(it))),'$'],...
+            'Color',colors(it,:)); hold on;
+    end
     end
     grid on
     title(['HeLaZ $k_x$ ',fieldname,' spectrum']); legend('show','Location','eastoutside')
     xlabel(xname); ylabel(yname)
-    
-subplot(1,2,2)
+
+    subplot(1,2,2)
 
     k     = data.ky;
     xname = '$k_y$';
     nmax  = floor(data.Nky/2*2/3);
-    AA     = @(x) x(1:nmax);
-    shiftx = @(x) x;%AA(x);
-    shifty = @(x) x;%AA(ifftshift(x));
     switch options.COMPT
-        case 'avg'
-            it0 = toplot.FRAMES(1); it1 = toplot.FRAMES(end);
-            Gk    = compx(abs(mean(toplot.FIELD(:,:,it0:it1),3)))';
-            Gk    = squeeze(Gk);
-            if options.NORM
-                Gk    = Gk./max(abs(Gk));
-            end
-            X = k(k>0); X = X(1:end-1);
-            Yp= Gk(k>0);
-            Ym= Gk(k<0);
-            Y = Yp(1:end-1) + Ym(end:-1:1); 
-            Y = Y(end:-1:1);
-            plot(X,Y,'DisplayName','t-averaged')  
-        otherwise
-        for it = 1:numel(toplot.FRAMES)
-            Gk    = compx(abs(toplot.FIELD(:,:,toplot.FRAMES(it))));
-            Gk    = squeeze(Gk);
-            if options.NORM
-                Gk    = Gk./max(abs(Gk));
-            end
-            X = k(k>0); X = X(1:end-1);
-            Yp= Gk(k>0);
-            Ym= Gk(k<0);
-            Y = Yp(1:end-1) + Ym(end:-1:1); 
-            Y = Y(end:-1:1);
-            plot(X,Y,'DisplayName',['$t=',num2str(t(frames(it))),'$'],...
-                'Color',colors(it,:)); hold on;
+    case 'avg'
+        it0 = toplot.FRAMES(1); it1 = toplot.FRAMES(end);
+        Gk    = compx(abs(mean(toplot.FIELD(:,:,it0:it1),3)))';
+        Gk    = squeeze(Gk);
+        if options.NORM
+            Gk    = Gk./max(max(abs(Gk)));
+        end
+        X = k(k>0); X = X(1:end-1);
+        Yp= Gk(k>0);
+        Ym= Gk(k<0);
+        Y = Yp(1:end-1) + Ym(end:-1:1); 
+        Y = Y(end:-1:1);
+        plot(X,Y,'DisplayName','t-averaged')  
+    otherwise
+    for it = 1:numel(toplot.FRAMES)
+        Gk    = compx(abs(toplot.FIELD(:,:,toplot.FRAMES(it))));
+        Gk    = squeeze(Gk);
+        if options.NORM
+            Gk    = Gk./max(max(abs(Gk)));
         end
+        X = k(k>0); X = X(1:end-1);
+        Yp= Gk(k>0);
+        Ym= Gk(k<0);
+        Y = Yp(1:end-1) + Ym(end:-1:1); 
+        Y = Y(end:-1:1);
+        plot(X,Y,'DisplayName',['$t=',num2str(t(frames(it))),'$'],...
+            'Color',colors(it,:)); hold on;
+    end
     end
     grid on
-%     title('HeLaZ $k_y$ transport spectrum'); 
+    %     title('HeLaZ $k_y$ transport spectrum'); 
     legend('show','Location','eastoutside');
     xlabel(xname); ylabel(yname)
+else
+    it0 = toplot.FRAMES(1); it1 = toplot.FRAMES(end);
+    Gk    = mean(abs(toplot.FIELD(:,:,it0:it1)),3);
+    Gk    = squeeze(Gk);
+    if options.NORM
+        Gk    = Gk./max(max(abs(Gk)));
+    end
+    pclr = pcolor(toplot.X,toplot.Y,Gk);
+    set(pclr, 'edgecolor','none');
+
 end
 
diff --git a/matlab/process_field.m b/matlab/process_field.m
index ff8d00ee..f19f1b2d 100644
--- a/matlab/process_field.m
+++ b/matlab/process_field.m
@@ -151,6 +151,26 @@ switch OPTIONS.NAME
                 FIELD(:,:,it) = squeeze(compr(tmp));
             end                
         end
+    case 'N_i^{00}'
+        NAME = 'Ni00';
+        if COMPDIM == 3
+            for it = FRAMES
+                tmp = squeeze(compr(DATA.Ni00(:,:,:,it)));
+                FIELD(:,:,it) = squeeze(process(tmp));
+            end
+        else
+            if REALP
+                tmp = zeros(Nx,Ny,Nz);
+            else
+                tmp = zeros(DATA.Nkx,DATA.Nky,Nz);
+            end
+            for it = FRAMES
+                for iz = 1:numel(DATA.z)
+                    tmp(:,:,iz) = squeeze(process(DATA.Ni00(:,:,iz,it)));
+                end
+                FIELD(:,:,it) = squeeze(compr(tmp));
+            end                
+        end
     case 'n_e'
         NAME = 'ne';
         if COMPDIM == 3
@@ -234,6 +254,26 @@ switch OPTIONS.NAME
                 FIELD(:,:,it) = squeeze(compr(tmp));
             end                
         end
+    case 'T_i'
+        NAME = 'Ti';
+        if COMPDIM == 3
+            for it = FRAMES
+                tmp = squeeze(compr(DATA.TEMP_I(:,:,:,it)));
+                FIELD(:,:,it) = squeeze(process(tmp));
+            end
+        else
+            if REALP
+                tmp = zeros(Nx,Ny,Nz);
+            else
+                tmp = zeros(DATA.Nkx,DATA.Nky,Nz);
+            end
+            for it = FRAMES
+                for iz = 1:numel(DATA.z)
+                    tmp(:,:,iz) = squeeze(process(DATA.TEMP_I(:,:,iz,it)));
+                end
+                FIELD(:,:,it) = squeeze(compr(tmp));
+            end                
+        end
     case 'n_i^{NZ}'
         NAME = 'niNZ';
         if COMPDIM == 3
diff --git a/src/advance_field.F90 b/src/advance_field.F90
index 071d1217..9ebdba45 100644
--- a/src/advance_field.F90
+++ b/src/advance_field.F90
@@ -32,7 +32,7 @@ CONTAINS
         p_int = parray_e(ip)
         DO ij=ijs_e,ije_e
           IF((CLOS .NE. 1) .OR. (ip-1+2*(ij-1)+1 .LE. dmaxe))&
-          CALL advance_field(moments_e(ip,ij,:,:,:,:), moments_rhs_e(ip,ij,:,:,:,:))
+          CALL advance_field(moments_e(ip,ij,ikxs:ikxe,ikys:ikye,izs:ize,:), moments_rhs_e(ip,ij,ikxs:ikxe,ikys:ikye,izs:ize,:))
         ENDDO
       ENDDO
     ENDIF
@@ -41,7 +41,7 @@ CONTAINS
       DO ij=ijs_i,ije_i
         j_int = jarray_i(ij)
         IF((CLOS .NE. 1) .OR. (ip-1+2*(ij-1)+1 .LE. dmaxi))&
-        CALL advance_field(moments_i(ip,ij,:,:,:,:), moments_rhs_i(ip,ij,:,:,:,:))
+        CALL advance_field(moments_i(ip,ij,ikxs:ikxe,ikys:ikye,izs:ize,:), moments_rhs_i(ip,ij,ikxs:ikxe,ikys:ikye,izs:ize,:))
       ENDDO
     ENDDO
     ! Execution time end
diff --git a/src/array_mod.F90 b/src/array_mod.F90
index d7765312..2193df1d 100644
--- a/src/array_mod.F90
+++ b/src/array_mod.F90
@@ -47,22 +47,22 @@ MODULE array
   REAL(dp), DIMENSION(:,:), ALLOCATABLE :: ynipp1j, ynipm1j,   ynipp1jm1, ynipm1jm1 ! mirror lin coeff for non adiab mom
   REAL(dp), DIMENSION(:,:), ALLOCATABLE :: zNipm1j, zNipm1jp1, zNipm1jm1            ! mirror lin coeff for adiab mom
   REAL(dp), DIMENSION(:,:), ALLOCATABLE :: xphij, xphijp1, xphijm1
-  ! Geoemtrical operators
+  ! Geometrical operators
   ! Curvature
   REAL(dp), DIMENSION(:,:,:,:), ALLOCATABLE :: Ckxky  ! dimensions: kx, ky, z, odd/even p
   ! Jacobian
   REAL(dp), DIMENSION(:,:), ALLOCATABLE :: Jacobian ! dimensions: z, odd/even p
   ! Metric
-  REAL(dp), DIMENSION(:,:), ALLOCATABLE :: gxx, gxy, gyy, gxz, gyz ! dimensions: z, odd/even p
+  REAL(dp), DIMENSION(:,:), ALLOCATABLE :: gxx, gxy, gxz, gyy, gyz, gzz ! dimensions: z, odd/even p
+  REAL(dp), DIMENSION(:,:), ALLOCATABLE :: dxdr, dxdZ, Rc, phic, Zc
   ! derivatives of magnetic field strength
-  REAL(dp), DIMENSION(:,:), allocatable :: gradzB  ! dimensions: z, odd/even p
-  REAL(dp), DIMENSION(:,:), allocatable :: gradxB
+  REAL(dp), DIMENSION(:,:), ALLOCATABLE :: gradxB, gradyB, gradzB
   ! Relative magnetic field strength
-  REAL(dp), DIMENSION(:,:), allocatable :: hatB
+  REAL(dp), DIMENSION(:,:), ALLOCATABLE :: hatB
   ! Relative strength of major radius
-  REAL(dp), DIMENSION(:,:), allocatable :: hatR
+  REAL(dp), DIMENSION(:,:), ALLOCATABLE :: hatR, hatZ
   ! Some geometrical coefficients
-  REAL(dp), DIMENSION(:,:) , allocatable :: gradz_coeff  ! 1 / [ J_{xyz} \hat{B} ]
+  REAL(dp), DIMENSION(:,:) , ALLOCATABLE :: gradz_coeff  ! 1 / [ J_{xyz} \hat{B} ]
   ! Kernel function evaluation (ij,ikx,iky,iz,odd/even p)
   REAL(dp), DIMENSION(:,:,:,:,:), ALLOCATABLE :: kernel_e
   REAL(dp), DIMENSION(:,:,:,:,:), ALLOCATABLE :: kernel_i
@@ -78,7 +78,17 @@ MODULE array
   COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: dens_e
   COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: dens_i
 
+  ! particle fluid velocity for electron and ions (ikx,iky,iz)
+  COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: upar_e
+  COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: upar_i
+  COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: uper_e
+  COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: uper_i
+
   ! particle temperature for electron and ions (ikx,iky,iz)
+  COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: Tpar_e
+  COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: Tpar_i
+  COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: Tper_e
+  COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: Tper_i
   COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: temp_e
   COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: temp_i
 
diff --git a/src/auxval.F90 b/src/auxval.F90
index 1d978124..e826615f 100644
--- a/src/auxval.F90
+++ b/src/auxval.F90
@@ -71,7 +71,6 @@ subroutine auxval
        '              izs   = ', izs  , ', ize    = ', ize
        ! write(*,*) 'local kx =', kxarray
        ! write(*,*) 'local ky =', kyarray
-       ! write(*,*) 'local iz =', izarray
       IF (my_id .NE. num_procs-1) WRITE (*,*) ''
       IF (my_id .EQ. num_procs-1) WRITE(*,*) '------------------------------------------'
     ENDIF
diff --git a/src/basic_mod.F90 b/src/basic_mod.F90
index ecda6e4a..75e2a6d4 100644
--- a/src/basic_mod.F90
+++ b/src/basic_mod.F90
@@ -12,7 +12,7 @@ MODULE basic
   real(dp) :: time   = 0           ! Current simulation time (Init from restart file)
 
   INTEGER :: comm0                 ! Default communicator with a topology
-  INTEGER :: comm_p, comm_kx          ! Communicators for 1-dim cartesian subgrids of comm0
+  INTEGER :: comm_p, comm_kx, comm_z! Communicators for 1-dim cartesian subgrids of comm0
   INTEGER :: commr_p0              ! Communicators along kx for only rank 0 on p
 
   INTEGER :: jobnum  = 0           ! Job number
@@ -26,9 +26,12 @@ MODULE basic
   INTEGER :: num_procs             ! number of MPI processes
   INTEGER :: num_procs_p           ! Number of processes in p
   INTEGER :: num_procs_kx          ! Number of processes in r
-  INTEGER :: rank_0, rank_p, rank_kx! Ranks in comm0, comm_p, comm_kx
+  INTEGER :: num_procs_z           ! Number of processes in z
+  INTEGER :: rank_0                ! Ranks in comm0
+  INTEGER :: rank_p, rank_kx, rank_z! Ranks in comm_p, comm_kx, comm_z
   INTEGER :: nbr_L, nbr_R          ! Left and right neighbours (along p)
   INTEGER :: nbr_T, nbr_B          ! Top and bottom neighbours (along kx)
+  INTEGER :: nbr_U, nbr_D          ! Upstream and downstream neighbours (along z)
 
   INTEGER :: iframe0d              ! counting the number of times 0d datasets are outputed (for diagnose)
   INTEGER :: iframe1d              ! counting the number of times 1d datasets are outputed (for diagnose)
@@ -83,7 +86,7 @@ CONTAINS
     INTEGER :: nargs, fileid, l
     LOGICAL :: mlexist
     nargs = COMMAND_ARGUMENT_COUNT()
-    IF((nargs .EQ. 1) .OR. (nargs .EQ. 3)) THEN
+    IF((nargs .EQ. 1) .OR. (nargs .EQ. 4)) THEN
       CALL GET_COMMAND_ARGUMENT(nargs, str, l, ierr)
       READ(str(1:l),'(i3)')  fileid
       WRITE(input_file,'(a,a1,i2.2,a3)') 'fort','_',fileid,'.90'
diff --git a/src/calculus_mod.F90 b/src/calculus_mod.F90
index dd2eea85..c06c9ca4 100644
--- a/src/calculus_mod.F90
+++ b/src/calculus_mod.F90
@@ -8,12 +8,14 @@ MODULE calculus
    (/  onetwelfth, -twothird, &
                        0._dp, &
          twothird, -onetwelfth /) ! fd4 centered stencil
+  REAL(dp), dimension(-2:2) :: dz4_usu = &
+  (/  1._dp, -4._dp, 6._dp, -4._dp, 1._dp /)* 0.0625 ! 4th derivative, 2nd order (for parallel hypdiff)
   REAL(dp), dimension(-2:1) :: dz_o2e = &
    (/ onetwentyfourth,-nineeighths, nineeighths,-onetwentyfourth /) ! fd4 odd to even stencil
   REAL(dp), dimension(-1:2) :: dz_e2o = &
    (/ onetwentyfourth,-nineeighths, nineeighths,-onetwentyfourth /) ! fd4 odd to even stencil
 
-  PUBLIC :: simpson_rule_z, interp_z, grad_z
+  PUBLIC :: simpson_rule_z, interp_z, grad_z, grad_z4
 
 CONTAINS
 
@@ -24,8 +26,8 @@ SUBROUTINE grad_z(target,f,ddzf)
   ! not staggered : the derivative results must be on the same grid as the field
   !     staggered : the derivative is computed from a grid to the other
   INTEGER, INTENT(IN) :: target
-  COMPLEX(dp),dimension( izs:ize ), intent(in)  :: f
-  COMPLEX(dp),dimension( izs:ize ), intent(out) :: ddzf
+  COMPLEX(dp),dimension( izgs:izge ), intent(in)  :: f
+  COMPLEX(dp),dimension(  izs:ize ), intent(out) :: ddzf
   IF(Nz .GT. 3) THEN ! Cannot apply four points stencil on less than four points grid
     IF(SG) THEN
       IF(TARGET .EQ. 0) THEN
@@ -34,60 +36,55 @@ SUBROUTINE grad_z(target,f,ddzf)
         CALL grad_z_e2o(f,ddzf)
       ENDIF
     ELSE ! No staggered grid -> usual centered finite differences
-      DO iz = 3,Nz-2
+      DO iz = izs,ize
        ddzf(iz) = dz_usu(-2)*f(iz-2) + dz_usu(-1)*f(iz-1) &
                  +dz_usu( 1)*f(iz+1) + dz_usu( 2)*f(iz+2)
       ENDDO
-      ! Periodic boundary conditions
-      ddzf(Nz-1) = dz_usu(-2)*f(Nz-3) + dz_usu(-1)*f(Nz-2) &
-                  +dz_usu(+1)*f(Nz  ) + dz_usu(+2)*f(1   )
-      ddzf(Nz  ) = dz_usu(-2)*f(Nz-2) + dz_usu(-1)*f(Nz-1) &
-                  +dz_usu(+1)*f(1   ) + dz_usu(+2)*f(2   )
-      ddzf(1   ) = dz_usu(-2)*f(Nz-1) + dz_usu(-1)*f(Nz  ) &
-                  +dz_usu(+1)*f(2   ) + dz_usu(+2)*f(3   )
-      ddzf(2   ) = dz_usu(-2)*f(Nz  ) + dz_usu(-1)*f(1   ) &
-                  +dz_usu(+1)*f(3   ) + dz_usu(+2)*f(4)
     ENDIF
   ELSE
     ddzf = 0._dp
   ENDIF
-END SUBROUTINE grad_z
+CONTAINS
+  SUBROUTINE grad_z_o2e(fo,ddzfe) ! Paruta 2018 eq (27)
+    ! gives the gradient of a field from the odd grid to the even one
+    implicit none
+    COMPLEX(dp),dimension(izgs:izge), intent(in)  :: fo
+    COMPLEX(dp),dimension( izs:ize ), intent(out) :: ddzfe !
+    DO iz = izs,ize
+     ddzfe(iz) = dz_o2e(-2)*fo(iz-2) + dz_o2e(-1)*fo(iz-1) &
+               +dz_o2e( 0)*fo(iz  ) + dz_o2e( 1)*fo(iz+1)
+    ENDDO
+    ddzfe(:) = ddzfe(:) * inv_deltaz
+  END SUBROUTINE grad_z_o2e
 
-SUBROUTINE grad_z_o2e(fo,dzfe) ! Paruta 2018 eq (27)
-  ! gives the value of a field from the odd grid to the even one
-  implicit none
-  COMPLEX(dp),dimension(1:Nz), intent(in)  :: fo
-  COMPLEX(dp),dimension(1:Nz), intent(out) :: dzfe !
-  DO iz = 3,Nz-1
-   dzfe(iz) = dz_o2e(-2)*fo(iz-2) + dz_o2e(-1)*fo(iz-1) &
-             +dz_o2e( 0)*fo(iz  ) + dz_o2e( 1)*fo(iz+1)
-  ENDDO
-  ! Periodic boundary conditions
-  dzfe(Nz) = dz_o2e(-2)*fo(Nz-2) + dz_o2e(-1)*fo(Nz-1) &
-            +dz_o2e( 0)*fo(Nz  ) + dz_o2e( 1)*fo(1)
-  dzfe(1 ) = dz_o2e(-2)*fo(Nz-1) + dz_o2e(-1)*fo(Nz  ) &
-            +dz_o2e( 0)*fo(1   ) + dz_o2e( 1)*fo(2)
-  dzfe(2 ) = dz_o2e(-2)*fo(Nz  ) + dz_o2e(-1)*fo(1   ) &
-            +dz_o2e( 0)*fo(2   ) + dz_o2e( 1)*fo(3)
-END SUBROUTINE grad_z_o2e
+  SUBROUTINE grad_z_e2o(fe,ddzfo) ! n2v for Paruta 2018 eq (28)
+    ! gives the gradient of a field from the even grid to the odd one
+    implicit none
+    COMPLEX(dp),dimension(izgs:izge), intent(in)  :: fe
+    COMPLEX(dp),dimension( izs:ize ), intent(out) :: ddzfo
+    DO iz = izs,ize
+     ddzfo(iz) = dz_e2o(-1)*fe(iz-1) + dz_e2o(0)*fe(iz  ) &
+                +dz_e2o( 1)*fe(iz+1) + dz_e2o(2)*fe(iz+2)
+    ENDDO
+    ddzfo(:) = ddzfo(:) * inv_deltaz
+  END SUBROUTINE grad_z_e2o
+END SUBROUTINE grad_z
 
-SUBROUTINE grad_z_e2o(fe,dzfo)
-  ! gives the value of a field from the even grid to the odd one
+SUBROUTINE grad_z4(f,ddz4f)
   implicit none
-  COMPLEX(dp),dimension(1:Nz), intent(in)  :: fe
-  COMPLEX(dp),dimension(1:Nz), intent(out) :: dzfo
-  DO iz = 2,Nz-2
-   dzfo(iz) = dz_e2o(-1)*fe(iz-1) + dz_e2o(0)*fe(iz  ) &
-             +dz_e2o( 1)*fe(iz+1) + dz_e2o(2)*fe(iz+2)
-  ENDDO
-  ! Periodic boundary conditions
-  dzfo(Nz-1) = dz_e2o(-1)*fe(Nz-2) + dz_e2o(0)*fe(Nz-1) &
-              +dz_e2o( 1)*fe(Nz  ) + dz_e2o(2)*fe(1   )
-  dzfo(Nz  ) = dz_e2o(-1)*fe(Nz-1) + dz_e2o(0)*fe(Nz  ) &
-              +dz_e2o( 1)*fe(1   ) + dz_e2o(2)*fe(2   )
-  dzfo(1   ) = dz_e2o(-1)*fe(Nz  ) + dz_e2o(0)*fe(1   ) &
-              +dz_e2o( 1)*fe(2   ) + dz_e2o(2)*fe(3   )
-END SUBROUTINE grad_z_e2o
+  ! Compute the second order fourth derivative for periodic boundary condition
+  COMPLEX(dp),dimension(izgs:izge), intent(in)  :: f
+  COMPLEX(dp),dimension( izs:ize ), intent(out) :: ddz4f
+  IF(Nz .GT. 3) THEN ! Cannot apply four points stencil on less than four points grid
+      DO iz = izs,ize
+       ddz4f(iz) = dz4_usu(-2)*f(iz-2) + dz4_usu(-1)*f(iz-1) &
+                  +dz4_usu( 1)*f(iz+1) + dz4_usu( 2)*f(iz+2)
+      ENDDO
+  ELSE
+    ddz4f = 0._dp
+  ENDIF
+  ddz4f = ddz4f * inv_deltaz**4
+END SUBROUTINE grad_z4
 
 
 SUBROUTINE interp_z(target,f_in,f_out)
@@ -96,10 +93,10 @@ SUBROUTINE interp_z(target,f_in,f_out)
   ! If Staggered Grid flag (SG) is false, returns identity
   implicit none
   INTEGER, intent(in) :: target ! target grid : 0 for even grid, 1 for odd
-  COMPLEX(dp),dimension(1:Nz), intent(in)  :: f_in
-  COMPLEX(dp),dimension(1:Nz), intent(out) :: f_out !
+  COMPLEX(dp),dimension(izgs:izge), intent(in)  :: f_in
+  COMPLEX(dp),dimension( izs:ize ), intent(out) :: f_out !
   IF(SG) THEN
-    IF(TARGET .EQ. 0) THEN
+    IF(target .EQ. 0) THEN
       CALL interp_o2e_z(f_in,f_out)
     ELSE
       CALL interp_e2o_z(f_in,f_out)
@@ -107,38 +104,36 @@ SUBROUTINE interp_z(target,f_in,f_out)
   ELSE ! No staggered grid -> identity
     f_out(:) = f_in(:)
   ENDIF
-END SUBROUTINE interp_z
-
-SUBROUTINE interp_o2e_z(fo,fe)
- ! gives the value of a field from the odd grid to the even one
- implicit none
- COMPLEX(dp),dimension(1:Nz), intent(in)  :: fo
- COMPLEX(dp),dimension(1:Nz), intent(out) :: fe !
- DO iz = 2,Nz
-   fe(iz) = 0.5_dp*(fo(iz)+fo(iz-1))
- ENDDO
- ! Periodic boundary conditions
- fe(1) = 0.5_dp*(fo(1) + fo(Nz))
-END SUBROUTINE interp_o2e_z
+CONTAINS
+  SUBROUTINE interp_o2e_z(fo,fe)
+   ! gives the value of a field from the odd grid to the even one
+   implicit none
+   COMPLEX(dp),dimension(izgs:izge), intent(in)  :: fo
+   COMPLEX(dp),dimension( izs:ize ), intent(out) :: fe !
+   ! 4th order interp
+   DO iz = izs,ize
+    fe(iz) = onesixteenth * (-fo(iz-2) + 9._dp*(fo(iz-1) + fo(iz)) - fo(iz+1))
+   ENDDO
+  END SUBROUTINE interp_o2e_z
 
-SUBROUTINE interp_e2o_z(fe,fo)
- ! gives the value of a field from the even grid to the odd one
- implicit none
- COMPLEX(dp),dimension(1:Nz), intent(in)  :: fe
- COMPLEX(dp),dimension(1:Nz), intent(out) :: fo
- DO iz = 1,Nz-1
-   fo(iz) = 0.5_dp*(fe(iz+1)+fe(iz))
- ENDDO
- ! Periodic boundary conditions
- fo(Nz) = 0.5_dp*(fe(1) + fe(Nz))
-END SUBROUTINE interp_e2o_z
+  SUBROUTINE interp_e2o_z(fe,fo)
+   ! gives the value of a field from the even grid to the odd one
+   implicit none
+   COMPLEX(dp),dimension(izgs:izge), intent(in)  :: fe
+   COMPLEX(dp),dimension( izs:ize ), intent(out) :: fo
+   ! 4th order interp
+   DO iz = 1,Nz
+    fo(iz) = onesixteenth * (-fe(iz-1) + 9._dp*(fe(iz) + fe(iz+1)) - fe(iz+2))
+   ENDDO
+  END SUBROUTINE interp_e2o_z
 
+END SUBROUTINE interp_z
 
 SUBROUTINE simpson_rule_z(f,intf)
  ! integrate f(z) over z using the simpon's rule. Assume periodic boundary conditions (f(ize+1) = f(izs))
  !from molix BJ Frei
  implicit none
- complex(dp),dimension(izs:ize), intent(in) :: f
+ complex(dp),dimension(izgs:izge), intent(in) :: f
  COMPLEX(dp), intent(out) :: intf
  COMPLEX(dp) :: buff_
  IF(Nz .GT. 1) THEN
@@ -159,4 +154,49 @@ SUBROUTINE simpson_rule_z(f,intf)
  ENDIF
 END SUBROUTINE simpson_rule_z
 
+! SUBROUTINE simpson_rule_z(f,intf)
+!  ! integrate f(z) over z using the simpon's rule. Assume periodic boundary conditions (f(ize+1) = f(izs))
+!  !from molix BJ Frei
+!  implicit none
+!  complex(dp),dimension(izs:ize), intent(in) :: f
+!  COMPLEX(dp), intent(out) :: intf
+!  COMPLEX(dp)              :: buffer(1:2), local_int
+!  INTEGER :: root, i_
+!
+!  IF(Nz .EQ. 1) THEN !2D zpinch simulations
+!    intf = f(izs)
+!
+!  ELSE !3D fluxtube
+!    IF(mod(Nz,2) .ne. 0 ) THEN
+!       ERROR STOP 'Simpson rule: Nz must be an even number  !!!!'
+!    ENDIF
+!    ! Buil local sum using the weights of composite Simpson's rule
+!    local_int = 0._dp
+!    DO iz = izs,ize
+!       local_int = local_int + zweights_SR(iz)*f(iz)
+!    ENDDO
+!
+!    buffer(2) = local_int
+!    root = 0
+!    !Gather manually among the rank_z=0 processes and perform the sum
+!    intf = 0._dp
+!    IF (num_procs_z .GT. 1) THEN
+!        !! Everyone sends its local_sum to root = 0
+!        IF (rank_z .NE. root) THEN
+!            CALL MPI_SEND(buffer, 2 , MPI_DOUBLE_COMPLEX, root, 5678, comm_z, ierr)
+!        ELSE
+!            ! Recieve from all the other processes
+!            DO i_ = 0,num_procs_z-1
+!                IF (i_ .NE. rank_kx) &
+!                    CALL MPI_RECV(buffer, 2 , MPI_DOUBLE_COMPLEX, i_, 5678, comm_z, MPI_STATUS_IGNORE, ierr)
+!                    intf = intf + buffer(2)
+!            ENDDO
+!        ENDIF
+!    ELSE
+!      intf = local_int
+!    ENDIF
+!    intf = onethird*deltaz*intf
+!   ENDIF
+! END SUBROUTINE simpson_rule_z
+
 END MODULE calculus
diff --git a/src/closure_mod.F90 b/src/closure_mod.F90
index b1a5a7ef..40be81ee 100644
--- a/src/closure_mod.F90
+++ b/src/closure_mod.F90
@@ -8,7 +8,7 @@ USE fields, ONLY: moments_e, moments_i
 USE time_integration, ONLY: updatetlevel
 IMPLICIT NONE
 
-PUBLIC :: apply_closure_model, ghosts_truncation
+PUBLIC :: apply_closure_model
 
 CONTAINS
 
@@ -19,7 +19,7 @@ SUBROUTINE apply_closure_model
   CALL cpu_time(t0_clos)
   IF (CLOS .EQ. 0) THEN
     ! zero truncation, An+1=0 for n+1>nmax only
-    CALL ghosts_truncation
+    CALL ghosts_upper_truncation
 
 
   ELSEIF (CLOS .EQ. 1) THEN
@@ -32,15 +32,15 @@ SUBROUTINE apply_closure_model
       DO iky = ikys,ikye
         DO iz = izs,ize
           IF(KIN_E) THEN
-          DO ip = ipsg_e,ipeg_e
-            DO ij = ijsg_e,ijeg_e
+          DO ip = ipgs_e,ipge_e
+            DO ij = ijgs_e,ijge_e
               IF ( parray_e(ip)+2*jarray_e(ip) .GT. dmaxe) &
               moments_e(ip,ij,ikx,iky,iz,updatetlevel) = 0._dp
             ENDDO
           ENDDO
           ENDIF
-          DO ip = ipsg_i,ipeg_i
-            DO ij = ijsg_i,ijeg_i
+          DO ip = ipgs_i,ipge_i
+            DO ij = ijgs_i,ijge_i
               IF ( parray_i(ip)+2*jarray_i(ip) .GT. dmaxi) &
               moments_i(ip,ij,ikx,iky,iz,updatetlevel) = 0._dp
             ENDDO
@@ -49,58 +49,102 @@ SUBROUTINE apply_closure_model
       ENDDO
     ENDDO
     ! + ghosts truncation
-    CALL ghosts_truncation
+    CALL ghosts_upper_truncation
   ELSE
-    if(my_id .EQ. 0) write(*,*) '! Closure scheme not found !'
+    ERROR STOP '! Closure scheme not found !'
 
   ENDIF
 
+  CALL ghosts_lower_truncation
+
   CALL cpu_time(t1_clos)
   tc_clos = tc_clos + (t1_clos - t0_clos)
 END SUBROUTINE apply_closure_model
 
 ! Positive Oob indices are approximated with a model
-SUBROUTINE ghosts_truncation
+SUBROUTINE ghosts_upper_truncation
   IMPLICIT NONE
 
 ! zero truncation, An+1=0 for n+1>nmax
-    DO ikx = ikxs,ikxe
-      DO iky = ikys,ikye
-        DO iz = izs,ize
-          IF(KIN_E) THEN
-          DO ip = ipsg_e,ipeg_e
-            moments_e(ip,ijsg_e,ikx,iky,iz,updatetlevel) = 0._dp
-            moments_e(ip,ijeg_e,ikx,iky,iz,updatetlevel) = 0._dp
-          ENDDO
-          DO ij = ijsg_e,ijeg_e
-            moments_e(ipsg_e  ,ij,ikx,iky,iz,updatetlevel) = 0._dp
-            moments_e(ipeg_e  ,ij,ikx,iky,iz,updatetlevel) = 0._dp
-            IF(deltape .EQ. 1) THEN ! Must truncate the second stencil
-            moments_e(ipsg_e+1,ij,ikx,iky,iz,updatetlevel) = 0._dp
-            moments_e(ipeg_e-1,ij,ikx,iky,iz,updatetlevel) = 0._dp
-            ENDIF
-          ENDDO
-          kernel_e(ijsg_e,ikx,iky,iz,:)      = 0._dp
-          kernel_e(ijeg_e,ikx,iky,iz,:)      = 0._dp
-          ENDIF
-          DO ip = ipsg_i,ipeg_i
-            moments_i(ip,ijsg_i,ikx,iky,iz,updatetlevel) = 0._dp
-            moments_i(ip,ijeg_i,ikx,iky,iz,updatetlevel) = 0._dp
-          ENDDO
-          DO ij = ijsg_i,ijeg_i
-            moments_i(ipsg_i  ,ij,ikx,iky,iz,updatetlevel) = 0._dp
-            moments_i(ipeg_i  ,ij,ikx,iky,iz,updatetlevel) = 0._dp
-            IF(deltapi .EQ. 1) THEN ! Must truncate the second stencil
-            moments_i(ipsg_i+1,ij,ikx,iky,iz,updatetlevel) = 0._dp
-            moments_i(ipeg_i-1,ij,ikx,iky,iz,updatetlevel) = 0._dp
-            ENDIF
-          ENDDO
-          kernel_i(ijsg_i,ikx,iky,iz,:)      = 0._dp
-          kernel_i(ijeg_i,ikx,iky,iz,:)      = 0._dp
-        ENDDO
+  ! Electrons
+  IF(KIN_E) THEN
+    ! applies only for the process that has largest j index
+    IF(ije_e .EQ. Jmaxe+1) THEN
+      DO ip = ipgs_e,ipge_e
+        moments_e(ip,ije_e+1,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel) = 0._dp
+      ENDDO
+    ENDIF
+    ! applies only for the process that has largest p index
+    IF(ipe_e .EQ. Pmaxe+1) THEN
+      DO ij = ijgs_e,ijge_e
+        moments_e(ipe_e+1,ij,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel) = 0._dp
+        IF(deltape .EQ. 1) THEN ! Must truncate the second stencil
+        moments_e(ipe_e+2,ij,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel) = 0._dp
+        ENDIF
       ENDDO
+    ENDIF
+  ENDIF
+
+  ! Ions
+  ! applies only for the process that has largest j index
+  IF(ije_i .EQ. Jmaxi+1) THEN
+    DO ip = ipgs_i,ipge_i
+      moments_i(ip,ije_i+1,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel) = 0._dp
     ENDDO
+  ENDIF
+  ! applies only for the process that has largest p index
+  IF(ipe_i .EQ. Pmaxi+1) THEN
+    DO ij = ijgs_i,ijge_i
+      moments_i(ipe_i+1,ij,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel) = 0._dp
+      IF(deltape .EQ. 1) THEN ! Must truncate the second stencil
+      moments_i(ipe_i+2,ij,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel) = 0._dp
+      ENDIF
+    ENDDO
+  ENDIF
+
+END SUBROUTINE ghosts_upper_truncation
+
+! Negative OoB indices are 0
+SUBROUTINE ghosts_lower_truncation
+  IMPLICIT NONE
+
+! zero truncation, An=0 for n<0
+  ! Electrons
+  IF(KIN_E) THEN
+    ! applies only for the process that has lowest j index
+    IF(ijs_e .EQ. 1) THEN
+      DO ip = ipgs_e,ipge_e
+        moments_e(ip,ijs_e-1,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel) = 0._dp
+      ENDDO
+    ENDIF
+    ! applies only for the process that has lowest p index
+    IF(ips_e .EQ. 1) THEN
+      DO ij = ijgs_e,ijge_e
+        moments_e(ips_e-1,ij,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel) = 0._dp
+        IF(deltape .EQ. 1) THEN ! Must truncate the second stencil
+        moments_e(ips_e-2,ij,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel) = 0._dp
+        ENDIF
+      ENDDO
+    ENDIF
+  ENDIF
+
+  ! Ions
+  IF(ijs_i .EQ. 1) THEN
+    ! applies only for the process that has lowest j index
+    DO ip = ipgs_i,ipge_i
+      moments_i(ip,ije_i-1,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel) = 0._dp
+    ENDDO
+  ENDIF
+  ! applies only for the process that has lowest p index
+  IF(ips_i .EQ. 1) THEN
+    DO ij = ijgs_i,ijge_i
+      moments_i(ips_i-1,ij,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel) = 0._dp
+      IF(deltape .EQ. 1) THEN ! Must truncate the second stencil
+      moments_i(ips_i-2,ij,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel) = 0._dp
+      ENDIF
+    ENDDO
+  ENDIF
 
-END SUBROUTINE ghosts_truncation
+END SUBROUTINE ghosts_lower_truncation
 
 END module closure
diff --git a/src/collision_mod.F90 b/src/collision_mod.F90
index 4cd4a596..451787e7 100644
--- a/src/collision_mod.F90
+++ b/src/collision_mod.F90
@@ -79,15 +79,26 @@ CONTAINS
     IMPLICIT NONE
     ! Execution time start
     CALL cpu_time(t0_coll)
+    
     IF (nu .NE. 0) THEN
       SELECT CASE(collision_model)
         CASE ('LB')
           CALL compute_lenard_bernstein
         CASE ('DG')
           CALL compute_dougherty
-        CASE DEFAULT
+        CASE ('SG','LR','LD')
           CALL compute_cosolver_coll
+        CASE ('none')
+          IF(KIN_E) &
+          TColl_e = 0._dp
+          TColl_i = 0._dp
+        CASE DEFAULT
+          ERROR STOP 'Error stop: collision operator not recognized!!'
       END SELECT
+    ELSE
+      IF(KIN_E) &
+      TColl_e = 0._dp
+      TColl_i = 0._dp
     ENDIF
 
     ! Execution time end
diff --git a/src/diagnose.F90 b/src/diagnose.F90
index 056661f9..84eb57d3 100644
--- a/src/diagnose.F90
+++ b/src/diagnose.F90
@@ -5,6 +5,7 @@ SUBROUTINE diagnose(kstep)
   USE grid
   USE diagnostics_par
   USE futils, ONLY: creatf, creatg, creatd, closef, putarr, putfile, attach, openf, putarrnd
+  USE array
   USE model
   USE initial_par
   USE fields
@@ -70,6 +71,24 @@ SUBROUTINE diagnose(kstep)
      CALL putarr(fidres, "/data/grid/coordp_i" , parray_i_full, "p_i", ionode=0)
      CALL putarr(fidres, "/data/grid/coordj_i" , jarray_i_full, "j_i", ionode=0)
 
+     ! Metric info
+     CALL   creatg(fidres, "/data/metric", "Metric data")
+     CALL putarrnd(fidres, "/data/metric/gxx",            gxx(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/gxy",            gxy(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/gyy",            gyy(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/gyz",            gyz(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/gzz",            gzz(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/hatR",          hatR(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/hatZ",          hatZ(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/hatB",          hatB(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/gradxB",      gradxB(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/gradyB",      gradyB(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/gradzB",      gradzB(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/Jacobian",    Jacobian(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/gradz_coeff", gradz_coeff(izs:ize,0:1), (/1, 1/))
+     CALL putarrnd(fidres, "/data/metric/Ckxky",       Ckxky(ikxs:ikxe,ikys:ikye,izs:ize,0:1), (/1, 3/))
+     CALL putarrnd(fidres, "/data/metric/kernel_i",    kernel_i(ijs_i:ije_i,ikxs:ikxe,ikys:ikye,izs:ize,0:1), (/1, 3/))
+
      !  var0d group (gyro transport)
      IF (nsave_0d .GT. 0) THEN
       CALL creatg(fidres, "/data/var0d", "0d profiles")
@@ -121,10 +140,24 @@ SUBROUTINE diagnose(kstep)
        CALL creatg(fidres, "/data/var3d/dens_i", "dens_i")
       ENDIF
 
+      IF (write_fvel) THEN
+        IF(KIN_E) THEN
+        CALL creatg(fidres, "/data/var3d/upar_e", "upar_e")
+        CALL creatg(fidres, "/data/var3d/uper_e", "uper_e")
+        ENDIF
+        CALL creatg(fidres, "/data/var3d/upar_i", "upar_i")
+        CALL creatg(fidres, "/data/var3d/uper_i", "uper_i")
+      ENDIF
+
       IF (write_temp) THEN
-        IF(KIN_E)&
-       CALL creatg(fidres, "/data/var3d/temp_e", "temp_e")
-       CALL creatg(fidres, "/data/var3d/temp_i", "temp_i")
+        IF(KIN_E) THEN
+        CALL creatg(fidres, "/data/var3d/Tper_e", "Tper_e")
+        CALL creatg(fidres, "/data/var3d/Tpar_e", "Tpar_e")
+        CALL creatg(fidres, "/data/var3d/temp_e", "temp_e")
+        ENDIF
+        CALL creatg(fidres, "/data/var3d/Tper_i", "Tper_i")
+        CALL creatg(fidres, "/data/var3d/Tpar_i", "Tpar_i")
+        CALL creatg(fidres, "/data/var3d/temp_i", "temp_i")
       ENDIF
 
       IF (cstep==0) THEN
@@ -190,6 +223,7 @@ SUBROUTINE diagnose(kstep)
      CALL attach(fidres, TRIM(str),  "write_Napj",  write_Napj)
      CALL attach(fidres, TRIM(str),  "write_Sapj",  write_Sapj)
      CALL attach(fidres, TRIM(str),  "write_dens",  write_dens)
+     CALL attach(fidres, TRIM(str),  "write_fvel",  write_fvel)
      CALL attach(fidres, TRIM(str),  "write_temp",  write_temp)
 
      CALL grid_outputinputs(fidres, str)
@@ -338,7 +372,7 @@ SUBROUTINE diagnose_2d
   USE basic
   USE futils, ONLY: append, getatt, attach, putarrnd
   USE fields
-  USE array, ONLY: Ne00, Ni00, dens_e, dens_i, temp_e, temp_i
+  USE array
   USE grid, ONLY: ikxs,ikxe, ikys,ikye, Nkx, Nky, local_nkx, ikx, iky, ips_e, ips_i
   USE time_integration
   USE diagnostics_par
@@ -393,7 +427,7 @@ SUBROUTINE diagnose_3d
   USE basic
   USE futils, ONLY: append, getatt, attach, putarrnd
   USE fields
-  USE array, ONLY: Ne00, Ni00, dens_e, dens_i, temp_e, temp_i
+  USE array
   USE grid, ONLY: ikxs,ikxe, ikys,ikye, Nkx, Nky, local_nkx, ikx, iky, ips_e, ips_i
   USE time_integration
   USE diagnostics_par
@@ -411,32 +445,49 @@ SUBROUTINE diagnose_3d
   iframe3d=iframe3d+1
   CALL attach(fidres,"/data/var3d/" , "frames", iframe3d)
 
-  IF (write_phi) CALL write_field3d(phi (:,:,:), 'phi')
+  IF (write_phi) CALL write_field3d(phi (ikxs:ikxe,ikys:ikye,izs:ize), 'phi')
 
   IF (write_Na00) THEN
     IF(KIN_E)THEN
     IF (ips_e .EQ. 1) THEN
       Ne00(ikxs:ikxe,ikys:ikye,izs:ize) = moments_e(ips_e,1,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel)
     ENDIF
-    CALL manual_3D_bcast(Ne00(ikxs:ikxe,ikys:ikye,izs:ize))
+    ! CALL manual_3D_bcast(Ne00(ikxs:ikxe,ikys:ikye,izs:ize))
     CALL write_field3d(Ne00(ikxs:ikxe,ikys:ikye,izs:ize), 'Ne00')
     ENDIF
     IF (ips_i .EQ. 1) THEN
       Ni00(ikxs:ikxe,ikys:ikye,izs:ize) = moments_i(ips_e,1,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel)
     ENDIF
-    CALL manual_3D_bcast(Ni00(ikxs:ikxe,ikys:ikye,izs:ize))
+    ! CALL manual_3D_bcast(Ni00(ikxs:ikxe,ikys:ikye,izs:ize))
     CALL write_field3d(Ni00(ikxs:ikxe,ikys:ikye,izs:ize), 'Ni00')
   ENDIF
 
+  !! Fuid moments
+  IF (write_dens .OR. write_fvel .OR. write_temp) &
+  CALL compute_fluid_moments
+
   IF (write_dens) THEN
-    CALL compute_density
     IF(KIN_E)&
     CALL write_field3d(dens_e(ikxs:ikxe,ikys:ikye,izs:ize), 'dens_e')
     CALL write_field3d(dens_i(ikxs:ikxe,ikys:ikye,izs:ize), 'dens_i')
   ENDIF
 
+  IF (write_fvel) THEN
+    IF(KIN_E)&
+    CALL write_field3d(upar_e(ikxs:ikxe,ikys:ikye,izs:ize), 'upar_e')
+    CALL write_field3d(upar_i(ikxs:ikxe,ikys:ikye,izs:ize), 'upar_i')
+    IF(KIN_E)&
+    CALL write_field3d(uper_e(ikxs:ikxe,ikys:ikye,izs:ize), 'uper_e')
+    CALL write_field3d(uper_i(ikxs:ikxe,ikys:ikye,izs:ize), 'uper_i')
+  ENDIF
+
   IF (write_temp) THEN
-    CALL compute_temperature
+    IF(KIN_E)&
+    CALL write_field3d(Tpar_e(ikxs:ikxe,ikys:ikye,izs:ize), 'Tpar_e')
+    CALL write_field3d(Tpar_i(ikxs:ikxe,ikys:ikye,izs:ize), 'Tpar_i')
+    IF(KIN_E)&
+    CALL write_field3d(Tper_e(ikxs:ikxe,ikys:ikye,izs:ize), 'Tper_e')
+    CALL write_field3d(Tper_i(ikxs:ikxe,ikys:ikye,izs:ize), 'Tper_i')
     IF(KIN_E)&
     CALL write_field3d(temp_e(ikxs:ikxe,ikys:ikye,izs:ize), 'temp_e')
     CALL write_field3d(temp_i(ikxs:ikxe,ikys:ikye,izs:ize), 'temp_i')
@@ -459,7 +510,7 @@ CONTAINS
     IF (num_procs .EQ. 1) THEN ! no data distribution
       CALL putarr(fidres, dset_name, field(ikxs:ikxe, ikys:ikye, izs:ize), ionode=0)
     ELSE
-      CALL putarrnd(fidres, dset_name, field(ikxs:ikxe, ikys:ikye, izs:ize),  (/1, 1/))
+      CALL putarrnd(fidres, dset_name, field(ikxs:ikxe, ikys:ikye, izs:ize),  (/1, 3/))
     ENDIF
     CALL attach(fidres, dset_name, "time", time)
 
@@ -516,7 +567,7 @@ SUBROUTINE diagnose_5d
      IF (num_procs .EQ. 1) THEN
        CALL putarr(fidres, dset_name, field(ips_e:ipe_e,ijs_e:ije_e,ikxs:ikxe,ikys:ikye,izs:ize), ionode=0)
      ELSE
-       CALL putarrnd(fidres, dset_name, field(ips_e:ipe_e,ijs_e:ije_e,ikxs:ikxe,ikys:ikye,izs:ize),  (/1,3/))
+       CALL putarrnd(fidres, dset_name, field(ips_e:ipe_e,ijs_e:ije_e,ikxs:ikxe,ikys:ikye,izs:ize),  (/1,3,5/))
      ENDIF
      CALL attach(fidres, dset_name, 'cstep', cstep)
      CALL attach(fidres, dset_name, 'time', time)
diff --git a/src/diagnostics_par_mod.F90 b/src/diagnostics_par_mod.F90
index 36f41076..59a7578f 100644
--- a/src/diagnostics_par_mod.F90
+++ b/src/diagnostics_par_mod.F90
@@ -9,7 +9,7 @@ MODULE diagnostics_par
   LOGICAL, PUBLIC, PROTECTED :: write_gamma, write_hf  ! output particle transport and heat flux
   LOGICAL, PUBLIC, PROTECTED :: write_phi,  write_Na00
   LOGICAL, PUBLIC, PROTECTED :: write_Napj, write_Sapj
-  LOGICAL, PUBLIC, PROTECTED :: write_dens, write_temp
+  LOGICAL, PUBLIC, PROTECTED :: write_dens, write_fvel, write_temp
 
   INTEGER, PUBLIC, PROTECTED :: nsave_0d, nsave_1d, nsave_2d, nsave_3d, nsave_5d
 
@@ -36,7 +36,7 @@ CONTAINS
     NAMELIST /OUTPUT_PAR/ nsave_0d, nsave_1d, nsave_2d, nsave_3d, nsave_5d
     NAMELIST /OUTPUT_PAR/ write_doubleprecision, write_gamma, write_hf, write_phi
     NAMELIST /OUTPUT_PAR/ write_Na00, write_Napj, write_Sapj
-    NAMELIST /OUTPUT_PAR/ write_dens, write_temp
+    NAMELIST /OUTPUT_PAR/ write_dens, write_fvel, write_temp
     NAMELIST /OUTPUT_PAR/ job2load
 
     READ(lu_in,output_par)
diff --git a/src/geometry_mod.F90 b/src/geometry_mod.F90
index d8bc22b7..460529a4 100644
--- a/src/geometry_mod.F90
+++ b/src/geometry_mod.F90
@@ -20,7 +20,8 @@ contains
     ! evalute metrix, elementwo_third_kpmaxts, jacobian and gradient
     implicit none
     REAL(dp) :: kx,ky
-    COMPLEX(dp), DIMENSION(izs:ize) :: integrant
+    COMPLEX(dp), DIMENSION(izgs:izge) :: integrant
+    INTEGER :: fid
     !
     IF( (Ny .EQ. 1) .AND. (Nz .EQ. 1)) THEN !1D perp linear run
       IF( my_id .eq. 0 ) WRITE(*,*) '1D perpendicular geometry'
@@ -34,11 +35,11 @@ contains
     !  k_\perp^2 = g^{xx} k_x^2 + 2 g^{xy}k_x k_y + k_y^2 g^{yy}
     !  normalized to rhos_
     DO eo = 0,1
-    DO iz = izs,ize
-       DO iky = ikys, ikye
-         ky = kyarray(iky)
-          DO ikx = ikxs, ikxe
-            kx = kxarray(ikx)
+     DO iky = ikys, ikye
+       ky = kyarray(iky)
+        DO ikx = ikxs, ikxe
+          kx = kxarray(ikx)
+          DO iz = izgs,izge
              kparray(ikx, iky, iz, eo) = &
               SQRT( gxx(iz,eo)*kx**2 + 2._dp*gxy(iz,eo)*kx*ky + gyy(iz,eo)*ky**2)/hatB(iz,eo)
               ! there is a factor 1/B from the normalization; important to match GENE
@@ -49,9 +50,10 @@ contains
     two_third_kpmax = 2._dp/3._dp * MAXVAL(kparray)
     !
     ! Compute the inverse z integrated Jacobian (useful for flux averaging)
-    integrant = Jacobian(:,0) ! Convert into complex array
+    integrant = Jacobian(izgs:izge,0) ! Convert into complex array
     CALL simpson_rule_z(integrant,iInt_Jacobian)
     iInt_Jacobian = 1._dp/iInt_Jacobian ! reverse it
+
   END SUBROUTINE eval_magnetic_geometry
   !
   !--------------------------------------------------------------------------------
@@ -60,19 +62,31 @@ contains
   subroutine eval_salphaB_geometry
   ! evaluate s-alpha geometry model
   implicit none
-  REAL(dp) :: z, kx, ky
+  REAL(dp) :: z, kx, ky, alpha_MHD
+  alpha_MHD = 0._dp
 
   parity: DO eo = 0,1
-  zloop: DO iz = izs,ize
+  zloop: DO iz = izgs,izge
     z = zarray(iz,eo)
 
     ! metric
       gxx(iz,eo) = 1._dp
-      gxy(iz,eo) = shear*z
-      gyy(iz,eo) = 1._dp + (shear*z)**2
+      gxy(iz,eo) = shear*z - alpha_MHD*SIN(z)
+      gxz(iz,eo) = 0._dp
+      gyy(iz,eo) = 1._dp + (shear*z - alpha_MHD*SIN(z))**2
+      gyz(iz,eo) = 1._dp/(eps + EPSILON(eps)) !avoid 1/0 in Zpinch config
+      gzz(iz,eo) = 0._dp
+      dxdR(iz,eo)= COS(z)
+      dxdZ(iz,eo)= SIN(z)
 
     ! Relative strengh of radius
       hatR(iz,eo) = 1._dp + eps*COS(z)
+      hatZ(iz,eo) = 1._dp + eps*SIN(z)
+
+    ! toroidal coordinates
+      Rc  (iz,eo) = hatR(iz,eo)
+      phic(iz,eo) = z
+      Zc  (iz,eo) = hatZ(iz,eo)
 
     ! Jacobian
       Jacobian(iz,eo) = q0*hatR(iz,eo)
@@ -81,15 +95,16 @@ contains
       hatB(iz,eo) = 1._dp / hatR(iz,eo)
 
     ! Derivative of the magnetic field strenght
-      gradxB(iz,eo) = -COS(z)
-      gradzB(iz,eo) = eps * SIN(z) / hatR(iz,eo)
+      gradxB(iz,eo) = -COS(z) ! Gene put a factor hatB^2 or 1/hatR^2 in this
+      gradyB(iz,eo) = 0._dp
+      gradzB(iz,eo) = eps * SIN(z) / hatR(iz,eo) ! Gene put a factor hatB or 1/hatR in this
 
     ! Curvature operator
       DO iky = ikys, ikye
         ky = kyarray(iky)
          DO ikx= ikxs, ikxe
            kx = kxarray(ikx)
-           Ckxky(ikx, iky, iz,eo) = (-SIN(z)*kx - (COS(z) + shear* z* SIN(z))*ky) * hatB(iz,eo) ! .. multiply by hatB to cancel the 1/ hatB factor in moments_eqs_rhs.f90 routine
+           Ckxky(ikx, iky, iz,eo) = (-SIN(z)*kx - (COS(z) + (shear*z - alpha_MHD*SIN(z))* SIN(z))*ky) * hatB(iz,eo) ! .. multiply by hatB to cancel the 1/ hatB factor in moments_eqs_rhs.f90 routine
          ENDDO
       ENDDO
     ! coefficient in the front of parallel derivative
diff --git a/src/ghosts_mod.F90 b/src/ghosts_mod.F90
index fa0757f9..a50e0fc3 100644
--- a/src/ghosts_mod.F90
+++ b/src/ghosts_mod.F90
@@ -1,6 +1,6 @@
 module ghosts
 USE basic
-USE fields, ONLY : moments_e, moments_i
+USE fields, ONLY : moments_e, moments_i, phi
 USE grid
 USE time_integration
 USE model, ONLY : KIN_E
@@ -9,11 +9,11 @@ IMPLICIT NONE
 
 INTEGER :: status(MPI_STATUS_SIZE), source, dest, count, ipg
 
-PUBLIC :: update_ghosts
+PUBLIC :: update_ghosts_p_moments, update_ghosts_z_phi, update_ghosts_z_moments
 
 CONTAINS
 
-SUBROUTINE update_ghosts
+SUBROUTINE update_ghosts_p_moments
     CALL cpu_time(t0_ghost)
 
     IF (num_procs_p .GT. 1) THEN ! Do it only if we share the p
@@ -24,9 +24,10 @@ SUBROUTINE update_ghosts
         CALL update_ghosts_p_i
     ENDIF
 
+    CALL update_ghosts_z_moments
     CALL cpu_time(t1_ghost)
     tc_ghost = tc_ghost + (t1_ghost - t0_ghost)
-END SUBROUTINE update_ghosts
+END SUBROUTINE update_ghosts_p_moments
 
 
 !Communicate p+1, p+2 moments to left neighboor and p-1, p-2 moments to right one
@@ -44,25 +45,25 @@ END SUBROUTINE update_ghosts
 SUBROUTINE update_ghosts_p_e
 
     IMPLICIT NONE
-    count = (ijeg_e-ijsg_e+1)*(ikxe-ikxs+1)*(ikye-ikys+1)*(ize-izs+1)
+    count = (ijge_e-ijgs_e+1)*(ikxe-ikxs+1)*(ikye-ikys+1)*(izge-izgs+1)
 
     !!!!!!!!!!! Send ghost to right neighbour !!!!!!!!!!!!!!!!!!!!!!
     ! Send the last local moment to fill the -1 neighbour ghost
-    CALL mpi_sendrecv(moments_e(ipe_e  ,ijsg_e:ijeg_e,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 10, & ! Send to right
-                      moments_e(ips_e-1,ijsg_e:ijeg_e,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 10, & ! Recieve from left
+    CALL mpi_sendrecv(moments_e(ipe_e  ,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 10, & ! Send to right
+                      moments_e(ips_e-1,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 10, & ! Recieve from left
                       comm0, status, ierr)
     IF (deltape .EQ. 1) & ! If we have odd Hermite degrees we need a 2nd order stencil
-    CALL mpi_sendrecv(moments_e(ipe_e-1,ijsg_e:ijeg_e,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 11, & ! Send to right
-                      moments_e(ips_e-2,ijsg_e:ijeg_e,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 11, & ! Recieve from left
+    CALL mpi_sendrecv(moments_e(ipe_e-1,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 11, & ! Send to right
+                      moments_e(ips_e-2,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 11, & ! Recieve from left
                       comm0, status, ierr)
 
     !!!!!!!!!!! Send ghost to left neighbour !!!!!!!!!!!!!!!!!!!!!!
-    CALL mpi_sendrecv(moments_e(ips_e  ,ijsg_e:ijeg_e,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 12, & ! Send to left
-                      moments_e(ipe_e+1,ijsg_e:ijeg_e,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 12, & ! Recieve from right
+    CALL mpi_sendrecv(moments_e(ips_e  ,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 12, & ! Send to left
+                      moments_e(ipe_e+1,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 12, & ! Recieve from right
                       comm0, status, ierr)
     IF (deltape .EQ. 1) & ! If we have odd Hermite degrees we need a 2nd order stencil
-    CALL mpi_sendrecv(moments_e(ips_e+1,ijsg_e:ijeg_e,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 13, & ! Send to left
-                      moments_e(ipe_e+2,ijsg_e:ijeg_e,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 13, & ! Recieve from right
+    CALL mpi_sendrecv(moments_e(ips_e+1,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 13, & ! Send to left
+                      moments_e(ipe_e+2,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 13, & ! Recieve from right
                       comm0, status, ierr)
 
 END SUBROUTINE update_ghosts_p_e
@@ -72,27 +73,144 @@ SUBROUTINE update_ghosts_p_i
 
     IMPLICIT NONE
 
-    count = (ijeg_i-ijsg_i+1)*(ikxe-ikxs+1)*(ikye-ikys+1)*(ize-izs+1) ! Number of elements sent
+    count = (ijge_i-ijgs_i+1)*(ikxe-ikxs+1)*(ikye-ikys+1)*(izge-izgs+1) ! Number of elements sent
 
     !!!!!!!!!!! Send ghost to right neighbour !!!!!!!!!!!!!!!!!!!!!!
-    CALL mpi_sendrecv(moments_i(ipe_i  ,ijsg_i:ijeg_i,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 14, &
-                      moments_i(ips_i-1,ijsg_i:ijeg_i,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 14, &
+    CALL mpi_sendrecv(moments_i(ipe_i  ,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 14, &
+                      moments_i(ips_i-1,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 14, &
                       comm0, status, ierr)
     IF (deltapi .EQ. 1) & ! If we have odd Hermite degrees we need a 2nd order stencil
-    CALL mpi_sendrecv(moments_i(ipe_i-1,ijsg_i:ijeg_i,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 15, &
-                      moments_i(ips_i-2,ijsg_i:ijeg_i,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 15, &
+    CALL mpi_sendrecv(moments_i(ipe_i-1,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 15, &
+                      moments_i(ips_i-2,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 15, &
                       comm0, status, ierr)
 
     !!!!!!!!!!! Send ghost to left neighbour !!!!!!!!!!!!!!!!!!!!!!
     CALL mpi_cart_shift(comm0, 0, -1, source , dest , ierr)
-    CALL mpi_sendrecv(moments_i(ips_i  ,ijsg_i:ijeg_i,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 16, &
-                      moments_i(ipe_i+1,ijsg_i:ijeg_i,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 16, &
+    CALL mpi_sendrecv(moments_i(ips_i  ,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 16, &
+                      moments_i(ipe_i+1,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 16, &
                       comm0, status, ierr)
     IF (deltapi .EQ. 1) & ! If we have odd Hermite degrees we need a 2nd order stencil
-    CALL mpi_sendrecv(moments_i(ips_i+1,ijsg_i:ijeg_i,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 17, &
-                      moments_i(ipe_i+2,ijsg_i:ijeg_i,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 17, &
+    CALL mpi_sendrecv(moments_i(ips_i+1,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_L, 17, &
+                      moments_i(ipe_i+2,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,izgs:izge,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_R, 17, &
                       comm0, status, ierr)
 
 END SUBROUTINE update_ghosts_p_i
 
+SUBROUTINE update_ghosts_z_moments
+  IMPLICIT NONE
+
+    IF(KIN_E) &
+    CALL update_ghosts_z_e
+    CALL update_ghosts_z_i
+
+END SUBROUTINE update_ghosts_z_moments
+
+!Communicate z+1, z+2 moments to left neighboor and z-1, z-2 moments to right one
+! [a b|C D|e f] : proc n has moments a to f where a,b,e,f are ghosts
+!
+!proc 0: [0 1 2 3 4|5 6]
+!               V V ^ ^
+!proc 1:       [3 4|5 6 7 8|9 10]
+!                       V V ^  ^
+!proc 2:               [7 8|9 10 11 12|13 14]
+!                                 V  V  ^  ^
+!proc 3:                        [11 12|13 14 15 16|17 18]
+!                                                   ^  ^
+!Periodic:                                          0  1
+SUBROUTINE update_ghosts_z_e
+
+  IMPLICIT NONE
+
+  CALL MPI_BARRIER(MPI_COMM_WORLD,ierr)
+  IF (num_procs_z .GT. 1) THEN
+    count = (ipge_e-ipgs_e+1)*(ijge_e-ijgs_e+1)*(ikxe-ikxs+1)*(ikye-ikys+1)
+
+    !!!!!!!!!!! Send ghost to right neighbour !!!!!!!!!!!!!!!!!!!!!!
+    ! Send the last local moment to fill the -1 neighbour ghost
+    CALL mpi_sendrecv(moments_e(ipgs_e:ipge_e,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,ize  ,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 20, & ! Send to right
+                      moments_e(ipgs_e:ipge_e,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,ize-1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 20, & ! Recieve from left
+                      comm0, status, ierr)
+    CALL mpi_sendrecv(moments_e(ipgs_e:ipge_e,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,ize-1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 21, & ! Send to right
+                      moments_e(ipgs_e:ipge_e,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,ize-2,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 21, & ! Recieve from left
+                      comm0, status, ierr)
+
+    !!!!!!!!!!! Send ghost to left neighbour !!!!!!!!!!!!!!!!!!!!!!
+    CALL mpi_sendrecv(moments_e(ipgs_e:ipge_e,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,izs  ,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 22, & ! Send to left
+                      moments_e(ipgs_e:ipge_e,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,izs+1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 22, & ! Recieve from right
+                      comm0, status, ierr)
+    CALL mpi_sendrecv(moments_e(ipgs_e:ipge_e,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,izs+1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 23, & ! Send to left
+                      moments_e(ipgs_e:ipge_e,ijgs_e:ijge_e,ikxs:ikxe,ikys:ikye,izs+2,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 23, & ! Recieve from right
+                      comm0, status, ierr)
+  ELSE ! still need to perform periodic boundary conditions
+      moments_e(:,:,:,:,   0,updatetlevel) = moments_e(:,:,:,:,  Nz,updatetlevel)
+      moments_e(:,:,:,:,  -1,updatetlevel) = moments_e(:,:,:,:,Nz-1,updatetlevel)
+      moments_e(:,:,:,:,Nz+1,updatetlevel) = moments_e(:,:,:,:,   1,updatetlevel)
+      moments_e(:,:,:,:,Nz+2,updatetlevel) = moments_e(:,:,:,:,   2,updatetlevel)
+  ENDIF
+
+END SUBROUTINE update_ghosts_z_e
+
+SUBROUTINE update_ghosts_z_i
+
+  IMPLICIT NONE
+  CALL MPI_BARRIER(MPI_COMM_WORLD,ierr)
+  IF (num_procs_z .GT. 1) THEN
+    count = (ipge_i-ipgs_i+1)*(ijge_i-ijgs_i+1)*(ikxe-ikxs+1)*(ikye-ikys+1)
+
+    !!!!!!!!!!! Send ghost to right neighbour !!!!!!!!!!!!!!!!!!!!!!
+    ! Send the last local moment to fill the -1 neighbour ghost
+    CALL mpi_sendrecv(moments_i(ipgs_i:ipge_i,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,ize  ,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 30, & ! Send to right
+                      moments_i(ipgs_i:ipge_i,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,ize-1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 30, & ! Recieve from left
+                      comm0, status, ierr)
+    CALL mpi_sendrecv(moments_i(ipgs_i:ipge_i,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,ize-1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 31, & ! Send to right
+                      moments_i(ipgs_i:ipge_i,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,ize-2,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 31, & ! Recieve from left
+                      comm0, status, ierr)
+
+    !!!!!!!!!!! Send ghost to left neighbour !!!!!!!!!!!!!!!!!!!!!!
+    CALL mpi_sendrecv(moments_i(ipgs_i:ipge_i,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,izs  ,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 32, & ! Send to left
+                      moments_i(ipgs_i:ipge_i,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,izs+1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 32, & ! Recieve from right
+                      comm0, status, ierr)
+    CALL mpi_sendrecv(moments_i(ipgs_i:ipge_i,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,izs+1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 33, & ! Send to left
+                      moments_i(ipgs_i:ipge_i,ijgs_i:ijge_i,ikxs:ikxe,ikys:ikye,izs+2,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 33, & ! Recieve from right
+                      comm0, status, ierr)
+  ELSE ! still need to perform periodic boundary conditions
+    moments_i(:,:,:,:,   0,updatetlevel) = moments_i(:,:,:,:,  Nz,updatetlevel)
+    moments_i(:,:,:,:,  -1,updatetlevel) = moments_i(:,:,:,:,Nz-1,updatetlevel)
+    moments_i(:,:,:,:,Nz+1,updatetlevel) = moments_i(:,:,:,:,   1,updatetlevel)
+    moments_i(:,:,:,:,Nz+2,updatetlevel) = moments_i(:,:,:,:,   2,updatetlevel)
+  ENDIF
+END SUBROUTINE update_ghosts_z_i
+
+SUBROUTINE update_ghosts_z_phi
+
+  IMPLICIT NONE
+  CALL MPI_BARRIER(MPI_COMM_WORLD,ierr)
+  IF (num_procs_z .GT. 1) THEN
+    count = (ikxe-ikxs+1)*(ikye-ikys+1)
+
+    !!!!!!!!!!! Send ghost to right neighbour !!!!!!!!!!!!!!!!!!!!!!
+    ! Send the last local moment to fill the -1 neighbour ghost
+    CALL mpi_sendrecv(phi(ikxs:ikxe,ikys:ikye,  ize), count, MPI_DOUBLE_COMPLEX, nbr_U, 40, & ! Send to right
+                      phi(ikxs:ikxe,ikys:ikye,ize-1), count, MPI_DOUBLE_COMPLEX, nbr_D, 40, & ! Recieve from left
+                      comm0, status, ierr)
+    CALL mpi_sendrecv(phi(ikxs:ikxe,ikys:ikye,ize-1), count, MPI_DOUBLE_COMPLEX, nbr_U, 41, & ! Send to right
+                      phi(ikxs:ikxe,ikys:ikye,ize-2), count, MPI_DOUBLE_COMPLEX, nbr_D, 41, & ! Recieve from left
+                      comm0, status, ierr)
+                      !!!!!!!!!!! Send ghost to left neighbour !!!!!!!!!!!!!!!!!!!!!!
+
+    CALL mpi_sendrecv(phi(ikxs:ikxe,ikys:ikye,  izs), count, MPI_DOUBLE_COMPLEX, nbr_U, 42, & ! Send to right
+                      phi(ikxs:ikxe,ikys:ikye,izs+1), count, MPI_DOUBLE_COMPLEX, nbr_D, 42, & ! Recieve from left
+                      comm0, status, ierr)
+    CALL mpi_sendrecv(phi(ikxs:ikxe,ikys:ikye,izs+1), count, MPI_DOUBLE_COMPLEX, nbr_U, 43, & ! Send to right
+                      phi(ikxs:ikxe,ikys:ikye,izs+2), count, MPI_DOUBLE_COMPLEX, nbr_D, 43, & ! Recieve from left
+                      comm0, status, ierr)
+
+  ELSE ! still need to perform periodic boundary conditions
+    phi(:,:,   0) = phi(:,:,   Nz)
+    phi(:,:,  -1) = phi(:,:, Nz-1)
+    phi(:,:,Nz+1) = phi(:,:,    1)
+    phi(:,:,Nz+2) = phi(:,:,    2)
+  ENDIF
+END SUBROUTINE update_ghosts_z_phi
+
 END MODULE ghosts
diff --git a/src/grid_mod.F90 b/src/grid_mod.F90
index 6bb65b00..4f67a86e 100644
--- a/src/grid_mod.F90
+++ b/src/grid_mod.F90
@@ -19,6 +19,8 @@ MODULE grid
   INTEGER,  PUBLIC, PROTECTED :: Ny    = 16     ! Number of total internal grid points in y
   REAL(dp), PUBLIC, PROTECTED :: Ly    = 1._dp  ! vertical length of the spatial box
   INTEGER,  PUBLIC, PROTECTED :: Nz    = 1      ! Number of total perpendicular planes
+  REAL(dp), PUBLIC, PROTECTED :: Npol  = 1._dp  ! number of poloidal turns
+  INTEGER,  PUBLIC, PROTECTED :: Odz   = 4      ! order of z interp and derivative schemes
   REAL(dp), PUBLIC, PROTECTED :: q0    = 1._dp  ! safety factor
   REAL(dp), PUBLIC, PROTECTED :: shear = 0._dp  ! magnetic field shear
   REAL(dp), PUBLIC, PROTECTED :: eps   = 0._dp ! inverse aspect ratio
@@ -42,21 +44,29 @@ MODULE grid
   ! Local and global z grids, 2D since it has to store odd and even grids
   REAL(dp), DIMENSION(:,:), ALLOCATABLE, PUBLIC :: zarray
   REAL(dp), DIMENSION(:),   ALLOCATABLE, PUBLIC :: zarray_full
-  INTEGER,  DIMENSION(:),   ALLOCATABLE, PUBLIC :: izarray
+  ! local z weights for computing simpson rule
+  INTEGER,  DIMENSION(:),   ALLOCATABLE, PUBLIC :: zweights_SR
   REAL(dp), PUBLIC, PROTECTED  ::  deltax,  deltay, deltaz, inv_deltaz
   INTEGER,  PUBLIC, PROTECTED  ::  ixs,  ixe,  iys,  iye,  izs,  ize
   INTEGER,  PUBLIC, PROTECTED  ::  izgs, izge ! ghosts
   LOGICAL,  PUBLIC, PROTECTED  ::  SG = .true.! shifted grid flag
   INTEGER,  PUBLIC :: ir,iz ! counters
+  ! Data about parallel distribution for kx
   integer(C_INTPTR_T), PUBLIC :: local_nkx, local_nky
   integer(C_INTPTR_T), PUBLIC :: local_nkx_offset, local_nky_offset
   INTEGER,             PUBLIC :: local_nkp
+  ! "" for p
   INTEGER,             PUBLIC :: local_np_e, local_np_i
   INTEGER,             PUBLIC :: total_np_e, total_np_i
   integer(C_INTPTR_T), PUBLIC :: local_np_e_offset, local_np_i_offset
   INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: counts_np_e, counts_np_i
   INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: displs_np_e, displs_np_i
-
+  ! "" for z
+  INTEGER,             PUBLIC :: local_nz
+  INTEGER,             PUBLIC :: total_nz
+  integer(C_INTPTR_T), PUBLIC :: local_nz_offset
+  INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: counts_nz
+  INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: displs_nz
   ! Grids containing position in fourier space
   REAL(dp), DIMENSION(:),     ALLOCATABLE, PUBLIC :: kxarray, kxarray_full
   REAL(dp), DIMENSION(:),     ALLOCATABLE, PUBLIC :: kyarray, kyarray_full
@@ -78,13 +88,15 @@ MODULE grid
   INTEGER,  DIMENSION(:), ALLOCATABLE, PUBLIC :: jarray_i, jarray_i_full
   INTEGER,  PUBLIC, PROTECTED ::  ips_e,ipe_e, ijs_e,ije_e ! Start and end indices for pol. deg.
   INTEGER,  PUBLIC, PROTECTED ::  ips_i,ipe_i, ijs_i,ije_i
-  INTEGER,  PUBLIC, PROTECTED ::  ipsg_e,ipeg_e, ijsg_e,ijeg_e ! Ghosts start and end indices
-  INTEGER,  PUBLIC, PROTECTED ::  ipsg_i,ipeg_i, ijsg_i,ijeg_i
+  INTEGER,  PUBLIC, PROTECTED ::  ipgs_e,ipge_e, ijgs_e,ijge_e ! Ghosts start and end indices
+  INTEGER,  PUBLIC, PROTECTED ::  ipgs_i,ipge_i, ijgs_i,ijge_i
   INTEGER,  PUBLIC, PROTECTED ::  deltape, ip0_e, ip1_e, ip2_e ! Pgrid spacing and moment 0,1,2 index
   INTEGER,  PUBLIC, PROTECTED ::  deltapi, ip0_i, ip1_i, ip2_i
-
+  LOGICAL,  PUBLIC, PROTECTED ::  CONTAINS_ip0_e, CONTAINS_ip0_i
+  LOGICAL,  PUBLIC, PROTECTED ::  CONTAINS_ip1_e, CONTAINS_ip1_i
+  LOGICAL,  PUBLIC, PROTECTED ::  CONTAINS_ip2_e, CONTAINS_ip2_i
   ! Usefull inverse numbers
-  REAL(dp), PUBLIC, PROTECTED :: inv_Nx, inv_Ny
+  REAL(dp), PUBLIC, PROTECTED :: inv_Nx, inv_Ny, inv_Nz
 
   ! Public Functions
   PUBLIC :: init_1Dgrid_distr
@@ -106,7 +118,7 @@ CONTAINS
     INTEGER :: lu_in   = 90              ! File duplicated from STDIN
 
     NAMELIST /GRID/ pmaxe, jmaxe, pmaxi, jmaxi, &
-                    Nx,  Lx,  Ny,  Ly, Nz, q0, shear, eps, SG
+                    Nx,  Lx,  Ny,  Ly, Nz, Npol, q0, shear, eps, SG
     READ(lu_in,grid)
 
     !! Compute the maximal degree of full GF moments set
@@ -162,8 +174,8 @@ CONTAINS
     local_np_e = ipe_e - ips_e + 1
     local_np_i = ipe_i - ips_i + 1
     ! Ghosts boundaries
-    ipsg_e = ips_e - 2/deltape; ipeg_e = ipe_e + 2/deltape;
-    ipsg_i = ips_i - 2/deltapi; ipeg_i = ipe_i + 2/deltapi;
+    ipgs_e = ips_e - 2/deltape; ipge_e = ipe_e + 2/deltape;
+    ipgs_i = ips_i - 2/deltapi; ipge_i = ipe_i + 2/deltapi;
     ! List of shift and local numbers between the different processes (used in scatterv and gatherv)
     ALLOCATE(counts_np_e (1:num_procs_p))
     ALLOCATE(counts_np_i (1:num_procs_p))
@@ -179,20 +191,45 @@ CONTAINS
     ENDDO
 
     ! local grid computation
-    ALLOCATE(parray_e(ipsg_e:ipeg_e))
-    ALLOCATE(parray_i(ipsg_i:ipeg_i))
-    DO ip = ipsg_e,ipeg_e
+    CONTAINS_ip0_e = .FALSE.
+    CONTAINS_ip1_e = .FALSE.
+    CONTAINS_ip2_e = .FALSE.
+    CONTAINS_ip0_i = .FALSE.
+    CONTAINS_ip1_i = .FALSE.
+    CONTAINS_ip2_i = .FALSE.
+    ALLOCATE(parray_e(ipgs_e:ipge_e))
+    ALLOCATE(parray_i(ipgs_i:ipge_i))
+    DO ip = ipgs_e,ipge_e
       parray_e(ip) = (ip-1)*deltape
-      ! Storing indices of particular degrees for DG and fluid moments computations
-      IF(parray_e(ip) .EQ. 0) ip0_e = ip
-      IF(parray_e(ip) .EQ. 1) ip1_e = ip
-      IF(parray_e(ip) .EQ. 2) ip2_e = ip
+      ! Storing indices of particular degrees for fluid moments computations
+      IF(parray_e(ip) .EQ. 0) THEN
+        ip0_e          = ip
+        CONTAINS_ip0_e = .TRUE.
+      ENDIF
+      IF(parray_e(ip) .EQ. 1) THEN
+        ip1_e          = ip
+        CONTAINS_ip1_e = .TRUE.
+      ENDIF
+      IF(parray_e(ip) .EQ. 2) THEN
+        ip2_e          = ip
+        CONTAINS_ip2_e = .TRUE.
+      ENDIF
     END DO
-    DO ip = ipsg_i,ipeg_i
+    DO ip = ipgs_i,ipge_i
       parray_i(ip) = (ip-1)*deltapi
-      IF(parray_i(ip) .EQ. 0) ip0_i = ip
-      IF(parray_i(ip) .EQ. 1) ip1_i = ip
-      IF(parray_i(ip) .EQ. 2) ip2_i = ip
+      ! Storing indices of particular degrees for fluid moments computations
+      IF(parray_i(ip) .EQ. 0) THEN
+        ip0_i          = ip
+        CONTAINS_ip0_i = .TRUE.
+      ENDIF
+      IF(parray_i(ip) .EQ. 1) THEN
+        ip1_i          = ip
+        CONTAINS_ip1_i = .TRUE.
+      ENDIF
+      IF(parray_i(ip) .EQ. 2) THEN
+        ip2_i          = ip
+        CONTAINS_ip2_i = .TRUE.
+      ENDIF
     END DO
     !DGGK operator uses moments at index p=2 (ip=3) for the p=0 term so the
     ! process that contains ip=1 MUST contain ip=3 as well for both e and i.
@@ -218,12 +255,12 @@ CONTAINS
     ijs_e = 1; ije_e = jmaxe + 1
     ijs_i = 1; ije_i = jmaxi + 1
     ! Ghosts boundaries
-    ijsg_e = ijs_e - 1; ijeg_e = ije_e + 1;
-    ijsg_i = ijs_i - 1; ijeg_i = ije_i + 1;
-    ALLOCATE(jarray_e(ijsg_e:ijeg_e))
-    ALLOCATE(jarray_i(ijsg_i:ijeg_i))
-    DO ij = ijsg_e,ijeg_e; jarray_e(ij) = ij-1; END DO
-    DO ij = ijsg_i,ijeg_i; jarray_i(ij) = ij-1; END DO
+    ijgs_e = ijs_e - 1; ijge_e = ije_e + 1;
+    ijgs_i = ijs_i - 1; ijge_i = ije_i + 1;
+    ALLOCATE(jarray_e(ijgs_e:ijge_e))
+    ALLOCATE(jarray_i(ijgs_i:ijge_i))
+    DO ij = ijgs_e,ijge_e; jarray_e(ij) = ij-1; END DO
+    DO ij = ijgs_i,ijge_i; jarray_i(ij) = ij-1; END DO
     ! Precomputations
     maxj  = MAX(jmaxi, jmaxe)
     jmaxe_dp   = real(jmaxe,dp)
@@ -236,7 +273,6 @@ CONTAINS
     USE model, ONLY: LINEARITY
     IMPLICIT NONE
     INTEGER :: i_
-
     Nkx = Nx/2+1 ! Defined only on positive kx since fields are real
     ! Grid spacings
     IF (Nx .EQ. 1) THEN
@@ -248,21 +284,16 @@ CONTAINS
       kx_max  = Nkx*deltakx
       kx_min  = deltakx
     ENDIF
-
     ! Build the full grids on process 0 to diagnose it without comm
     ALLOCATE(kxarray_full(1:Nkx))
     DO ikx = 1,Nkx
      kxarray_full(ikx) = REAL(ikx-1,dp) * deltakx
     END DO
-
     !! Parallel distribution
     ! Start and END indices of grid
-    ! ikxs = 1
-    ! ikxe = Nkx
     ikxs = local_nkx_offset + 1
     ikxe = ikxs + local_nkx - 1
     ALLOCATE(kxarray(ikxs:ikxe))
-
     local_kxmax = 0._dp
     ! Creating a grid ordered as dk*(0 1 2 3)
     DO ikx = ikxs,ikxe
@@ -282,7 +313,6 @@ CONTAINS
         contains_kxmax = .true.
       ENDIF
     END DO
-
     ! Orszag 2/3 filter
     two_third_kxmax = 2._dp/3._dp*deltakx*(Nkx-1)
     ALLOCATE(AA_x(ikxs:ikxe))
@@ -363,60 +393,76 @@ CONTAINS
   SUBROUTINE set_zgrid
     USE prec_const
     IMPLICIT NONE
-    INTEGER :: i_, ngz
-    REAL    :: grids_shift
-    ! Start and END indices of grid
-    izs     = 1
-    ize     = Nz
-    ALLOCATE(zarray(izs:ize,0:1))
-    IF (Nz .EQ. 1) THEN ! full perp case
-      deltaz      = 1._dp
-      zarray(1,0) = 0._dp
-      zarray(1,1) = 0._dp
-      SG          = .false. ! unique perp plane at z=0
-      izgs        = izs
-      izge        = ize
-    ELSE ! Parallel dimension exists
-      deltaz     = 2._dp*PI/REAL(Nz,dp)
-      inv_deltaz = 1._dp/deltaz
-      IF(SG) THEN ! Shifted grids option
-        grids_shift = deltaz/2._dp ! we shift both z grid
-      ELSE
-        grids_shift = 0._dp
-      ENDIF
-      DO iz = izs,ize
-        ! Even z grid (Napj with p even and phi)
-        zarray(iz,0) = REAL((iz-1),dp)*deltaz - PI
-        ! Odd  z grid (Napj with p odd)
-        zarray(iz,1) = REAL((iz-1),dp)*deltaz - PI + grids_shift
-      ENDDO
-      ! 2 ghosts cell for four point stencil
-      izgs = izs-2
-      izge = ize+2
+    INTEGER :: i_, fid
+    REAL    :: grid_shift, Lz
+    INTEGER :: ip, istart, iend, in
+    total_nz = Nz
+    ! Length of the flux tube (in ballooning angle)
+    Lz         = 2_dp*pi*Npol
+    ! Z stepping (#interval = #points since periodic)
+    deltaz     = Lz/REAL(Nz,dp)
+    inv_deltaz = 1._dp/deltaz
+    IF (SG) THEN
+      grid_shift = deltaz/2._dp
+    ELSE
+      grid_shift = 0._dp
     ENDIF
-    if(my_id.EQ.0) write(*,*) '#parallel planes = ', Nz
     ! Build the full grids on process 0 to diagnose it without comm
     ALLOCATE(zarray_full(1:Nz))
-    ! z from -pi to pi
-    IF (Nz .GT. 1) THEN
-      DO iz = 1,Nz
-        zarray_full(iz) = deltaz*(iz-1) - PI
-      END DO
+    DO iz = 1,total_nz
+      zarray_full(iz) = REAL(iz-1,dp)*deltaz - PI*REAL(Npol,dp)
+    END DO
+    !! Parallel data distribution
+    ! Local data distribution
+    CALL decomp1D(total_nz, num_procs_z, rank_z, izs, ize)
+    local_nz = ize - izs + 1
+    ! Ghosts boundaries (depend on the order of z operators)
+    IF(Nz .EQ. 1) THEN
+      izgs = izs;     izge = ize;
+    ELSEIF(Nz .GE. 4) THEN
+      izgs = izs - 2; izge = ize + 2;
     ELSE
-      zarray_full(1) =  0
+      ERROR STOP 'Error stop: Nz is not appropriate!!'
     ENDIF
-
-    ! Boundary conditions for FDF ddz derivative
-    ! 4 stencil deritative -> 2 ghosts each sides
-    ngz = 2
-    ALLOCATE(izarray((1-ngz):(Nz+ngz)))
-    DO iz = 1,Nz
-      izarray(iz) = iz !points to usuall indices
-    END DO
-    ! Periodic BC for  parallel centered finite differences
-    izarray(-1)   = Nz-1; izarray(0)    = Nz;
-    izarray(Nz+1) =    1; izarray(Nz+2) =  2;
-
+    ! List of shift and local numbers between the different processes (used in scatterv and gatherv)
+    ALLOCATE(counts_nz (1:num_procs_z))
+    ALLOCATE(displs_nz (1:num_procs_z))
+    DO in = 0,num_procs_z-1
+      CALL decomp1D(total_nz, num_procs_z, in, istart, iend)
+      counts_nz(in+1) = iend-istart+1
+      displs_nz(in+1) = istart-1
+    ENDDO
+    ! Local z array
+    ALLOCATE(zarray(izgs:izge,0:1))
+    DO iz = izgs,izge
+      IF(iz .EQ. 0) THEN
+        zarray(iz,0) = zarray_full(total_nz)
+        zarray(iz,1) = zarray_full(total_nz) + grid_shift
+      ELSEIF(iz .EQ. -1) THEN
+        zarray(iz,0) = zarray_full(total_nz-1)
+        zarray(iz,1) = zarray_full(total_nz-1) + grid_shift
+      ELSEIF(iz .EQ. total_nz + 1) THEN
+        zarray(iz,0) = zarray_full(1)
+        zarray(iz,1) = zarray_full(1) + grid_shift
+      ELSEIF(iz .EQ. total_nz + 2) THEN
+        zarray(iz,0) = zarray_full(2)
+        zarray(iz,1) = zarray_full(2) + grid_shift
+      ELSE
+        zarray(iz,0) = zarray_full(iz)
+        zarray(iz,1) = zarray_full(iz) + grid_shift
+      ENDIF
+    ENDDO
+    ! Weitghs for Simpson rule
+    ALLOCATE(zweights_SR(izs:ize))
+    DO iz = izs,ize
+      IF((iz .EQ. 1) .OR. (iz .EQ. Nz)) THEN
+        zweights_SR(iz) = 1._dp
+      ELSEIF(MODULO(iz-1,2)) THEN
+        zweights_SR(iz) = 4._dp
+      ELSE
+        zweights_SR(iz) = 2._dp
+      ENDIF
+    ENDDO
   END SUBROUTINE set_zgrid
 
   SUBROUTINE grid_outputinputs(fidres, str)
diff --git a/src/inital.F90 b/src/inital.F90
index 43cd7a49..d527d74f 100644
--- a/src/inital.F90
+++ b/src/inital.F90
@@ -13,9 +13,10 @@ SUBROUTINE inital
   USE closure
   USE ghosts
   USE restarts
-  USE numerics, ONLY: play_with_modes, save_EM_ZF_modes
-  USE processing, ONLY: compute_nadiab_moments
-  USE model, ONLY: KIN_E, LINEARITY
+  USE numerics,   ONLY: play_with_modes, save_EM_ZF_modes
+  USE processing, ONLY: compute_nadiab_moments, compute_fluid_moments
+  USE model,      ONLY: KIN_E, LINEARITY
+  USE nonlinear,  ONLY: compute_Sapj, nonlinear_init
   IMPLICIT NONE
 
   CALL set_updatetlevel(1)
@@ -25,7 +26,7 @@ SUBROUTINE inital
   IF ( job2load .GE. 0 ) THEN
     IF (my_id .EQ. 0) WRITE(*,*) 'Load moments'
     CALL load_moments ! get N_0
-
+    CALL update_ghosts_z_moments
     CALL poisson ! compute phi_0=phi(N_0)
   ! through initialization
   ELSE
@@ -34,51 +35,60 @@ SUBROUTINE inital
     CASE ('phi')
       IF (my_id .EQ. 0) WRITE(*,*) 'Init noisy phi'
       CALL init_phi
+      CALL update_ghosts_z_phi
     ! set moments_00 (GC density) with noise and compute phi afterwards
     CASE('mom00')
       IF (my_id .EQ. 0) WRITE(*,*) 'Init noisy gyrocenter density'
       CALL init_gyrodens ! init only gyrocenter density
-      ! CALL init_moments ! init all moments randomly (unadvised)
-      CALL poisson ! get phi_0 = phi(N_0)
+      CALL update_ghosts_z_moments
+      CALL poisson
+    ! init all moments randomly (unadvised)
     CASE('allmom')
       IF (my_id .EQ. 0) WRITE(*,*) 'Init noisy moments'
       CALL init_moments ! init all moments
-      CALL poisson ! get phi_0 = phi(N_0)
+      CALL update_ghosts_z_moments
+      CALL poisson
+    ! init a gaussian blob in gyrodens
     CASE('blob')
       IF (my_id .EQ. 0) WRITE(*,*) '--init a blob'
       CALL initialize_blob
-      CALL poisson ! get phi_0 = phi(N_0)
+      CALL update_ghosts_z_moments
+      CALL poisson
+    ! init moments 00 with a power law similarly to GENE
     CASE('ppj')
       IF (my_id .EQ. 0) WRITE(*,*) 'ppj init ~ GENE'
       call init_ppj
-      CALL poisson ! get phi_0 = phi(N_0)
+      CALL update_ghosts_z_moments
+      CALL poisson
     END SELECT
   ENDIF
+  ! closure of j>J, p>P and j<0, p<0 moments
+  IF (my_id .EQ. 0) WRITE(*,*) 'Apply closure'
+  CALL apply_closure_model
+  ! ghosts for p parallelization
+  IF (my_id .EQ. 0) WRITE(*,*) 'Ghosts communication'
+  CALL update_ghosts_p_moments
+  CALL update_ghosts_z_moments
+  !! End of phi and moments initialization
 
-  ! Save zonal and entropy modes
+  ! Save (kx,0) and (0,ky) modes for num exp
   CALL save_EM_ZF_modes
-
   ! Freeze/Wipe some selected modes (entropy,zonal,turbulent)
   CALL play_with_modes
 
-  IF (my_id .EQ. 0) WRITE(*,*) 'Apply closure'
-  CALL apply_closure_model
-
-  IF (my_id .EQ. 0) WRITE(*,*) 'Ghosts communication'
-  CALL update_ghosts
+  ! Load the COSOlver collision operator coefficients
+  IF(cosolver_coll) CALL load_COSOlver_mat
 
-  IF (my_id .EQ. 0) WRITE(*,*) 'Computing non adiab moments'
-  CALL compute_nadiab_moments
+  !! Preparing auxiliary arrays at initial state
+  ! particle density, fluid velocity and temperature (used in diagnose)
+  IF (my_id .EQ. 0) WRITE(*,*) 'Computing fluid moments'
+  CALL compute_fluid_moments
 
-  !!!!!! Set Sepj, Sipj and dnjs coeff table !!!!!!
-  IF (my_id .EQ. 0) WRITE(*,*) 'Init Sapj'
+  ! init auxval for nonlinear
+  CALL nonlinear_init
+  ! compute nonlinear for t=0 diagnostic
   CALL compute_Sapj ! compute S_0 = S(phi_0,N_0)
 
-  !!!!!! Load the COSOlver collision operator coefficients !!!!!!
-  IF(cosolver_coll) CALL load_COSOlver_mat
-  ! Compute collision
-  CALL compute_TColl ! compute C_0 = C(N_0)
-
 END SUBROUTINE inital
 !******************************************************************************!
 
@@ -379,16 +389,16 @@ SUBROUTINE init_ppj
   USE utility, ONLY: checkfield
   USE initial_par
   USE model, ONLY: KIN_E, LINEARITY
+  USE geometry, ONLY: Jacobian, iInt_Jacobian
 
   IMPLICIT NONE
 
   REAL(dp) :: noise
-  REAL(dp) :: kx, ky, sigma, gain, ky_shift
+  REAL(dp) :: kx, ky, sigma_z, amplitude, ky_shift, z
   INTEGER, DIMENSION(12) :: iseedarr
 
-  ! Seed random number generator
-  iseedarr(:)=iseed
-  CALL RANDOM_SEED(PUT=iseedarr+my_id)
+  sigma_z = pi/4.0
+  amplitude = 0.1
 
     !**** Broad noise initialization *******************************************
     ! Electrons
@@ -401,19 +411,24 @@ SUBROUTINE init_ppj
             DO iky=ikys,ikye
               ky = kyarray(iky)
               DO iz=izs,ize
-                IF (kx .NE. 0) THEN
-                  IF(ky .NE. 0) THEN
+                z = zarray(iz,0)
+                IF (kx .EQ. 0) THEN
+                  IF(ky .EQ. 0) THEN
                     moments_e(ip,ij,ikx,iky,iz,:) = 0._dp
                   ELSE
                     moments_e(ip,ij,ikx,iky,iz,:) = 0.5_dp * ky_min/(ABS(ky)+ky_min)
                   ENDIF
                 ELSE
-                  IF(ky .NE. 0) THEN
+                  IF(ky .GT. 0) THEN
                     moments_e(ip,ij,ikx,iky,iz,:) = (kx_min/(ABS(kx)+kx_min))*(ky_min/(ABS(ky)+ky_min))
                   ELSE
                     moments_e(ip,ij,ikx,iky,iz,:) = 0.5_dp*(kx_min/(ABS(kx)+kx_min))
                   ENDIF
                 ENDIF
+                ! z-dep
+                moments_e(ip,ij,ikx,iky,iz,:) = moments_e(ip,ij,ikx,iky,iz,:) * &
+                ! (1 + exp(-(z/sigma_z)**2/2.0)*sqrt(2.0*sqrt(pi)/sigma_z))
+                (Jacobian(iz,0)*iInt_Jacobian)**2
               END DO
             END DO
           END DO
@@ -439,19 +454,24 @@ SUBROUTINE init_ppj
             DO iky=ikys,ikye
               ky = kyarray(iky)
               DO iz=izs,ize
-                IF (kx .NE. 0) THEN
-                  IF(ky .NE. 0) THEN
+                z = zarray(iz,0)
+                IF (kx .EQ. 0) THEN
+                  IF(ky .EQ. 0) THEN
                     moments_i(ip,ij,ikx,iky,iz,:) = 0._dp
                   ELSE
                     moments_i(ip,ij,ikx,iky,iz,:) = 0.5_dp * ky_min/(ABS(ky)+ky_min)
                   ENDIF
                 ELSE
-                  IF(ky .NE. 0) THEN
+                  IF(ky .GT. 0) THEN
                     moments_i(ip,ij,ikx,iky,iz,:) = (kx_min/(ABS(kx)+kx_min))*(ky_min/(ABS(ky)+ky_min))
                   ELSE
                     moments_i(ip,ij,ikx,iky,iz,:) = 0.5_dp*(kx_min/(ABS(kx)+kx_min))
                   ENDIF
                 ENDIF
+                ! z-dep
+                moments_i(ip,ij,ikx,iky,iz,:) = moments_i(ip,ij,ikx,iky,iz,:) * &
+                ! (1 + exp(-(z/sigma_z)**2/2.0)*sqrt(2.0*sqrt(pi)/sigma_z))
+                (Jacobian(iz,0)*iInt_Jacobian)**2
               END DO
             END DO
           END DO
diff --git a/src/memory.F90 b/src/memory.F90
index b1508b08..24be2ae9 100644
--- a/src/memory.F90
+++ b/src/memory.F90
@@ -13,22 +13,26 @@ SUBROUTINE memory
   IMPLICIT NONE
 
   ! Electrostatic potential
-  CALL allocate_array(           phi, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(           phi, ikxs,ikxe, ikys,ikye, izgs,izge)
   CALL allocate_array(        phi_ZF, ikxs,ikxe, izs,ize)
   CALL allocate_array(        phi_EM, ikys,ikye, izs,ize)
-  CALL allocate_array(inv_poisson_op, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(inv_poisson_op, ikxs,ikxe, ikys,ikye, izgs,izge)
 
   !Electrons arrays
   IF(KIN_E) THEN
   CALL allocate_array(             Ne00, ikxs,ikxe, ikys,ikye, izs,ize)
   CALL allocate_array(           dens_e, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(           upar_e, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(           uper_e, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(           Tpar_e, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(           Tper_e, ikxs,ikxe, ikys,ikye, izs,ize)
   CALL allocate_array(           temp_e, ikxs,ikxe, ikys,ikye, izs,ize)
-  CALL allocate_array(         Kernel_e,                ijsg_e,ijeg_e, ikxs,ikxe, ikys,ikye, izs,ize, 0,1)
-  CALL allocate_array(        moments_e, ipsg_e,ipeg_e, ijsg_e,ijeg_e, ikxs,ikxe, ikys,ikye, izs,ize, 1,ntimelevel )
-  CALL allocate_array(    moments_rhs_e,  ips_e,ipe_e,   ijs_e,ije_e,  ikxs,ikxe, ikys,ikye, izs,ize, 1,ntimelevel )
-  CALL allocate_array( nadiab_moments_e, ipsg_e,ipeg_e, ijsg_e,ijeg_e, ikxs,ikxe, ikys,ikye, izs,ize)
-  CALL allocate_array(     moments_e_ZF, ipsg_e,ipeg_e, ijsg_e,ijeg_e, ikxs,ikxe, izs,ize)
-  CALL allocate_array(     moments_e_EM, ipsg_e,ipeg_e, ijsg_e,ijeg_e, ikys,ikye, izs,ize)
+  CALL allocate_array(         Kernel_e,                ijgs_e,ijge_e, ikxs,ikxe, ikys,ikye, izgs,izge,  0,1)
+  CALL allocate_array(        moments_e, ipgs_e,ipge_e, ijgs_e,ijge_e, ikxs,ikxe, ikys,ikye, izgs,izge, 1,ntimelevel )
+  CALL allocate_array(    moments_rhs_e,  ips_e,ipe_e,   ijs_e,ije_e,  ikxs,ikxe, ikys,ikye,  izs,ize,  1,ntimelevel )
+  CALL allocate_array( nadiab_moments_e, ipgs_e,ipge_e, ijgs_e,ijge_e, ikxs,ikxe, ikys,ikye, izgs,izge)
+  CALL allocate_array(     moments_e_ZF, ipgs_e,ipge_e, ijgs_e,ijge_e, ikxs,ikxe, izs,ize)
+  CALL allocate_array(     moments_e_EM, ipgs_e,ipge_e, ijgs_e,ijge_e, ikys,ikye, izs,ize)
   CALL allocate_array(          TColl_e,  ips_e,ipe_e,   ijs_e,ije_e , ikxs,ikxe, ikys,ikye, izs,ize)
   CALL allocate_array(             Sepj,  ips_e,ipe_e,   ijs_e,ije_e,  ikxs,ikxe, ikys,ikye, izs,ize)
   CALL allocate_array(           xnepj,   ips_e,ipe_e,   ijs_e,ije_e)
@@ -48,15 +52,19 @@ SUBROUTINE memory
   ENDIF
 
   !Ions arrays
-  CALL allocate_array(Ni00, ikxs,ikxe, ikys,ikye, izs,ize)
-  CALL allocate_array(dens_i, ikxs,ikxe, ikys,ikye, izs,ize)
-  CALL allocate_array(temp_i, ikxs,ikxe, ikys,ikye, izs,ize)
-  CALL allocate_array(         Kernel_i,                ijsg_i,ijeg_i, ikxs,ikxe, ikys,ikye, izs,ize, 0,1)
-  CALL allocate_array(        moments_i, ipsg_i,ipeg_i, ijsg_i,ijeg_i, ikxs,ikxe, ikys,ikye, izs,ize, 1,ntimelevel )
-  CALL allocate_array(    moments_rhs_i,  ips_i,ipe_i,   ijs_i,ije_i,  ikxs,ikxe, ikys,ikye, izs,ize, 1,ntimelevel )
-  CALL allocate_array( nadiab_moments_i, ipsg_i,ipeg_i, ijsg_i,ijeg_i, ikxs,ikxe, ikys,ikye, izs,ize)
-  CALL allocate_array(     moments_i_ZF, ipsg_i,ipeg_i, ijsg_i,ijeg_i, ikxs,ikxe, izs,ize)
-  CALL allocate_array(     moments_i_EM, ipsg_i,ipeg_i, ijsg_i,ijeg_i, ikys,ikye, izs,ize)
+  CALL allocate_array(             Ni00, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(           dens_i, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(           upar_i, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(           uper_i, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(           Tpar_i, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(           Tper_i, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(           temp_i, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(         Kernel_i,                ijgs_i,ijge_i, ikxs,ikxe, ikys,ikye, izgs,izge,  0,1)
+  CALL allocate_array(        moments_i, ipgs_i,ipge_i, ijgs_i,ijge_i, ikxs,ikxe, ikys,ikye, izgs,izge, 1,ntimelevel )
+  CALL allocate_array(    moments_rhs_i,  ips_i,ipe_i,   ijs_i,ije_i,  ikxs,ikxe, ikys,ikye,  izs,ize,  1,ntimelevel )
+  CALL allocate_array( nadiab_moments_i, ipgs_i,ipge_i, ijgs_i,ijge_i, ikxs,ikxe, ikys,ikye, izgs,izge)
+  CALL allocate_array(     moments_i_ZF, ipgs_i,ipge_i, ijgs_i,ijge_i, ikxs,ikxe, izs,ize)
+  CALL allocate_array(     moments_i_EM, ipgs_i,ipge_i, ijgs_i,ijge_i, ikys,ikye, izs,ize)
   CALL allocate_array(          TColl_i,  ips_i,ipe_i,   ijs_i,ije_i,  ikxs,ikxe, ikys,ikye, izs,ize)
   CALL allocate_array(             Sipj,  ips_i,ipe_i,   ijs_i,ije_i,  ikxs,ikxe, ikys,ikye, izs,ize)
   CALL allocate_array( xnipj,   ips_i,ipe_i, ijs_i,ije_i)
@@ -83,19 +91,27 @@ SUBROUTINE memory
   CALL allocate_array( xphijm1, ips_i,ipe_i, ijs_i,ije_i)
 
   ! Curvature and geometry
-  CALL allocate_array( Ckxky,   ikxs,ikxe, ikys,ikye, izs,ize, 0,1)
-  CALL allocate_array( kparray, ikxs,ikxe, ikys,ikye, izs,ize, 0,1)
-  CALL allocate_array(   Jacobian, izs,ize, 0,1)
-  CALL allocate_array(        gxx, izs,ize, 0,1)
-  CALL allocate_array(        gxy, izs,ize, 0,1)
-  CALL allocate_array(        gyy, izs,ize, 0,1)
-  CALL allocate_array(        gyz, izs,ize, 0,1)
-  CALL allocate_array(        gxz, izs,ize, 0,1)
-  CALL allocate_array(     gradzB, izs,ize, 0,1)
-  CALL allocate_array(     gradxB, izs,ize, 0,1)
-  CALL allocate_array(       hatB, izs,ize, 0,1)
-  CALL allocate_array(       hatR, izs,ize, 0,1)
-  call allocate_array(gradz_coeff, izs,ize, 0,1)
+  CALL allocate_array( Ckxky,   ikxs,ikxe, ikys,ikye,izgs,izge,0,1)
+  CALL allocate_array( kparray, ikxs,ikxe, ikys,ikye,izgs,izge,0,1)
+  CALL allocate_array(   Jacobian,izgs,izge, 0,1)
+  CALL allocate_array(        gxx,izgs,izge, 0,1)
+  CALL allocate_array(        gxy,izgs,izge, 0,1)
+  CALL allocate_array(        gxz,izgs,izge, 0,1)
+  CALL allocate_array(        gyy,izgs,izge, 0,1)
+  CALL allocate_array(        gyz,izgs,izge, 0,1)
+  CALL allocate_array(        gzz,izgs,izge, 0,1)
+  CALL allocate_array(     gradxB,izgs,izge, 0,1)
+  CALL allocate_array(     gradyB,izgs,izge, 0,1)
+  CALL allocate_array(     gradzB,izgs,izge, 0,1)
+  CALL allocate_array(       hatB,izgs,izge, 0,1)
+  CALL allocate_array(       hatR,izgs,izge, 0,1)
+  CALL allocate_array(       hatZ,izgs,izge, 0,1)
+  CALL allocate_array(         Rc,izgs,izge, 0,1)
+  CALL allocate_array(       phic,izgs,izge, 0,1)
+  CALL allocate_array(         Zc,izgs,izge, 0,1)
+  CALL allocate_array(       dxdR,izgs,izge, 0,1)
+  CALL allocate_array(       dxdZ,izgs,izge, 0,1)
+  call allocate_array(gradz_coeff,izgs,izge, 0,1)
 
   !___________________ 2x5D ARRAYS __________________________
   !! Collision matrices
diff --git a/src/moments_eq_rhs.F90 b/src/moments_eq_rhs_mod.F90
similarity index 61%
rename from src/moments_eq_rhs.F90
rename to src/moments_eq_rhs_mod.F90
index a7d1a71b..10c765b3 100644
--- a/src/moments_eq_rhs.F90
+++ b/src/moments_eq_rhs_mod.F90
@@ -1,3 +1,7 @@
+MODULE moments_eq_rhs
+  IMPLICIT NONE
+  PUBLIC :: moments_eq_rhs_e, moments_eq_rhs_i
+CONTAINS
 !_____________________________________________________________________________!
 !_____________________________________________________________________________!
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -15,19 +19,19 @@ SUBROUTINE moments_eq_rhs_e
   USE prec_const
   USE collision
   use geometry
-  USE calculus, ONLY : interp_z, grad_z
+  USE calculus, ONLY : interp_z, grad_z, grad_z4
   IMPLICIT NONE
 
   INTEGER     :: p_int, j_int ! loops indices and polynom. degrees
   REAL(dp)    :: kx, ky, kperp2, dzlnB_o_J
-  COMPLEX(dp) :: Tnepj, Tnepp2j, Tnepm2j, Tnepjp1, Tnepjm1, Tpare, Tphi ! Terms from b x gradB and drives
-  COMPLEX(dp) :: Tmir, Tnepp1j, Tnepm1j, Tnepp1jm1, Tnepm1jm1 ! Terms from mirror force with non adiab moments
-  COMPLEX(dp) :: UNepm1j, UNepm1jp1, UNepm1jm1 ! Terms from mirror force with adiab moments
+  COMPLEX(dp) :: Tnepj, Tnepp2j, Tnepm2j, Tnepjp1, Tnepjm1 ! Terms from b x gradB and drives
+  COMPLEX(dp) :: Tnepp1j, Tnepm1j, Tnepp1jm1, Tnepm1jm1 ! Terms from mirror force with non adiab moments
+  COMPLEX(dp) :: Tperp, Tpar, Tmir, Tphi
+  COMPLEX(dp) :: Unepm1j, Unepm1jp1, Unepm1jm1 ! Terms from mirror force with adiab moments
   COMPLEX(dp) :: i_ky
-  INTEGER     :: izm2, izm1, izp1, izp2 ! indices for centered FDF ddz
   ! To store derivatives and odd-even z grid interpolations
   COMPLEX(dp), DIMENSION(izs:ize) :: ddznepp1j, ddznepm1j, &
-              nepp1j, nepp1jm1, nepm1j, nepm1jm1, nepm1jp1
+              nepp1j, nepp1jm1, nepm1j, nepm1jm1, nepm1jp1, ddz4Nepj
 
    ! Measuring execution time
   CALL cpu_time(t0_rhs)
@@ -46,22 +50,22 @@ SUBROUTINE moments_eq_rhs_e
         i_ky   = imagu * ky     ! toroidal derivative
         IF (Nky .EQ. 1) i_ky = imagu * kxarray(ikx) ! If 1D simulation we put kx as ky
         ! Compute z derivatives and odd-even z interpolations
-        CALL   grad_z(eo,nadiab_moments_e(ip+1,ij  ,ikx,iky,:),ddznepp1j(:))
-        CALL   grad_z(eo,nadiab_moments_e(ip-1,ij  ,ikx,iky,:),ddznepm1j(:))
-        CALL interp_z(eo,nadiab_moments_e(ip+1,ij  ,ikx,iky,:),   nepp1j  (:))
-        CALL interp_z(eo,nadiab_moments_e(ip+1,ij-1,ikx,iky,:),   nepp1jm1(:))
-        CALL interp_z(eo,nadiab_moments_e(ip-1,ij  ,ikx,iky,:),   nepm1j  (:))
-        CALL interp_z(eo,nadiab_moments_e(ip-1,ij+1,ikx,iky,:),   nepm1jp1(:))
-        CALL interp_z(eo,nadiab_moments_e(ip-1,ij-1,ikx,iky,:),   nepm1jm1(:))
+        CALL   grad_z(eo,nadiab_moments_e(ip+1,ij  ,ikx,iky,izgs:izge), ddznepp1j(izs:ize))
+        CALL   grad_z(eo,nadiab_moments_e(ip-1,ij  ,ikx,iky,izgs:izge), ddznepm1j(izs:ize))
+        CALL interp_z(eo,nadiab_moments_e(ip+1,ij  ,ikx,iky,izgs:izge),  nepp1j  (izs:ize))
+        CALL interp_z(eo,nadiab_moments_e(ip+1,ij-1,ikx,iky,izgs:izge),  nepp1jm1(izs:ize))
+        CALL interp_z(eo,nadiab_moments_e(ip-1,ij  ,ikx,iky,izgs:izge),  nepm1j  (izs:ize))
+        CALL interp_z(eo,nadiab_moments_e(ip-1,ij+1,ikx,iky,izgs:izge),  nepm1jp1(izs:ize))
+        CALL interp_z(eo,nadiab_moments_e(ip-1,ij-1,ikx,iky,izgs:izge),  nepm1jm1(izs:ize))
+        ! Parallel hyperdiffusion
+        CALL  grad_z4(moments_e(ip,ij,ikx,iky,:,updatetlevel),   ddz4Nepj(:))
+
         zloope : DO  iz = izs,ize
-          ! Obtain the index with an array that accounts for boundary conditions
-          !   e.g. : 4 stencil with periodic BC, izarray(Nz+2) = 2, izarray(-1) = Nz-1
-          izp1 = izarray(iz+1); izp2 = izarray(iz+2);
-          izm1 = izarray(iz-1); izm2 = izarray(iz-2);
-            !
+          ! kperp
           kperp2= kparray(ikx,iky,iz,eo)**2
 
           !! Compute moments mixing terms
+          Tperp = 0._dp; Tpar = 0._dp; Tmir = 0._dp
           ! Perpendicular dynamic
           ! term propto n_e^{p,j}
           Tnepj   = xnepj(ip,ij)* nadiab_moments_e(ip,ij,ikx,iky,iz)
@@ -74,21 +78,20 @@ SUBROUTINE moments_eq_rhs_e
           ! term propto n_e^{p,j-1}
           Tnepjm1 = xnepjm1(ij) * nadiab_moments_e(ip,ij-1,ikx,iky,iz)
           ! Parallel dynamic
-          Tpare = 0._dp; Tmir = 0._dp
           IF(Nz .GT. 1) THEN
-          ! ddz derivative for Landau damping term
-          Tpare = xnepp1j(ip) * ddznepp1j(iz) + xnepm1j(ip) * ddznepm1j(iz)
-          ! Mirror terms
-          Tnepp1j   = ynepp1j  (ip,ij) * nepp1j  (iz)
-          Tnepp1jm1 = ynepp1jm1(ip,ij) * nepp1jm1(iz)
-          Tnepm1j   = ynepm1j  (ip,ij) * nepm1j  (iz)
-          Tnepm1jm1 = ynepm1jm1(ip,ij) * nepm1jm1(iz)
-          ! Trapping terms
-          UNepm1j   = znepm1j  (ip,ij) * nepm1j  (iz)
-          UNepm1jp1 = znepm1jp1(ip,ij) * nepm1jp1(iz)
-          UNepm1jm1 = znepm1jm1(ip,ij) * nepm1jm1(iz)
+            ! ddz derivative for Landau damping term
+            Tpar = xnepp1j(ip) * ddznepp1j(iz) + xnepm1j(ip) * ddznepm1j(iz)
+            ! Mirror terms (trapping)
+            Tnepp1j   = ynepp1j  (ip,ij) * nepp1j  (iz)
+            Tnepp1jm1 = ynepp1jm1(ip,ij) * nepp1jm1(iz)
+            Tnepm1j   = ynepm1j  (ip,ij) * nepm1j  (iz)
+            Tnepm1jm1 = ynepm1jm1(ip,ij) * nepm1jm1(iz)
+            ! Trapping terms
+            Unepm1j   = znepm1j  (ip,ij) * nepm1j  (iz)
+            Unepm1jp1 = znepm1jp1(ip,ij) * nepm1jp1(iz)
+            Unepm1jm1 = znepm1jm1(ip,ij) * nepm1jm1(iz)
 
-          Tmir = Tnepp1j + Tnepp1jm1 + Tnepm1j + Tnepm1jm1 + UNepm1j + UNepm1jp1 + UNepm1jm1
+            Tmir = Tnepp1j + Tnepp1jm1 + Tnepm1j + Tnepm1jm1 + Unepm1j + Unepm1jp1 + Unepm1jm1
           ENDIF
           !! Electrical potential term
           IF ( p_int .LE. 2 ) THEN ! kronecker p0 p1 p2
@@ -99,29 +102,22 @@ SUBROUTINE moments_eq_rhs_e
             Tphi = 0._dp
           ENDIF
 
-          !! Collision
-          ! IF (CO .EQ. 0) THEN ! Lenard Bernstein
-          !   CALL LenardBernstein_e(ip,ij,ikx,iky,iz,TColl)
-          ! ELSEIF (CO .EQ. 1) THEN ! GK Dougherty
-          !   CALL DoughertyGK_e(ip,ij,ikx,iky,iz,TColl)
-          ! ELSE ! COSOLver matrix
-          !   TColl = TColl_e(ip,ij,ikx,iky,iz)
-          ! ENDIF
-
           !! Sum of all linear terms (the sign is inverted to match RHS)
           moments_rhs_e(ip,ij,ikx,iky,iz,updatetlevel) = &
               ! Perpendicular magnetic gradient/curvature effects
               - imagu*Ckxky(ikx,iky,iz,eo)*hatR(iz,eo)* (Tnepj + Tnepp2j + Tnepm2j + Tnepjp1 + Tnepjm1)&
               ! Parallel coupling (Landau Damping)
-              - Tpare*inv_deltaz*gradz_coeff(iz,eo) &
+              - Tpar*gradz_coeff(iz,eo) &
               ! Mirror term (parallel magnetic gradient)
               - gradzB(iz,eo)* Tmir  *gradz_coeff(iz,eo) &
               ! Drives (density + temperature gradients)
               - i_ky * Tphi &
               ! Electrostatic background gradients
               - i_ky * K_E * moments_e(ip,ij,ikx,iky,iz,updatetlevel) &
-              ! Numerical hyperdiffusion (totally artificial, for stability purpose)
+              ! Numerical perpendicular hyperdiffusion (totally artificial, for stability purpose)
               - (mu_x*kx**4 + mu_y*ky**4)*moments_e(ip,ij,ikx,iky,iz,updatetlevel) &
+              ! Numerical parallel hyperdiffusion "- (mu_z*kz**4)"
+              - mu_z * ddz4Nepj(iz) &
               ! Collision term
               + TColl_e(ip,ij,ikx,iky,iz)
 
@@ -156,19 +152,19 @@ SUBROUTINE moments_eq_rhs_i
   USE model
   USE prec_const
   USE collision
-  USE calculus, ONLY : interp_z, grad_z
+  USE calculus, ONLY : interp_z, grad_z, grad_z4
   IMPLICIT NONE
 
   INTEGER     :: p_int, j_int ! loops indices and polynom. degrees
   REAL(dp)    :: kx, ky, kperp2
-  COMPLEX(dp) :: Tnipj, Tnipp2j, Tnipm2j, Tnipjp1, Tnipjm1, Tpari, Tphi
-  COMPLEX(dp) :: Tmir, Tnipp1j, Tnipm1j, Tnipp1jm1, Tnipm1jm1 ! Terms from mirror force with non adiab moments
-  COMPLEX(dp) :: UNipm1j, UNipm1jp1, UNipm1jm1 ! Terms from mirror force with adiab moments
+  COMPLEX(dp) :: Tnipj, Tnipp2j, Tnipm2j, Tnipjp1, Tnipjm1
+  COMPLEX(dp) :: Tnipp1j, Tnipm1j, Tnipp1jm1, Tnipm1jm1 ! Terms from mirror force with non adiab moments
+  COMPLEX(dp) :: Unipm1j, Unipm1jp1, Unipm1jm1 ! Terms from mirror force with adiab moments
+  COMPLEX(dp) :: Tperp, Tpar, Tmir, Tphi
   COMPLEX(dp) :: i_ky
-  INTEGER     :: izm2, izm1, izp1, izp2 ! indices for centered FDF ddz
   ! To store derivatives and odd-even z grid interpolations
   COMPLEX(dp), DIMENSION(izs:ize) :: ddznipp1j, ddznipm1j, &
-              nipp1j, nipp1jm1, nipm1j, nipm1jm1, nipm1jp1
+              nipp1j, nipp1jm1, nipm1j, nipm1jm1, nipm1jp1, ddz4Nipj
   ! Measuring execution time
   CALL cpu_time(t0_rhs)
 
@@ -186,18 +182,21 @@ SUBROUTINE moments_eq_rhs_i
         i_ky   = imagu * ky     ! toroidal derivative
         IF (Nky .EQ. 1) i_ky = imagu * kxarray(ikx) ! If 1D simulation we put kx as ky
         ! Compute z derivatives and odd-even z interpolations
-        CALL   grad_z(eo,nadiab_moments_i(ip+1,ij  ,ikx,iky,:),ddznipp1j(:))
-        CALL   grad_z(eo,nadiab_moments_i(ip-1,ij  ,ikx,iky,:),ddznipm1j(:))
-        CALL interp_z(eo,nadiab_moments_i(ip+1,ij  ,ikx,iky,:), nipp1j  (:))
-        CALL interp_z(eo,nadiab_moments_i(ip+1,ij-1,ikx,iky,:), nipp1jm1(:))
-        CALL interp_z(eo,nadiab_moments_i(ip-1,ij  ,ikx,iky,:), nipm1j  (:))
-        CALL interp_z(eo,nadiab_moments_i(ip-1,ij+1,ikx,iky,:), nipm1jp1(:))
-        CALL interp_z(eo,nadiab_moments_i(ip-1,ij-1,ikx,iky,:), nipm1jm1(:))
+        CALL   grad_z(eo,nadiab_moments_i(ip+1,ij  ,ikx,iky,izgs:izge),ddznipp1j(izs:ize))
+        CALL   grad_z(eo,nadiab_moments_i(ip-1,ij  ,ikx,iky,izgs:izge),ddznipm1j(izs:ize))
+        CALL interp_z(eo,nadiab_moments_i(ip+1,ij  ,ikx,iky,izgs:izge), nipp1j  (izs:ize))
+        CALL interp_z(eo,nadiab_moments_i(ip+1,ij-1,ikx,iky,izgs:izge), nipp1jm1(izs:ize))
+        CALL interp_z(eo,nadiab_moments_i(ip-1,ij  ,ikx,iky,izgs:izge), nipm1j  (izs:ize))
+        CALL interp_z(eo,nadiab_moments_i(ip-1,ij+1,ikx,iky,izgs:izge), nipm1jp1(izs:ize))
+        CALL interp_z(eo,nadiab_moments_i(ip-1,ij-1,ikx,iky,izgs:izge), nipm1jm1(izs:ize))
+        ! for hyperdiffusion
+        CALL  grad_z4(moments_i(ip,ij,ikx,iky,:,updatetlevel),  ddz4Nipj(:))
+
         zloopi : DO  iz = izs,ize
-          ! kperp2= gxx(iz)*kx**2 + 2._dp*gxy(iz)*kx*ky + gyy(iz)*ky**2
           kperp2= kparray(ikx,iky,iz,eo)**2
 
           !! Compute moments mixing terms
+          Tperp = 0._dp; Tpar = 0._dp; Tmir = 0._dp
           ! Perpendicular dynamic
           ! term propto n_i^{p,j}
           Tnipj   = xnipj(ip,ij) * nadiab_moments_i(ip    ,ij  ,ikx,iky,iz)
@@ -205,27 +204,27 @@ SUBROUTINE moments_eq_rhs_i
           Tnipp2j = xnipp2j(ip)  * nadiab_moments_i(ip+pp2,ij  ,ikx,iky,iz)
           ! term propto n_i^{p-2,j}
           Tnipm2j = xnipm2j(ip)  * nadiab_moments_i(ip-pp2,ij  ,ikx,iky,iz)
-          ! term propto n_e^{p,j+1}
+          ! term propto n_i^{p,j+1}
           Tnipjp1 = xnipjp1(ij)  * nadiab_moments_i(ip    ,ij+1,ikx,iky,iz)
-          ! term propto n_e^{p,j-1}
+          ! term propto n_i^{p,j-1}
           Tnipjm1 = xnipjm1(ij)  * nadiab_moments_i(ip    ,ij-1,ikx,iky,iz)
+          ! Tperp
+          Tperp = Tnipj + Tnipp2j + Tnipm2j + Tnipjp1 + Tnipjm1
           ! Parallel dynamic
-          Tpari = 0._dp; Tmir = 0._dp
           IF(Nz .GT. 1) THEN
-          ! term propto N_i^{p,j+1}, centered FDF
-          Tpari = xnipp1j(ip) * ddznipp1j(iz) + xnipm1j(ip) * ddznipm1j(iz)
-
-          ! Mirror terms
-          Tnipp1j   = ynipp1j  (ip,ij) * nipp1j  (iz)
-          Tnipp1jm1 = ynipp1jm1(ip,ij) * nipp1jm1(iz)
-          Tnipm1j   = ynipm1j  (ip,ij) * nipm1j  (iz)
-          Tnipm1jm1 = ynipm1jm1(ip,ij) * nipm1jm1(iz)
-          ! Trapping terms
-          UNipm1j   = znipm1j  (ip,ij) * nipm1j  (iz)
-          UNipm1jp1 = znipm1jp1(ip,ij) * nipm1jp1(iz)
-          UNipm1jm1 = znipm1jm1(ip,ij) * nipm1jm1(iz)
+            ! ddz derivative for Landau damping term
+            Tpar = xnipp1j(ip) * ddznipp1j(iz) + xnipm1j(ip) * ddznipm1j(iz)
+            ! Mirror terms
+            Tnipp1j   = ynipp1j  (ip,ij) * nipp1j  (iz)
+            Tnipp1jm1 = ynipp1jm1(ip,ij) * nipp1jm1(iz)
+            Tnipm1j   = ynipm1j  (ip,ij) * nipm1j  (iz)
+            Tnipm1jm1 = ynipm1jm1(ip,ij) * nipm1jm1(iz)
+            ! Trapping terms
+            Unipm1j   = znipm1j  (ip,ij) * nipm1j  (iz)
+            Unipm1jp1 = znipm1jp1(ip,ij) * nipm1jp1(iz)
+            Unipm1jm1 = znipm1jm1(ip,ij) * nipm1jm1(iz)
 
-          Tmir = Tnipp1j + Tnipp1jm1 + Tnipm1j + Tnipm1jm1 + UNipm1j + UNipm1jp1 + UNipm1jm1
+            Tmir = Tnipp1j + Tnipp1jm1 + Tnipm1j + Tnipm1jm1 + Unipm1j + Unipm1jp1 + Unipm1jm1
           ENDIF
           !! Electrical potential term
           IF ( p_int .LE. 2 ) THEN ! kronecker p0 p1 p2
@@ -236,29 +235,22 @@ SUBROUTINE moments_eq_rhs_i
             Tphi = 0._dp
           ENDIF
 
-          !! Collision
-          ! IF     (CO .EQ. 0) THEN ! Lenard Bernstein
-          !   CALL LenardBernstein_i(ip,ij,ikx,iky,iz,TColl)
-          ! ELSEIF (CO .EQ. 1) THEN ! GK Dougherty
-          !   CALL DoughertyGK_i(ip,ij,ikx,iky,iz,TColl)
-          ! ELSE! COSOLver matrix (Sugama, Coulomb)
-          !   TColl = TColl_i(ip,ij,ikx,iky,iz)
-          ! ENDIF
-
           !! Sum of all linear terms (the sign is inverted to match RHS)
           moments_rhs_i(ip,ij,ikx,iky,iz,updatetlevel) = &
               ! Perpendicular magnetic gradient/curvature effects
-              - imagu*Ckxky(ikx,iky,iz,eo)*hatR(iz,eo)*(Tnipj + Tnipp2j + Tnipm2j + Tnipjp1 + Tnipjm1)&
+              - imagu*Ckxky(ikx,iky,iz,eo)*hatR(iz,eo) * Tperp &
               ! Parallel coupling (Landau Damping)
-              - Tpari*inv_deltaz*gradz_coeff(iz,eo) &
+              - gradz_coeff(iz,eo) * Tpar &
               ! Mirror term (parallel magnetic gradient)
-              - gradzB(iz,eo)*Tmir*gradz_coeff(iz,eo) &
+              - gradzB(iz,eo) * gradz_coeff(iz,eo) * Tmir &
               ! Drives (density + temperature gradients)
               - i_ky * Tphi &
               ! Electrostatic background gradients
               - i_ky * K_E * moments_i(ip,ij,ikx,iky,iz,updatetlevel) &
               ! Numerical hyperdiffusion (totally artificial, for stability purpose)
               - (mu_x*kx**4 + mu_y*ky**4)*moments_i(ip,ij,ikx,iky,iz,updatetlevel) &
+              ! Numerical parallel hyperdiffusion "- (mu_z*kz**4)"
+              - mu_z * ddz4Nipj(iz) &
               ! Collision term
               + TColl_i(ip,ij,ikx,iky,iz)
 
@@ -276,3 +268,5 @@ SUBROUTINE moments_eq_rhs_i
   tc_rhs = tc_rhs + (t1_rhs-t0_rhs)
 
 END SUBROUTINE moments_eq_rhs_i
+
+END MODULE moments_eq_rhs
diff --git a/src/compute_Sapj.F90 b/src/nonlinear_mod.F90
similarity index 96%
rename from src/compute_Sapj.F90
rename to src/nonlinear_mod.F90
index ecf8df56..b327b44b 100644
--- a/src/compute_Sapj.F90
+++ b/src/nonlinear_mod.F90
@@ -1,8 +1,4 @@
-SUBROUTINE compute_Sapj
-  ! This routine is meant to compute the non linear term for each specie and degree
-  !! In real space Sapj ~ b*(grad(phi) x grad(g)) which in moments in fourier becomes
-  !! Sapj = Sum_n (ikx Kn phi)#(iky Sum_s d_njs Naps) - (iky Kn phi)#(ikx Sum_s d_njs Naps)
-  !! where # denotes the convolution.
+MODULE nonlinear
   USE array, ONLY : dnjs, Sepj, Sipj, kernel_i, kernel_e,&
                     moments_e_ZF, moments_i_ZF, phi_ZF
   USE initial_par, ONLY : ACT_ON_MODES
@@ -16,15 +12,34 @@ SUBROUTINE compute_Sapj
   IMPLICIT NONE
   INCLUDE 'fftw3-mpi.f03'
 
-  COMPLEX(dp), DIMENSION(ikxs:ikxe,ikys:ikye) :: F_cmpx, G_cmpx
-  COMPLEX(dp), DIMENSION(ikxs:ikxe,ikys:ikye) :: Fx_cmpx, Gy_cmpx
-  COMPLEX(dp), DIMENSION(ikxs:ikxe,ikys:ikye) :: Fy_cmpx, Gx_cmpx, F_conv_G
-  REAL(dp),    DIMENSION(ixs:ixe,iys:iye)     :: fr_real, gz_real
-  REAL(dp),    DIMENSION(ixs:ixe,iys:iye)     :: fz_real, gr_real, f_times_g
+  COMPLEX(dp), DIMENSION(:,:), ALLOCATABLE :: F_cmpx, G_cmpx
+  COMPLEX(dp), DIMENSION(:,:), ALLOCATABLE :: Fx_cmpx, Gy_cmpx
+  COMPLEX(dp), DIMENSION(:,:), ALLOCATABLE :: Fy_cmpx, Gx_cmpx, F_conv_G
 
   INTEGER :: in, is, p_int, j_int
   INTEGER :: nmax, smax ! Upper bound of the sums
   REAL(dp):: kx, ky, kerneln
+  PUBLIC :: compute_Sapj, nonlinear_init
+
+CONTAINS
+
+SUBROUTINE nonlinear_init
+  ALLOCATE( F_cmpx(ikxs:ikxe,ikys:ikye))
+  ALLOCATE( G_cmpx(ikxs:ikxe,ikys:ikye))
+
+  ALLOCATE(Fx_cmpx(ikxs:ikxe,ikys:ikye))
+  ALLOCATE(Gy_cmpx(ikxs:ikxe,ikys:ikye))
+  ALLOCATE(Fy_cmpx(ikxs:ikxe,ikys:ikye))
+  ALLOCATE(Gx_cmpx(ikxs:ikxe,ikys:ikye))
+
+  ALLOCATE(F_conv_G(ikxs:ikxe,ikys:ikye))
+END SUBROUTINE nonlinear_init
+
+SUBROUTINE compute_Sapj
+  ! This routine is meant to compute the non linear term for each specie and degree
+  !! In real space Sapj ~ b*(grad(phi) x grad(g)) which in moments in fourier becomes
+  !! Sapj = Sum_n (ikx Kn phi)#(iky Sum_s d_njs Naps) - (iky Kn phi)#(ikx Sum_s d_njs Naps)
+  !! where # denotes the convolution.
 
   ! Execution time start
   CALL cpu_time(t0_Sapj)
@@ -47,7 +62,7 @@ SUBROUTINE compute_Sapj
   CALL cpu_time(t1_Sapj)
   tc_Sapj = tc_Sapj + (t1_Sapj - t0_Sapj)
 
-CONTAINS
+END SUBROUTINE compute_Sapj
 
 SUBROUTINE compute_nonlinear
   IMPLICIT NONE
@@ -402,4 +417,4 @@ zloopi: DO iz = izs,ize
 ENDDO zloopi
 END SUBROUTINE compute_semi_linear_NZ
 
-END SUBROUTINE compute_Sapj
+END MODULE nonlinear
diff --git a/src/numerics_mod.F90 b/src/numerics_mod.F90
index a925f3fb..4d3f5af8 100644
--- a/src/numerics_mod.F90
+++ b/src/numerics_mod.F90
@@ -60,23 +60,27 @@ SUBROUTINE evaluate_kernels
 DO eo  = 0,1
 DO ikx = ikxs,ikxe
 DO iky = ikys,ikye
-DO iz = izs,ize
+DO iz  = izgs,izge
   !!!!! Electron kernels !!!!!
   IF(KIN_E) THEN
-  DO ij = ijsg_e, ijeg_e
+  DO ij = ijgs_e, ijge_e
     j_int = jarray_e(ij)
     j_dp  = REAL(j_int,dp)
     y_    =  sigmae2_taue_o2 * kparray(ikx,iky,iz,eo)**2
     kernel_e(ij,ikx,iky,iz,eo) = y_**j_int*EXP(-y_)/GAMMA(j_dp+1._dp)!factj
   ENDDO
+  IF (ijs_e .EQ. 1) &
+  kernel_e(ijgs_e,ikx,iky,iz,eo) = 0._dp
   ENDIF
   !!!!! Ion kernels !!!!!
-  DO ij = ijsg_i, ijeg_i
+  DO ij = ijgs_i, ijge_i
     j_int = jarray_i(ij)
     j_dp  = REAL(j_int,dp)
     y_    =  sigmai2_taui_o2 * kparray(ikx,iky,iz,eo)**2
     kernel_i(ij,ikx,iky,iz,eo) = y_**j_int*EXP(-y_)/GAMMA(j_dp+1._dp)!factj
   ENDDO
+  IF (ijs_i .EQ. 1) &
+  kernel_i(ijgs_i,ikx,iky,iz,eo) = 0._dp
 ENDDO
 ENDDO
 ENDDO
@@ -99,7 +103,7 @@ SUBROUTINE evaluate_poisson_op
 
   kxloop: DO ikx = ikxs,ikxe
   kyloop: DO iky = ikys,ikye
-  zloop:  DO iz  =  izs,ize
+  zloop:  DO iz  = izgs,izge
   ! This term is evalued on the even z grid since poisson uses only p=0 and phi
   IF( (kxarray(ikx).EQ.0._dp) .AND. (kyarray(iky).EQ.0._dp) ) THEN
       inv_poisson_op(ikx, iky, iz) =  0._dp
diff --git a/src/poisson.F90 b/src/poisson.F90
index 95b5342a..18eac749 100644
--- a/src/poisson.F90
+++ b/src/poisson.F90
@@ -6,6 +6,7 @@ SUBROUTINE poisson
   USE array
   USE fields
   USE grid
+  USE ghosts, ONLY: update_ghosts_z_phi
   USE calculus, ONLY : simpson_rule_z
   USE utility,  ONLY : manual_3D_bcast
   use model, ONLY : qe2_taue, qi2_taui, q_e, q_i, lambdaD, KIN_E
@@ -18,8 +19,7 @@ SUBROUTINE poisson
   COMPLEX(dp) :: fa_phi, intf_   ! current flux averaged phi
   INTEGER     :: count !! mpi integer to broadcast the electric potential at the end
   COMPLEX(dp) :: buffer(ikxs:ikxe,ikys:ikye)
-  COMPLEX(dp), DIMENSION(izs:ize) :: rho_i, rho_e     ! charge density q_a n_a
-  COMPLEX(dp), DIMENSION(izs:ize) :: integrant        ! charge density q_a n_a
+  COMPLEX(dp), DIMENSION(izgs:izge) :: rho_i, rho_e     ! charge density q_a n_a
 
   !! Poisson can be solved only for process containing ip=1
   IF ( (ips_e .EQ. ip0_e) .AND. (ips_i .EQ. ip0_i) ) THEN
@@ -31,38 +31,38 @@ SUBROUTINE poisson
         !!!! Compute ion gyro charge density
         rho_i = 0._dp
         DO ini=1,jmaxi+1
-          rho_i = rho_i &
-           +q_i*kernel_i(ini,ikx,iky,:,0)*moments_i(ip0_i,ini,ikx,iky,:,updatetlevel)
+          rho_i(izs:ize) = rho_i(izs:ize) &
+           +q_i*kernel_i(ini,ikx,iky,izs:ize,0)*moments_i(ip0_i,ini,ikx,iky,izs:ize,updatetlevel)
         END DO
 
         !!!! Compute electron gyro charge density
         rho_e = 0._dp
         IF (KIN_E) THEN ! Kinetic electrons
           DO ine=1,jmaxe+1
-            rho_e = rho_e &
-             +q_e*kernel_e(ine,ikx,iky,:,0)*moments_e(ip0_e,ine, ikx,iky,:,updatetlevel)
+            rho_e(izs:ize) = rho_e(izs:ize) &
+             +q_e*kernel_e(ine,ikx,iky,izs:ize,0)*moments_e(ip0_e,ine, ikx,iky,izs:ize,updatetlevel)
           END DO
         ELSE  ! Adiabatic electrons
           ! Adiabatic charge density (linked to flux averaged phi)
           fa_phi = 0._dp
-          IF(kyarray(iky).EQ.0._dp) THEN
-            DO ini=1,jmaxi+1
-                rho_e(:) = Jacobian(:,0)*moments_i(ip0_i,ini,ikx,iky,:,updatetlevel)&
-                           *kernel_i(ini,ikx,iky,:,0)*(inv_poisson_op(ikx,iky,:)-1._dp)
-                call simpson_rule_z(rho_e,intf_)
+          IF(kyarray(iky).EQ.0._dp) THEN ! take ky=0 mode (average)
+            DO ini=1,jmaxi+1 ! some over FLR contributions
+                rho_e(izgs:izge) = Jacobian(izgs:izge,0)*moments_i(ip0_i,ini,ikx,iky,izgs:izge,updatetlevel)&
+                           *kernel_i(ini,ikx,iky,izgs:izge,0)*(inv_poisson_op(ikx,iky,izgs:izge)-1._dp)
+                call simpson_rule_z(rho_e,intf_) ! integrate over z
                 fa_phi = fa_phi + intf_
             ENDDO
-            rho_e = fa_phi*iInt_Jacobian !Normalize by 1/int(Jxyz)dz
+            rho_e(izs:ize) = fa_phi*iInt_Jacobian !Normalize by 1/int(Jxyz)dz
           ENDIF
         ENDIF
 
         !!!!!!!!!!!!!!! Inverting the poisson equation !!!!!!!!!!!!!!!!!!!!!!!!!!
-        phi(ikx, iky, :) =  (rho_e + rho_i)*inv_poisson_op(ikx,iky,:)
+        phi(ikx, iky, izs:ize) =  (rho_e(izs:ize) + rho_i(izs:ize))*inv_poisson_op(ikx,iky,izs:ize)
       END DO kyloop
     END DO kxloop
 
     ! Cancel origin singularity
-    IF (contains_kx0 .AND. contains_ky0) phi(ikx_0,iky_0,:) = 0._dp
+    IF (contains_kx0 .AND. contains_ky0) phi(ikx_0,iky_0,izs:ize) = 0._dp
 
   ENDIF
 
diff --git a/src/ppinit.F90 b/src/ppinit.F90
index c9418310..a51d666a 100644
--- a/src/ppinit.F90
+++ b/src/ppinit.F90
@@ -7,7 +7,7 @@ SUBROUTINE ppinit
 
   INTEGER :: version_prov=-1
   ! Variables for cartesian domain decomposition
-  INTEGER, PARAMETER :: ndims=2 ! p and kx
+  INTEGER, PARAMETER :: ndims=3 ! p, kx and z
   INTEGER, DIMENSION(ndims) :: dims=0, coords=0, coords_L=0, coords_R=0
   LOGICAL :: periods(ndims) = .FALSE., reorder=.FALSE.
   CHARACTER(len=32) :: str
@@ -33,16 +33,20 @@ SUBROUTINE ppinit
     !  CALL MPI_DIMS_CREATE(num_procs, ndims, dims, ierr)
     dims(1) = 1
     dims(2) = num_procs
+    dims(3) = 1
   END IF
 
-  num_procs_p = dims(1) ! Number of processes along p
+  num_procs_p  = dims(1) ! Number of processes along p
   num_procs_kx = dims(2) ! Number of processes along kx
+  num_procs_z  = dims(3) ! Number of processes along z
 
   !
   !periodicity in p
   periods(1)=.FALSE.
   !periodicity in kx
   periods(2)=.FALSE.
+  !periodicity in z
+  periods(3)=.TRUE.
 
   CALL MPI_CART_CREATE(MPI_COMM_WORLD, ndims, dims, periods, reorder, comm0, ierr)
 
@@ -53,13 +57,16 @@ SUBROUTINE ppinit
   !
   !  Partitions 2-dim cartesian topology of comm0 into 1-dim cartesian subgrids
   !
-  CALL MPI_CART_SUB (comm0, (/.TRUE.,.FALSE./), comm_p, ierr)
-  CALL MPI_CART_SUB (comm0, (/.FALSE.,.TRUE./), comm_kx, ierr)
+  CALL MPI_CART_SUB (comm0, (/.TRUE.,.FALSE.,.FALSE./), comm_p, ierr)
+  CALL MPI_CART_SUB (comm0, (/.FALSE.,.TRUE.,.FALSE./), comm_kx, ierr)
+  CALL MPI_CART_SUB (comm0, (/.FALSE.,.FALSE.,.TRUE./),  comm_z, ierr)
   ! Find id inside the sub communicators
-  CALL MPI_COMM_RANK(comm_p, rank_p, ierr)
+  CALL MPI_COMM_RANK(comm_p,  rank_p,  ierr)
   CALL MPI_COMM_RANK(comm_kx, rank_kx, ierr)
+  CALL MPI_COMM_RANK(comm_z,  rank_z,  ierr)
   ! Find neighbours
   CALL MPI_CART_SHIFT(comm0, 0, 1, nbr_L, nbr_R, ierr)
   CALL MPI_CART_SHIFT(comm0, 1, 1, nbr_B, nbr_T, ierr)
+  CALL MPI_CART_SHIFT(comm0, 2, 1, nbr_D, nbr_U, ierr)
 
 END SUBROUTINE ppinit
diff --git a/src/prec_const_mod.F90 b/src/prec_const_mod.F90
index da75b190..90388443 100644
--- a/src/prec_const_mod.F90
+++ b/src/prec_const_mod.F90
@@ -26,6 +26,7 @@ MODULE prec_const
   REAL(dp),    PARAMETER :: PI=3.141592653589793238462643383279502884197_dp
   REAL(dp),    PARAMETER :: PIO2=1.57079632679489661923132169163975144209858_dp
   REAL(dp),    PARAMETER :: TWOPI=6.283185307179586476925286766559005768394_dp
+  REAL(dp),    PARAMETER :: ONEOPI=0.3183098861837906912164442019275156781077_dp
   REAL(dp),    PARAMETER :: SQRT2=1.41421356237309504880168872420969807856967_dp
   REAL(dp),    PARAMETER :: INVSQRT2=0.7071067811865475244008443621048490392848359377_dp
   REAL(dp),    PARAMETER :: SQRT3=1.73205080756887729352744634150587236694281_dp
diff --git a/src/processing_mod.F90 b/src/processing_mod.F90
index 5419e3b7..06430661 100644
--- a/src/processing_mod.F90
+++ b/src/processing_mod.F90
@@ -3,111 +3,138 @@ MODULE processing
     USE basic
     USE prec_const
     USE grid
+    USE geometry
     USE utility
     implicit none
 
     REAL(dp), PUBLIC, PROTECTED :: pflux_ri, gflux_ri
     REAL(dp), PUBLIC, PROTECTED :: hflux_x
 
-    PUBLIC :: compute_density, compute_temperature, compute_nadiab_moments
+    PUBLIC :: compute_nadiab_moments
+    PUBLIC :: compute_density, compute_upar, compute_uperp
+    PUBLIC :: compute_Tpar, compute_Tperp, compute_fluid_moments
     PUBLIC :: compute_radial_ion_transport, compute_radial_heatflux
 CONTAINS
 
 ! 1D diagnostic to compute the average radial particle transport <n_i v_ExB>_r
 SUBROUTINE compute_radial_ion_transport
     USE fields,           ONLY : moments_i, phi
-    USE array,            ONLY : kernel_i
+    USE array,            ONLY : kernel_i, Jacobian
     USE time_integration, ONLY : updatetlevel
     IMPLICIT NONE
-    COMPLEX(dp) :: pflux_local, gflux_local
+    COMPLEX(dp) :: pflux_local, gflux_local, integral
     REAL(dp)    :: ky_, buffer(1:2)
     INTEGER     :: i_, world_rank, world_size, root
+    COMPLEX(dp), DIMENSION(izgs:izge) :: integrant
 
     pflux_local = 0._dp ! particle flux
     gflux_local = 0._dp ! gyrocenter flux
+    integrant   = 0._dp ! auxiliary variable for z integration
     IF(ips_i .EQ. 1) THEN
-        ! Loop to compute gamma_kx = sum_ky sum_j -i k_z Kernel_j Ni00 * phi
-        DO iz = izs,ize
-          DO iky = ikys,ikye
-              ky_ = kyarray(iky)
-              DO ikx = ikxs,ikxe
-                  gflux_local = gflux_local + &
-                      imagu * ky_ * moments_i(ip0_i,1,ikx,iky,iz,updatetlevel) * CONJG(phi(ikx,iky,iz))
-                  DO ij = ijs_i, ije_i
-                      pflux_local = pflux_local + &
-                          imagu * ky_ * kernel_i(ij,ikx,iky,iz,0) * moments_i(ip0_i,ij,ikx,iky,iz,updatetlevel) * CONJG(phi(ikx,iky,iz))
-                  ENDDO
-              ENDDO
-          ENDDO
+      !! Gyro center flux (drift kinetic)
+      DO iky = ikys,ikye
+          ky_ = kyarray(iky)
+          DO ikx = ikxs,ikxe
+            DO iz = izgs,izge
+              integrant(iz) = Jacobian(iz,0)*imagu * ky_ * moments_i(ip0_i,1,ikx,iky,iz,updatetlevel) * CONJG(phi(ikx,iky,iz))
+            ENDDO
+            ! Integrate over z
+            call simpson_rule_z(integrant,integral)
+            ! add contribution
+            gflux_local = gflux_local + integral*iInt_Jacobian
         ENDDO
-        gflux_local = gflux_local/Nz ! Average over parallel planes
-        pflux_local = pflux_local/Nz
-
-        buffer(1) = REAL(gflux_local)
-        buffer(2) = REAL(pflux_local)
-        root = 0
-        !Gather manually among the rank_p=0 processes and perform the sum
-        gflux_ri = 0
-        pflux_ri = 0
-        IF (num_procs_kx .GT. 1) THEN
-            !! Everyone sends its local_sum to root = 0
-            IF (rank_kx .NE. root) THEN
-                CALL MPI_SEND(buffer, 2 , MPI_DOUBLE_PRECISION, root, 1234, comm_kx, ierr)
-            ELSE
-                ! Recieve from all the other processes
-                DO i_ = 0,num_procs_kx-1
-                    IF (i_ .NE. rank_kx) &
-                        CALL MPI_RECV(buffer, 2 , MPI_DOUBLE_PRECISION, i_, 1234, comm_kx, MPI_STATUS_IGNORE, ierr)
-                        gflux_ri = gflux_ri + buffer(1)
-                        pflux_ri = pflux_ri + buffer(2)
+      ENDDO
+      !! Particle flux
+      DO iky = ikys,ikye
+          ky_ = kyarray(iky)
+          DO ikx = ikxs,ikxe
+            integrant   = 0._dp ! auxiliary variable for z integration
+              DO ij = ijs_i, ije_i
+                DO iz = izgs,izge
+                  integrant(iz) = integrant(iz) + &
+                      Jacobian(iz,0)*imagu * ky_ * kernel_i(ij,ikx,iky,iz,0) &
+                      *moments_i(ip0_i,ij,ikx,iky,iz,updatetlevel) * CONJG(phi(ikx,iky,iz))
                 ENDDO
-            ENDIF
+              ENDDO
+              ! Integrate over z
+              call simpson_rule_z(integrant,integral)
+              ! add contribution
+              pflux_local = pflux_local + integral*iInt_Jacobian
+        ENDDO
+      ENDDO
+    ENDIF
+    buffer(1) = REAL(gflux_local)
+    buffer(2) = REAL(pflux_local)
+    root = 0
+    !Gather manually among the rank_p=0 processes and perform the sum
+    gflux_ri = 0
+    pflux_ri = 0
+    IF (num_procs_kx .GT. 1) THEN
+        !! Everyone sends its local_sum to root = 0
+        IF (rank_kx .NE. root) THEN
+            CALL MPI_SEND(buffer, 2 , MPI_DOUBLE_PRECISION, root, 1234, comm_kx, ierr)
+        ELSE
+            ! Recieve from all the other processes
+            DO i_ = 0,num_procs_kx-1
+                IF (i_ .NE. rank_kx) &
+                    CALL MPI_RECV(buffer, 2 , MPI_DOUBLE_PRECISION, i_, 1234, comm_kx, MPI_STATUS_IGNORE, ierr)
+                    gflux_ri = gflux_ri + buffer(1)
+                    pflux_ri = pflux_ri + buffer(2)
+            ENDDO
         ENDIF
+    ELSE
+      gflux_ri = gflux_local
+      pflux_ri = pflux_local
     ENDIF
+    ! if(my_id .eq. 0) write(*,*) 'pflux_ri = ',pflux_ri
 END SUBROUTINE compute_radial_ion_transport
 
 ! 1D diagnostic to compute the average radial particle transport <n_i v_ExB>_r
 SUBROUTINE compute_radial_heatflux
     USE fields,           ONLY : moments_i, moments_e, phi
-    USE array,            ONLY : dens_e, dens_i, kernel_e, kernel_i
+    USE array,            ONLY : kernel_e, kernel_i, Jacobian
     USE time_integration, ONLY : updatetlevel
-    USE model, ONLY : q_e, q_i, tau_e, tau_i, KIN_E
+    USE model, ONLY : qe_taue, qi_taui, KIN_E
     IMPLICIT NONE
-    COMPLEX(dp) :: hflux_local
+    COMPLEX(dp) :: hflux_local, integral
     REAL(dp)    :: ky_, buffer(1:2), j_dp
     INTEGER     :: i_, world_rank, world_size, root
+    COMPLEX(dp), DIMENSION(izgs:izge) :: integrant        ! charge density q_a n_a
 
     hflux_local = 0._dp ! particle flux
     IF(ips_i .EQ. 1 .AND. ips_e .EQ. 1) THEN
         ! Loop to compute gamma_kx = sum_ky sum_j -i k_z Kernel_j Ni00 * phi
-        DO iz = izs,ize
-          DO iky = ikys,ikye
-            ky_ = kyarray(iky)
-            DO ikx = ikxs,ikxe
-              DO ij = ijs_i, ije_i
-                j_dp = REAL(ij-1,dp)
-                hflux_local = hflux_local - imagu*ky_*CONJG(phi(ikx,iky,iz))&
-                 *(2._dp/3._dp * (2._dp*j_dp*kernel_i(ij,ikx,iky,iz,0) - (j_dp+1)*kernel_i(ij+1,ikx,iky,iz,0) - j_dp*kernel_i(ij-1,ikx,iky,iz,0))&
-                 * (moments_i(ip0_i,ij,ikx,iky,iz,updatetlevel)+q_i/tau_i*kernel_i(ij,ikx,iky,iz,0)*phi(ikx,iky,iz)) &
-                + SQRT2/3._dp * kernel_i(ij,ikx,iky,iz,0) * moments_i(ip2_i,ij,ikx,iky,iz,updatetlevel))
+        DO iky = ikys,ikye
+          ky_ = kyarray(iky)
+          DO ikx = ikxs,ikxe
+            integrant = 0._dp
+            DO ij = ijs_i, ije_i
+              DO iz = izgs,izge
+              integrant(iz) = integrant(iz) + Jacobian(iz,0)*imagu*ky_*CONJG(phi(ikx,iky,iz))&
+               *(twothird * (   2._dp*j_dp  * kernel_i(ij  ,ikx,iky,iz,0) &
+                                - (j_dp+1)  * kernel_i(ij+1,ikx,iky,iz,0) &
+                                -    j_dp   * kernel_i(ij-1,ikx,iky,iz,0))&
+               * (moments_i(ip0_i,ij,ikx,iky,iz,updatetlevel)+qi_taui*kernel_i(ij,ikx,iky,iz,0)*phi(ikx,iky,iz)) &
+              + SQRT2*onethird * kernel_i(ij,ikx,iky,iz,0) * moments_i(ip2_i,ij,ikx,iky,iz,updatetlevel))
               ENDDO
-              IF(KIN_E) THEN
-              DO ij = ijs_e, ije_e
-                j_dp = REAL(ij-1,dp)
-                hflux_local = hflux_local - imagu*ky_*CONJG(phi(ikx,iky,iz))&
-                 *(2._dp/3._dp *(2._dp*j_dp  * kernel_e(ij  ,ikx,iky,iz,0) &
-                                  -(j_dp+1)  * kernel_e(ij+1,ikx,iky,iz,0) &
-                                  -j_dp      * kernel_e(ij-1,ikx,iky,iz,0))&
-                               *(moments_e(ip0_e,ij,ikx,iky,iz,updatetlevel)&
-                                  +q_e/tau_e * kernel_e(ij  ,ikx,iky,iz,0) * phi(ikx,iky,iz)) &
-                  +SQRT2/3._dp * kernel_e(ij,ikx,iky,iz,0) *                                                                                                     moments_e(ip2_e,ij,ikx,iky,iz,updatetlevel))
+            ENDDO
+            IF(KIN_E) THEN
+            DO ij = ijs_e, ije_e
+              DO iz = izgs,izge
+              integrant(iz) = integrant(iz) + Jacobian(iz,0)*imagu*ky_*CONJG(phi(ikx,iky,iz))&
+               *(twothird * (   2._dp*j_dp  * kernel_e(ij  ,ikx,iky,iz,0) &
+                                - (j_dp+1)  * kernel_e(ij+1,ikx,iky,iz,0) &
+                                -    j_dp   * kernel_e(ij-1,ikx,iky,iz,0))&
+               * (moments_e(ip0_e,ij,ikx,iky,iz,updatetlevel)+qe_taue*kernel_e(ij,ikx,iky,iz,0)*phi(ikx,iky,iz)) &
+              + SQRT2*onethird * kernel_e(ij,ikx,iky,iz,0) * moments_e(ip2_e,ij,ikx,iky,iz,updatetlevel))
               ENDDO
-              ENDIF
             ENDDO
+            ENDIF
+            ! Integrate over z
+            call simpson_rule_z(integrant,integral)
+            hflux_local = hflux_local + integral*iInt_Jacobian
           ENDDO
         ENDDO
-        hflux_local = hflux_local/Nz
-
         buffer(2) = REAL(hflux_local)
         root = 0
         !Gather manually among the rank_p=0 processes and perform the sum
@@ -124,6 +151,8 @@ SUBROUTINE compute_radial_heatflux
                         hflux_x = hflux_x + buffer(2)
                 ENDDO
             ENDIF
+        ELSE
+          hflux_x = hflux_local
         ENDIF
     ENDIF
 END SUBROUTINE compute_radial_heatflux
@@ -139,115 +168,302 @@ SUBROUTINE compute_nadiab_moments
   USE model,            ONLY : qe_taue, qi_taui, KIN_E
   implicit none
 
-  ! Add non-adiabatique term
+  ! Electron non adiab moments
+  DO ikx = ikxs,ikxe
+  DO iky = ikys,ikye
+  DO iz  = izgs,izge
   IF(KIN_E) THEN
-  DO ip=ipsg_e,ipeg_e
+  DO ip=ipgs_e,ipge_e
     IF(parray_e(ip) .EQ. 0) THEN
-      DO ij=ijsg_e,ijeg_e
-        nadiab_moments_e(ip,ij,ikxs:ikxe,ikys:ikye,izs:ize)&
-         = moments_e(ip,ij,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel) &
-           + qe_taue*kernel_e(ij,ikxs:ikxe,ikys:ikye,izs:ize,0)*phi(ikxs:ikxe,ikys:ikye,izs:ize)
+      DO ij=ijgs_e,ijge_e
+        nadiab_moments_e(ip,ij,ikx,iky,iz) = moments_e(ip,ij,ikx,iky,iz,updatetlevel) &
+                                  + qe_taue*kernel_e(ij,ikx,iky,iz,0)*phi(ikx,iky,iz)
       ENDDO
     ELSE
-      nadiab_moments_e(ip,ijsg_e:ijeg_e,ikxs:ikxe,ikys:ikye,izs:ize) &
-      = moments_e(ip,ijsg_e:ijeg_e,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel)
+      DO ij=ijgs_e,ijge_e
+        nadiab_moments_e(ip,ij,ikx,iky,iz) = moments_e(ip,ij,ikx,iky,iz,updatetlevel)
+      ENDDO
     ENDIF
   ENDDO
   ENDIF
-  ! Add non-adiabatique term
-  DO ip=ipsg_i,ipeg_i
+  ! Ions non adiab moments
+  DO ip=ipgs_i,ipge_i
     IF(parray_i(ip) .EQ. 0) THEN
-      DO ij=ijsg_i,ijeg_i
-        nadiab_moments_i(ip,ij,ikxs:ikxe,ikys:ikye,izs:ize)&
-         = moments_i(ip,ij,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel) &
-           + qi_taui*kernel_i(ij,ikxs:ikxe,ikys:ikye,izs:ize,0)*phi(ikxs:ikxe,ikys:ikye,izs:ize)
+      DO ij=ijgs_i,ijge_i
+        nadiab_moments_i(ip,ij,ikx,iky,iz) = moments_i(ip,ij,ikx,iky,iz,updatetlevel) &
+                                  + qi_taui*kernel_i(ij,ikx,iky,iz,0)*phi(ikx,iky,iz)
       ENDDO
     ELSE
-      nadiab_moments_i(ip,ijsg_i:ijeg_i,ikxs:ikxe,ikys:ikye,izs:ize) &
-      = moments_i(ip,ijsg_i:ijeg_i,ikxs:ikxe,ikys:ikye,izs:ize,updatetlevel)
+      DO ij=ijgs_i,ijge_i
+        nadiab_moments_i(ip,ij,ikx,iky,iz) = moments_i(ip,ij,ikx,iky,iz,updatetlevel)
+      ENDDO
     ENDIF
   ENDDO
+  ENDDO
+  ENDDO
+  ENDDO
   !
 END SUBROUTINE compute_nadiab_moments
 
 ! Compute the 2D particle density for electron and ions (sum over Laguerre)
 SUBROUTINE compute_density
-  USE fields,           ONLY : moments_i, moments_e, phi
-  USE array,            ONLY : dens_e, dens_i, kernel_e, kernel_i
-  USE time_integration, ONLY : updatetlevel
-  USE model, ONLY : q_e, q_i, tau_e, tau_i, KIN_E
+  USE array, ONLY : dens_e, dens_i, kernel_e, kernel_i, nadiab_moments_e, nadiab_moments_i
+  USE model, ONLY : KIN_E
   IMPLICIT NONE
+  COMPLEX(dp) :: dens
 
-  IF ( (ips_e .EQ. ip0_e) .AND. (ips_i .EQ. ip0_i) ) THEN
+  IF ( CONTAINS_ip0_e .AND. CONTAINS_ip0_i ) THEN
       ! Loop to compute dens_i = sum_j kernel_j Ni0j at each k
       DO iky = ikys,ikye
         DO ikx = ikxs,ikxe
           DO iz = izs,ize
             IF(KIN_E) THEN
             ! electron density
-            dens_e(ikx,iky,iz) = 0._dp
+            dens = 0._dp
             DO ij = ijs_e, ije_e
-                dens_e(ikx,iky,iz) = dens_e(ikx,iky,iz) + kernel_e(ij,ikx,iky,iz,0) * &
-                 (moments_e(ip0_e,ij,ikx,iky,iz,updatetlevel)+q_e/tau_e*kernel_e(ij,ikx,iky,iz,0)*phi(ikx,iky,iz))
+                dens = dens + kernel_e(ij,ikx,iky,iz,0) * nadiab_moments_e(ip0_e,ij,ikx,iky,iz)
             ENDDO
+            dens_e(ikx,iky,iz) = dens
             ENDIF
             ! ion density
-            dens_i(ikx,iky,iz) = 0._dp
+            dens = 0._dp
             DO ij = ijs_i, ije_i
-                dens_i(ikx,iky,iz) = dens_i(ikx,iky,iz) + kernel_i(ij,ikx,iky,iz,0) * &
-                (moments_i(ip0_i,ij,ikx,iky,iz,updatetlevel)+q_i/tau_i*kernel_i(ij,ikx,iky,iz,0)*phi(ikx,iky,iz))
+                dens = dens + kernel_i(ij,ikx,iky,iz,0) * nadiab_moments_i(ip0_e,ij,ikx,iky,iz)
             ENDDO
+            dens_i(ikx,iky,iz) = dens
           ENDDO
         ENDDO
       ENDDO
   ENDIF
-  IF(KIN_E)&
-  CALL manual_3D_bcast(dens_e(ikxs:ikxe,ikys:ikye,izs:ize))
-  CALL manual_3D_bcast(dens_i(ikxs:ikxe,ikys:ikye,izs:ize))
+  ! IF(KIN_E)&
+  ! CALL manual_3D_bcast(dens_e(ikxs:ikxe,ikys:ikye,izs:ize))
+  ! CALL manual_3D_bcast(dens_i(ikxs:ikxe,ikys:ikye,izs:ize))
 END SUBROUTINE compute_density
 
+! Compute the 2D particle fluid perp velocity for electron and ions (sum over Laguerre)
+SUBROUTINE compute_uperp
+  USE array, ONLY : uper_e, uper_i, kernel_e, kernel_i, nadiab_moments_e, nadiab_moments_i
+  USE model, ONLY : KIN_E
+  IMPLICIT NONE
+  COMPLEX(dp) :: uperp
+
+  IF ( CONTAINS_ip0_e .AND. CONTAINS_ip0_i ) THEN
+      DO iky = ikys,ikye
+        DO ikx = ikxs,ikxe
+          DO iz = izs,ize
+            IF(KIN_E) THEN
+            ! electron
+            uperp = 0._dp
+            DO ij = ijs_e, ije_e
+                uperp = uperp + kernel_e(ij,ikx,iky,iz,0) *&
+                 0.5_dp*(nadiab_moments_e(ip0_e,ij,ikx,iky,iz) - nadiab_moments_e(ip0_e,ij-1,ikx,iky,iz))
+            ENDDO
+            uper_e(ikx,iky,iz) = uperp
+            ENDIF
+            ! ion
+            uperp = 0._dp
+            DO ij = ijs_i, ije_i
+              uperp = uperp + kernel_i(ij,ikx,iky,iz,0) *&
+               0.5_dp*(nadiab_moments_i(ip0_i,ij,ikx,iky,iz) - nadiab_moments_i(ip0_e,ij-1,ikx,iky,iz))
+             ENDDO
+            uper_i(ikx,iky,iz) = uperp
+          ENDDO
+        ENDDO
+      ENDDO
+  ENDIF
+  ! IF(KIN_E)&
+  ! CALL manual_3D_bcast(uper_e(ikxs:ikxe,ikys:ikye,izs:ize))
+  ! CALL manual_3D_bcast(uper_i(ikxs:ikxe,ikys:ikye,izs:ize))
+END SUBROUTINE compute_uperp
+
+! Compute the 2D particle fluid par velocity for electron and ions (sum over Laguerre)
+SUBROUTINE compute_upar
+  USE array, ONLY : upar_e, upar_i, kernel_e, kernel_i, nadiab_moments_e, nadiab_moments_i
+  USE model, ONLY : KIN_E
+  IMPLICIT NONE
+  COMPLEX(dp) :: upar
+
+  IF ( CONTAINS_ip1_e .AND. CONTAINS_ip1_i ) THEN
+      DO iky = ikys,ikye
+        DO ikx = ikxs,ikxe
+          DO iz = izs,ize
+            IF(KIN_E) THEN
+            ! electron
+            upar = 0._dp
+            DO ij = ijs_e, ije_e
+              upar = upar + kernel_e(ij,ikx,iky,iz,1)*nadiab_moments_e(ip1_e,ij,ikx,iky,iz)
+            ENDDO
+            upar_e(ikx,iky,iz) = upar
+            ENDIF
+            ! ion
+            upar = 0._dp
+            DO ij = ijs_i, ije_i
+              upar = upar + kernel_i(ij,ikx,iky,iz,1)*nadiab_moments_i(ip1_i,ij,ikx,iky,iz)
+             ENDDO
+            upar_i(ikx,iky,iz) = upar
+          ENDDO
+        ENDDO
+      ENDDO
+  ELSE
+    IF(KIN_E)&
+    upar_e = 0
+    upar_i = 0
+  ENDIF
+  ! IF(KIN_E)&
+  ! CALL manual_3D_bcast(upar_e(ikxs:ikxe,ikys:ikye,izs:ize))
+  ! CALL manual_3D_bcast(upar_i(ikxs:ikxe,ikys:ikye,izs:ize))
+END SUBROUTINE compute_upar
+
 ! Compute the 2D particle temperature for electron and ions (sum over Laguerre)
-SUBROUTINE compute_temperature
-  USE fields,           ONLY : moments_i, moments_e, phi
-  USE array,            ONLY : temp_e, temp_i, kernel_e, kernel_i
-  USE time_integration, ONLY : updatetlevel
-  USE model, ONLY : q_e, q_i, tau_e, tau_i, KIN_E
+SUBROUTINE compute_tperp
+  USE array, ONLY : Tper_e, Tper_i, kernel_e, kernel_i, nadiab_moments_e, nadiab_moments_i
+  USE model, ONLY : KIN_E
+  IMPLICIT NONE
+  REAL(dp)    :: j_dp
+  COMPLEX(dp) :: Tperp
+
+  IF ( CONTAINS_ip0_e .AND. CONTAINS_ip0_i .AND. &
+       CONTAINS_ip2_e .AND. CONTAINS_ip2_i ) THEN
+      ! Loop to compute T = 1/3*(Tpar + 2Tperp)
+      DO iky = ikys,ikye
+        DO ikx = ikxs,ikxe
+          DO iz = izs,ize
+            ! electron temperature
+            IF(KIN_E) THEN
+            Tperp  = 0._dp
+            DO ij = ijs_e, ije_e
+              j_dp = REAL(ij-1,dp)
+              Tperp = Tperp + kernel_e(ij,ikx,iky,iz,0)*&
+                  ((2_dp*j_dp+1)*nadiab_moments_e(ip0_e,ij  ,ikx,iky,iz)&
+                  -j_dp         *nadiab_moments_e(ip0_e,ij-1,ikx,iky,iz)&
+                  -j_dp+1       *nadiab_moments_e(ip0_e,ij+1,ikx,iky,iz))
+            ENDDO
+            Tper_e(ikx,iky,iz) = Tperp
+            ENDIF
+            ! ion temperature
+            Tperp = 0._dp
+            DO ij = ijs_i, ije_i
+              j_dp = REAL(ij-1,dp)
+              Tperp = Tperp + kernel_i(ij,ikx,iky,iz,0)*&
+                  ((2_dp*j_dp+1)*nadiab_moments_i(ip0_i,ij  ,ikx,iky,iz)&
+                  -j_dp         *nadiab_moments_i(ip0_i,ij-1,ikx,iky,iz)&
+                  -j_dp+1       *nadiab_moments_i(ip0_i,ij+1,ikx,iky,iz))
+            ENDDO
+            Tper_i(ikx,iky,iz) = Tperp
+          ENDDO
+        ENDDO
+      ENDDO
+  ENDIF
+  ! IF(KIN_E)&
+  ! CALL manual_3D_bcast(Tper_e(ikxs:ikxe,ikys:ikye,izs:ize))
+  ! CALL manual_3D_bcast(Tper_i(ikxs:ikxe,ikys:ikye,izs:ize))
+END SUBROUTINE compute_Tperp
+
+! Compute the 2D particle temperature for electron and ions (sum over Laguerre)
+SUBROUTINE compute_Tpar
+  USE array, ONLY : Tpar_e, Tpar_i, kernel_e, kernel_i, nadiab_moments_e, nadiab_moments_i
+  USE model, ONLY : KIN_E
   IMPLICIT NONE
   REAL(dp)    :: j_dp
-  COMPLEX(dp) :: Tperp, Tpar
+  COMPLEX(dp) :: tpar
 
-  IF( ((ips_i .EQ. 1) .AND. (ips_e .EQ. 1)) ) THEN
+  IF ( CONTAINS_ip0_e .AND. CONTAINS_ip0_i .AND. &
+       CONTAINS_ip2_e .AND. CONTAINS_ip2_i ) THEN
       ! Loop to compute T = 1/3*(Tpar + 2Tperp)
       DO iky = ikys,ikye
         DO ikx = ikxs,ikxe
           DO iz = izs,ize
             ! electron temperature
             IF(KIN_E) THEN
-            temp_e(ikx,iky,iz) = 0._dp
+            Tpar  = 0._dp
             DO ij = ijs_e, ije_e
               j_dp = REAL(ij-1,dp)
-              temp_e(ikx,iky,iz) = temp_e(ikx,iky,iz) + &
-                2._dp/3._dp * (2._dp*j_dp*kernel_e(ij,ikx,iky,iz,0) - (j_dp+1)*kernel_e(ij+1,ikx,iky,iz,0) - j_dp*kernel_e(ij-1,ikx,iky,iz,0))&
-                 * (moments_e(ip0_e,ij,ikx,iky,iz,updatetlevel)+q_e/tau_e*kernel_e(ij,ikx,iky,iz,0)*phi(ikx,iky,iz)) &
-                + SQRT2/3._dp * kernel_e(ij,ikx,iky,iz,0) * moments_e(ip2_e,ij,ikx,iky,iz,updatetlevel)
+              Tpar  = Tpar + kernel_e(ij,ikx,iky,iz,0)*&
+               (SQRT2 * nadiab_moments_e(ip2_e,ij,ikx,iky,iz) &
+                      + nadiab_moments_e(ip0_e,ij,ikx,iky,iz))
             ENDDO
+            Tpar_e(ikx,iky,iz) = Tpar
             ENDIF
             ! ion temperature
-            temp_i(ikx,iky,iz) = 0._dp
+            Tpar  = 0._dp
             DO ij = ijs_i, ije_i
               j_dp = REAL(ij-1,dp)
-              temp_i(ikx,iky,iz) = temp_i(ikx,iky,iz) + &
-                2._dp/3._dp * (2._dp*j_dp*kernel_i(ij,ikx,iky,iz,0) - (j_dp+1)*kernel_i(ij+1,ikx,iky,iz,0) - j_dp*kernel_i(ij-1,ikx,iky,iz,0))&
-                 * (moments_i(ip0_i,ij,ikx,iky,iz,updatetlevel)+q_i/tau_i*kernel_i(ij,ikx,iky,iz,0)*phi(ikx,iky,iz)) &
-                + SQRT2/3._dp * kernel_i(ij,ikx,iky,iz,0) * moments_i(ip2_i,ij,ikx,iky,iz,updatetlevel)
+              Tpar  = Tpar + kernel_i(ij,ikx,iky,iz,0)*&
+               (SQRT2 * nadiab_moments_i(ip2_i,ij,ikx,iky,iz) &
+                      + nadiab_moments_i(ip0_i,ij,ikx,iky,iz))
             ENDDO
+            Tpar_i(ikx,iky,iz) = Tpar
           ENDDO
         ENDDO
       ENDDO
   ENDIF
-  IF(KIN_E)&
-  CALL manual_3D_bcast(temp_e(ikxs:ikxe,ikys:ikye,izs:ize))
-  CALL manual_3D_bcast(temp_i(ikxs:ikxe,ikys:ikye,izs:ize))
-END SUBROUTINE compute_temperature
+  ! IF(KIN_E)&
+  ! CALL manual_3D_bcast(Tpar_e(ikxs:ikxe,ikys:ikye,izs:ize))
+  ! CALL manual_3D_bcast(Tpar_i(ikxs:ikxe,ikys:ikye,izs:ize))
+END SUBROUTINE compute_Tpar
+
+! Compute the 2D particle fluid moments for electron and ions (sum over Laguerre)
+SUBROUTINE compute_fluid_moments
+  USE array, ONLY : dens_e, Tpar_e, Tper_e, dens_i, Tpar_i, Tper_i
+  USE model, ONLY : KIN_E
+  IMPLICIT NONE
+  CALL compute_density
+  CALL compute_upar
+  CALL compute_uperp
+  CALL compute_Tpar
+  CALL compute_Tperp
+  ! Temperature
+  temp_e = (Tpar_e - 2._dp * Tper_e)/3._dp - dens_e
+  temp_i = (Tpar_i - 2._dp * Tper_i)/3._dp - dens_i
+END SUBROUTINE compute_fluid_moments
+
+! Compute the 2D particle temperature for electron and ions (sum over Laguerre)
+! SUBROUTINE compute_temperature
+!   USE array, ONLY : temp_e, temp_i, kernel_e, kernel_i, nadiab_moments_e, nadiab_moments_i
+!   USE model, ONLY : KIN_E
+!   IMPLICIT NONE
+!   REAL(dp)    :: j_dp
+!   COMPLEX(dp) :: Tperp, Tpar, dens
+!
+!   IF ( CONTAINS_ip0_e .AND. CONTAINS_ip0_i .AND. &
+!        CONTAINS_ip2_e .AND. CONTAINS_ip2_i ) THEN
+!       ! Loop to compute T = 1/3*(Tpar + 2Tperp)
+!       DO iky = ikys,ikye
+!         DO ikx = ikxs,ikxe
+!           DO iz = izs,ize
+!             ! electron temperature
+!             IF(KIN_E) THEN
+!             dens  = 0._dp
+!             Tpar  = 0._dp
+!             Tperp = 0._dp
+!             DO ij = ijs_e, ije_e
+!               j_dp = REAL(ij-1,dp)
+!               temp_e(ikx,iky,iz) = temp_e(ikx,iky,iz) + &
+!                 2._dp/3._dp * (2._dp*j_dp*kernel_e(ij,ikx,iky,iz,0) - (j_dp+1)*kernel_e(ij+1,ikx,iky,iz,0) - j_dp*kernel_e(ij-1,ikx,iky,iz,0))&
+!                  * (moments_e(ip0_e,ij,ikx,iky,iz,updatetlevel)+q_e/tau_e*kernel_e(ij,ikx,iky,iz,0)*phi(ikx,iky,iz)) &
+!                 + SQRT2/3._dp * kernel_e(ij,ikx,iky,iz,0) * moments_e(ip2_e,ij,ikx,iky,iz,updatetlevel)
+!             ENDDO
+!             temp_e(ikx,iky,iz) = (Tpar - 2._dp * Tperp)/3._dp - dens
+!             ENDIF
+!             ! ion temperature
+!             dens  = 0._dp
+!             Tpar  = 0._dp
+!             Tperp = 0._dp
+!             DO ij = ijs_i, ije_i
+!               j_dp = REAL(ij-1,dp)
+!               temp_i(ikx,iky,iz) = temp_i(ikx,iky,iz) + &
+!                 2._dp/3._dp * (2._dp*j_dp*kernel_i(ij,ikx,iky,iz,0) - (j_dp+1)*kernel_i(ij+1,ikx,iky,iz,0) - j_dp*kernel_i(ij-1,ikx,iky,iz,0))&
+!                  * (moments_i(ip0_i,ij,ikx,iky,iz,updatetlevel)+q_i/tau_i*kernel_i(ij,ikx,iky,iz,0)*phi(ikx,iky,iz)) &
+!                 + SQRT2/3._dp * kernel_i(ij,ikx,iky,iz,0) * moments_i(ip2_i,ij,ikx,iky,iz,updatetlevel)
+!             ENDDO
+!             temp_i(ikx,iky,iz) = (Tpar - 2._dp * Tperp)/3._dp - dens
+!           ENDDO
+!         ENDDO
+!       ENDDO
+!   ENDIF
+!   IF(KIN_E) CALL manual_3D_bcast(temp_e(ikxs:ikxe,ikys:ikye,izs:ize))
+!   CALL manual_3D_bcast(temp_i(ikxs:ikxe,ikys:ikye,izs:ize))
+! END SUBROUTINE compute_temperature
+
 
 END MODULE processing
diff --git a/src/srcinfo.h b/src/srcinfo.h
index b1faef28..e4739288 100644
--- a/src/srcinfo.h
+++ b/src/srcinfo.h
@@ -3,8 +3,8 @@ character(len=40) BRANCH
 character(len=20) AUTHOR
 character(len=40) EXECDATE
 character(len=40) HOST
-parameter (VERSION='65a7746-dirty')
+parameter (VERSION='aa401ea-dirty')
 parameter (BRANCH='master')
 parameter (AUTHOR='ahoffman')
-parameter (EXECDATE='Mon Mar 14 16:05:57 CET 2022')
+parameter (EXECDATE='Tue Apr 5 17:06:15 CEST 2022')
 parameter (HOST ='spcpc606')
diff --git a/src/srcinfo/srcinfo.h b/src/srcinfo/srcinfo.h
index b1faef28..e4739288 100644
--- a/src/srcinfo/srcinfo.h
+++ b/src/srcinfo/srcinfo.h
@@ -3,8 +3,8 @@ character(len=40) BRANCH
 character(len=20) AUTHOR
 character(len=40) EXECDATE
 character(len=40) HOST
-parameter (VERSION='65a7746-dirty')
+parameter (VERSION='aa401ea-dirty')
 parameter (BRANCH='master')
 parameter (AUTHOR='ahoffman')
-parameter (EXECDATE='Mon Mar 14 16:05:57 CET 2022')
+parameter (EXECDATE='Tue Apr 5 17:06:15 CEST 2022')
 parameter (HOST ='spcpc606')
diff --git a/src/stepon.F90 b/src/stepon.F90
index 79f5dfbb..5aef1d2e 100644
--- a/src/stepon.F90
+++ b/src/stepon.F90
@@ -4,7 +4,6 @@ SUBROUTINE stepon
   USE array , ONLY: moments_rhs_e, moments_rhs_i, Sepj, Sipj
   USE basic
   USE closure
-  USE collision, ONLY : compute_TColl
   USE fields, ONLY: moments_e, moments_i, phi
   USE initial_par, ONLY: ACT_ON_MODES
   USE ghosts
@@ -13,9 +12,8 @@ SUBROUTINE stepon
   use prec_const
   USE time_integration
   USE numerics, ONLY: play_with_modes
-  USE processing, ONLY: compute_nadiab_moments
+  USE processing, ONLY: compute_nadiab_moments, compute_fluid_moments
   USE utility, ONLY: checkfield
-
   IMPLICIT NONE
 
   INTEGER :: num_step
@@ -25,29 +23,30 @@ SUBROUTINE stepon
    !----- BEFORE: All fields are updated for step = n
       ! Compute right hand side from current fields
       ! N_rhs(N_n, nadia_n, phi_n, S_n, Tcoll_n)
-      IF(KIN_E) CALL moments_eq_rhs_e
-      CALL moments_eq_rhs_i
+      CALL compute_RHS
 
       ! ---- step n -> n+1 transition
       ! Advance from updatetlevel to updatetlevel+1 (according to num. scheme)
       CALL advance_time_level
+      ! ----
+
       ! Update moments with the hierarchy RHS (step by step)
       ! N_n+1 = N_n + N_rhs(n)
       CALL advance_moments
-      ! Closure enforcement of N_n+1
+      ! Closure enforcement of moments
       CALL apply_closure_model
       ! Exchanges the ghosts values of N_n+1
-      CALL update_ghosts
+      CALL update_ghosts_p_moments
+      CALL update_ghosts_z_moments
+
       ! Update electrostatic potential phi_n = phi(N_n+1)
       CALL poisson
-      ! Update non adiabatic moments n -> n+1
-      CALL compute_nadiab_moments
-      ! Update collision C_n+1 = C(N_n+1)
-      CALL compute_TColl
-      ! Update nonlinear term S_n -> S_n+1(phi_n+1,N_n+1)
-      CALL compute_Sapj
+      CALL update_ghosts_z_phi
+
+      ! Numerical experiments
       ! Store or cancel/maintain zonal modes artificially
       CALL play_with_modes
+
       !-  Check before next step
       CALL checkfield_all()
       IF( nlend ) EXIT ! exit do loop
@@ -57,6 +56,23 @@ SUBROUTINE stepon
    END DO
 
    CONTAINS
+     !!!! Basic structure to simplify stepon
+     SUBROUTINE compute_RHS
+       USE moments_eq_rhs, ONLY: moments_eq_rhs_e,moments_eq_rhs_i
+       USE collision, ONLY: compute_TColl
+       USE nonlinear, ONLY: compute_Sapj
+       IMPLICIT NONE
+         ! compute auxiliary non adiabatic moments arrays
+         CALL compute_nadiab_moments
+         ! compute nonlinear term ("if linear" is included inside)
+         CALL compute_Sapj
+         ! compute collision term ("if coll, if nu >0" is included inside)
+         CALL compute_TColl
+         ! compute the moments equation rhs for electrons and ions
+         IF (KIN_E) &
+         CALL moments_eq_rhs_e
+         CALL moments_eq_rhs_i
+     END SUBROUTINE compute_RHS
 
       SUBROUTINE checkfield_all ! Check all the fields for inf or nan
         ! Execution time start
diff --git a/src/utility_mod.F90 b/src/utility_mod.F90
index a295575e..577a130f 100644
--- a/src/utility_mod.F90
+++ b/src/utility_mod.F90
@@ -114,8 +114,10 @@ SUBROUTINE manual_3D_bcast(field_)
   IMPLICIT NONE
   COMPLEX(dp), INTENT(INOUT) :: field_(ikxs:ikxe,ikys:ikye,izs:ize)
   COMPLEX(dp) :: buffer(ikxs:ikxe,ikys:ikye,izs:ize)
-  INTEGER     :: i_, root, world_rank, world_size
+  INTEGER     :: i_, root, world_rank, world_size, count
   root = 0;
+  count = (ikxe-ikxs+1) * (ikye-ikys+1) * (ize-izs+1);
+
   CALL MPI_COMM_RANK(comm_p,world_rank,ierr)
   CALL MPI_COMM_SIZE(comm_p,world_size,ierr)
   IF (world_size .GT. 1) THEN
@@ -132,11 +134,11 @@ SUBROUTINE manual_3D_bcast(field_)
       ! Send it to all the other processes
       DO i_ = 0,num_procs_p-1
         IF (i_ .NE. world_rank) &
-        CALL MPI_SEND(buffer, local_nkx * Nky * Nz, MPI_DOUBLE_COMPLEX, i_, 0, comm_p, ierr)
+        CALL MPI_SEND(buffer, count, MPI_DOUBLE_COMPLEX, i_, 0, comm_p, ierr)
       ENDDO
     ELSE
       ! Recieve buffer from root
-      CALL MPI_RECV(buffer, local_nkx * Nky * Nz, MPI_DOUBLE_COMPLEX, root, 0, comm_p, MPI_STATUS_IGNORE, ierr)
+      CALL MPI_RECV(buffer, count, MPI_DOUBLE_COMPLEX, root, 0, comm_p, MPI_STATUS_IGNORE, ierr)
       ! Write it in phi
       DO ikx = ikxs,ikxe
         DO iky = ikys,ikye
diff --git a/wk/analysis_3D.m b/wk/analysis_3D.m
index cb59d386..7c194520 100644
--- a/wk/analysis_3D.m
+++ b/wk/analysis_3D.m
@@ -1,16 +1,17 @@
-addpath(genpath('../matlab')) % ... add
-addpath(genpath('../matlab/plot')) % ... add
-addpath(genpath('../matlab/compute')) % ... add
-addpath(genpath('../matlab/load')) % ... add
+helazdir = '/home/ahoffman/HeLaZ/';
+addpath(genpath([helazdir,'matlab'])) % ... add
+addpath(genpath([helazdir,'matlab/plot'])) % ... add
+addpath(genpath([helazdir,'matlab/compute'])) % ... add
+addpath(genpath([helazdir,'matlab/load'])) % ... add
 
 %% Load the results
-LOCALDIR  = ['../results/',outfile,'/'];
+LOCALDIR  = [helazdir,'results/',outfile,'/'];
 MISCDIR   = ['/misc/HeLaZ_outputs/results/',outfile,'/'];
 system(['mkdir -p ',MISCDIR]);
 CMD = ['rsync ', LOCALDIR,'outputs* ',MISCDIR]; disp(CMD);
 system(CMD);
 % Load outputs from jobnummin up to jobnummax
-JOBNUMMIN = 00; JOBNUMMAX = 20; 
+JOBNUMMIN = 00; JOBNUMMAX = 10; 
 data = compile_results(MISCDIR,JOBNUMMIN,JOBNUMMAX); %Compile the results from first output found to JOBNUMMAX if existing
 
 
@@ -19,17 +20,18 @@ default_plots_options
 disp('Plots')
 FMT = '.fig';
 
-if 1
+if 0
 %% Space time diagramm (fig 11 Ivanov 2020)
-TAVG_0 = 1000; TAVG_1 = 11000; % Averaging times duration
+TAVG_0 = 0; TAVG_1 = 400; % Averaging times duration
+compz  = 'avg';
 % chose your field to plot in spacetime diag (uzf,szf,Gx)
-fig = plot_radial_transport_and_spacetime(data,TAVG_0,TAVG_1,'v_y',1);
+fig = plot_radial_transport_and_spacetime(data,TAVG_0,TAVG_1,'phi',1,compz);
 save_figure(data,fig)
 end
 
 if 0
 %% statistical transport averaging
-options.T = [1500 2500];
+options.T = [16000 17000];
 fig = statistical_transport_averaging(data,options);
 end
 
@@ -39,16 +41,18 @@ if 0
 options.INTERP    = 1;
 options.POLARPLOT = 0;
 options.NAME      = '\phi';
-% options.NAME      = 'v_x';
+% options.NAME      = 'N_i^{00}';
+% options.NAME      = 'v_y';
 % options.NAME      = 'n_i^{NZ}';
 % options.NAME      = '\Gamma_x';
 % options.NAME      = 'n_i';
-% options.PLAN      = 'xy';
+options.PLAN      = 'yz';
 % options.NAME      = 'f_e';
 % options.PLAN      = 'sx';
 options.COMP      = 1;
-% options.TIME      = data.Ts5D;
-options.TIME      = 900:10:2000;
+% options.TIME      = dat.Ts5D;
+options.TIME      = 0:0.5:400;
+data.EPS          = 0.1;
 data.a = data.EPS * 2000;
 create_film(data,options,'.gif')
 end
@@ -56,19 +60,20 @@ end
 if 0
 %% 2D snapshots
 % Options
-options.INTERP    = 1;
+options.INTERP    = 0;
 options.POLARPLOT = 0;
 options.AXISEQUAL = 1;
-% options.NAME      = '\phi';
-options.NAME      = 'v_y';
-% options.NAME      = 'n_e^{NZ}';
+options.NAME      = '\phi';
+% options.NAME      = 'v_y';
+% options.NAME      = 'N_i^{00}';
+% options.NAME      = 'T_i';
 % options.NAME      = '\Gamma_x';
 % options.NAME      = 'k^2n_e';
-options.PLAN      = 'xy';
+options.PLAN      = 'yz';
 % options.NAME      = 'f_e';
 % options.PLAN      = 'sx';
 options.COMP      = 'avg';
-options.TIME      = [000:200:1000];
+options.TIME      = [10 20 100];
 data.a = data.EPS * 2000;
 fig = photomaton(data,options);
 save_figure(data,fig)
@@ -78,9 +83,10 @@ if 0
 %% 3D plot on the geometry
 options.INTERP    = 1;
 options.NAME      = 'n_i';
-options.PLANES    = 1;
-options.TIME      = [0 500 1000];
-data.rho_o_R      = 1e-3; % Sound larmor radius over Machine size ratio
+options.PLANES    = 1:3:30;
+options.TIME      = [100];
+options.PLT_MTOPO = 1;
+data.rho_o_R      = 2e-3; % Sound larmor radius over Machine size ratio
 fig = show_geometry(data,options);
 save_figure(data,fig)
 end
@@ -102,25 +108,24 @@ end
 if 0
 %% Hermite-Laguerre spectrum
 % options.TIME = 'avg';
-options.TIME = 1000:4000;
 options.P2J  = 1;
-options.ST   = 0;
+options.ST   = 1;
 options.NORMALIZED = 0;
 fig = show_moments_spectrum(data,options);
 save_figure(data,fig)
 end
 
 if 0
-%% 1D spectrum
-options.TIME   = 5000:10:5050;
-options.NORM   = 1;
+%% Time averaged spectrum
+options.TIME   = 1000:5000;
+options.NORM   = 0;
 options.NAME   = '\phi';
-% options.NAME      = 'n_i';
-% options.NAME      ='\Gamma_x';
+options.NAME      = 'n_i';
+options.NAME      ='\Gamma_x';
 options.PLAN   = 'kxky';
-options.COMPZ  = 1;
+options.COMPZ  = 'avg';
 options.OK     = 0;
-options.COMPXY = 'sum';
+options.COMPXY = 0;
 options.COMPT  = 'avg';
 options.PLOT   = 'semilogy';
 fig = spectrum_1D(data,options);
@@ -145,9 +150,9 @@ end
 
 if 0
 %% Mode evolution
-options.NORMALIZED = 0;
+options.NORMALIZED = 1;
 options.K2PLOT = 0.01:0.01:1.0;
-options.TIME   = 4900:1:5100;
+options.TIME   = 20:1:600;
 options.NMA    = 1;
 options.NMODES = 20;
 fig = mode_growth_meter(data,options);
@@ -155,9 +160,21 @@ save_figure(data,fig)
 end
 
 if 0
-%% ZF caracteristics (space time diagrams
+%% ZF caracteristics (space time diagrams)
 TAVG_0 = 200; TAVG_1 = 3000; % Averaging times duration
 % chose your field to plot in spacetime diag (uzf,szf,Gx)
 fig = ZF_spacetime(data,TAVG_0,TAVG_1);
 save_figure(data,fig)
 end
+
+if 0
+%% Metric infos
+fig = plot_metric(data);
+end
+
+if 1
+%% linear growth rate for 3D fluxtube
+trange = [0 100];
+nplots = 1;
+lg = compute_fluxtube_growth_rate(data,trange,nplots);
+end
\ No newline at end of file
diff --git a/wk/analysis_header.m b/wk/analysis_header.m
index 4ac8664b..18b07606 100644
--- a/wk/analysis_header.m
+++ b/wk/analysis_header.m
@@ -1,166 +1,10 @@
 %% Directory of the simulation
 % if 1% Local results
 outfile ='';
-outfile ='';
-outfile ='';
-outfile ='';
-% outfile ='debug/ppj_init';
-%% nu = 5e-1
-% Sugama
-% outfile ='Hallenbert_nu_5e-01/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_5e-01_SGGK';% also in 7x4
-% outfile ='Hallenbert_nu_5e-01/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_5e-01_SGGK';
-% outfile ='Hallenbert_nu_5e-01/200x32_7x4_L_120_kN_1.7_kT_0.425_nu_5e-01_SGGK';% also in 7x4
-% outfile ='Hallenbert_nu_5e-01/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_5e-01_SGGK';
-% outfile ='Hallenbert_nu_5e-01/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_5e-01_SGGK';%also in 7x4
-
-%% nu = 1e-1
-% Landau
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-01_LDGK';
-% outfile ='Hallenbert_nu_1e-01/150x50_5x3_L_120_kN_1.6_kT_0.4_nu_1e-01_LDGK';
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-01_LDGK';
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-01_LDGK';
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-01_LDGK';
-% outfile ='Hallenbert_nu_1e-01/150x50_5x3_L_120_kN_1.8_kT_0.45_nu_1e-01_LDGK';
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_1e-01_LDGK';
-
-% Sugama
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-01_SGGK';
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-01_SGGK';
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-01_SGGK';
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_1e-01_SGGK';
-
-% Dougherty
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-01_DGGK';
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-01_DGGK';
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-01_DGGK';
-% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-01_DGGK';
-
-%% nu = 5e-2
-% outfile ='Hallenbert_nu_5e-02/200x32_11x6_L_120_kN_1.8_kT_0.45_nu_5e-02_SGGK';%For GENE benchmark % to analyse (added HD)
-% outfile ='Hallenbert_nu_5e-02/200x32_11x6_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGGK';
-
-% testing various NL closures
-% outfile ='Hallenbert_nu_5e-02/200x32_7x4_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGGK';
-
-% outfile ='Hallenbert_nu_5e-02/200x32_5x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
-% outfile ='Hallenbert_nu_5e-02/200x32_11x6_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
-
-% outfile ='Hallenbert_nu_5e-02/256x64_5x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
-% outfile ='Hallenbert_nu_5e-02/256x64_11x6_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
-% outfile ='Hallenbert_nu_5e-02/200x32_21x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
-% outfile ='Hallenbert_nu_5e-02/200x32_17x9_L_120_kN_1.8_kT_0.45_nu_5e-02_SGDK';
-
-% outfile ='Hallenbert_nu_5e-02/200x32_5x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_DGGK';
-% outfile ='Hallenbert_nu_5e-02/200x32_11x6_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_DGGK';
-% outfile ='Hallenbert_nu_5e-02/128x32_5x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_FCGK';
-
-%% nu = 1e-2
-% Landau
-% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-02_LDGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-02_LDGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-02_LDGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-02_LDGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_1e-02_LDGK';
-
-% Sugama
-% outfile ='kobayashi_2015_fig1/150x150_5x3_L_100_kN_1.4_nu_5e-03_SGGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_7x4_L_120_kN_1.5_kT_0.375_nu_1e-02_SGGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-02_SGGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-02_SGGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_7x4_L_120_kN_1.6_kT_0.4_nu_1e-02_SGGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-02_SGGK';
-% outfile ='Hallenbert_nu_1e-02/300x64_5x3_L_120_kN_1.7_kT_0.425_nu_1e-02_SGGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_11x6_L_120_kN_1.7_kT_0.425_nu_1e-02_SGGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-02_SGGK'; % To analyse (added HD)
-% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_1e-02_SGGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_11x6_L_120_kN_1.9_kT_0.475_nu_1e-02_SGGK';
-% Dougherty
-% outfile ='Hallenbert_nu_1e-02/200x32_7x4_L_120_kN_1.5_kT_0.375_nu_1e-02_DGGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-02_DGGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_8x5_L_120_kN_1.6_kT_0.4_nu_0e+00_DGGK';
-% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-02_DGGK';
-
-%% nu = 5e-3
-% outfile ='Hallenbert_nu_5e-03/200x32_5x3_Lx_120_Ly_60_kN_1.8_eta_0.25_nuSG_5e-03_muxy_5e-2';
-% outfile ='Hallenbert_nu_5e-03/200x32_5x3_Lx_120_Ly_60_kN_1.8_eta_0.25_nuSG_5e-03_mux_5e-2_muy_6e-1';
-% outfile ='Hallenbert_nu_5e-03/200x32_11x6_Lx_120_Ly_60_kN_1.8_eta_0.25_nuSG_5e-03_mux_5e-2_muy_6e-1';
-% outfile ='Hallenbert_nu_5e-03/200x32_11x6_Lx_120_Ly_60_kN_1.8_eta_0.25_nuSG_5e-03_muxy_5e-2';
-
-%% nu = 0
-
-% outfile ='Hallenbert_fig2a/200x32_21x11_Lx_120_Ly_60_kN_1.6_eta_0.4_nu_0_muxy_1e-2';
-% outfile ='Hallenbert_fig2a/200x32_11x6_Lx_120_Ly_60_kN_1.6_eta_0.4_nu_0_muxy_1e-2';
-% outfile ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nu_0_muxy_1e-2';
-% outfile ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nuDGGK_0.1_muxy_1e-2';
-% outfile ='Hallenbert_fig2a/200x32_11x6_Lx_120_Ly_60_kN_1.6_eta_0.4_nuDGGK_0.1_muxy_1e-2';
-% outfile ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nuSGGK_0.1_muxy_1e-2';
-% outfile ='Hallenbert_fig2a/200x32_11x6_Lx_120_Ly_60_kN_1.6_eta_0.4_nuSGGK_0.1_muxy_1e-2';
-% outfile ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nuLDGK_0.1_muxy_1e-2';
-% outfile ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nuLRGK_0.1_muxy_1e-2';
-
-
-% outfile ='Hallenbert_fig2b/200x32_11x6_Lx_240_Ly_120_kN_2.5_eta_0.25_nu_0_muxy_1e-1';
-% outfile ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nu_0_muxy_1e-1';
-% outfile ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nuSGGK_0.1_muxy_1e-1';
-% outfile ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nuDGGK_0.1_muxy_1e-1';
-% outfile ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nuLDGK_0.1_muxy_1e-1';
-% outfile ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nuLRGK_0.1_muxy_1e-1';
-
-% outfile ='Hallenbert_fig2c/200x32_11x6_Lx_120_Ly_60_kN_2.0_eta_0.25_nu_0_muxy_5e-2';
-% outfile ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nu_0_muxy_5e-2';
-% outfile ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nuSGGK_0.1_muxy_5e-2';
-% outfile ='Hallenbert_fig2c/200x32_11x6_Lx_120_Ly_60_kN_2.0_eta_0.25_nuSGGK_0.1_muxy_5e-2';
-% outfile ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nuDGGK_0.1_muxy_5e-2';
-% outfile ='Hallenbert_fig2c/200x32_11x6_Lx_120_Ly_60_kN_2.0_eta_0.25_nuDGGK_0.1_muxy_5e-2';
-% outfile ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nuLDGK_0.1_muxy_5e-2';
-% outfile ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nuLRGK_0.1_muxy_5e-2';
-% outfile ='Hallenbert_fig2c/200x32_9x5_Lx_120_Ly_60_kN_2.0_eta_0.25_nuLRGK_0.1_muxy_5e-2';
-
-%% Transport scan
-% outfile = 'nu_0.1_transport_scan/colless_kn_1.7_to_2.0';
-% outfile = 'nu_0.1_transport_scan/colless_kn_2.1_to_2.5';
-
-% outfile = 'nu_0.1_transport_scan/LB_kn_2.0';
-
-% outfile = 'nu_0.1_transport_scan/DG_kn_1.8_to_2.1';
-% outfile = 'nu_0.1_transport_scan/DG_kn_2.2_to_2.5';
-% outfile = 'nu_0.1_transport_scan/DG_conv_kN_1.9';
-
-% outfile = 'nu_0.1_transport_scan/SG_kn_1.7_to_2.0';
-% outfile = 'nu_0.1_transport_scan/SG_10x5_conv_test';
-% outfile = 'nu_0.1_transport_scan/SG_kn_2.2_to_2.5';
-
-% outfile = 'nu_0.1_transport_scan/LD_kn_2.0_to_2.5';
-% outfile = 'nu_0.1_transport_scan/LD_kn_1.7_to_2.5';
-
-% outfile = 'nu_0.1_transport_scan/LR_kn_1.7_to_2.0';
-% outfile = 'nu_0.1_transport_scan/LR_kn_2.1_to_2.5';
-
-% outfile = 'nu_0.1_transport_scan/colless_kn_2.2_Lx1.5';
-% outfile = 'nu_0.1_transport_scan/colless_kn_2.2_HD';
-
-% outfile = 'nu_0.1_transport_scan/colless_kn_1.6_HD';
-
-% outfile = 'nu_0.1_transport_scan/large_box_kN_2.1_nu_0.1';
-% outfile = 'nu_0.1_transport_scan/large_box_kN_2.0_nu_0.1';
-
-outfile = 'predator_prey_nu_scan/DG_Kn_1.7_nu_0.01';
-
-% outfile = 'ZF_damping_linear_nu_0_20x10_kn_1.6_GK/LR_4x2_nu_0.1';
-% outfile = 'ZF_damping_nu_0_20x10_kn_1.6_GK/HSG_4x2_nu_0.1';
-% outfile = 'ZF_damping_nu_0_5x3_kn_2.5_GK/LR_4x2_nu_0.1';
-% outfile = 'hacked_sugama/hacked_B_kn_1.6_200x32_L_120x60_nu_0.1';
+outfile ='linear_shearless_cyclone/dbg';
+% outfile ='debug/test_zpar/';
+% outfile ='shearless_cyclone/128x128x16x4x2_L_120_CTC_1.0_colless/';
+% outfile ='shearless_cyclone/128x128x16x4x2_L_120_CTC_0.8/';
 
-% outfile = 'shearless_cyclone/200x32x24_5x4_Lx_120_Ly_60_q0_1.4_e_0.18_kN_2.22_kT_6.9_nu_0';
-% else% Marconi results
-% outfile ='';
-% outfile ='';
-% outfile ='';
-% outfile ='';
-% outfile ='/marconi_scratch/userexternal/ahoffman/HeLaZ/results/simulation_A_new/300x300_5x3_L_120_kN_1.6667_nu_1e-01_SGGK/out.txt';
-% % outfile ='/marconi_scratch/userexternal/ahoffman/HeLaZ/results/simulation_A/300x150_L_120_P_8_J_4_eta_0.6_nu_1e-01_SGGK_mu_0e+00/out.txt';
-% % BASIC.RESDIR      = ['../',outfile(46:end-8),'/'];
-% MISCDIR = ['/misc/HeLaZ_outputs/',outfile(46:end-8),'/'];
-% end
 
 analysis_3D
\ No newline at end of file
diff --git a/wk/analysis_header_2DZP.m b/wk/analysis_header_2DZP.m
new file mode 100644
index 00000000..cd4f356a
--- /dev/null
+++ b/wk/analysis_header_2DZP.m
@@ -0,0 +1,171 @@
+%% Directory of the simulation
+% if 1% Local results
+outfile ='';
+outfile ='';
+outfile ='';
+outfile ='';
+% outfile ='debug/ppj_init';
+%% nu = 5e-1
+% Sugama
+% outfile ='Hallenbert_nu_5e-01/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_5e-01_SGGK';% also in 7x4
+% outfile ='Hallenbert_nu_5e-01/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_5e-01_SGGK';
+% outfile ='Hallenbert_nu_5e-01/200x32_7x4_L_120_kN_1.7_kT_0.425_nu_5e-01_SGGK';% also in 7x4
+% outfile ='Hallenbert_nu_5e-01/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_5e-01_SGGK';
+% outfile ='Hallenbert_nu_5e-01/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_5e-01_SGGK';%also in 7x4
+
+%% nu = 1e-1
+% Landau
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-01_LDGK';
+% outfile ='Hallenbert_nu_1e-01/150x50_5x3_L_120_kN_1.6_kT_0.4_nu_1e-01_LDGK';
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-01_LDGK';
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-01_LDGK';
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-01_LDGK';
+% outfile ='Hallenbert_nu_1e-01/150x50_5x3_L_120_kN_1.8_kT_0.45_nu_1e-01_LDGK';
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_1e-01_LDGK';
+
+% Sugama
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-01_SGGK';
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-01_SGGK';
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-01_SGGK';
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_1e-01_SGGK';
+
+% Dougherty
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-01_DGGK';
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-01_DGGK';
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-01_DGGK';
+% outfile ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-01_DGGK';
+
+%% nu = 5e-2
+% outfile ='Hallenbert_nu_5e-02/200x32_11x6_L_120_kN_1.8_kT_0.45_nu_5e-02_SGGK';%For GENE benchmark % to analyse (added HD)
+% outfile ='Hallenbert_nu_5e-02/200x32_11x6_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGGK';
+
+% testing various NL closures
+% outfile ='Hallenbert_nu_5e-02/200x32_7x4_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGGK';
+
+% outfile ='Hallenbert_nu_5e-02/200x32_5x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
+% outfile ='Hallenbert_nu_5e-02/200x32_11x6_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
+
+% outfile ='Hallenbert_nu_5e-02/256x64_5x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
+% outfile ='Hallenbert_nu_5e-02/256x64_11x6_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
+% outfile ='Hallenbert_nu_5e-02/200x32_21x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
+% outfile ='Hallenbert_nu_5e-02/200x32_17x9_L_120_kN_1.8_kT_0.45_nu_5e-02_SGDK';
+
+% outfile ='Hallenbert_nu_5e-02/200x32_5x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_DGGK';
+% outfile ='Hallenbert_nu_5e-02/200x32_11x6_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_DGGK';
+% outfile ='Hallenbert_nu_5e-02/128x32_5x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_FCGK';
+
+%% nu = 1e-2
+% Landau
+% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-02_LDGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-02_LDGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-02_LDGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-02_LDGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_1e-02_LDGK';
+
+% Sugama
+% outfile ='kobayashi_2015_fig1/150x150_5x3_L_100_kN_1.4_nu_5e-03_SGGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_7x4_L_120_kN_1.5_kT_0.375_nu_1e-02_SGGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-02_SGGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-02_SGGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_7x4_L_120_kN_1.6_kT_0.4_nu_1e-02_SGGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-02_SGGK';
+% outfile ='Hallenbert_nu_1e-02/300x64_5x3_L_120_kN_1.7_kT_0.425_nu_1e-02_SGGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_11x6_L_120_kN_1.7_kT_0.425_nu_1e-02_SGGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-02_SGGK'; % To analyse (added HD)
+% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_1e-02_SGGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_11x6_L_120_kN_1.9_kT_0.475_nu_1e-02_SGGK';
+% Dougherty
+% outfile ='Hallenbert_nu_1e-02/200x32_7x4_L_120_kN_1.5_kT_0.375_nu_1e-02_DGGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-02_DGGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_8x5_L_120_kN_1.6_kT_0.4_nu_0e+00_DGGK';
+% outfile ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-02_DGGK';
+
+%% nu = 5e-3
+% outfile ='Hallenbert_nu_5e-03/200x32_5x3_Lx_120_Ly_60_kN_1.8_eta_0.25_nuSG_5e-03_muxy_5e-2';
+% outfile ='Hallenbert_nu_5e-03/200x32_5x3_Lx_120_Ly_60_kN_1.8_eta_0.25_nuSG_5e-03_mux_5e-2_muy_6e-1';
+% outfile ='Hallenbert_nu_5e-03/200x32_11x6_Lx_120_Ly_60_kN_1.8_eta_0.25_nuSG_5e-03_mux_5e-2_muy_6e-1';
+% outfile ='Hallenbert_nu_5e-03/200x32_11x6_Lx_120_Ly_60_kN_1.8_eta_0.25_nuSG_5e-03_muxy_5e-2';
+
+%% nu = 0
+
+% outfile ='Hallenbert_fig2a/200x32_21x11_Lx_120_Ly_60_kN_1.6_eta_0.4_nu_0_muxy_1e-2';
+% outfile ='Hallenbert_fig2a/200x32_11x6_Lx_120_Ly_60_kN_1.6_eta_0.4_nu_0_muxy_1e-2';
+% outfile ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nu_0_muxy_1e-2';
+% outfile ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nuDGGK_0.1_muxy_1e-2';
+% outfile ='Hallenbert_fig2a/200x32_11x6_Lx_120_Ly_60_kN_1.6_eta_0.4_nuDGGK_0.1_muxy_1e-2';
+% outfile ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nuSGGK_0.1_muxy_1e-2';
+% outfile ='Hallenbert_fig2a/200x32_11x6_Lx_120_Ly_60_kN_1.6_eta_0.4_nuSGGK_0.1_muxy_1e-2';
+% outfile ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nuLDGK_0.1_muxy_1e-2';
+% outfile ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nuLRGK_0.1_muxy_1e-2';
+
+
+% outfile ='Hallenbert_fig2b/200x32_11x6_Lx_240_Ly_120_kN_2.5_eta_0.25_nu_0_muxy_1e-1';
+% outfile ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nu_0_muxy_1e-1';
+% outfile ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nuSGGK_0.1_muxy_1e-1';
+% outfile ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nuDGGK_0.1_muxy_1e-1';
+% outfile ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nuLDGK_0.1_muxy_1e-1';
+% outfile ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nuLRGK_0.1_muxy_1e-1';
+
+% outfile ='Hallenbert_fig2c/200x32_11x6_Lx_120_Ly_60_kN_2.0_eta_0.25_nu_0_muxy_5e-2';
+% outfile ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nu_0_muxy_5e-2';
+% outfile ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nuSGGK_0.1_muxy_5e-2';
+% outfile ='Hallenbert_fig2c/200x32_11x6_Lx_120_Ly_60_kN_2.0_eta_0.25_nuSGGK_0.1_muxy_5e-2';
+% outfile ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nuDGGK_0.1_muxy_5e-2';
+% outfile ='Hallenbert_fig2c/200x32_11x6_Lx_120_Ly_60_kN_2.0_eta_0.25_nuDGGK_0.1_muxy_5e-2';
+% outfile ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nuLDGK_0.1_muxy_5e-2';
+% outfile ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nuLRGK_0.1_muxy_5e-2';
+% outfile ='Hallenbert_fig2c/200x32_9x5_Lx_120_Ly_60_kN_2.0_eta_0.25_nuLRGK_0.1_muxy_5e-2';
+
+%% Transport scan
+% outfile = 'nu_0.1_transport_scan/colless_kn_1.7_to_2.0';
+% outfile = 'nu_0.1_transport_scan/colless_kn_2.1_to_2.5';
+
+% outfile = 'nu_0.1_transport_scan/LB_kn_2.0';
+
+% outfile = 'nu_0.1_transport_scan/DG_kn_1.8_to_2.1';
+% outfile = 'nu_0.1_transport_scan/DG_kn_2.2_to_2.5';
+% outfile = 'nu_0.1_transport_scan/DG_conv_kN_1.9';
+
+% outfile = 'nu_0.1_transport_scan/SG_kn_1.7_to_2.0';
+% outfile = 'nu_0.1_transport_scan/SG_10x5_conv_test';
+% outfile = 'nu_0.1_transport_scan/SG_kn_2.2_to_2.5';
+
+% outfile = 'nu_0.1_transport_scan/LD_kn_2.0_to_2.5';
+% outfile = 'nu_0.1_transport_scan/LD_kn_1.7_to_2.5';
+
+% outfile = 'nu_0.1_transport_scan/LR_kn_1.7_to_2.0';
+% outfile = 'nu_0.1_transport_scan/LR_kn_2.1_to_2.5';
+
+% outfile = 'nu_0.1_transport_scan/colless_kn_2.2_Lx1.5';
+% outfile = 'nu_0.1_transport_scan/colless_kn_2.2_HD';
+
+% outfile = 'nu_0.1_transport_scan/colless_kn_1.6_HD';
+
+% outfile = 'nu_0.1_transport_scan/large_box_kN_2.1_nu_0.1';
+% outfile = 'nu_0.1_transport_scan/large_box_kN_2.0_nu_0.1';
+
+% outfile = 'predator_prey_nu_scan/DG_Kn_1.7_nu_0.01';
+
+% outfile = 'ZF_damping_linear_nu_0_20x10_kn_1.6_GK/LR_4x2_nu_0.1';
+% outfile = 'ZF_damping_nu_0_20x10_kn_1.6_GK/HSG_4x2_nu_0.1';
+% outfile = 'ZF_damping_nu_0_5x3_kn_2.5_GK/LR_4x2_nu_0.1';
+% outfile = 'hacked_sugama/hacked_B_kn_1.6_200x32_L_120x60_nu_0.1';
+
+% outfile = 'shearless_cyclone/200x32x24_5x4_Lx_120_Ly_60_q0_1.4_e_0.18_kN_2.22_kT_6.9_nuLR_0.01_adiab_e';
+% outfile = 'shearless_cyclone/no_sg_128x32x36_6x3_Lx_120_Ly_60_q0_1.4_e_0.18_kN_2.22_kT_6.9_adiab_e';
+% outfile = 'shearless_cyclone/sgrid_128x64x32_4x2_Lx_100_Ly_120_q0_1.4_e_0.18_kN_2.22_kT_6.96_adiab_e';
+% outfile = 'shearless_cyclone/sgrid_128x64x32_4x2_Lx_100_Ly_120_q0_1.4_e_0.18_kN_1.78_kT_5.52_adiab_e';
+% outfile = 'linear_shearless_cyclone/4_2_cyclone_1.0';
+% outfile = 'linear_shearless_cyclone/test_fmom';
+% else% Marconi results
+% outfile ='';
+% outfile ='';
+% outfile ='';fd
+% outfile ='';
+% outfile ='/marconi_scratch/userexternal/ahoffman/HeLaZ/results/simulation_A_new/300x300_5x3_L_120_kN_1.6667_nu_1e-01_SGGK/out.txt';
+% % outfile ='/marconi_scratch/userexternal/ahoffman/HeLaZ/results/simulation_A/300x150_L_120_P_8_J_4_eta_0.6_nu_1e-01_SGGK_mu_0e+00/out.txt';
+% % BASIC.RESDIR      = ['../',outfile(46:end-8),'/'];
+% MISCDIR = ['/misc/HeLaZ_outputs/',outfile(46:end-8),'/'];
+% end
+
+analysis_3D
\ No newline at end of file
diff --git a/wk/benchmark_HeLaZ_gene_transport_zpinch.m b/wk/benchmark_HeLaZ_gene_transport_zpinch.m
index f0e5ddc6..b10312db 100644
--- a/wk/benchmark_HeLaZ_gene_transport_zpinch.m
+++ b/wk/benchmark_HeLaZ_gene_transport_zpinch.m
@@ -119,9 +119,9 @@ xlim([ 1.55 2.55]);
 %% Burst study Kn = 1.7
 Kn = 1.7;
 NU                = [0.0e+0 1.0e-2 2.0e-2 3.0e-2 4.0e-2 5.0e-2 6.0e-2 7.0e-2 8.0e-2 9.0e-2 1.0e-1];
-SGGK_200x32x05x03 = [1.0e-2 2.4e-2 2.8e-2 3.5e-2 4.5e-2 5.5e-2 6.5e-2 7.5e-2 8.3e-2 8.8e-2 1.0e-1];
-DGGK_200x32x05x03 = [1.0e-2 7.0e-3 7.3e-3 0.0e+0 0.0e+0 0.0e+0 0.0e+0 0.0e+0 0.0e+0 0.0e+0 0.0e+0];
-LDGK_200x32x05x03 = [1.0e-2 8.5e-2 1.4e-1 2.0e-1 0.0e-2 0.0e+0 0.0e+0 0.0e+0 0.0e+0 0.0e+0 0.0e+0];
+SGGK_200x32x05x03 = [1.0e-2 1.1e-2 1.7e-2 2.3e-2 3.1e-2 4.1e-2 5.1e-2 6.1e-2 8.3e-2 8.8e-2 1.0e-1];
+DGGK_200x32x05x03 = [1.0e-2 1.0e-3 1.1e-3 2.3e-3 3.0e-3 3.0e-3 3.7e-3 4.0e-3 5.7e-3 5.8e-3 9.2e-3];
+LDGK_200x32x05x03 = [1.0e-2 9.0e-2 1.5e-1 2.2e-1 2.8e-1 3.5e-1 4.0e-1 4.5e-1 5.0e-1 5.6e-1 6.2e-1];
 % NOCO_200x32x05x03 = [0.0e+0 0.0e+0 0.0e+0 0.0e+0];
 figure
 plot(NU,SGGK_200x32x05x03/Kn,'s','Color',clr_(1,:)); hold on
diff --git a/wk/gene_analysis_3D.m b/wk/gene_analysis_3D.m
new file mode 100644
index 00000000..2289b64f
--- /dev/null
+++ b/wk/gene_analysis_3D.m
@@ -0,0 +1,84 @@
+% folder = '/misc/gene_results/shearless_cyclone/miller_output_1.0/';
+% folder = '/misc/gene_results/shearless_cyclone/miller_output_0.8/';
+% folder = '/misc/gene_results/shearless_cyclone/s_alpha_output_1.0/';
+folder = '/misc/gene_results/shearless_cyclone/s_alpha_output_0.8/';
+% folder = '/misc/gene_results/HP_fig_2b_mu_5e-2/';
+% folder = '/misc/gene_results/HP_fig_2c_mu_5e-2/';
+gene_data = load_gene_data(folder);
+gene_data = rotate_c_plane_nxnky_to_nkxny(gene_data);
+if 1
+%% Space time diagramm (fig 11 Ivanov 2020)
+TAVG_0 = 500; TAVG_1 = 700; % Averaging times duration
+% chose your field to plot in spacetime diag (uzf,szf,Gx)
+field = 'phi';
+compz = 'avg';
+nmvm  = 1;
+fig = plot_radial_transport_and_spacetime(gene_data,TAVG_0,TAVG_1,field,nmvm,compz);
+% save_figure(data,fig)
+end
+
+if 0
+%% 2D snapshots
+% Options
+options.INTERP    = 0;
+options.POLARPLOT = 0;
+options.AXISEQUAL = 1;
+options.NAME      = '\phi';
+% options.NAME      = 'v_y';
+% options.NAME      = 'T_i';
+% options.NAME      = '\Gamma_x';
+% options.NAME      = 'k^2n_e';
+options.PLAN      = 'xy';
+% options.NAME      ='f_e';
+% options.PLAN      = 'sx';
+options.COMP      = 9;
+options.TIME      = [100 200 400];
+data.a = data.EPS * 2000;
+fig = photomaton(gene_data,options);
+save_figure(gene_data,fig)
+end
+
+if 0
+%% MOVIES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Options
+options.INTERP    = 1;
+options.POLARPLOT = 0;
+options.NAME      = '\phi';
+% options.NAME      = 'v_y';
+% options.NAME      = 'n_i^{NZ}';
+% options.NAME      = '\Gamma_x';
+% options.NAME      = 'n_i';
+options.PLAN      = 'xy';
+% options.NAME      = 'f_e';
+% options.PLAN      = 'sx';
+options.COMP      = 9;
+options.TIME      = 0:700;
+gene_data.a = data.EPS * 2000;
+create_film(gene_data,options,'.gif')
+end
+
+if 0
+%% Geometry
+names = {'$g^{xx}$','$g^{xy}$','$g^{xz}$','$g^{yy}$','$g^{yz}$','$g^{zz}$',...
+         '$B_0$','$\partial_x B_0$','$\partial_y B_0$','$\partial_z B_0$',...
+         '$J$','$R$','$\phi$','$Z$','$\partial_R x$','$\partial_Z x$'};
+figure;
+subplot(311)
+    for i = 1:6
+    plot(gene_data.z, gene_data.geo_arrays(:,i),'DisplayName',names{i}); hold on;
+    end
+    xlim([min(gene_data.z),max(gene_data.z)]); legend('show'); title('GENE geometry');
+    
+subplot(312)
+    for i = 7:10
+    plot(gene_data.z, gene_data.geo_arrays(:,i),'DisplayName',names{i}); hold on;
+    end
+    xlim([min(gene_data.z),max(gene_data.z)]); legend('show');
+
+subplot(313)
+    for i = 11:16
+    plot(gene_data.z, gene_data.geo_arrays(:,i),'DisplayName',names{i}); hold on;
+    end
+    xlim([min(gene_data.z),max(gene_data.z)]); legend('show');
+
+end
diff --git a/wk/tmp.txt b/wk/tmp.txt
deleted file mode 100644
index e69de29b..00000000
-- 
GitLab