diff --git a/src/array_mod.F90 b/src/array_mod.F90
index 1cb6d141da980927dcce532bea67e626bbc25672..16a1bdf32392a716c9321f4b8a3b4ab113f23f14 100644
--- a/src/array_mod.F90
+++ b/src/array_mod.F90
@@ -6,6 +6,9 @@ MODULE array
   ! Arrays to store the rhs, for time integration (ip,ij,ikx,iky,iz,updatetlevel)
   COMPLEX(dp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE :: moments_rhs_e
   COMPLEX(dp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE :: moments_rhs_i
+  ! Non linear term array (ip,ij,ikx,iky,iz)
+  COMPLEX(dp), DIMENSION(:,:,:,:,:), ALLOCATABLE :: Sepj ! electron
+  COMPLEX(dp), DIMENSION(:,:,:,:,:), ALLOCATABLE :: Sipj ! ion
 
   ! To load collision matrix (ip1,ij1,ip2,ij2)
   REAL(dp), DIMENSION(:,:,:,:), ALLOCATABLE :: Ceepj, CeipjT
@@ -26,17 +29,31 @@ MODULE array
   REAL(dp), DIMENSION(:),   ALLOCATABLE :: xnipp1j, xnipm1j, xnipp2j, xnipm2j, xnipjp1, xnipjm1
   REAL(dp), DIMENSION(:,:), ALLOCATABLE :: xphij, xphijp1, xphijm1
 
-  ! Curvature array
-  COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: Ckxky
-
+  ! Geoemtrical operators
+  ! Curvature
+  REAL(dp), DIMENSION(:,:,:), ALLOCATABLE :: Ckxky  ! dimensions: kx, ky, z
+  ! Jacobian
+  REAL(dp), DIMENSION(:), ALLOCATABLE :: Jacobian ! dimensions: z
+  ! Metric
+  REAL(dp), DIMENSION(:), ALLOCATABLE :: gxx, gxy, gyy, gxz, gyz
+  ! derivatives of magnetic field strength
+  REAL(dp), DIMENSION(:), allocatable :: gradzB  ! dimensions: z
+  REAL(dp), DIMENSION(:), allocatable :: gradxB
+  ! Relative magnetic field strength
+  REAL(dp), DIMENSION(:), allocatable :: hatB
+  ! Relative strength of major radius
+  REAL(dp), DIMENSION(:), allocatable :: hatR
+  ! Geometrical factors
+  REAL(dp), DIMENSION(:), allocatable :: Gamma1
+  REAL(dp), DIMENSION(:), allocatable :: Gamma2
+  REAL(dp), DIMENSION(:), allocatable :: Gamma3
+  ! Some geometrical coefficients
+  REAL(dp), DIMENSION(:) , allocatable :: gradz_coeff  ! 1 / [ J_{xyz} \hat{B} ]
   ! Kernel function evaluation (ij,ikx,iky)
   REAL(dp), DIMENSION(:,:,:), ALLOCATABLE :: kernel_e
   REAL(dp), DIMENSION(:,:,:), ALLOCATABLE :: kernel_i
 
-  ! Non linear term array (ip,ij,ikx,iky,iz)
-  COMPLEX(dp), DIMENSION(:,:,:,:,:), ALLOCATABLE :: Sepj ! electron
-  COMPLEX(dp), DIMENSION(:,:,:,:,:), ALLOCATABLE :: Sipj ! ion
-
+  !! Diagnostics
   ! Gyrocenter density for electron and ions (ikx,iky,iz)
   COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: Ne00
   COMPLEX(dp), DIMENSION(:,:,:), ALLOCATABLE :: Ni00
diff --git a/src/auxval.F90 b/src/auxval.F90
index f1c3fd6935474a90b282e8297dff3cc3241ab2aa..22d63d44a7281ab7f57f2aaf524528ef3cf0700f 100644
--- a/src/auxval.F90
+++ b/src/auxval.F90
@@ -8,6 +8,7 @@ subroutine auxval
   USE fourier, ONLY: init_grid_distr_and_plans, alloc_local_1, alloc_local_2
   use prec_const
   USE numerics
+  USE geometry
   IMPLICIT NONE
 
   INTEGER :: irows,irowe, irow, icol, i_
@@ -29,7 +30,9 @@ subroutine auxval
 
   CALL memory ! Allocate memory for global arrays
 
-  CALL lin_coeff_and_geometry ! precompute coeff for lin equation and geometry
+  CALL eval_magnetic_geometry ! precompute coeff for lin equation
+
+  CALL compute_lin_coeff ! precompute coeff for lin equation and geometry
 
   CALL evaluate_kernels ! precompute the kernels
 
diff --git a/src/geometry_mod.F90 b/src/geometry_mod.F90
new file mode 100644
index 0000000000000000000000000000000000000000..2ebda8f58f3260142c1a780927c2abe9ef7f2d22
--- /dev/null
+++ b/src/geometry_mod.F90
@@ -0,0 +1,95 @@
+module geometry
+! computes geometrical quantities
+! Adapted from B.J.Frei MOLIX code (2021)
+
+  use prec_const
+  use model
+  use grid
+  use array
+  use fields
+  use basic
+
+implicit none
+  public
+
+contains
+
+  subroutine eval_magnetic_geometry
+    ! evalute metrix, elements, jacobian and gradient
+    implicit none
+    !
+     IF( my_id .eq. 0 ) WRITE(*,*) 'circular geometry'
+     ! circular model
+     call eval_circular_geometry
+    !
+  END SUBROUTINE eval_magnetic_geometry
+  !
+  !--------------------------------------------------------------------------------
+  !
+  subroutine eval_circular_geometry
+   ! evaluate circular geometry model
+
+    ! Ref: Lapilonne et al., PoP, 2009
+   implicit none
+   REAL(dp) :: shear   = 0._dp
+   REAL(dp) :: epsilon = 0.18_dp
+
+   ! Metric elements
+
+   DO iz = izs,ize
+      gxx(iz) = 1._dp
+      gxy(iz) = shear*zarray(iz) - epsilon*sin(zarray(iz))
+      gyy(iz) = 1._dp + (shear*zarray(iz))**2 &
+           - 2._dp * epsilon *COS(zarray(iz)) - 2._dp*shear * epsilon * zarray(iz)*SIN(zarray(iz))
+      gxz( iz) = - SIN(zarray(iz))
+      gyz( iz) = ( 1._dp - 2._dp * epsilon *COS(zarray( iz)) - epsilon*shear * zarray( iz) * SIN(zarray(iz)) ) /epsilon
+   ENDDO
+
+   ! Relative strengh of radius
+   DO iz = izs,ize
+       hatR(iz) = 1._dp + epsilon*cos(zarray(iz))
+    ENDDO
+
+    DO iz = izs, ize
+       hatB( iz) = sqrt(gxx(iz) * gyy(iz) - gxy(iz)*  gxy(iz))
+   ENDDO
+
+
+   ! Jacobian
+    DO iz = izs,ize
+       Jacobian(iz) = q0*hatR(iz)*hatR(iz)
+    ENDDO
+
+    ! Derivative of the magnetic field strenght
+    DO iz = izs, ize
+       gradxB(iz) = - ( COS( zarray(iz))   + epsilon* SIN( zarray(iz)) * SIN(zarray(iz) )) / hatB(iz)/hatB(iz)
+       gradzB( iz) = epsilon * SIN(zarray(iz)) *( 1._dp - epsilon*COS(zarray(iz)) ) / hatB(iz)/hatB(iz)
+    ENDDO
+
+    ! Gemoetrical coefficients for the curvature operator
+    ! Note: Gamma2 and Gamma3 are obtained directly form Gamma1 in the expression of the curvature operator implemented here
+   DO iz = izs, ize
+      Gamma1( iz) = gxy(iz) * gxy(iz) - gxx(iz) * gyy(iz)
+      Gamma2( iz) = gxz( iz) * gxy( iz) - gxx( iz) * gyz( iz)
+      Gamma3( iz) = gxz( iz) * gyy( iz) - gxy(iz) * gyz(  iz)
+   ENDDO
+
+    ! Curvature operator
+    DO iz = izs, ize
+       DO iky = ikys, ikye
+          DO ikx= ikxs, ikxe
+             Ckxky( ikx, iky,  iz) = Gamma1(iz)/hatB(iz)*((kxarray(ikx) &
+                  + shear*zarray(iz)*kyarray(iky)) * gradzB(iz)/epsilon &
+                  - gradxB(iz)* kyarray(iky))
+          ENDDO
+       ENDDO
+    ENDDO
+
+    ! coefficient in the front of parallel derivative
+    DO iz = izs, ize
+       gradz_coeff( iz) = 1._dp / Jacobian( iz) / hatB( iz)
+    ENDDO
+
+  END SUBROUTINE eval_circular_geometry
+
+end module geometry
diff --git a/src/lin_coeff_and_geometry.F90 b/src/lin_coeff_and_geometry.F90
deleted file mode 100644
index f2736623f03389363fe70c93f897242bba01a66d..0000000000000000000000000000000000000000
--- a/src/lin_coeff_and_geometry.F90
+++ /dev/null
@@ -1,99 +0,0 @@
-SUBROUTINE lin_coeff_and_geometry
-  USE array, ONLY: xnepj, xnepp1j, xnepm1j, xnepp2j, xnepm2j, xnepjp1, xnepjm1, &
-                   xnipj, xnipp1j, xnipm1j, xnipp2j, xnipm2j, xnipjp1, xnipjm1, &
-                   xphij, xphijp1, xphijm1, Ckxky
-  USE model, ONLY: taue_qe, taui_qi, sqrtTaue_qe, sqrtTaui_qi, eta_T, eta_n
-  USE prec_const
-  USE grid,  ONLY: parray_e, parray_i, jarray_e, jarray_i, &
-                   ip,ij, ips_e,ipe_e, ips_i,ipe_i, ijs_e,ije_e, ijs_i,ije_i,&
-                   kxarray, kyarray, zarray, &
-                   ikx,iky,iz, ikxs,ikxe, ikys,ikye, izs,ize
-  IMPLICIT NONE
-  INTEGER     :: p_int, j_int ! polynom. degrees
-  REAL(dp)    :: p_dp, j_dp
-  REAL(dp)    :: kx, ky, z
-
-  !! Electrons linear coefficients for moment RHS !!!!!!!!!!
-  DO ip = ips_e, ipe_e
-    p_int= parray_e(ip)   ! Hermite degree
-    p_dp = REAL(p_int,dp) ! REAL of Hermite degree
-    DO ij = ijs_e, ije_e
-      j_int= jarray_e(ij)   ! Laguerre degree
-      j_dp = REAL(j_int,dp) ! REAL of Laguerre degree
-      xnepj(ip,ij) = taue_qe * 2._dp * (p_dp + j_dp + 1._dp)
-    ENDDO
-  ENDDO
-  DO ip = ips_e, ipe_e
-    p_int= parray_e(ip)   ! Hermite degree
-    p_dp = REAL(p_int,dp) ! REAL of Hermite degree
-    xnepp1j(ip) = sqrtTaue_qe * SQRT(p_dp + 1_dp)
-    xnepm1j(ip) = sqrtTaue_qe * SQRT(p_dp)
-    xnepp2j(ip) = taue_qe * SQRT((p_dp + 1._dp) * (p_dp + 2._dp))
-    xnepm2j(ip) = taue_qe * SQRT(p_dp * (p_dp - 1._dp))
-  ENDDO
-  DO ij = ijs_e, ije_e
-    j_int= jarray_e(ij)   ! Laguerre degree
-    j_dp = REAL(j_int,dp) ! REAL of Laguerre degree
-    xnepjp1(ij) = -taue_qe * (j_dp + 1._dp)
-    xnepjm1(ij) = -taue_qe * j_dp
-  ENDDO
-  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-  !! Ions linear coefficients for moment RHS !!!!!!!!!!
-  DO ip = ips_i, ipe_i
-    p_int= parray_i(ip)   ! Hermite degree
-    p_dp = REAL(p_int,dp) ! REAL of Hermite degree
-    DO ij = ijs_i, ije_i
-      j_int= jarray_i(ij)   ! Laguerre degree
-      j_dp = REAL(j_int,dp) ! REAL of Laguerre degree
-      xnipj(ip,ij) = taui_qi * 2._dp * (p_dp + j_dp + 1._dp)
-    ENDDO
-  ENDDO
-  DO ip = ips_i, ipe_i
-    p_int= parray_i(ip)   ! Hermite degree
-    p_dp = REAL(p_int,dp) ! REAL of Hermite degree
-    xnipp1j(ip) = sqrtTaui_qi * SQRT(p_dp + 1._dp)
-    xnipm1j(ip) = sqrtTaui_qi * SQRT(p_dp)
-    xnipp2j(ip) = taui_qi * SQRT((p_dp + 1._dp) * (p_dp + 2._dp))
-    xnipm2j(ip) = taui_qi * SQRT(p_dp * (p_dp - 1._dp))
-  ENDDO
-  DO ij = ijs_i, ije_i
-    j_int= jarray_i(ij)   ! Laguerre degree
-    j_dp = REAL(j_int,dp) ! REAL of Laguerre degree
-    xnipjp1(ij) = -taui_qi * (j_dp + 1._dp)
-    xnipjm1(ij) = -taui_qi * j_dp
-  ENDDO
-  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-  !! ES linear coefficients for moment RHS !!!!!!!!!!
-  DO ip = ips_i, ipe_i
-    p_int= parray_i(ip)   ! Hermite degree
-    DO ij = ijs_i, ije_i
-      j_int= jarray_i(ij)   ! REALof Laguerre degree
-      j_dp = REAL(j_int,dp) ! REALof Laguerre degree
-      !! Electrostatic potential pj terms
-      IF (p_int .EQ. 0) THEN ! kronecker p0
-        xphij(ip,ij)    = eta_n + 2.*j_dp*eta_T
-        xphijp1(ip,ij)  =-eta_T*(j_dp+1._dp)
-        xphijm1(ip,ij)  =-eta_T* j_dp
-      ELSE IF (p_int .EQ. 2) THEN ! kronecker p2
-        xphij(ip,ij)    = eta_T/SQRT2
-        xphijp1(ip,ij)  = 0._dp; xphijm1(ip,ij)  = 0._dp;
-      ELSE
-        xphij(ip,ij)    = 0._dp; xphijp1(ip,ij)  = 0._dp
-        xphijm1(ip,ij)  = 0._dp;
-      ENDIF
-    ENDDO
-  ENDDO
-  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-  !! Curvature and geometric coefficients !!!!!!!!!!
-  DO  iz = izs,ize
-    z      = zarray(iz)
-    DO ikx = ikxs,ikxe
-      kx     = kxarray(ikx)   ! Poloidal wavevector
-      DO iky = ikys,ikye
-        ky     = kyarray(iky)   ! Toroidal wavevector
-        Ckxky(ikx,iky,iz) = SIN(z)*imagu*kx +COS(z)*imagu*ky
-      ENDDO
-    ENDDO
-  ENDDO
-
-END SUBROUTINE lin_coeff_and_geometry
diff --git a/src/memory.F90 b/src/memory.F90
index 6c5f3fe1051209ef813f9b4d082a02426fa2d4dc..dab37da4e1edd0056f0d168d767a81364e016761 100644
--- a/src/memory.F90
+++ b/src/memory.F90
@@ -73,6 +73,20 @@ SUBROUTINE memory
 
   ! Curvature and geometry
   CALL allocate_array( Ckxky, ikxs,ikxe, ikys,ikye, izs,ize)
+  CALL allocate_array(Jacobian,izs,ize)
+  CALL allocate_array(gxx, izs,ize)
+  CALL allocate_array(gxy, izs,ize)
+  CALL allocate_array(gyy, izs,ize)
+  CALL allocate_array(gyz, izs,ize)
+  CALL allocate_array(gxz, izs,ize)
+  CALL allocate_array(gradzB,izs,ize)
+  CALL allocate_array(gradxB,izs,ize)
+  CALL allocate_array(hatB,izs,ize)
+  CALL allocate_array(hatR,izs,ize)
+  CALL allocate_array(Gamma1,  izs,ize)
+  call allocate_array(Gamma2, izs,ize)
+  call allocate_array(Gamma3, izs, ize)
+  call allocate_array(gradz_coeff, izs, ize)
 
   !___________________ 2x5D ARRAYS __________________________
   !! Collision matrices
diff --git a/src/numerics.F90 b/src/numerics.F90
deleted file mode 100644
index b7870565722df3157fb0148d9c086924dff076ac..0000000000000000000000000000000000000000
--- a/src/numerics.F90
+++ /dev/null
@@ -1,150 +0,0 @@
-MODULE numerics
-    USE basic
-    USE prec_const
-    USE grid
-    USE utility
-    USE coeff
-    implicit none
-
-    PUBLIC :: compute_derivatives, build_dnjs_table, evaluate_kernels
-
-CONTAINS
-
-! Compute the 2D particle temperature for electron and ions (sum over Laguerre)
-SUBROUTINE compute_derivatives
-
-END SUBROUTINE compute_derivatives
-
-!******************************************************************************!
-!!!!!!! Build the Laguerre-Laguerre coupling coefficient table for nonlin
-!******************************************************************************!
-SUBROUTINE build_dnjs_table
-  USE array, Only : dnjs
-  USE coeff
-  IMPLICIT NONE
-
-  INTEGER :: in, ij, is, J
-  INTEGER :: n_, j_, s_
-
-  J = max(jmaxe,jmaxi)
-
-  DO in = 1,J+1 ! Nested dependent loops to make benefit from dnjs symmetry
-    n_ = in - 1
-    DO ij = in,J+1
-      j_ = ij - 1
-      DO is = ij,J+1
-        s_ = is - 1
-
-        dnjs(in,ij,is) = TO_DP(ALL2L(n_,j_,s_,0))
-        ! By symmetry
-        dnjs(in,is,ij) = dnjs(in,ij,is)
-        dnjs(ij,in,is) = dnjs(in,ij,is)
-        dnjs(ij,is,in) = dnjs(in,ij,is)
-        dnjs(is,ij,in) = dnjs(in,ij,is)
-        dnjs(is,in,ij) = dnjs(in,ij,is)
-      ENDDO
-    ENDDO
-  ENDDO
-END SUBROUTINE build_dnjs_table
-!******************************************************************************!
-
-!******************************************************************************!
-!!!!!!! Evaluate the kernels once for all
-!******************************************************************************!
-SUBROUTINE evaluate_kernels
-  USE basic
-  USE array, Only : kernel_e, kernel_i
-  USE grid
-  use model, ONLY : tau_e, tau_i, sigma_e, sigma_i, q_e, q_i, lambdaD, CLOS, sigmae2_taue_o2, sigmai2_taui_o2
-  IMPLICIT NONE
-
-  REAL(dp)    :: factj, j_dp, j_int
-  REAL(dp)    :: be_2, bi_2, alphaD
-  REAL(dp)    :: kx, ky, kperp2
-
-  !!!!! Electron kernels !!!!!
-  !Precompute species dependant factors
-  factj = 1.0 ! Start of the recursive factorial
-  DO ij = 1, jmaxe+1
-    j_int = jarray_e(ij)
-    j_dp = REAL(j_int,dp) ! REAL of degree
-
-    ! Recursive factorial
-    IF (j_dp .GT. 0) THEN
-      factj = factj * j_dp
-    ELSE
-      factj = 1._dp
-    ENDIF
-
-    DO ikx = ikxs,ikxe
-      kx     = kxarray(ikx)
-      DO iky = ikys,ikye
-        ky    = kyarray(iky)
-
-        be_2  =  (kx**2 + ky**2) * sigmae2_taue_o2
-
-        kernel_e(ij, ikx, iky) = be_2**j_int * exp(-be_2)/factj
-
-      ENDDO
-    ENDDO
-  ENDDO
-  ! Kernels closure
-  DO ikx = ikxs,ikxe
-    kx     = kxarray(ikx)
-    DO iky = ikys,ikye
-      ky    = kyarray(iky)
-      be_2  =  (kx**2 + ky**2) * sigmae2_taue_o2
-      ! Kernel ghost + 1 with Kj+1 = y/(j+1) Kj (/!\ ij = j+1)
-      kernel_e(ijeg_e,ikx,iky) = be_2/(real(ijeg_e-1,dp))*kernel_e(ije_e,ikx,iky)
-      ! Kernel ghost - 1 with Kj-1 = j/y Kj(careful about the kperp=0)
-      IF ( be_2 .NE. 0 ) THEN
-        kernel_e(ijsg_e,ikx,iky) = (real(ijsg_e,dp))/be_2*kernel_e(ijs_e,ikx,iky)
-      ELSE
-        kernel_e(ijsg_e,ikx,iky) = 0._dp
-      ENDIF
-    ENDDO
-  ENDDO
-
-  !!!!! Ion kernels !!!!!
-  factj = 1.0 ! Start of the recursive factorial
-  DO ij = 1, jmaxi+1
-    j_int = jarray_e(ij)
-    j_dp = REAL(j_int,dp) ! REAL of degree
-
-    ! Recursive factorial
-    IF (j_dp .GT. 0) THEN
-      factj = factj * j_dp
-    ELSE
-      factj = 1._dp
-    ENDIF
-
-    DO ikx = ikxs,ikxe
-      kx     = kxarray(ikx)
-      DO iky = ikys,ikye
-        ky    = kyarray(iky)
-        bi_2  =  (kx**2 + ky**2) * sigmai2_taui_o2
-        kernel_i(ij, ikx, iky) = bi_2**j_int * exp(-bi_2)/factj
-
-      ENDDO
-    ENDDO
-  ENDDO
-  ! Kernels closure
-  DO ikx = ikxs,ikxe
-    kx     = kxarray(ikx)
-    DO iky = ikys,ikye
-      ky    = kyarray(iky)
-      bi_2  =  (kx**2 + ky**2) * sigmai2_taui_o2
-      ! Kernel ghost + 1 with Kj+1 = y/(j+1) Kj
-      kernel_i(ijeg_i,ikx,iky) = bi_2/(real(ijeg_i-1,dp))*kernel_i(ije_i,ikx,iky)
-      ! Kernel ghost - 1 with Kj-1 = j/y Kj(careful about the kperp=0)
-      IF ( bi_2 .NE. 0 ) THEN
-        kernel_i(ijsg_i,ikx,iky) = (real(ijsg_i,dp))/bi_2*kernel_i(ijs_i,ikx,iky)
-      ELSE
-        kernel_i(ijsg_i,ikx,iky) = 0._dp
-      ENDIF
-    ENDDO
-  ENDDO
-END SUBROUTINE evaluate_kernels
-!******************************************************************************!
-
-END MODULE numerics